Use shorthand attributes in Home connect (#99385)

Co-authored-by: Robert Resch <robert@resch.dev>
This commit is contained in:
Joost Lekkerkerker 2023-09-04 09:15:25 +02:00 committed by GitHub
parent f4f98010f9
commit 13ebb68b84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 115 deletions

View File

@ -21,8 +21,14 @@ class HomeConnectEntity(Entity):
def __init__(self, device: HomeConnectDevice, desc: str) -> None: def __init__(self, device: HomeConnectDevice, desc: str) -> None:
"""Initialize the entity.""" """Initialize the entity."""
self.device = device self.device = device
self.desc = desc self._attr_name = f"{device.appliance.name} {desc}"
self._name = f"{self.device.appliance.name} {desc}" self._attr_unique_id = f"{device.appliance.haId}-{desc}"
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device.appliance.haId)},
manufacturer=device.appliance.brand,
model=device.appliance.vib,
name=device.appliance.name,
)
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Register callbacks.""" """Register callbacks."""
@ -38,26 +44,6 @@ class HomeConnectEntity(Entity):
if ha_id == self.device.appliance.haId: if ha_id == self.device.appliance.haId:
self.async_entity_update() self.async_entity_update()
@property
def name(self):
"""Return the name of the node (used for Entity_ID)."""
return self._name
@property
def unique_id(self):
"""Return the unique id base on the id returned by Home Connect and the entity name."""
return f"{self.device.appliance.haId}-{self.desc}"
@property
def device_info(self) -> DeviceInfo:
"""Return info about the device."""
return DeviceInfo(
identifiers={(DOMAIN, self.device.appliance.haId)},
manufacturer=self.device.appliance.brand,
model=self.device.appliance.vib,
name=self.device.appliance.name,
)
@callback @callback
def async_entity_update(self): def async_entity_update(self):
"""Update the entity.""" """Update the entity."""

View File

@ -59,11 +59,8 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
def __init__(self, device, desc, ambient): def __init__(self, device, desc, ambient):
"""Initialize the entity.""" """Initialize the entity."""
super().__init__(device, desc) super().__init__(device, desc)
self._state = None
self._brightness = None
self._hs_color = None
self._ambient = ambient self._ambient = ambient
if self._ambient: if ambient:
self._brightness_key = BSH_AMBIENT_LIGHT_BRIGHTNESS self._brightness_key = BSH_AMBIENT_LIGHT_BRIGHTNESS
self._key = BSH_AMBIENT_LIGHT_ENABLED self._key = BSH_AMBIENT_LIGHT_ENABLED
self._custom_color_key = BSH_AMBIENT_LIGHT_CUSTOM_COLOR self._custom_color_key = BSH_AMBIENT_LIGHT_CUSTOM_COLOR
@ -78,21 +75,6 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
self._attr_color_mode = ColorMode.BRIGHTNESS self._attr_color_mode = ColorMode.BRIGHTNESS
self._attr_supported_color_modes = {ColorMode.BRIGHTNESS} self._attr_supported_color_modes = {ColorMode.BRIGHTNESS}
@property
def is_on(self):
"""Return true if the light is on."""
return bool(self._state)
@property
def brightness(self):
"""Return the brightness of the light."""
return self._brightness
@property
def hs_color(self):
"""Return the color property."""
return self._hs_color
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Switch the light on, change brightness, change color.""" """Switch the light on, change brightness, change color."""
if self._ambient: if self._ambient:
@ -113,12 +95,12 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
) )
except HomeConnectError as err: except HomeConnectError as err:
_LOGGER.error("Error while trying selecting customcolor: %s", err) _LOGGER.error("Error while trying selecting customcolor: %s", err)
if self._brightness is not None: if self._attr_brightness is not None:
brightness = 10 + ceil(self._brightness / 255 * 90) brightness = 10 + ceil(self._attr_brightness / 255 * 90)
if ATTR_BRIGHTNESS in kwargs: if ATTR_BRIGHTNESS in kwargs:
brightness = 10 + ceil(kwargs[ATTR_BRIGHTNESS] / 255 * 90) brightness = 10 + ceil(kwargs[ATTR_BRIGHTNESS] / 255 * 90)
hs_color = kwargs.get(ATTR_HS_COLOR, self._hs_color) hs_color = kwargs.get(ATTR_HS_COLOR, self._attr_hs_color)
if hs_color is not None: if hs_color is not None:
rgb = color_util.color_hsv_to_RGB( rgb = color_util.color_hsv_to_RGB(
@ -170,32 +152,34 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update the light's status.""" """Update the light's status."""
if self.device.appliance.status.get(self._key, {}).get(ATTR_VALUE) is True: if self.device.appliance.status.get(self._key, {}).get(ATTR_VALUE) is True:
self._state = True self._attr_is_on = True
elif self.device.appliance.status.get(self._key, {}).get(ATTR_VALUE) is False: elif self.device.appliance.status.get(self._key, {}).get(ATTR_VALUE) is False:
self._state = False self._attr_is_on = False
else: else:
self._state = None self._attr_is_on = None
_LOGGER.debug("Updated, new light state: %s", self._state) _LOGGER.debug("Updated, new light state: %s", self._attr_is_on)
if self._ambient: if self._ambient:
color = self.device.appliance.status.get(self._custom_color_key, {}) color = self.device.appliance.status.get(self._custom_color_key, {})
if not color: if not color:
self._hs_color = None self._attr_hs_color = None
self._brightness = None self._attr_brightness = None
else: else:
colorvalue = color.get(ATTR_VALUE)[1:] colorvalue = color.get(ATTR_VALUE)[1:]
rgb = color_util.rgb_hex_to_rgb_list(colorvalue) rgb = color_util.rgb_hex_to_rgb_list(colorvalue)
hsv = color_util.color_RGB_to_hsv(rgb[0], rgb[1], rgb[2]) hsv = color_util.color_RGB_to_hsv(rgb[0], rgb[1], rgb[2])
self._hs_color = [hsv[0], hsv[1]] self._attr_hs_color = (hsv[0], hsv[1])
self._brightness = ceil((hsv[2] - 10) * 255 / 90) self._attr_brightness = ceil((hsv[2] - 10) * 255 / 90)
_LOGGER.debug("Updated, new brightness: %s", self._brightness) _LOGGER.debug("Updated, new brightness: %s", self._attr_brightness)
else: else:
brightness = self.device.appliance.status.get(self._brightness_key, {}) brightness = self.device.appliance.status.get(self._brightness_key, {})
if brightness is None: if brightness is None:
self._brightness = None self._attr_brightness = None
else: else:
self._brightness = ceil((brightness.get(ATTR_VALUE) - 10) * 255 / 90) self._attr_brightness = ceil(
_LOGGER.debug("Updated, new brightness: %s", self._brightness) (brightness.get(ATTR_VALUE) - 10) * 255 / 90
)
_LOGGER.debug("Updated, new brightness: %s", self._attr_brightness)

View File

@ -1,6 +1,7 @@
"""Provides a sensor for Home Connect.""" """Provides a sensor for Home Connect."""
from datetime import timedelta from datetime import datetime, timedelta
import logging import logging
from typing import cast
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -40,62 +41,44 @@ class HomeConnectSensor(HomeConnectEntity, SensorEntity):
def __init__(self, device, desc, key, unit, icon, device_class, sign=1): def __init__(self, device, desc, key, unit, icon, device_class, sign=1):
"""Initialize the entity.""" """Initialize the entity."""
super().__init__(device, desc) super().__init__(device, desc)
self._state = None
self._key = key self._key = key
self._unit = unit
self._icon = icon
self._device_class = device_class
self._sign = sign self._sign = sign
self._attr_native_unit_of_measurement = unit
@property self._attr_icon = icon
def native_value(self): self._attr_device_class = device_class
"""Return sensor value."""
return self._state
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return true if the sensor is available.""" """Return true if the sensor is available."""
return self._state is not None return self._attr_native_value is not None
async def async_update(self) -> None: async def async_update(self) -> None:
"""Update the sensor's status.""" """Update the sensor's status."""
status = self.device.appliance.status status = self.device.appliance.status
if self._key not in status: if self._key not in status:
self._state = None self._attr_native_value = None
elif self.device_class == SensorDeviceClass.TIMESTAMP: elif self.device_class == SensorDeviceClass.TIMESTAMP:
if ATTR_VALUE not in status[self._key]: if ATTR_VALUE not in status[self._key]:
self._state = None self._attr_native_value = None
elif ( elif (
self._state is not None self._attr_native_value is not None
and self._sign == 1 and self._sign == 1
and self._state < dt_util.utcnow() 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 # if the date is supposed to be in the future but we're
# already past it, set state to None. # already past it, set state to None.
self._state = None self._attr_native_value = None
else: else:
seconds = self._sign * float(status[self._key][ATTR_VALUE]) seconds = self._sign * float(status[self._key][ATTR_VALUE])
self._state = dt_util.utcnow() + timedelta(seconds=seconds) self._attr_native_value = dt_util.utcnow() + timedelta(seconds=seconds)
else: else:
self._state = status[self._key].get(ATTR_VALUE) self._attr_native_value = status[self._key].get(ATTR_VALUE)
if self._key == BSH_OPERATION_STATE: if self._key == BSH_OPERATION_STATE:
# Value comes back as an enum, we only really care about the # Value comes back as an enum, we only really care about the
# last part, so split it off # last part, so split it off
# https://developer.home-connect.com/docs/status/operation_state # https://developer.home-connect.com/docs/status/operation_state
self._state = self._state.split(".")[-1] self._attr_native_value = cast(str, self._attr_native_value).split(".")[
_LOGGER.debug("Updated, new state: %s", self._state) -1
]
@property _LOGGER.debug("Updated, new state: %s", self._attr_native_value)
def native_unit_of_measurement(self):
"""Return the unit of measurement."""
return self._unit
@property
def icon(self):
"""Return the icon."""
return self._icon
@property
def device_class(self):
"""Return the device class."""
return self._device_class

View File

@ -56,13 +56,6 @@ class HomeConnectProgramSwitch(HomeConnectEntity, SwitchEntity):
) )
super().__init__(device, desc) super().__init__(device, desc)
self.program_name = program_name self.program_name = program_name
self._state = None
self._remote_allowed = None
@property
def is_on(self):
"""Return true if the switch is on."""
return bool(self._state)
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Start the program.""" """Start the program."""
@ -88,10 +81,10 @@ class HomeConnectProgramSwitch(HomeConnectEntity, SwitchEntity):
"""Update the switch's status.""" """Update the switch's status."""
state = self.device.appliance.status.get(BSH_ACTIVE_PROGRAM, {}) state = self.device.appliance.status.get(BSH_ACTIVE_PROGRAM, {})
if state.get(ATTR_VALUE) == self.program_name: if state.get(ATTR_VALUE) == self.program_name:
self._state = True self._attr_is_on = True
else: else:
self._state = False self._attr_is_on = False
_LOGGER.debug("Updated, new state: %s", self._state) _LOGGER.debug("Updated, new state: %s", self._attr_is_on)
class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity): class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
@ -100,12 +93,6 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
def __init__(self, device): def __init__(self, device):
"""Inititialize the entity.""" """Inititialize the entity."""
super().__init__(device, "Power") super().__init__(device, "Power")
self._state = None
@property
def is_on(self):
"""Return true if the switch is on."""
return bool(self._state)
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Switch the device on.""" """Switch the device on."""
@ -116,7 +103,7 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
) )
except HomeConnectError as err: except HomeConnectError as err:
_LOGGER.error("Error while trying to turn on device: %s", err) _LOGGER.error("Error while trying to turn on device: %s", err)
self._state = False self._attr_is_on = False
self.async_entity_update() self.async_entity_update()
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
@ -130,7 +117,7 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
) )
except HomeConnectError as err: except HomeConnectError as err:
_LOGGER.error("Error while trying to turn off device: %s", err) _LOGGER.error("Error while trying to turn off device: %s", err)
self._state = True self._attr_is_on = True
self.async_entity_update() self.async_entity_update()
async def async_update(self) -> None: async def async_update(self) -> None:
@ -139,12 +126,12 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
self.device.appliance.status.get(BSH_POWER_STATE, {}).get(ATTR_VALUE) self.device.appliance.status.get(BSH_POWER_STATE, {}).get(ATTR_VALUE)
== BSH_POWER_ON == BSH_POWER_ON
): ):
self._state = True self._attr_is_on = True
elif ( elif (
self.device.appliance.status.get(BSH_POWER_STATE, {}).get(ATTR_VALUE) self.device.appliance.status.get(BSH_POWER_STATE, {}).get(ATTR_VALUE)
== self.device.power_off_state == self.device.power_off_state
): ):
self._state = False self._attr_is_on = False
elif self.device.appliance.status.get(BSH_OPERATION_STATE, {}).get( elif self.device.appliance.status.get(BSH_OPERATION_STATE, {}).get(
ATTR_VALUE, None ATTR_VALUE, None
) in [ ) in [
@ -156,12 +143,12 @@ class HomeConnectPowerSwitch(HomeConnectEntity, SwitchEntity):
"BSH.Common.EnumType.OperationState.Aborting", "BSH.Common.EnumType.OperationState.Aborting",
"BSH.Common.EnumType.OperationState.Finished", "BSH.Common.EnumType.OperationState.Finished",
]: ]:
self._state = True self._attr_is_on = True
elif ( elif (
self.device.appliance.status.get(BSH_OPERATION_STATE, {}).get(ATTR_VALUE) self.device.appliance.status.get(BSH_OPERATION_STATE, {}).get(ATTR_VALUE)
== "BSH.Common.EnumType.OperationState.Inactive" == "BSH.Common.EnumType.OperationState.Inactive"
): ):
self._state = False self._attr_is_on = False
else: else:
self._state = None self._attr_is_on = None
_LOGGER.debug("Updated, new state: %s", self._state) _LOGGER.debug("Updated, new state: %s", self._attr_is_on)