diff --git a/homeassistant/components/wiffi/__init__.py b/homeassistant/components/wiffi/__init__.py index c465bc0d2ca..6cf216011f2 100644 --- a/homeassistant/components/wiffi/__init__.py +++ b/homeassistant/components/wiffi/__init__.py @@ -7,26 +7,19 @@ import logging from wiffi import WiffiTcpServer from homeassistant.config_entries import ConfigEntry -from homeassistant.const import CONF_PORT, CONF_TIMEOUT, Platform +from homeassistant.const import CONF_PORT, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.helpers import device_registry as dr -from homeassistant.helpers.device_registry import DeviceInfo -from homeassistant.helpers.dispatcher import ( - async_dispatcher_connect, - async_dispatcher_send, -) -from homeassistant.helpers.entity import Entity +from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval -from homeassistant.util.dt import utcnow from .const import ( CHECK_ENTITIES_SIGNAL, CREATE_ENTITY_SIGNAL, - DEFAULT_TIMEOUT, DOMAIN, UPDATE_ENTITY_SIGNAL, ) +from .entity import generate_unique_id _LOGGER = logging.getLogger(__name__) @@ -78,11 +71,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: return unload_ok -def generate_unique_id(device, metric): - """Generate a unique string for the entity.""" - return f"{device.mac_address.replace(':', '')}-{metric.name}" - - class WiffiIntegrationApi: """API object for wiffi handling. Stored in hass.data.""" @@ -135,78 +123,3 @@ class WiffiIntegrationApi: def _periodic_tick(self, now=None): """Check if any entity has timed out because it has not been updated.""" async_dispatcher_send(self._hass, CHECK_ENTITIES_SIGNAL) - - -class WiffiEntity(Entity): - """Common functionality for all wiffi entities.""" - - _attr_should_poll = False - - def __init__(self, device, metric, options): - """Initialize the base elements of a wiffi entity.""" - self._id = generate_unique_id(device, metric) - self._attr_unique_id = self._id - self._attr_device_info = DeviceInfo( - connections={(dr.CONNECTION_NETWORK_MAC, device.mac_address)}, - identifiers={(DOMAIN, device.mac_address)}, - manufacturer="stall.biz", - model=device.moduletype, - name=f"{device.moduletype} {device.mac_address}", - sw_version=device.sw_version, - configuration_url=device.configuration_url, - ) - self._attr_name = metric.description - self._expiration_date = None - self._value = None - self._timeout = options.get(CONF_TIMEOUT, DEFAULT_TIMEOUT) - - async def async_added_to_hass(self): - """Entity has been added to hass.""" - self.async_on_remove( - async_dispatcher_connect( - self.hass, - f"{UPDATE_ENTITY_SIGNAL}-{self._id}", - self._update_value_callback, - ) - ) - self.async_on_remove( - async_dispatcher_connect( - self.hass, CHECK_ENTITIES_SIGNAL, self._check_expiration_date - ) - ) - - def reset_expiration_date(self): - """Reset value expiration date. - - Will be called by derived classes after a value update has been received. - """ - self._expiration_date = utcnow() + timedelta(minutes=self._timeout) - - @callback - def _update_value_callback(self, device, metric): - """Update the value of the entity.""" - - @callback - def _check_expiration_date(self): - """Periodically check if entity value has been updated. - - If there are no more updates from the wiffi device, the value will be - set to unavailable. - """ - if ( - self._value is not None - and self._expiration_date is not None - and utcnow() > self._expiration_date - ): - self._value = None - self.async_write_ha_state() - - def _is_measurement_entity(self): - """Measurement entities have a value in present time.""" - return ( - not self._attr_name.endswith("_gestern") and not self._is_metered_entity() - ) - - def _is_metered_entity(self): - """Metered entities have a value that keeps increasing until reset.""" - return self._attr_name.endswith("_pro_h") or self._attr_name.endswith("_heute") diff --git a/homeassistant/components/wiffi/binary_sensor.py b/homeassistant/components/wiffi/binary_sensor.py index 80088f373b4..b7431b2555c 100644 --- a/homeassistant/components/wiffi/binary_sensor.py +++ b/homeassistant/components/wiffi/binary_sensor.py @@ -6,8 +6,8 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import WiffiEntity from .const import CREATE_ENTITY_SIGNAL +from .entity import WiffiEntity async def async_setup_entry( diff --git a/homeassistant/components/wiffi/entity.py b/homeassistant/components/wiffi/entity.py new file mode 100644 index 00000000000..fd774c930c8 --- /dev/null +++ b/homeassistant/components/wiffi/entity.py @@ -0,0 +1,93 @@ +"""Component for wiffi support.""" + +from datetime import timedelta + +from homeassistant.const import CONF_TIMEOUT +from homeassistant.core import callback +from homeassistant.helpers import device_registry as dr +from homeassistant.helpers.device_registry import DeviceInfo +from homeassistant.helpers.dispatcher import async_dispatcher_connect +from homeassistant.helpers.entity import Entity +from homeassistant.util.dt import utcnow + +from .const import CHECK_ENTITIES_SIGNAL, DEFAULT_TIMEOUT, DOMAIN, UPDATE_ENTITY_SIGNAL + + +def generate_unique_id(device, metric): + """Generate a unique string for the entity.""" + return f"{device.mac_address.replace(':', '')}-{metric.name}" + + +class WiffiEntity(Entity): + """Common functionality for all wiffi entities.""" + + _attr_should_poll = False + + def __init__(self, device, metric, options): + """Initialize the base elements of a wiffi entity.""" + self._id = generate_unique_id(device, metric) + self._attr_unique_id = self._id + self._attr_device_info = DeviceInfo( + connections={(dr.CONNECTION_NETWORK_MAC, device.mac_address)}, + identifiers={(DOMAIN, device.mac_address)}, + manufacturer="stall.biz", + model=device.moduletype, + name=f"{device.moduletype} {device.mac_address}", + sw_version=device.sw_version, + configuration_url=device.configuration_url, + ) + self._attr_name = metric.description + self._expiration_date = None + self._value = None + self._timeout = options.get(CONF_TIMEOUT, DEFAULT_TIMEOUT) + + async def async_added_to_hass(self): + """Entity has been added to hass.""" + self.async_on_remove( + async_dispatcher_connect( + self.hass, + f"{UPDATE_ENTITY_SIGNAL}-{self._id}", + self._update_value_callback, + ) + ) + self.async_on_remove( + async_dispatcher_connect( + self.hass, CHECK_ENTITIES_SIGNAL, self._check_expiration_date + ) + ) + + def reset_expiration_date(self): + """Reset value expiration date. + + Will be called by derived classes after a value update has been received. + """ + self._expiration_date = utcnow() + timedelta(minutes=self._timeout) + + @callback + def _update_value_callback(self, device, metric): + """Update the value of the entity.""" + + @callback + def _check_expiration_date(self): + """Periodically check if entity value has been updated. + + If there are no more updates from the wiffi device, the value will be + set to unavailable. + """ + if ( + self._value is not None + and self._expiration_date is not None + and utcnow() > self._expiration_date + ): + self._value = None + self.async_write_ha_state() + + def _is_measurement_entity(self): + """Measurement entities have a value in present time.""" + return ( + not self._attr_name.endswith("_gestern") and not self._is_metered_entity() + ) + + def _is_metered_entity(self): + """Metered entities have a value that keeps increasing until reset.""" + return self._attr_name.endswith("_pro_h") or self._attr_name.endswith("_heute") diff --git a/homeassistant/components/wiffi/sensor.py b/homeassistant/components/wiffi/sensor.py index cf8cf8719c3..699a760685a 100644 --- a/homeassistant/components/wiffi/sensor.py +++ b/homeassistant/components/wiffi/sensor.py @@ -11,8 +11,8 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import WiffiEntity from .const import CREATE_ENTITY_SIGNAL +from .entity import WiffiEntity from .wiffi_strings import ( WIFFI_UOM_DEGREE, WIFFI_UOM_LUX,