From 564f4f31b602f3a61aa1fbc7cd6d43eb45794bc7 Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Thu, 5 Sep 2019 15:24:13 +0200 Subject: [PATCH 1/5] unifi DSA for Homematic IP Cloud --- .../homematicip_cloud/binary_sensor.py | 79 +++++++++---------- .../components/homematicip_cloud/light.py | 26 +++--- .../components/homematicip_cloud/sensor.py | 34 ++++---- .../components/homematicip_cloud/switch.py | 6 +- 4 files changed, 75 insertions(+), 70 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index d6bc24d21edf1..021d0fee3df59 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -43,14 +43,26 @@ _LOGGER = logging.getLogger(__name__) ATTR_LOW_BATTERY = "low_battery" +ATTR_MOISTUREDETECTED = "moisture detected" ATTR_MOTIONDETECTED = "motion detected" -ATTR_PRESENCEDETECTED = "presence detected" ATTR_POWERMAINSFAILURE = "power mains failure" -ATTR_WINDOWSTATE = "window state" -ATTR_MOISTUREDETECTED = "moisture detected" -ATTR_WATERLEVELDETECTED = "water level detected" +ATTR_PRESENCEDETECTED = "presence detected" ATTR_SMOKEDETECTORALARM = "smoke detector alarm" ATTR_TODAY_SUNSHINE_DURATION = "today_sunshine_duration_in_minutes" +ATTR_WATERLEVELDETECTED = "water level detected" +ATTR_WINDOWSTATE = "window state" + +GROUP_ATTRIBUTES = { + "lowBat": ATTR_LOW_BATTERY, + "modelType": ATTR_MODEL_TYPE, + "moistureDetected": ATTR_MOISTUREDETECTED, + "motionDetected": ATTR_MOTIONDETECTED, + "powerMainsFailure": ATTR_POWERMAINSFAILURE, + "presenceDetected": ATTR_PRESENCEDETECTED, + "todaySunshineDuration": ATTR_TODAY_SUNSHINE_DURATION, + "unreach": ATTR_GROUP_MEMBER_UNREACHABLE, + "waterlevelDetected": ATTR_WATERLEVELDETECTED, +} async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): @@ -259,13 +271,13 @@ def is_on(self) -> bool: @property def device_state_attributes(self): """Return the state attributes of the illuminance sensor.""" - attr = super().device_state_attributes - if ( - hasattr(self._device, "todaySunshineDuration") - and self._device.todaySunshineDuration - ): - attr[ATTR_TODAY_SUNSHINE_DURATION] = self._device.todaySunshineDuration - return attr + state_attr = super().device_state_attributes + + today_sunshine_duration = getattr(self._device, "todaySunshineDuration", None) + if today_sunshine_duration: + state_attr[ATTR_TODAY_SUNSHINE_DURATION] = today_sunshine_duration + + return state_attr class HomematicipBatterySensor(HomematicipGenericDevice, BinarySensorDevice): @@ -309,21 +321,18 @@ def available(self) -> bool: @property def device_state_attributes(self): """Return the state attributes of the security zone group.""" - attr = {ATTR_MODEL_TYPE: self._device.modelType} + state_attr = {ATTR_MODEL_TYPE: self._device.modelType} - if self._device.motionDetected: - attr[ATTR_MOTIONDETECTED] = True - if self._device.presenceDetected: - attr[ATTR_PRESENCEDETECTED] = True + for attr, attr_key in GROUP_ATTRIBUTES.items(): + attr_value = getattr(self._device, attr, None) + if attr_value: + state_attr[attr_key] = attr_value - if ( - self._device.windowState is not None - and self._device.windowState != WindowState.CLOSED - ): - attr[ATTR_WINDOWSTATE] = str(self._device.windowState) - if self._device.unreach: - attr[ATTR_GROUP_MEMBER_UNREACHABLE] = True - return attr + window_state = getattr(self._device, "windowState", None) + if window_state and window_state != WindowState.CLOSED: + state_attr[ATTR_WINDOWSTATE] = str(window_state) + + return state_attr @property def is_on(self) -> bool: @@ -356,23 +365,13 @@ def __init__(self, home: AsyncHome, device) -> None: @property def device_state_attributes(self): """Return the state attributes of the security group.""" - attr = super().device_state_attributes - - if self._device.powerMainsFailure: - attr[ATTR_POWERMAINSFAILURE] = True - if self._device.moistureDetected: - attr[ATTR_MOISTUREDETECTED] = True - if self._device.waterlevelDetected: - attr[ATTR_WATERLEVELDETECTED] = True - if self._device.lowBat: - attr[ATTR_LOW_BATTERY] = True - if ( - self._device.smokeDetectorAlarmType is not None - and self._device.smokeDetectorAlarmType != SmokeDetectorAlarmType.IDLE_OFF - ): - attr[ATTR_SMOKEDETECTORALARM] = str(self._device.smokeDetectorAlarmType) + state_attr = super().device_state_attributes + + smoke_detector_at = getattr(self._device, "smokeDetectorAlarmType", None) + if smoke_detector_at and smoke_detector_at != SmokeDetectorAlarmType.IDLE_OFF: + state_attr[ATTR_SMOKEDETECTORALARM] = str(smoke_detector_at) - return attr + return state_attr @property def is_on(self) -> bool: diff --git a/homeassistant/components/homematicip_cloud/light.py b/homeassistant/components/homematicip_cloud/light.py index bc7b12f9653ea..42ff6d30478fb 100644 --- a/homeassistant/components/homematicip_cloud/light.py +++ b/homeassistant/components/homematicip_cloud/light.py @@ -93,13 +93,15 @@ class HomematicipLightMeasuring(HomematicipLight): @property def device_state_attributes(self): """Return the state attributes of the generic device.""" - attr = super().device_state_attributes - if self._device.currentPowerConsumption > 0.05: - attr[ATTR_POWER_CONSUMPTION] = round( - self._device.currentPowerConsumption, 2 - ) - attr[ATTR_ENERGY_COUNTER] = round(self._device.energyCounter, 2) - return attr + state_attr = super().device_state_attributes + + current_power_consumption = self._device.currentPowerConsumption + if current_power_consumption > 0.05: + state_attr[ATTR_POWER_CONSUMPTION] = round(current_power_consumption, 2) + + state_attr[ATTR_ENERGY_COUNTER] = round(self._device.energyCounter, 2) + + return state_attr class HomematicipDimmer(HomematicipGenericDevice, Light): @@ -187,15 +189,17 @@ def hs_color(self) -> tuple: @property def device_state_attributes(self): """Return the state attributes of the generic device.""" - attr = super().device_state_attributes + state_attr = super().device_state_attributes + if self.is_on: - attr[ATTR_COLOR_NAME] = self._func_channel.simpleRGBColorState - return attr + state_attr[ATTR_COLOR_NAME] = self._func_channel.simpleRGBColorState + + return state_attr @property def name(self) -> str: """Return the name of the generic device.""" - return "{} {}".format(super().name, "Notification") + return f"{super().name} Notification" @property def supported_features(self) -> int: diff --git a/homeassistant/components/homematicip_cloud/sensor.py b/homeassistant/components/homematicip_cloud/sensor.py index c15b3121d3a63..b396a8d9defad 100644 --- a/homeassistant/components/homematicip_cloud/sensor.py +++ b/homeassistant/components/homematicip_cloud/sensor.py @@ -229,13 +229,13 @@ def unit_of_measurement(self) -> str: @property def device_state_attributes(self): """Return the state attributes of the windspeed sensor.""" - attr = super().device_state_attributes - if ( - hasattr(self._device, "temperatureOffset") - and self._device.temperatureOffset - ): - attr[ATTR_TEMPERATURE_OFFSET] = self._device.temperatureOffset - return attr + state_attr = super().device_state_attributes + + temperature_offset = getattr(self._device, "temperatureOffset", None) + if temperature_offset: + state_attr[ATTR_TEMPERATURE_OFFSET] = temperature_offset + + return state_attr class HomematicipIlluminanceSensor(HomematicipGenericDevice): @@ -307,15 +307,17 @@ def unit_of_measurement(self) -> str: @property def device_state_attributes(self): """Return the state attributes of the wind speed sensor.""" - attr = super().device_state_attributes - if hasattr(self._device, "windDirection") and self._device.windDirection: - attr[ATTR_WIND_DIRECTION] = _get_wind_direction(self._device.windDirection) - if ( - hasattr(self._device, "windDirectionVariation") - and self._device.windDirectionVariation - ): - attr[ATTR_WIND_DIRECTION_VARIATION] = self._device.windDirectionVariation - return attr + state_attr = super().device_state_attributes + + wind_direction = getattr(self._device, "windDirection", None) + if wind_direction: + state_attr[ATTR_WIND_DIRECTION] = _get_wind_direction(wind_direction) + + wind_direction_variation = getattr(self._device, "windDirectionVariation", None) + if wind_direction_variation: + state_attr[ATTR_WIND_DIRECTION_VARIATION] = wind_direction_variation + + return state_attr class HomematicipTodayRainSensor(HomematicipGenericDevice): diff --git a/homeassistant/components/homematicip_cloud/switch.py b/homeassistant/components/homematicip_cloud/switch.py index 6d19087781dae..058e21262e3e8 100644 --- a/homeassistant/components/homematicip_cloud/switch.py +++ b/homeassistant/components/homematicip_cloud/switch.py @@ -113,10 +113,10 @@ def available(self) -> bool: @property def device_state_attributes(self): """Return the state attributes of the switch-group.""" - attr = {} + state_attr = {} if self._device.unreach: - attr[ATTR_GROUP_MEMBER_UNREACHABLE] = True - return attr + state_attr[ATTR_GROUP_MEMBER_UNREACHABLE] = True + return state_attr async def async_turn_on(self, **kwargs): """Turn the group on.""" From d685d59dc24d356d7fae36b512a247b368256c73 Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Thu, 5 Sep 2019 15:38:44 +0200 Subject: [PATCH 2/5] sabotage is not relevant for state --- .../components/homematicip_cloud/binary_sensor.py | 8 -------- homeassistant/components/homematicip_cloud/weather.py | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index 021d0fee3df59..719287c6bddd3 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -130,8 +130,6 @@ def device_class(self) -> str: @property def is_on(self) -> bool: """Return true if the contact interface is on/open.""" - if hasattr(self._device, "sabotage") and self._device.sabotage: - return True if self._device.windowState is None: return None return self._device.windowState != WindowState.CLOSED @@ -148,8 +146,6 @@ def device_class(self) -> str: @property def is_on(self) -> bool: """Return true if the shutter contact is on/open.""" - if hasattr(self._device, "sabotage") and self._device.sabotage: - return True if self._device.windowState is None: return None return self._device.windowState != WindowState.CLOSED @@ -166,8 +162,6 @@ def device_class(self) -> str: @property def is_on(self) -> bool: """Return true if motion is detected.""" - if hasattr(self._device, "sabotage") and self._device.sabotage: - return True return self._device.motionDetected @@ -182,8 +176,6 @@ def device_class(self) -> str: @property def is_on(self) -> bool: """Return true if presence is detected.""" - if hasattr(self._device, "sabotage") and self._device.sabotage: - return True return self._device.presenceDetected diff --git a/homeassistant/components/homematicip_cloud/weather.py b/homeassistant/components/homematicip_cloud/weather.py index 463e1bfb7410f..2d0a69d7d0632 100644 --- a/homeassistant/components/homematicip_cloud/weather.py +++ b/homeassistant/components/homematicip_cloud/weather.py @@ -79,7 +79,7 @@ def attribution(self) -> str: @property def condition(self) -> str: """Return the current condition.""" - if hasattr(self._device, "raining") and self._device.raining: + if getattr(self._device, "raining", None): return "rainy" if self._device.storm: return "windy" From 701b6421625d956e25eb4da4b5aa653ed0dc1a28 Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Thu, 5 Sep 2019 16:06:50 +0200 Subject: [PATCH 3/5] TODAY_SUNSHINE_DURATION is not a group attribute --- homeassistant/components/homematicip_cloud/binary_sensor.py | 1 - 1 file changed, 1 deletion(-) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index 719287c6bddd3..bb5f587550f2b 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -59,7 +59,6 @@ "motionDetected": ATTR_MOTIONDETECTED, "powerMainsFailure": ATTR_POWERMAINSFAILURE, "presenceDetected": ATTR_PRESENCEDETECTED, - "todaySunshineDuration": ATTR_TODAY_SUNSHINE_DURATION, "unreach": ATTR_GROUP_MEMBER_UNREACHABLE, "waterlevelDetected": ATTR_WATERLEVELDETECTED, } From a78a063839cc5895d738aef93f536309fc5ecb14 Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Fri, 6 Sep 2019 09:42:04 +0200 Subject: [PATCH 4/5] Separated the words as requested --- .../homematicip_cloud/binary_sensor.py | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index bb5f587550f2b..9335fc3c7dcef 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -43,24 +43,24 @@ _LOGGER = logging.getLogger(__name__) ATTR_LOW_BATTERY = "low_battery" -ATTR_MOISTUREDETECTED = "moisture detected" -ATTR_MOTIONDETECTED = "motion detected" -ATTR_POWERMAINSFAILURE = "power mains failure" -ATTR_PRESENCEDETECTED = "presence detected" -ATTR_SMOKEDETECTORALARM = "smoke detector alarm" +ATTR_MOISTURE_DETECTED = "moisture detected" +ATTR_MOTION_DETECTED = "motion detected" +ATTR_POWER_MAINS_FAILURE = "power mains failure" +ATTR_PRESENCE_DETECTED = "presence detected" +ATTR_SMOKE_DETECTOR_ALARM = "smoke detector alarm" ATTR_TODAY_SUNSHINE_DURATION = "today_sunshine_duration_in_minutes" -ATTR_WATERLEVELDETECTED = "water level detected" -ATTR_WINDOWSTATE = "window state" +ATTR_WATER_LEVEL_DETECTED = "water level detected" +ATTR_WINDOW_STATE = "window state" GROUP_ATTRIBUTES = { "lowBat": ATTR_LOW_BATTERY, "modelType": ATTR_MODEL_TYPE, - "moistureDetected": ATTR_MOISTUREDETECTED, - "motionDetected": ATTR_MOTIONDETECTED, - "powerMainsFailure": ATTR_POWERMAINSFAILURE, - "presenceDetected": ATTR_PRESENCEDETECTED, + "moistureDetected": ATTR_MOISTURE_DETECTED, + "motionDetected": ATTR_MOTION_DETECTED, + "powerMainsFailure": ATTR_POWER_MAINS_FAILURE, + "presenceDetected": ATTR_PRESENCE_DETECTED, "unreach": ATTR_GROUP_MEMBER_UNREACHABLE, - "waterlevelDetected": ATTR_WATERLEVELDETECTED, + "waterlevelDetected": ATTR_WATER_LEVEL_DETECTED, } @@ -321,7 +321,7 @@ def device_state_attributes(self): window_state = getattr(self._device, "windowState", None) if window_state and window_state != WindowState.CLOSED: - state_attr[ATTR_WINDOWSTATE] = str(window_state) + state_attr[ATTR_WINDOW_STATE] = str(window_state) return state_attr @@ -360,7 +360,7 @@ def device_state_attributes(self): smoke_detector_at = getattr(self._device, "smokeDetectorAlarmType", None) if smoke_detector_at and smoke_detector_at != SmokeDetectorAlarmType.IDLE_OFF: - state_attr[ATTR_SMOKEDETECTORALARM] = str(smoke_detector_at) + state_attr[ATTR_SMOKE_DETECTOR_ALARM] = str(smoke_detector_at) return state_attr From 5347b131d635ee8490cab47955aea4fe4d11c850 Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Fri, 6 Sep 2019 11:42:49 +0200 Subject: [PATCH 5/5] add missing underscores --- .../components/homematicip_cloud/binary_sensor.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index 9335fc3c7dcef..594f4f6c54aa4 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -43,14 +43,14 @@ _LOGGER = logging.getLogger(__name__) ATTR_LOW_BATTERY = "low_battery" -ATTR_MOISTURE_DETECTED = "moisture detected" -ATTR_MOTION_DETECTED = "motion detected" -ATTR_POWER_MAINS_FAILURE = "power mains failure" -ATTR_PRESENCE_DETECTED = "presence detected" -ATTR_SMOKE_DETECTOR_ALARM = "smoke detector alarm" +ATTR_MOISTURE_DETECTED = "moisture_detected" +ATTR_MOTION_DETECTED = "motion_detected" +ATTR_POWER_MAINS_FAILURE = "power_mains_failure" +ATTR_PRESENCE_DETECTED = "presence_detected" +ATTR_SMOKE_DETECTOR_ALARM = "smoke_detector_alarm" ATTR_TODAY_SUNSHINE_DURATION = "today_sunshine_duration_in_minutes" -ATTR_WATER_LEVEL_DETECTED = "water level detected" -ATTR_WINDOW_STATE = "window state" +ATTR_WATER_LEVEL_DETECTED = "water_level_detected" +ATTR_WINDOW_STATE = "window_state" GROUP_ATTRIBUTES = { "lowBat": ATTR_LOW_BATTERY,