From 8ef3c6d4d346a0fcaed2d72299597ed8aa1b8594 Mon Sep 17 00:00:00 2001 From: sander76 Date: Thu, 9 May 2019 19:38:51 +0200 Subject: [PATCH] Add battery binary sensor to homematic (#23067) * first proposal * parameter rename * retrigger CI * remove separate binary sensor * remove batter_sensor * battery device distinction at binary sensor discovery --- .../components/homematic/__init__.py | 27 ++++++++++--- .../components/homematic/binary_sensor.py | 38 ++++++++++++++++++- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/homematic/__init__.py b/homeassistant/components/homematic/__init__.py index 578fae064f8..7f6f9a6d522 100644 --- a/homeassistant/components/homematic/__init__.py +++ b/homeassistant/components/homematic/__init__.py @@ -27,8 +27,10 @@ DISCOVER_BINARY_SENSORS = 'homematic.binary_sensor' DISCOVER_COVER = 'homematic.cover' DISCOVER_CLIMATE = 'homematic.climate' DISCOVER_LOCKS = 'homematic.locks' +DISCOVER_BUTTONS = 'homematic.binary_sensor' ATTR_DISCOVER_DEVICES = 'devices' +ATTR_BATTERY_DEVICES = 'battery_devices' ATTR_PARAM = 'param' ATTR_CHANNEL = 'channel' ATTR_ADDRESS = 'address' @@ -42,6 +44,7 @@ ATTR_UNIQUE_ID = 'unique_id' ATTR_PARAMSET_KEY = 'paramset_key' ATTR_PARAMSET = 'paramset' + EVENT_KEYPRESS = 'homematic.keypress' EVENT_IMPULSE = 'homematic.impulse' EVENT_ERROR = 'homematic.error' @@ -84,7 +87,8 @@ HM_DEVICE_TYPES = { 'SmartwareMotion', 'IPWeatherSensorPlus', 'MotionIPV2', 'WaterIP', 'IPMultiIO', 'TiltIP', 'IPShutterContactSabotage'], DISCOVER_COVER: ['Blind', 'KeyBlind', 'IPKeyBlind', 'IPKeyBlindTilt'], - DISCOVER_LOCKS: ['KeyMatic'] + DISCOVER_LOCKS: ['KeyMatic'], + DISCOVER_BUTTONS: ['HmIP-WRC6', 'HmIP-RC8'] } HM_IGNORE_DISCOVERY_NODE = [ @@ -460,7 +464,8 @@ def _system_callback_handler(hass, config, src, *args): ('binary_sensor', DISCOVER_BINARY_SENSORS), ('sensor', DISCOVER_SENSORS), ('climate', DISCOVER_CLIMATE), - ('lock', DISCOVER_LOCKS)): + ('lock', DISCOVER_LOCKS), + ('binary_sensor', DISCOVER_SWITCHES)): # Get all devices of a specific type found_devices = _get_devices( hass, discovery_type, addresses, interface) @@ -468,9 +473,21 @@ def _system_callback_handler(hass, config, src, *args): # When devices of this type are found # they are setup in HASS and a discovery event is fired if found_devices: - discovery.load_platform(hass, component_name, DOMAIN, { - ATTR_DISCOVER_DEVICES: found_devices - }, config) + discovery_info = {ATTR_DISCOVER_DEVICES: found_devices, + ATTR_BATTERY_DEVICES: False} + + # Switches are skipped as a component. They will only + # appear in hass as a battery device. + if not discovery_type == DISCOVER_SWITCHES: + discovery.load_platform(hass, component_name, DOMAIN, + discovery_info, config) + + # Pass all devices to binary sensor discovery, + # check whether they are battery operated and + # add them as a battery operated binary sensor device. + discovery_info[ATTR_BATTERY_DEVICES] = True + discovery.load_platform(hass, 'binary_sensor', DOMAIN, + discovery_info, config) # Homegear error message elif src == 'error': diff --git a/homeassistant/components/homematic/binary_sensor.py b/homeassistant/components/homematic/binary_sensor.py index dfd7b7a72bd..91960cd8570 100644 --- a/homeassistant/components/homematic/binary_sensor.py +++ b/homeassistant/components/homematic/binary_sensor.py @@ -2,12 +2,16 @@ import logging from homeassistant.components.binary_sensor import BinarySensorDevice -from homeassistant.const import STATE_UNKNOWN +from homeassistant.components.homematic import ATTR_BATTERY_DEVICES +from homeassistant.const import STATE_UNKNOWN, DEVICE_CLASS_BATTERY from . import ATTR_DISCOVER_DEVICES, HMDevice _LOGGER = logging.getLogger(__name__) +ATTR_LOW_BAT = 'LOW_BAT' +ATTR_LOWBAT = 'LOWBAT' + SENSOR_TYPES_CLASS = { 'IPShutterContact': 'opening', 'MaxShutterContact': 'opening', @@ -30,8 +34,15 @@ def setup_platform(hass, config, add_entities, discovery_info=None): return devices = [] + battery_devices = discovery_info[ATTR_BATTERY_DEVICES] + for conf in discovery_info[ATTR_DISCOVER_DEVICES]: - new_device = HMBinarySensor(conf) + if battery_devices: + battery_device = conf.get(ATTR_LOWBAT) or conf.get(ATTR_LOW_BAT) + if battery_device: + new_device = HMBatterySensor(conf) + else: + new_device = HMBinarySensor(conf) devices.append(new_device) add_entities(devices) @@ -60,3 +71,26 @@ class HMBinarySensor(HMDevice, BinarySensorDevice): # Add state to data struct if self._state: self._data.update({self._state: STATE_UNKNOWN}) + + +class HMBatterySensor(HMDevice, BinarySensorDevice): + """Representation of an HomeMatic low battery sensor.""" + + @property + def device_class(self): + """Return battery as a device class.""" + return DEVICE_CLASS_BATTERY + + @property + def is_on(self): + """Return True if battery is low.""" + is_on = self._data.get(ATTR_LOW_BAT, False) or self._data.get( + ATTR_LOWBAT, False + ) + return is_on + + def _init_data_struct(self): + """Generate the data dictionary (self._data) from metadata.""" + # Add state to data struct + if self._state: + self._data.update({self._state: STATE_UNKNOWN})