* fix remaining progress time for home connect component The home connect API is sending some default values (on dishwashers) for the remaining progress time after the program finished. This is a problem because this value is stored and on every API event, for example opening the door of a dishwasher, the value for remaining progress time is updated with this wrong value. So I see a wrong value the whole time the dishwasher is not running and therefore has no remaining progress time. This coming fixes this problem and adds a check if the appliance is in running, pause or finished state, because there we have valid data. In the other states the new code just returns none like on other edge cases. Now there is no value if there is no program running. * fix some formating according to the ruff rules * fix some formating according to the ruff rules again * fix alphabetic order of imports * add check if keys exist in dict before accessing them check if BSH_OPERATION_STATE and ATTR_VALUE key values exist before accessing them later in the elif statement * fix formating because forgotten local ruff run
102 lines
3.8 KiB
Python
102 lines
3.8 KiB
Python
"""Provides a sensor for Home Connect."""
|
|
from datetime import datetime, timedelta
|
|
import logging
|
|
from typing import cast
|
|
|
|
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
|
from homeassistant.config_entries import ConfigEntry
|
|
from homeassistant.const import CONF_ENTITIES
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
import homeassistant.util.dt as dt_util
|
|
|
|
from .const import (
|
|
ATTR_VALUE,
|
|
BSH_OPERATION_STATE,
|
|
BSH_OPERATION_STATE_FINISHED,
|
|
BSH_OPERATION_STATE_PAUSE,
|
|
BSH_OPERATION_STATE_RUN,
|
|
DOMAIN,
|
|
)
|
|
from .entity import HomeConnectEntity
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
async def async_setup_entry(
|
|
hass: HomeAssistant,
|
|
config_entry: ConfigEntry,
|
|
async_add_entities: AddEntitiesCallback,
|
|
) -> None:
|
|
"""Set up the Home Connect sensor."""
|
|
|
|
def get_entities():
|
|
"""Get a list of entities."""
|
|
entities = []
|
|
hc_api = hass.data[DOMAIN][config_entry.entry_id]
|
|
for device_dict in hc_api.devices:
|
|
entity_dicts = device_dict.get(CONF_ENTITIES, {}).get("sensor", [])
|
|
entities += [HomeConnectSensor(**d) for d in entity_dicts]
|
|
return entities
|
|
|
|
async_add_entities(await hass.async_add_executor_job(get_entities), True)
|
|
|
|
|
|
class HomeConnectSensor(HomeConnectEntity, SensorEntity):
|
|
"""Sensor class for Home Connect."""
|
|
|
|
def __init__(self, device, desc, key, unit, icon, device_class, sign=1):
|
|
"""Initialize the entity."""
|
|
super().__init__(device, desc)
|
|
self._key = key
|
|
self._sign = sign
|
|
self._attr_native_unit_of_measurement = unit
|
|
self._attr_icon = icon
|
|
self._attr_device_class = device_class
|
|
|
|
@property
|
|
def available(self) -> bool:
|
|
"""Return true if the sensor is available."""
|
|
return self._attr_native_value is not None
|
|
|
|
async def async_update(self) -> None:
|
|
"""Update the sensor's status."""
|
|
status = self.device.appliance.status
|
|
if self._key not in status:
|
|
self._attr_native_value = None
|
|
elif self.device_class == SensorDeviceClass.TIMESTAMP:
|
|
if ATTR_VALUE not in status[self._key]:
|
|
self._attr_native_value = None
|
|
elif (
|
|
self._attr_native_value is not None
|
|
and self._sign == 1
|
|
and isinstance(self._attr_native_value, datetime)
|
|
and self._attr_native_value < dt_util.utcnow()
|
|
):
|
|
# if the date is supposed to be in the future but we're
|
|
# already past it, set state to None.
|
|
self._attr_native_value = None
|
|
elif (
|
|
BSH_OPERATION_STATE in status
|
|
and ATTR_VALUE in status[BSH_OPERATION_STATE]
|
|
and status[BSH_OPERATION_STATE][ATTR_VALUE]
|
|
in [
|
|
BSH_OPERATION_STATE_RUN,
|
|
BSH_OPERATION_STATE_PAUSE,
|
|
BSH_OPERATION_STATE_FINISHED,
|
|
]
|
|
):
|
|
seconds = self._sign * float(status[self._key][ATTR_VALUE])
|
|
self._attr_native_value = dt_util.utcnow() + timedelta(seconds=seconds)
|
|
else:
|
|
self._attr_native_value = None
|
|
else:
|
|
self._attr_native_value = status[self._key].get(ATTR_VALUE)
|
|
if self._key == BSH_OPERATION_STATE:
|
|
# Value comes back as an enum, we only really care about the
|
|
# last part, so split it off
|
|
# https://developer.home-connect.com/docs/status/operation_state
|
|
self._attr_native_value = cast(str, self._attr_native_value).split(".")[
|
|
-1
|
|
]
|
|
_LOGGER.debug("Updated, new state: %s", self._attr_native_value)
|