Closed syntesys87 closed 4 months ago
I'll check it as soon as possible, thank you!
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):
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)
Hi, I just updated the code following your hints, let me know if it is ok so we can close this issue
Working! Closing the issue, thank you!
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
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.