Use shorthand attributes in Home connect (#99385)

Co-authored-by: Robert Resch <robert@resch.dev>
pull/99236/head
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:
"""Initialize the entity."""
self.device = device
self.desc = desc
self._name = f"{self.device.appliance.name} {desc}"
self._attr_name = f"{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):
"""Register callbacks."""
@ -38,26 +44,6 @@ class HomeConnectEntity(Entity):
if ha_id == self.device.appliance.haId:
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
def async_entity_update(self):
"""Update the entity."""

View File

@ -59,11 +59,8 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
def __init__(self, device, desc, ambient):
"""Initialize the entity."""
super().__init__(device, desc)
self._state = None
self._brightness = None
self._hs_color = None
self._ambient = ambient
if self._ambient:
if ambient:
self._brightness_key = BSH_AMBIENT_LIGHT_BRIGHTNESS
self._key = BSH_AMBIENT_LIGHT_ENABLED
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_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:
"""Switch the light on, change brightness, change color."""
if self._ambient:
@ -113,12 +95,12 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
)
except HomeConnectError as err:
_LOGGER.error("Error while trying selecting customcolor: %s", err)
if self._brightness is not None:
brightness = 10 + ceil(self._brightness / 255 * 90)
if self._attr_brightness is not None:
brightness = 10 + ceil(self._attr_brightness / 255 * 90)
if ATTR_BRIGHTNESS in kwargs:
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:
rgb = color_util.color_hsv_to_RGB(
@ -170,32 +152,34 @@ class HomeConnectLight(HomeConnectEntity, LightEntity):
async def async_update(self) -> None:
"""Update the light's status."""
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:
self._state = False
self._attr_is_on = False
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:
color = self.device.appliance.status.get(self._custom_color_key, {})
if not color:
self._hs_color = None
self._brightness = None
self._attr_hs_color = None
self._attr_brightness = None
else:
colorvalue = color.get(ATTR_VALUE)[1:]
rgb = color_util.rgb_hex_to_rgb_list(colorvalue)
hsv = color_util.color_RGB_to_hsv(rgb[0], rgb[1], rgb[2])
self._hs_color = [hsv[0], hsv[1]]
self._brightness = ceil((hsv[2] - 10) * 255 / 90)
_LOGGER.debug("Updated, new brightness: %s", self._brightness)
self._attr_hs_color = (hsv[0], hsv[1])
self._attr_brightness = ceil((hsv[2] - 10) * 255 / 90)
_LOGGER.debug("Updated, new brightness: %s", self._attr_brightness)
else:
brightness = self.device.appliance.status.get(self._brightness_key, {})
if brightness is None:
self._brightness = None
self._attr_brightness = None
else:
self._brightness = ceil((brightness.get(ATTR_VALUE) - 10) * 255 / 90)
_LOGGER.debug("Updated, new brightness: %s", self._brightness)
self._attr_brightness = ceil(
(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."""
from datetime import timedelta
from datetime import datetime, timedelta
import logging
from typing import cast
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
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):
"""Initialize the entity."""
super().__init__(device, desc)
self._state = None
self._key = key
self._unit = unit
self._icon = icon
self._device_class = device_class
self._sign = sign
@property
def native_value(self):
"""Return sensor value."""
return self._state
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._state is not None
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._state = None
self._attr_native_value = None
elif self.device_class == SensorDeviceClass.TIMESTAMP:
if ATTR_VALUE not in status[self._key]:
self._state = None
self._attr_native_value = None
elif (
self._state is not None
self._attr_native_value is not None
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
# already past it, set state to None.
self._state = None
self._attr_native_value = None
else:
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:
self._state = status[self._key].get(ATTR_VALUE)
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._state = self._state.split(".")[-1]
_LOGGER.debug("Updated, new state: %s", self._state)
@property
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
self._attr_native_value = cast(str, self._attr_native_value).split(".")[
-1
]
_LOGGER.debug("Updated, new state: %s", self._attr_native_value)

View File

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