From 16d8e92b06022297515e45d0b9c9859e579e1504 Mon Sep 17 00:00:00 2001 From: Markus Jankowski Date: Wed, 24 Apr 2019 01:47:31 +0200 Subject: [PATCH] Reorg Homematic IP Cloud imports and minor fixes (#23330) * reorg HmiP Imports after introduction of manifests * add type to some functions * fix usage of dimLevel (HomematicipDimmer,HomematicipNotificationLight) * align naming to HomematicipMultiSwitch: channel_index -> channel for (HomematicipNotificationLight) * fix lint * Fix is_on for dimmers * fix lint --- .../homematicip_cloud/alarm_control_panel.py | 9 ++-- .../homematicip_cloud/binary_sensor.py | 27 +++++------- .../components/homematicip_cloud/climate.py | 4 +- .../components/homematicip_cloud/cover.py | 4 +- .../components/homematicip_cloud/device.py | 3 +- .../components/homematicip_cloud/hap.py | 20 +++------ .../components/homematicip_cloud/light.py | 41 +++++++++++-------- .../components/homematicip_cloud/sensor.py | 27 ++++++------ .../components/homematicip_cloud/switch.py | 17 +++----- .../components/homematicip_cloud/weather.py | 7 ++-- 10 files changed, 70 insertions(+), 89 deletions(-) diff --git a/homeassistant/components/homematicip_cloud/alarm_control_panel.py b/homeassistant/components/homematicip_cloud/alarm_control_panel.py index cb35833c231..1326e46d7d3 100644 --- a/homeassistant/components/homematicip_cloud/alarm_control_panel.py +++ b/homeassistant/components/homematicip_cloud/alarm_control_panel.py @@ -1,6 +1,9 @@ """Support for HomematicIP Cloud alarm control panel.""" import logging +from homematicip.aio.group import AsyncSecurityZoneGroup +from homematicip.base.enums import WindowState + from homeassistant.components.alarm_control_panel import AlarmControlPanel from homeassistant.const import ( STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, @@ -18,9 +21,7 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): - """Set up the HomematicIP alarm control panel from a config entry.""" - from homematicip.aio.group import AsyncSecurityZoneGroup - + """Set up the HomematicIP alrm control panel from a config entry.""" home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for group in home.groups: @@ -43,8 +44,6 @@ class HomematicipSecurityZone(HomematicipGenericDevice, AlarmControlPanel): @property def state(self): """Return the state of the device.""" - from homematicip.base.enums import WindowState - if self._device.active: if (self._device.sabotage or self._device.motionDetected or self._device.windowState == WindowState.OPEN or diff --git a/homeassistant/components/homematicip_cloud/binary_sensor.py b/homeassistant/components/homematicip_cloud/binary_sensor.py index 48e9520a952..1396493a527 100644 --- a/homeassistant/components/homematicip_cloud/binary_sensor.py +++ b/homeassistant/components/homematicip_cloud/binary_sensor.py @@ -1,6 +1,14 @@ """Support for HomematicIP Cloud binary sensor.""" import logging +from homematicip.aio.device import ( + AsyncDevice, AsyncMotionDetectorIndoor, AsyncMotionDetectorOutdoor, + AsyncMotionDetectorPushButton, AsyncRotaryHandleSensor, + AsyncShutterContact, AsyncSmokeDetector, AsyncWaterSensor, + AsyncWeatherSensor, AsyncWeatherSensorPlus, AsyncWeatherSensorPro) +from homematicip.aio.group import AsyncSecurityGroup, AsyncSecurityZoneGroup +from homematicip.base.enums import SmokeDetectorAlarmType, WindowState + from homeassistant.components.binary_sensor import BinarySensorDevice from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice @@ -26,15 +34,6 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the HomematicIP Cloud binary sensor from a config entry.""" - from homematicip.aio.device import ( - AsyncDevice, AsyncShutterContact, AsyncMotionDetectorIndoor, - AsyncMotionDetectorOutdoor, AsyncSmokeDetector, AsyncWaterSensor, - AsyncRotaryHandleSensor, AsyncMotionDetectorPushButton, - AsyncWeatherSensor, AsyncWeatherSensorPlus, AsyncWeatherSensorPro) - - from homematicip.aio.group import ( - AsyncSecurityGroup, AsyncSecurityZoneGroup) - home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.devices: @@ -79,8 +78,6 @@ class HomematicipShutterContact(HomematicipGenericDevice, BinarySensorDevice): @property def is_on(self): """Return true if the shutter contact is on/open.""" - from homematicip.base.enums import WindowState - if self._device.sabotage: return True if self._device.windowState is None: @@ -115,7 +112,6 @@ class HomematicipSmokeDetector(HomematicipGenericDevice, BinarySensorDevice): @property def is_on(self): """Return true if smoke is detected.""" - from homematicip.base.enums import SmokeDetectorAlarmType return (self._device.smokeDetectorAlarmType != SmokeDetectorAlarmType.IDLE_OFF) @@ -246,7 +242,7 @@ class HomematicipSecurityZoneSensorGroup(HomematicipGenericDevice, attr[ATTR_MOTIONDETECTED] = True if self._device.presenceDetected: attr[ATTR_PRESENCEDETECTED] = True - from homematicip.base.enums import WindowState + if self._device.windowState is not None and \ self._device.windowState != WindowState.CLOSED: attr[ATTR_WINDOWSTATE] = str(self._device.windowState) @@ -262,7 +258,7 @@ class HomematicipSecurityZoneSensorGroup(HomematicipGenericDevice, self._device.unreach or \ self._device.sabotage: return True - from homematicip.base.enums import WindowState + if self._device.windowState is not None and \ self._device.windowState != WindowState.CLOSED: return True @@ -288,7 +284,7 @@ class HomematicipSecuritySensorGroup(HomematicipSecurityZoneSensorGroup, attr[ATTR_MOISTUREDETECTED] = True if self._device.waterlevelDetected: attr[ATTR_WATERLEVELDETECTED] = True - from homematicip.base.enums import SmokeDetectorAlarmType + if self._device.smokeDetectorAlarmType is not None and \ self._device.smokeDetectorAlarmType != \ SmokeDetectorAlarmType.IDLE_OFF: @@ -301,7 +297,6 @@ class HomematicipSecuritySensorGroup(HomematicipSecurityZoneSensorGroup, def is_on(self): """Return true if safety issue detected.""" parent_is_on = super().is_on - from homematicip.base.enums import SmokeDetectorAlarmType if parent_is_on or \ self._device.powerMainsFailure or \ self._device.moistureDetected or \ diff --git a/homeassistant/components/homematicip_cloud/climate.py b/homeassistant/components/homematicip_cloud/climate.py index 5055858e9c7..8a2ad8738df 100644 --- a/homeassistant/components/homematicip_cloud/climate.py +++ b/homeassistant/components/homematicip_cloud/climate.py @@ -1,6 +1,8 @@ """Support for HomematicIP Cloud climate devices.""" import logging +from homematicip.group import HeatingGroup + from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate.const import ( STATE_AUTO, STATE_MANUAL, SUPPORT_TARGET_TEMPERATURE) @@ -26,8 +28,6 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the HomematicIP climate from a config entry.""" - from homematicip.group import HeatingGroup - home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.groups: diff --git a/homeassistant/components/homematicip_cloud/cover.py b/homeassistant/components/homematicip_cloud/cover.py index e572e3d9754..381bcf1980e 100644 --- a/homeassistant/components/homematicip_cloud/cover.py +++ b/homeassistant/components/homematicip_cloud/cover.py @@ -1,6 +1,8 @@ """Support for HomematicIP Cloud cover devices.""" import logging +from homematicip.aio.device import AsyncFullFlushShutter + from homeassistant.components.cover import ATTR_POSITION, CoverDevice from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice @@ -19,8 +21,6 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the HomematicIP cover from a config entry.""" - from homematicip.aio.device import AsyncFullFlushShutter - home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.devices: diff --git a/homeassistant/components/homematicip_cloud/device.py b/homeassistant/components/homematicip_cloud/device.py index 0b815d0ec7e..f6da8b27cf7 100644 --- a/homeassistant/components/homematicip_cloud/device.py +++ b/homeassistant/components/homematicip_cloud/device.py @@ -1,6 +1,8 @@ """Generic device for the HomematicIP Cloud component.""" import logging +from homematicip.aio.device import AsyncDevice + from homeassistant.components import homematicip_cloud from homeassistant.helpers.entity import Entity @@ -29,7 +31,6 @@ class HomematicipGenericDevice(Entity): @property def device_info(self): """Return device specific attributes.""" - from homematicip.aio.device import AsyncDevice # Only physical devices should be HA devices. if isinstance(self._device, AsyncDevice): return { diff --git a/homeassistant/components/homematicip_cloud/hap.py b/homeassistant/components/homematicip_cloud/hap.py index 64721c0a96c..99e98b5a1d2 100644 --- a/homeassistant/components/homematicip_cloud/hap.py +++ b/homeassistant/components/homematicip_cloud/hap.py @@ -2,6 +2,10 @@ import asyncio import logging +from homematicip.aio.auth import AsyncAuth +from homematicip.aio.home import AsyncHome +from homematicip.base.base_connection import HmipConnectionError + from homeassistant.core import callback from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.aiohttp_client import async_get_clientsession @@ -36,8 +40,6 @@ class HomematicipAuth: async def async_checkbutton(self): """Check blue butten has been pressed.""" - from homematicip.base.base_connection import HmipConnectionError - try: return await self.auth.isRequestAcknowledged() except HmipConnectionError: @@ -45,8 +47,6 @@ class HomematicipAuth: async def async_register(self): """Register client at HomematicIP.""" - from homematicip.base.base_connection import HmipConnectionError - try: authtoken = await self.auth.requestAuthToken() await self.auth.confirmAuthToken(authtoken) @@ -56,9 +56,6 @@ class HomematicipAuth: async def get_auth(self, hass, hapid, pin): """Create a HomematicIP access point object.""" - from homematicip.aio.auth import AsyncAuth - from homematicip.base.base_connection import HmipConnectionError - auth = AsyncAuth(hass.loop, async_get_clientsession(hass)) try: await auth.init(hapid) @@ -138,8 +135,6 @@ class HomematicipHAP: def get_state_finished(self, future): """Execute when get_state coroutine has finished.""" - from homematicip.base.base_connection import HmipConnectionError - try: future.result() except HmipConnectionError: @@ -162,8 +157,6 @@ class HomematicipHAP: async def async_connect(self): """Start WebSocket connection.""" - from homematicip.base.base_connection import HmipConnectionError - tries = 0 while True: retry_delay = 2 ** min(tries, 8) @@ -203,11 +196,8 @@ class HomematicipHAP: self.config_entry, component) return True - async def get_hap(self, hass, hapid, authtoken, name): + async def get_hap(self, hass, hapid, authtoken, name) -> AsyncHome: """Create a HomematicIP access point object.""" - from homematicip.aio.home import AsyncHome - from homematicip.base.base_connection import HmipConnectionError - home = AsyncHome(hass.loop, async_get_clientsession(hass)) home.name = name diff --git a/homeassistant/components/homematicip_cloud/light.py b/homeassistant/components/homematicip_cloud/light.py index b67e4114db2..e783214a447 100644 --- a/homeassistant/components/homematicip_cloud/light.py +++ b/homeassistant/components/homematicip_cloud/light.py @@ -1,6 +1,8 @@ """Support for HomematicIP Cloud lights.""" import logging +from homematicip.base.enums import RGBColorState + from homeassistant.components.light import ( ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_HS_COLOR, SUPPORT_BRIGHTNESS, SUPPORT_COLOR, Light) @@ -90,12 +92,15 @@ class HomematicipDimmer(HomematicipGenericDevice, Light): @property def is_on(self): """Return true if device is on.""" - return self._device.dimLevel != 0 + return self._device.dimLevel is not None and \ + self._device.dimLevel > 0.0 @property def brightness(self): """Return the brightness of this light between 0..255.""" - return int(self._device.dimLevel*255) + if self._device.dimLevel: + return int(self._device.dimLevel*255) + return 0 @property def supported_features(self): @@ -117,15 +122,14 @@ class HomematicipDimmer(HomematicipGenericDevice, Light): class HomematicipNotificationLight(HomematicipGenericDevice, Light): """Representation of HomematicIP Cloud dimmer light device.""" - def __init__(self, home, device, channel_index): + def __init__(self, home, device, channel): """Initialize the dimmer light device.""" - self._channel_index = channel_index - if self._channel_index == 2: + self.channel = channel + if self.channel == 2: super().__init__(home, device, 'Top') else: super().__init__(home, device, 'Bottom') - from homematicip.base.enums import RGBColorState self._color_switcher = { RGBColorState.WHITE: [0.0, 0.0], RGBColorState.RED: [0.0, 100.0], @@ -137,23 +141,26 @@ class HomematicipNotificationLight(HomematicipGenericDevice, Light): } @property - def _channel(self): - return self._device.functionalChannels[self._channel_index] + def _func_channel(self): + return self._device.functionalChannels[self.channel] @property def is_on(self): """Return true if device is on.""" - return self._channel.dimLevel > 0.0 + return self._func_channel.dimLevel is not None and \ + self._func_channel.dimLevel > 0.0 @property def brightness(self): """Return the brightness of this light between 0..255.""" - return int(self._channel.dimLevel * 255) + if self._func_channel.dimLevel: + return int(self._func_channel.dimLevel * 255) + return 0 @property def hs_color(self): """Return the hue and saturation color value [float, float].""" - simple_rgb_color = self._channel.simpleRGBColorState + simple_rgb_color = self._func_channel.simpleRGBColorState return self._color_switcher.get(simple_rgb_color, [0.0, 0.0]) @property @@ -161,7 +168,7 @@ class HomematicipNotificationLight(HomematicipGenericDevice, Light): """Return the state attributes of the generic device.""" attr = super().device_state_attributes if self.is_on: - attr[ATTR_COLOR_NAME] = self._channel.simpleRGBColorState + attr[ATTR_COLOR_NAME] = self._func_channel.simpleRGBColorState return attr @property @@ -201,27 +208,25 @@ class HomematicipNotificationLight(HomematicipGenericDevice, Light): dim_level = brightness / 255.0 await self._device.set_rgb_dim_level( - self._channel_index, + self.channel, simple_rgb_color, dim_level) async def async_turn_off(self, **kwargs): """Turn the light off.""" - simple_rgb_color = self._channel.simpleRGBColorState + simple_rgb_color = self._func_channel.simpleRGBColorState await self._device.set_rgb_dim_level( - self._channel_index, + self.channel, simple_rgb_color, 0.0) -def _convert_color(color): +def _convert_color(color) -> RGBColorState: """ Convert the given color to the reduced RGBColorState color. RGBColorStat contains only 8 colors including white and black, so a conversion is required. """ - from homematicip.base.enums import RGBColorState - if color is None: return RGBColorState.WHITE diff --git a/homeassistant/components/homematicip_cloud/sensor.py b/homeassistant/components/homematicip_cloud/sensor.py index 316bf1f4cd8..4816eacd08f 100644 --- a/homeassistant/components/homematicip_cloud/sensor.py +++ b/homeassistant/components/homematicip_cloud/sensor.py @@ -1,6 +1,17 @@ """Support for HomematicIP Cloud sensors.""" import logging +from homematicip.aio.device import ( + AsyncBrandSwitchMeasuring, AsyncFullFlushSwitchMeasuring, + AsyncHeatingThermostat, AsyncHeatingThermostatCompact, AsyncLightSensor, + AsyncMotionDetectorIndoor, AsyncMotionDetectorOutdoor, + AsyncMotionDetectorPushButton, AsyncPlugableSwitchMeasuring, + AsyncTemperatureHumiditySensorDisplay, + AsyncTemperatureHumiditySensorOutdoor, + AsyncTemperatureHumiditySensorWithoutDisplay, AsyncWeatherSensor, + AsyncWeatherSensorPlus, AsyncWeatherSensorPro) +from homematicip.base.enums import ValveState + from homeassistant.const import ( DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_POWER, DEVICE_CLASS_TEMPERATURE, POWER_WATT, TEMP_CELSIUS) @@ -22,16 +33,6 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the HomematicIP Cloud sensors from a config entry.""" - from homematicip.aio.device import ( - AsyncHeatingThermostat, AsyncHeatingThermostatCompact, - AsyncTemperatureHumiditySensorWithoutDisplay, - AsyncTemperatureHumiditySensorDisplay, AsyncMotionDetectorIndoor, - AsyncMotionDetectorOutdoor, AsyncTemperatureHumiditySensorOutdoor, - AsyncMotionDetectorPushButton, AsyncLightSensor, - AsyncPlugableSwitchMeasuring, AsyncBrandSwitchMeasuring, - AsyncFullFlushSwitchMeasuring, AsyncWeatherSensor, - AsyncWeatherSensorPlus, AsyncWeatherSensorPro) - home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [HomematicipAccesspointStatus(home)] for device in home.devices: @@ -119,8 +120,6 @@ class HomematicipHeatingThermostat(HomematicipGenericDevice): @property def icon(self): """Return the icon.""" - from homematicip.base.enums import ValveState - if super().icon: return super().icon if self._device.valveState != ValveState.ADAPTION_DONE: @@ -130,8 +129,6 @@ class HomematicipHeatingThermostat(HomematicipGenericDevice): @property def state(self): """Return the state of the radiator valve.""" - from homematicip.base.enums import ValveState - if self._device.valveState != ValveState.ADAPTION_DONE: return self._device.valveState return round(self._device.valvePosition*100) @@ -299,7 +296,7 @@ class HomematicipTodayRainSensor(HomematicipGenericDevice): return 'mm' -def _get_wind_direction(wind_direction_degree): +def _get_wind_direction(wind_direction_degree) -> str: """Convert wind direction degree to named direction.""" if 11.25 <= wind_direction_degree < 33.75: return 'NNE' diff --git a/homeassistant/components/homematicip_cloud/switch.py b/homeassistant/components/homematicip_cloud/switch.py index b96e0c4cf4d..9a0d48ac253 100644 --- a/homeassistant/components/homematicip_cloud/switch.py +++ b/homeassistant/components/homematicip_cloud/switch.py @@ -1,6 +1,12 @@ """Support for HomematicIP Cloud switches.""" import logging +from homematicip.aio.device import ( + AsyncBrandSwitchMeasuring, AsyncFullFlushSwitchMeasuring, AsyncMultiIOBox, + AsyncOpenCollector8Module, AsyncPlugableSwitch, + AsyncPlugableSwitchMeasuring) +from homematicip.aio.group import AsyncSwitchingGroup + from homeassistant.components.switch import SwitchDevice from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice @@ -17,17 +23,6 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the HomematicIP switch from a config entry.""" - from homematicip.aio.device import ( - AsyncPlugableSwitch, - AsyncPlugableSwitchMeasuring, - AsyncBrandSwitchMeasuring, - AsyncFullFlushSwitchMeasuring, - AsyncOpenCollector8Module, - AsyncMultiIOBox, - ) - - from homematicip.aio.group import AsyncSwitchingGroup - home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.devices: diff --git a/homeassistant/components/homematicip_cloud/weather.py b/homeassistant/components/homematicip_cloud/weather.py index 74b302b18fc..9c7d843b448 100644 --- a/homeassistant/components/homematicip_cloud/weather.py +++ b/homeassistant/components/homematicip_cloud/weather.py @@ -2,6 +2,9 @@ """Support for HomematicIP Cloud weather devices.""" import logging +from homematicip.aio.device import ( + AsyncWeatherSensor, AsyncWeatherSensorPlus, AsyncWeatherSensorPro) + from homeassistant.components.weather import WeatherEntity from homeassistant.const import TEMP_CELSIUS @@ -18,10 +21,6 @@ async def async_setup_platform( async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the HomematicIP weather sensor from a config entry.""" - from homematicip.aio.device import ( - AsyncWeatherSensor, AsyncWeatherSensorPlus, AsyncWeatherSensorPro, - ) - home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home devices = [] for device in home.devices: