diff --git a/custom_components/tahoma/__init__.py b/custom_components/tahoma/__init__.py index 9a6cc5507..5a06b51cd 100644 --- a/custom_components/tahoma/__init__.py +++ b/custom_components/tahoma/__init__.py @@ -38,6 +38,7 @@ ) PLATFORMS = [ + "binary_sensor", "cover", "light", "lock", diff --git a/custom_components/tahoma/binary_sensor.py b/custom_components/tahoma/binary_sensor.py new file mode 100644 index 000000000..a9e929383 --- /dev/null +++ b/custom_components/tahoma/binary_sensor.py @@ -0,0 +1,72 @@ +"""Support for Tahoma binary sensors.""" +from datetime import timedelta +import logging + +from homeassistant.components.binary_sensor import BinarySensorEntity +from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_OFF, STATE_ON + +from .const import DOMAIN, TAHOMA_TYPES, TAHOMA_BINARY_SENSOR_DEVICE_CLASSES +from .tahoma_device import TahomaDevice + +_LOGGER = logging.getLogger(__name__) + +SCAN_INTERVAL = timedelta(seconds=120) + + +async def async_setup_entry(hass, entry, async_add_entities): + """Set up the Tahoma sensors from a config entry.""" + + data = hass.data[DOMAIN][entry.entry_id] + + entities = [] + controller = data.get("controller") + + for device in data.get("devices"): + if TAHOMA_TYPES[device.uiclass] == "binary_sensor": + entities.append(TahomaBinarySensor(device, controller)) + + async_add_entities(entities) + + +class TahomaBinarySensor(TahomaDevice, BinarySensorEntity): + """Representation of a Tahoma Binary Sensor.""" + + def __init__(self, tahoma_device, controller): + """Initialize the sensor.""" + super().__init__(tahoma_device, controller) + + self._state = None + + @property + def is_on(self): + """Return the state of the sensor.""" + return bool(self._state == STATE_ON) + + @property + def device_class(self): + """Return the class of the device.""" + return ( + TAHOMA_BINARY_SENSOR_DEVICE_CLASSES.get(self.tahoma_device.widget) + or TAHOMA_BINARY_SENSOR_DEVICE_CLASSES.get(self.tahoma_device.uiclass) + or None + ) + + def update(self): + """Update the state.""" + self.controller.get_states([self.tahoma_device]) + + if "core:ContactState" in self.tahoma_device.active_states: + self.current_value = self.tahoma_device.active_states.get("core:ContactState") == "open" + + if "core:OccupancyState" in self.tahoma_device.active_states: + self.current_value = self.tahoma_device.active_states.get("core:OccupancyState") + + if "core:SmokeState" in self.tahoma_device.active_states: + self.current_value = self.tahoma_device.active_states.get("core:SmokeState") != "notDetected" + + if self.current_value: + self._state = STATE_ON + else: + self._sate = STATE_OFF + + _LOGGER.debug("Update %s, state: %s", self._name, self._state) diff --git a/custom_components/tahoma/const.py b/custom_components/tahoma/const.py index a8e94ad8f..1ff44e4f3 100644 --- a/custom_components/tahoma/const.py +++ b/custom_components/tahoma/const.py @@ -7,6 +7,12 @@ DEVICE_CLASS_WINDOW, ) +from homeassistant.components.binary_sensor import ( + DEVICE_CLASS_SMOKE, + DEVICE_CLASS_MOTION, + DEVICE_CLASS_OPENING +) + """Constants for the Tahoma integration.""" DOMAIN = "tahoma" @@ -21,17 +27,32 @@ "RemoteController": "", "HeatingSystem": "climate", "TemperatureSensor": "sensor", + "LightSensor": "sensor", "DoorLock": "lock", "OnOff": "switch", "HumiditySensor": "sensor", + "GarageDoor": "cover", + "ContactSensor": "binary_sensor", + "SmokeSensor": "binary_sensor", + "MotionSensor": "binary_sensor", + "ExteriorVenetianBlind": "cover" } -## TODO Make sure widgetName has priority over uiClass for specific overrides. TAHOMA_COVER_DEVICE_CLASSES = { "ExteriorScreen": DEVICE_CLASS_BLIND, "Pergola": DEVICE_CLASS_AWNING, "RollerShutter": DEVICE_CLASS_SHUTTER, "Window": DEVICE_CLASS_WINDOW, + "GarageDoor": DEVICE_CLASS_GARAGE, + "HorizontalAwning": DEVICE_CLASS_AWNING, + "ExteriorVenetianBlind": DEVICE_CLASS_BLIND, + "VeluxInteriorBlind": DEVICE_CLASS_BLIND +} + +TAHOMA_BINARY_SENSOR_DEVICE_CLASSES = { + "SmokeSensor": DEVICE_CLASS_SMOKE, + "MotionSensor": DEVICE_CLASS_MOTION, + "ContactSensor": DEVICE_CLASS_OPENING } # Tahoma Attributes diff --git a/custom_components/tahoma/sensor.py b/custom_components/tahoma/sensor.py index 8cf2de517..ac3a3aa93 100644 --- a/custom_components/tahoma/sensor.py +++ b/custom_components/tahoma/sensor.py @@ -47,7 +47,7 @@ def unit_of_measurement(self): """Return the unit of measurement of this entity, if any.""" if self.tahoma_device.uiclass == "TemperatureSensor": - return TEMP_CELSIUS + return TEMP_CELSIUS # TODO Retrieve core:MeasuredValueType to understand if it is Celsius or Kelvin if self.tahoma_device.uiclass == "HumiditySensor": return UNIT_PERCENTAGE @@ -60,31 +60,15 @@ def unit_of_measurement(self): def update(self): """Update the state.""" self.controller.get_states([self.tahoma_device]) - if self.tahoma_device.type == "io:LightIOSystemSensor": - self.current_value = self.tahoma_device.active_states["core:LuminanceState"] - self._available = bool( - self.tahoma_device.active_states.get("core:StatusState") == "available" - ) - if self.tahoma_device.type == "io:SomfyContactIOSystemSensor": - self.current_value = self.tahoma_device.active_states["core:ContactState"] - self._available = bool( - self.tahoma_device.active_states.get("core:StatusState") == "available" - ) - if self.tahoma_device.type == "io:SomfyBasicContactIOSystemSensor": - self.current_value = self.tahoma_device.active_states["core:ContactState"] - self._available = bool( - self.tahoma_device.active_states.get("core:StatusState") == "available" + + if "core:LuminanceState" in self.tahoma_device.active_states: + self.current_value = self.tahoma_device.active_states.get( + "core:LuminanceState" ) - if self.tahoma_device.type == "rtds:RTDSContactSensor": - self.current_value = self.tahoma_device.active_states["core:ContactState"] - self._available = True - if self.tahoma_device.type == "rtds:RTDSMotionSensor": - self.current_value = self.tahoma_device.active_states["core:OccupancyState"] - self._available = True - if self.tahoma_device.type == "io:TemperatureIOSystemSensor": + + if "core:TemperatureState" in self.tahoma_device.active_states: self.current_value = round( - float(self.tahoma_device.active_states["core:TemperatureState"]), 1 + float(self.tahoma_device.active_states.get("core:TemperatureState"), 1) ) - self._available = True _LOGGER.debug("Update %s, value: %d", self._name, self.current_value)