gcarmix / azzurrozcs

Azzurro ZCS Solar Inverter Integration for Home Assistant
10 stars 3 forks source link

Deprecation warning on load component with Home Assistant 2024.1.6 #5

Closed syntesys87 closed 4 months ago

syntesys87 commented 7 months ago

Hello,

I see this warning on the HomeAssistant log: DEVICE_CLASS_ENERGY was used from azzurrozcs, this is a deprecated constant which will be removed in HA Core 2025.1. Use SensorDeviceClass.ENERGY instead, please create a bug report at https://github.com/gcarmix/azzurrozcs

STATE_CLASS_MEASUREMENT was used from azzurrozcs, this is a deprecated constant which will be removed in HA Core 2025.1. Use SensorStateClass.MEASUREMENT instead, please create a bug report at https://github.com/gcarmix/azzurrozcs

Could you please verify it?

Thank you.

gcarmix commented 7 months ago

I'll check it as soon as possible, thank you!

syntesys87 commented 4 months ago

I modified the code but I don't know how to do a pull request... This is the working code:

from future import annotations import re from inspect import signature from datetime import timedelta import logging

import voluptuous as vol from homeassistant.components.rest.data import RestData from requests.auth import HTTPBasicAuth from homeassistant.components.sensor import SensorDeviceClass from homeassistant.components.sensor import SensorStateClass from homeassistant.components.sensor import ( PLATFORM_SCHEMA, SensorEntity, ) from homeassistant.const import UnitOfEnergy from homeassistant.const import ( ATTR_DATE, ATTR_TEMPERATURE, ATTR_TIME, CONF_NAME, ) from homeassistant.core import callback import homeassistant.helpers.config_validation as cv

import json

_LOGGER = logging.getLogger(name)

CONF_IP_ADDR = "ip_address" CONF_USERNAME = "username" CONF_PASSWORD = "password"

DEFAULT_NAME = "azzurrozcs" DEFAULT_VERIFY_SSL = False

SCAN_INTERVAL = timedelta(minutes=2)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required(CONF_IP_ADDR): cv.string, vol.Required(CONF_USERNAME): cv.string, vol.Required(CONF_PASSWORD): cv.string, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, } )

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):

Azzurro ZCS Setup

name = config.get(CONF_NAME)
zcs_username = config.get(CONF_USERNAME)
zcs_password = config.get(CONF_PASSWORD)
zcs_address = "http://" + config.get(CONF_IP_ADDR) + "/status.html"
method = "GET"
auth = HTTPBasicAuth(zcs_username, zcs_password)
verify_ssl = DEFAULT_VERIFY_SSL
timeout = 60
headers = None

_LOGGER.info("method: %s", method)

sig = signature(RestData)
if len(sig.parameters) == 11:
    #for compatibility with Home Assistant 2023.5
    rest = RestData(hass, method, zcs_address,'utf-8', auth, headers, None, None, verify_ssl, "python_default", timeout)
elif len(sig.parameters) == 10:    
    #for compatibility with Home Assistant 2023
    rest = RestData(hass, method, zcs_address,'utf-8', auth, headers, None, None, verify_ssl, timeout)
else:
    rest = RestData(hass, method, zcs_address, auth, headers, None, None, verify_ssl, timeout)

await rest.async_update()

if rest.data is None:
    _LOGGER.error("Unable to start fetching data from Azzurro ZCS")
    # return False

async_add_entities([ZCSSensor(rest, name)],update_before_add=True)

class ZCSSensor(SensorEntity): """Representation of a ZCSAzzurro sensor."""

_attr_state_class = SensorStateClass.MEASUREMENT
_attr_device_class = SensorDeviceClass.ENERGY
_attr_native_unit_of_measurement = UnitOfEnergy.WATT_HOUR

def __init__(self, rest, name):
    """Initialize a ZCSAzzurro sensor."""
    self.rest = rest
    self.req_retries = 0
    self._attr_name = name
    self._attributes = None
    self.zcs_sensor = {}
    self._state = False

