diff --git a/.coveragerc b/.coveragerc index bcd3b80b812..6f286fc6a69 100644 --- a/.coveragerc +++ b/.coveragerc @@ -171,6 +171,8 @@ omit = homeassistant/components/devolo_home_control/binary_sensor.py homeassistant/components/devolo_home_control/const.py homeassistant/components/devolo_home_control/devolo_device.py + homeassistant/components/devolo_home_control/devolo_multi_level_switch.py + homeassistant/components/devolo_home_control/light.py homeassistant/components/devolo_home_control/sensor.py homeassistant/components/devolo_home_control/subscriber.py homeassistant/components/devolo_home_control/switch.py diff --git a/homeassistant/components/devolo_home_control/const.py b/homeassistant/components/devolo_home_control/const.py index 599e44fe8f0..60923235916 100644 --- a/homeassistant/components/devolo_home_control/const.py +++ b/homeassistant/components/devolo_home_control/const.py @@ -3,6 +3,6 @@ DOMAIN = "devolo_home_control" DEFAULT_MYDEVOLO = "https://www.mydevolo.com" DEFAULT_MPRM = "https://homecontrol.mydevolo.com" -PLATFORMS = ["binary_sensor", "sensor", "switch"] +PLATFORMS = ["binary_sensor", "light", "sensor", "switch"] CONF_MYDEVOLO = "mydevolo_url" CONF_HOMECONTROL = "home_control_url" diff --git a/homeassistant/components/devolo_home_control/devolo_multi_level_switch.py b/homeassistant/components/devolo_home_control/devolo_multi_level_switch.py new file mode 100644 index 00000000000..897899e725c --- /dev/null +++ b/homeassistant/components/devolo_home_control/devolo_multi_level_switch.py @@ -0,0 +1,35 @@ +"""Base class for multi level switches in devolo Home Control.""" +import logging + +from .devolo_device import DevoloDeviceEntity + +_LOGGER = logging.getLogger(__name__) + + +class DevoloMultiLevelSwitchDeviceEntity(DevoloDeviceEntity): + """Representation of a multi level switch device within devolo Home Control. Something like a dimmer or a thermostat.""" + + def __init__(self, homecontrol, device_instance, element_uid): + """Initialize a multi level switch within devolo Home Control.""" + super().__init__( + homecontrol=homecontrol, + device_instance=device_instance, + element_uid=element_uid, + name=f"{device_instance.itemName}", + sync=self._sync, + ) + self._multi_level_switch_property = device_instance.multi_level_switch_property[ + element_uid + ] + + self._value = self._multi_level_switch_property.value + + def _sync(self, message): + """Update the multi level switch state.""" + if message[0] == self._multi_level_switch_property.element_uid: + self._value = message[1] + elif message[0].startswith("hdm"): + self._available = self._device_instance.is_online() + else: + _LOGGER.debug("No valid message received: %s", message) + self.schedule_update_ha_state() diff --git a/homeassistant/components/devolo_home_control/light.py b/homeassistant/components/devolo_home_control/light.py new file mode 100644 index 00000000000..c2f678425be --- /dev/null +++ b/homeassistant/components/devolo_home_control/light.py @@ -0,0 +1,80 @@ +"""Platform for light integration.""" +from homeassistant.components.light import ( + ATTR_BRIGHTNESS, + SUPPORT_BRIGHTNESS, + LightEntity, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.helpers.typing import HomeAssistantType + +from .const import DOMAIN +from .devolo_multi_level_switch import DevoloMultiLevelSwitchDeviceEntity + + +async def async_setup_entry( + hass: HomeAssistantType, entry: ConfigEntry, async_add_entities +) -> None: + """Get all light devices and setup them via config entry.""" + entities = [] + + for device in hass.data[DOMAIN]["homecontrol"].multi_level_switch_devices: + for multi_level_switch in device.multi_level_switch_property.values(): + if multi_level_switch.switch_type == "dimmer": + entities.append( + DevoloLightDeviceEntity( + homecontrol=hass.data[DOMAIN]["homecontrol"], + device_instance=device, + element_uid=multi_level_switch.element_uid, + ) + ) + + async_add_entities(entities, False) + + +class DevoloLightDeviceEntity(DevoloMultiLevelSwitchDeviceEntity, LightEntity): + """Representation of a light within devolo Home Control.""" + + def __init__(self, homecontrol, device_instance, element_uid): + """Initialize a devolo multi level switch.""" + super().__init__( + homecontrol=homecontrol, + device_instance=device_instance, + element_uid=element_uid, + ) + + self._binary_switch_property = device_instance.binary_switch_property.get( + element_uid.replace("Dimmer", "BinarySwitch") + ) + + @property + def brightness(self): + """Return the brightness value of the light.""" + return round(self._value / 100 * 255) + + @property + def is_on(self): + """Return the state of the light.""" + return bool(self._value) + + @property + def supported_features(self): + """Return the supported features.""" + return SUPPORT_BRIGHTNESS + + def turn_on(self, **kwargs) -> None: + """Turn device on.""" + if kwargs.get(ATTR_BRIGHTNESS) is not None: + self._multi_level_switch_property.set( + round(kwargs[ATTR_BRIGHTNESS] / 255 * 100) + ) + else: + if self._binary_switch_property is not None: + # Turn on the light device to the latest known value. The value is known by the device itself. + self._binary_switch_property.set(True) + else: + # If there is no binary switch attached to the device, turn it on to 100 %. + self._multi_level_switch_property.set(100) + + def turn_off(self, **kwargs) -> None: + """Turn device off.""" + self._multi_level_switch_property.set(0) diff --git a/homeassistant/components/devolo_home_control/switch.py b/homeassistant/components/devolo_home_control/switch.py index e70474a8d5d..d14b6c059de 100644 --- a/homeassistant/components/devolo_home_control/switch.py +++ b/homeassistant/components/devolo_home_control/switch.py @@ -19,13 +19,15 @@ async def async_setup_entry( entities = [] for device in devices: for binary_switch in device.binary_switch_property: - entities.append( - DevoloSwitch( - homecontrol=hass.data[DOMAIN]["homecontrol"], - device_instance=device, - element_uid=binary_switch, + # Exclude the binary switch which have also a multi_level_switches here, because they are implemented as light devices now. + if not hasattr(device, "multi_level_switch_property"): + entities.append( + DevoloSwitch( + homecontrol=hass.data[DOMAIN]["homecontrol"], + device_instance=device, + element_uid=binary_switch, + ) ) - ) async_add_entities(entities)