diff --git a/.coveragerc b/.coveragerc index 2443e30a2c3..f12d1ce88fa 100644 --- a/.coveragerc +++ b/.coveragerc @@ -276,6 +276,7 @@ omit = homeassistant/components/elmax/__init__.py homeassistant/components/elmax/common.py homeassistant/components/elmax/const.py + homeassistant/components/elmax/binary_sensor.py homeassistant/components/elmax/switch.py homeassistant/components/elv/* homeassistant/components/emby/media_player.py diff --git a/homeassistant/components/elmax/binary_sensor.py b/homeassistant/components/elmax/binary_sensor.py new file mode 100644 index 00000000000..71588b4687f --- /dev/null +++ b/homeassistant/components/elmax/binary_sensor.py @@ -0,0 +1,68 @@ +"""Elmax sensor platform.""" +from __future__ import annotations + +from elmax_api.model.panel import PanelStatus + +from homeassistant.components.binary_sensor import ( + BinarySensorDeviceClass, + BinarySensorEntity, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from . import ElmaxCoordinator +from .common import ElmaxEntity +from .const import DOMAIN + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the Elmax sensor platform.""" + coordinator: ElmaxCoordinator = hass.data[DOMAIN][config_entry.entry_id] + known_devices = set() + + def _discover_new_devices(): + panel_status: PanelStatus = coordinator.data + # In case the panel is offline, its status will be None. In that case, simply do nothing + if panel_status is None: + return + + # Otherwise, add all the entities we found + entities = [] + for zone in panel_status.zones: + # Skip already handled devices + if zone.endpoint_id in known_devices: + continue + entity = ElmaxSensor( + panel=coordinator.panel_entry, + elmax_device=zone, + panel_version=panel_status.release, + coordinator=coordinator, + ) + entities.append(entity) + async_add_entities(entities, True) + known_devices.update([e.unique_id for e in entities]) + + # Register a listener for the discovery of new devices + coordinator.async_add_listener(_discover_new_devices) + + # Immediately run a discovery, so we don't need to wait for the next update + _discover_new_devices() + + +class ElmaxSensor(ElmaxEntity, BinarySensorEntity): + """Elmax Sensor entity implementation.""" + + @property + def is_on(self) -> bool: + """Return true if the binary sensor is on.""" + return self.coordinator.get_zone_state(self._device.endpoint_id).opened + + @property + def device_class(self) -> BinarySensorDeviceClass: + """Return the class of this device, from component DEVICE_CLASSES.""" + return BinarySensorDeviceClass.DOOR diff --git a/homeassistant/components/elmax/common.py b/homeassistant/components/elmax/common.py index 2d66ca9f72e..4116ff05f44 100644 --- a/homeassistant/components/elmax/common.py +++ b/homeassistant/components/elmax/common.py @@ -65,6 +65,12 @@ class ElmaxCoordinator(DataUpdateCoordinator[PanelStatus]): return self._state_by_endpoint.get(actuator_id) raise HomeAssistantError("Unknown actuator") + def get_zone_state(self, zone_id: str) -> Actuator: + """Return state of a specific zone.""" + if self._state_by_endpoint is not None: + return self._state_by_endpoint.get(zone_id) + raise HomeAssistantError("Unknown zone") + @property def http_client(self): """Return the current http client being used by this instance.""" diff --git a/homeassistant/components/elmax/const.py b/homeassistant/components/elmax/const.py index 21864e98f1a..514412d6897 100644 --- a/homeassistant/components/elmax/const.py +++ b/homeassistant/components/elmax/const.py @@ -11,7 +11,7 @@ CONF_ELMAX_PANEL_NAME = "panel_name" CONF_CONFIG_ENTRY_ID = "config_entry_id" CONF_ENDPOINT_ID = "endpoint_id" -ELMAX_PLATFORMS = [Platform.SWITCH] +ELMAX_PLATFORMS = [Platform.SWITCH, Platform.BINARY_SENSOR] POLLING_SECONDS = 30 DEFAULT_TIMEOUT = 10.0