@property
def state(self):
    """Return the state of the device."""
    value = self._state
    _LOGGER.info("Return the state: %s", value)
    return value

@property
def extra_state_attributes(self):
    """Return the state attributes of the monitored installation."""
    if self.zcs_sensor is not None:
        _LOGGER.info("Return the state attributes")

        try: power_now = self.zcs_sensor["power_now"]
        except: power_now = 0
        try: energy_today = self.zcs_sensor["energy_today"]
        except: energy_today = 0
        try: energy_total = self.zcs_sensor["energy_total"]
        except: energy_total = 0
        _LOGGER.info("Power_now = " + str(power_now))
        return {"power_now": power_now,"energy_today":energy_today,"energy_total":energy_total}

async def async_update(self):
    await self.rest.async_update()
    self._async_update_from_rest_data()

async def async_added_to_hass(self):
    """Ensure the data from the initial update is reflected in the state."""
    self._async_update_from_rest_data()

@callback
def _async_update_from_rest_data(self):
    """Update state from the rest data."""
    _LOGGER.info("ZCS Rest response")
    try:
        rest_data = self.rest.data
        if rest_data is not None:
            self.req_retries = 0
            self._state = True
            for line in rest_data.splitlines():
                if("var webdata_now_p" in line):
                    self.zcs_sensor["power_now"] = float(re.search(r'\"(.*?)\"',line).group(1))
                    _LOGGER.info(self.zcs_sensor["power_now"])
                if("var webdata_today_e" in line):
                    self.zcs_sensor["energy_today"] = float(re.search(r'\"(.*?)\"',line).group(1))
                    _LOGGER.info(self.zcs_sensor["energy_today"])
                if("var webdata_total_e" in line):
                    self.zcs_sensor["energy_total"] = float(re.search(r'\"(.*?)\"',line).group(1))
                    _LOGGER.info(self.zcs_sensor["energy_total"])
        else:
            _LOGGER.warning("Empty reply")
            if(self.req_retries < 5):
                self.req_retries += 1
            else:
                self.zcs_sensor["power_now"] = 0.0
                self._state = False

    except TypeError:
        _LOGGER.warning("REST result not valid")
        _LOGGER.info("Erroneous data: %s", rest_data)
gcarmix commented 4 months ago

Hi, I just updated the code following your hints, let me know if it is ok so we can close this issue

syntesys87 commented 4 months ago

Working! Closing the issue, thank you!

Ocramius commented 1 month ago

Runing this with HA 2024.6, I get:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1264, in _load_platform
    cache[full_name] = self._import_platform(platform_name)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/loader.py", line 1296, in _import_platform
    return importlib.import_module(f"{self.pkg_path}.{platform_name}")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/util/loop.py", line 200, in protected_loop_func
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/config/custom_components/azzurrozcs/sensor.py", line 83, in <module>
    class ZCSSensor(SensorEntity):
  File "/config/custom_components/azzurrozcs/sensor.py", line 88, in ZCSSensor
    _attr_native_unit_of_measurement = UnitOfEnergy.ENERGY_WATT_HOUR
                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'UnitOfEnergy' has no attribute 'ENERGY_WATT_HOUR'. Did you mean: 'MEGA_WATT_HOUR'?

I think we want to use WATT_HOUR: https://github.com/home-assistant/core/blob/799888df2fc491dcb09c6a2ef111c88393451c5f/homeassistant/const.py#L688

More stuff kinda breaks when switching to WATT_HOUR:

Entity sensor.zcs_azzurro_1_energy_today (<class 'homeassistant.components.template.sensor.SensorTemplate'>) is using state class 'measurement' which is impossible considering device class ('energy') it is using; expected None or one of 'total_increasing', 'total'; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+template%22
Entity sensor.zcs_azzurro_1_energy_total (<class 'homeassistant.components.template.sensor.SensorTemplate'>) is using state class 'measurement' which is impossible considering device class ('energy') it is using; expected None or one of 'total_increasing', 'total'; Please update your configuration if your entity is manually configured, otherwise create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue+label%3A%22integration%3A+template%22