Add Types to Homematic IP (#23401)

pull/23417/head
Markus Jankowski 2019-04-26 00:13:07 +02:00 committed by Paulus Schoutsen
parent cef7ce11ad
commit 9d67c9feb6
12 changed files with 174 additions and 130 deletions

View File

@ -4,9 +4,12 @@ import logging
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers import device_registry as dr
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import ConfigType
from .config_flow import configured_haps
from .const import (
@ -26,7 +29,7 @@ CONFIG_SCHEMA = vol.Schema({
}, extra=vol.ALLOW_EXTRA)
async def async_setup(hass, config):
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the HomematicIP Cloud component."""
hass.data[DOMAIN] = {}
@ -46,7 +49,7 @@ async def async_setup(hass, config):
return True
async def async_setup_entry(hass, entry):
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up an access point from a config entry."""
hap = HomematicipHAP(hass, entry)
hapid = entry.data[HMIPC_HAPID].replace('-', '').upper()

View File

@ -2,12 +2,15 @@
import logging
from homematicip.aio.group import AsyncSecurityZoneGroup
from homematicip.aio.home import AsyncHome
from homematicip.base.enums import WindowState
from homeassistant.components.alarm_control_panel import AlarmControlPanel
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_TRIGGERED)
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
@ -20,7 +23,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP alrm control panel from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
@ -35,14 +39,14 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class HomematicipSecurityZone(HomematicipGenericDevice, AlarmControlPanel):
"""Representation of an HomematicIP Cloud security zone group."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the security zone group."""
device.modelType = 'Group-SecurityZone'
device.windowState = None
super().__init__(home, device)
@property
def state(self):
def state(self) -> str:
"""Return the state of the device."""
if self._device.active:
if (self._device.sabotage or self._device.motionDetected or

View File

@ -7,9 +7,12 @@ from homematicip.aio.device import (
AsyncShutterContact, AsyncSmokeDetector, AsyncWaterSensor,
AsyncWeatherSensor, AsyncWeatherSensorPlus, AsyncWeatherSensorPro)
from homematicip.aio.group import AsyncSecurityGroup, AsyncSecurityZoneGroup
from homematicip.aio.home import AsyncHome
from homematicip.base.enums import SmokeDetectorAlarmType, WindowState
from homeassistant.components.binary_sensor import BinarySensorDevice
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
from .device import ATTR_GROUP_MEMBER_UNREACHABLE
@ -32,7 +35,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP Cloud binary sensor from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
@ -71,12 +75,12 @@ class HomematicipShutterContact(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud shutter contact."""
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'door'
@property
def is_on(self):
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
@ -89,12 +93,12 @@ class HomematicipMotionDetector(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud motion detector."""
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'motion'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if motion is detected."""
if hasattr(self._device, 'sabotage') and self._device.sabotage:
return True
@ -105,12 +109,12 @@ class HomematicipSmokeDetector(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud smoke detector."""
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'smoke'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if smoke is detected."""
return (self._device.smokeDetectorAlarmType
!= SmokeDetectorAlarmType.IDLE_OFF)
@ -120,12 +124,12 @@ class HomematicipWaterDetector(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud water detector."""
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'moisture'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true, if moisture or waterlevel is detected."""
return self._device.moistureDetected or self._device.waterlevelDetected
@ -133,17 +137,17 @@ class HomematicipWaterDetector(HomematicipGenericDevice, BinarySensorDevice):
class HomematicipStormSensor(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud storm sensor."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize storm sensor."""
super().__init__(home, device, "Storm")
@property
def icon(self):
def icon(self) -> str:
"""Return the icon."""
return 'mdi:weather-windy' if self.is_on else 'mdi:pinwheel-outline'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true, if storm is detected."""
return self._device.storm
@ -151,17 +155,17 @@ class HomematicipStormSensor(HomematicipGenericDevice, BinarySensorDevice):
class HomematicipRainSensor(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud rain sensor."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize rain sensor."""
super().__init__(home, device, "Raining")
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'moisture'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true, if it is raining."""
return self._device.raining
@ -169,17 +173,17 @@ class HomematicipRainSensor(HomematicipGenericDevice, BinarySensorDevice):
class HomematicipSunshineSensor(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud sunshine sensor."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize sunshine sensor."""
super().__init__(home, device, 'Sunshine')
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'light'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if sun is shining."""
return self._device.sunshine
@ -197,17 +201,17 @@ class HomematicipSunshineSensor(HomematicipGenericDevice, BinarySensorDevice):
class HomematicipBatterySensor(HomematicipGenericDevice, BinarySensorDevice):
"""Representation of a HomematicIP Cloud low battery sensor."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize battery sensor."""
super().__init__(home, device, 'Battery')
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'battery'
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if battery is low."""
return self._device.lowBat
@ -216,18 +220,19 @@ class HomematicipSecurityZoneSensorGroup(HomematicipGenericDevice,
BinarySensorDevice):
"""Representation of a HomematicIP Cloud security zone group."""
def __init__(self, home, device, post='SecurityZone'):
def __init__(self, home: AsyncHome, device,
post: str = 'SecurityZone') -> None:
"""Initialize security zone group."""
device.modelType = 'HmIP-{}'.format(post)
super().__init__(home, device, post)
@property
def device_class(self):
def device_class(self) -> str:
"""Return the class of this sensor."""
return 'safety'
@property
def available(self):
def available(self) -> bool:
"""Security-Group available."""
# A security-group must be available, and should not be affected by
# the individual availability of group members.
@ -251,7 +256,7 @@ class HomematicipSecurityZoneSensorGroup(HomematicipGenericDevice,
return attr
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if security issue detected."""
if self._device.motionDetected or \
self._device.presenceDetected or \
@ -269,7 +274,7 @@ class HomematicipSecuritySensorGroup(HomematicipSecurityZoneSensorGroup,
BinarySensorDevice):
"""Representation of a HomematicIP security group."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize security group."""
super().__init__(home, device, 'Sensors')
@ -294,7 +299,7 @@ class HomematicipSecuritySensorGroup(HomematicipSecurityZoneSensorGroup,
return attr
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if safety issue detected."""
parent_is_on = super().is_on
if parent_is_on or \

View File

@ -1,12 +1,15 @@
"""Support for HomematicIP Cloud climate devices."""
import logging
from homematicip.group import HeatingGroup
from homematicip.aio.group import AsyncHeatingGroup
from homematicip.aio.home import AsyncHome
from homeassistant.components.climate import ClimateDevice
from homeassistant.components.climate.const import (
STATE_AUTO, STATE_MANUAL, SUPPORT_TARGET_TEMPERATURE)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
@ -26,12 +29,13 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP climate from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
for device in home.groups:
if isinstance(device, HeatingGroup):
if isinstance(device, AsyncHeatingGroup):
devices.append(HomematicipHeatingGroup(home, device))
if devices:
@ -41,48 +45,48 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class HomematicipHeatingGroup(HomematicipGenericDevice, ClimateDevice):
"""Representation of a HomematicIP heating group."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize heating group."""
device.modelType = 'Group-Heating'
super().__init__(home, device)
@property
def temperature_unit(self):
def temperature_unit(self) -> str:
"""Return the unit of measurement."""
return TEMP_CELSIUS
@property
def supported_features(self):
def supported_features(self) -> int:
"""Return the list of supported features."""
return SUPPORT_TARGET_TEMPERATURE
@property
def target_temperature(self):
def target_temperature(self) -> float:
"""Return the temperature we try to reach."""
return self._device.setPointTemperature
@property
def current_temperature(self):
def current_temperature(self) -> float:
"""Return the current temperature."""
return self._device.actualTemperature
@property
def current_humidity(self):
def current_humidity(self) -> int:
"""Return the current humidity."""
return self._device.humidity
@property
def current_operation(self):
def current_operation(self) -> str:
"""Return current operation ie. automatic or manual."""
return HMIP_STATE_TO_HA.get(self._device.controlMode)
@property
def min_temp(self):
def min_temp(self) -> float:
"""Return the minimum temperature."""
return self._device.minTemperature
@property
def max_temp(self):
def max_temp(self) -> float:
"""Return the maximum temperature."""
return self._device.maxTemperature

View File

@ -1,8 +1,10 @@
"""Config flow to configure the HomematicIP Cloud component."""
from typing import Set
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from homeassistant.core import HomeAssistant, callback
from .const import (
_LOGGER, DOMAIN as HMIPC_DOMAIN, HMIPC_AUTHTOKEN, HMIPC_HAPID, HMIPC_NAME,
@ -11,7 +13,7 @@ from .hap import HomematicipAuth
@callback
def configured_haps(hass):
def configured_haps(hass: HomeAssistant) -> Set[str]:
"""Return a set of the configured access points."""
return set(entry.data[HMIPC_HAPID] for entry
in hass.config_entries.async_entries(HMIPC_DOMAIN))

View File

@ -1,9 +1,12 @@
"""Support for HomematicIP Cloud cover devices."""
import logging
from typing import Optional
from homematicip.aio.device import AsyncFullFlushShutter
from homeassistant.components.cover import ATTR_POSITION, CoverDevice
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
@ -19,7 +22,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP cover from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
@ -35,7 +39,7 @@ class HomematicipCoverShutter(HomematicipGenericDevice, CoverDevice):
"""Representation of a HomematicIP Cloud cover device."""
@property
def current_cover_position(self):
def current_cover_position(self) -> int:
"""Return current position of cover."""
return int((1 - self._device.shutterLevel) * 100)
@ -47,7 +51,7 @@ class HomematicipCoverShutter(HomematicipGenericDevice, CoverDevice):
await self._device.set_shutter_level(level)
@property
def is_closed(self):
def is_closed(self) -> Optional[bool]:
"""Return if the cover is closed."""
if self._device.shutterLevel is not None:
return self._device.shutterLevel == HMIP_COVER_CLOSED

View File

@ -1,7 +1,9 @@
"""Generic device for the HomematicIP Cloud component."""
import logging
from typing import Optional
from homematicip.aio.device import AsyncDevice
from homematicip.aio.home import AsyncHome
from homeassistant.components import homematicip_cloud
from homeassistant.helpers.entity import Entity
@ -21,7 +23,8 @@ ATTR_GROUP_MEMBER_UNREACHABLE = 'group_member_unreachable'
class HomematicipGenericDevice(Entity):
"""Representation of an HomematicIP generic device."""
def __init__(self, home, device, post=None):
def __init__(self, home: AsyncHome, device,
post: Optional[str] = None) -> None:
"""Initialize the generic device."""
self._home = home
self._device = device
@ -56,7 +59,7 @@ class HomematicipGenericDevice(Entity):
self.async_schedule_update_ha_state()
@property
def name(self):
def name(self) -> str:
"""Return the name of the generic device."""
name = self._device.label
if self._home.name is not None and self._home.name != '':
@ -66,22 +69,22 @@ class HomematicipGenericDevice(Entity):
return name
@property
def should_poll(self):
def should_poll(self) -> bool:
"""No polling needed."""
return False
@property
def available(self):
def available(self) -> bool:
"""Device available."""
return not self._device.unreach
@property
def unique_id(self):
def unique_id(self) -> str:
"""Return a unique ID."""
return "{}_{}".format(self.__class__.__name__, self._device.id)
@property
def icon(self):
def icon(self) -> Optional[str]:
"""Return the icon."""
if hasattr(self._device, 'lowBat') and self._device.lowBat:
return 'mdi:battery-outline'

View File

@ -6,7 +6,8 @@ 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.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession
@ -70,7 +71,7 @@ class HomematicipAuth:
class HomematicipHAP:
"""Manages HomematicIP HTTP and WebSocket connection."""
def __init__(self, hass, config_entry):
def __init__(self, hass: HomeAssistant, config_entry: ConfigEntry) -> None:
"""Initialize HomematicIP Cloud connection."""
self.hass = hass
self.config_entry = config_entry
@ -81,7 +82,7 @@ class HomematicipHAP:
self._tries = 0
self._accesspoint_connected = True
async def async_setup(self, tries=0):
async def async_setup(self, tries: int = 0):
"""Initialize connection."""
try:
self.home = await self.get_hap(
@ -196,7 +197,8 @@ class HomematicipHAP:
self.config_entry, component)
return True
async def get_hap(self, hass, hapid, authtoken, name) -> AsyncHome:
async def get_hap(self, hass: HomeAssistant, hapid: str, authtoken: str,
name: str) -> AsyncHome:
"""Create a HomematicIP access point object."""
home = AsyncHome(hass.loop, async_get_clientsession(hass))

View File

@ -2,14 +2,18 @@
import logging
from homematicip.aio.device import (
AsyncBrandSwitchMeasuring, AsyncDimmer, AsyncPluggableDimmer,
AsyncBrandDimmer, AsyncFullFlushDimmer,
AsyncBrandSwitchNotificationLight)
AsyncBrandDimmer, AsyncBrandSwitchMeasuring,
AsyncBrandSwitchNotificationLight, AsyncDimmer, AsyncFullFlushDimmer,
AsyncPluggableDimmer)
from homematicip.aio.home import AsyncHome
from homematicip.base.enums import RGBColorState
from homematicip.base.functionalChannels import NotificationLightChannel
from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_COLOR_NAME, ATTR_HS_COLOR, SUPPORT_BRIGHTNESS,
SUPPORT_COLOR, Light)
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
@ -25,7 +29,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP Cloud lights from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
@ -50,12 +55,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class HomematicipLight(HomematicipGenericDevice, Light):
"""Representation of a HomematicIP Cloud light device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the light device."""
super().__init__(home, device)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if device is on."""
return self._device.on
@ -85,25 +90,25 @@ class HomematicipLightMeasuring(HomematicipLight):
class HomematicipDimmer(HomematicipGenericDevice, Light):
"""Representation of HomematicIP Cloud dimmer light device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the dimmer light device."""
super().__init__(home, device)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if device is on."""
return self._device.dimLevel is not None and \
self._device.dimLevel > 0.0
@property
def brightness(self):
def brightness(self) -> int:
"""Return the brightness of this light between 0..255."""
if self._device.dimLevel:
return int(self._device.dimLevel*255)
return 0
@property
def supported_features(self):
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_BRIGHTNESS
@ -122,7 +127,7 @@ class HomematicipDimmer(HomematicipGenericDevice, Light):
class HomematicipNotificationLight(HomematicipGenericDevice, Light):
"""Representation of HomematicIP Cloud dimmer light device."""
def __init__(self, home, device, channel):
def __init__(self, home: AsyncHome, device, channel: int) -> None:
"""Initialize the dimmer light device."""
self.channel = channel
if self.channel == 2:
@ -141,24 +146,24 @@ class HomematicipNotificationLight(HomematicipGenericDevice, Light):
}
@property
def _func_channel(self):
def _func_channel(self) -> NotificationLightChannel:
return self._device.functionalChannels[self.channel]
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if device is on."""
return self._func_channel.dimLevel is not None and \
self._func_channel.dimLevel > 0.0
@property
def brightness(self):
def brightness(self) -> int:
"""Return the brightness of this light between 0..255."""
if self._func_channel.dimLevel:
return int(self._func_channel.dimLevel * 255)
return 0
@property
def hs_color(self):
def hs_color(self) -> tuple:
"""Return the hue and saturation color value [float, float]."""
simple_rgb_color = self._func_channel.simpleRGBColorState
return self._color_switcher.get(simple_rgb_color, [0.0, 0.0])
@ -172,12 +177,12 @@ class HomematicipNotificationLight(HomematicipGenericDevice, Light):
return attr
@property
def name(self):
def name(self) -> str:
"""Return the name of the generic device."""
return "{} {}".format(super().name, 'Notification')
@property
def supported_features(self):
def supported_features(self) -> int:
"""Flag supported features."""
return SUPPORT_BRIGHTNESS | SUPPORT_COLOR

View File

@ -10,11 +10,14 @@ from homematicip.aio.device import (
AsyncTemperatureHumiditySensorOutdoor,
AsyncTemperatureHumiditySensorWithoutDisplay, AsyncWeatherSensor,
AsyncWeatherSensorPlus, AsyncWeatherSensorPro)
from homematicip.aio.home import AsyncHome
from homematicip.base.enums import ValveState
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_ILLUMINANCE, DEVICE_CLASS_POWER,
DEVICE_CLASS_TEMPERATURE, POWER_WATT, TEMP_CELSIUS)
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
@ -31,7 +34,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP Cloud sensors from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = [HomematicipAccesspointStatus(home)]
@ -74,7 +78,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class HomematicipAccesspointStatus(HomematicipGenericDevice):
"""Representation of an HomeMaticIP Cloud access point."""
def __init__(self, home):
def __init__(self, home: AsyncHome) -> None:
"""Initialize access point device."""
super().__init__(home, home)
@ -90,22 +94,22 @@ class HomematicipAccesspointStatus(HomematicipGenericDevice):
}
@property
def icon(self):
def icon(self) -> str:
"""Return the icon of the access point device."""
return 'mdi:access-point-network'
@property
def state(self):
def state(self) -> float:
"""Return the state of the access point."""
return self._home.dutyCycle
@property
def available(self):
def available(self) -> bool:
"""Device available."""
return self._home.connected
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return '%'
@ -113,12 +117,12 @@ class HomematicipAccesspointStatus(HomematicipGenericDevice):
class HomematicipHeatingThermostat(HomematicipGenericDevice):
"""Represenation of a HomematicIP heating thermostat device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize heating thermostat device."""
super().__init__(home, device, 'Heating')
@property
def icon(self):
def icon(self) -> str:
"""Return the icon."""
if super().icon:
return super().icon
@ -127,14 +131,14 @@ class HomematicipHeatingThermostat(HomematicipGenericDevice):
return 'mdi:radiator'
@property
def state(self):
def state(self) -> int:
"""Return the state of the radiator valve."""
if self._device.valveState != ValveState.ADAPTION_DONE:
return self._device.valveState
return round(self._device.valvePosition*100)
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return '%'
@ -142,22 +146,22 @@ class HomematicipHeatingThermostat(HomematicipGenericDevice):
class HomematicipHumiditySensor(HomematicipGenericDevice):
"""Represenation of a HomematicIP Cloud humidity device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the thermometer device."""
super().__init__(home, device, 'Humidity')
@property
def device_class(self):
def device_class(self) -> str:
"""Return the device class of the sensor."""
return DEVICE_CLASS_HUMIDITY
@property
def state(self):
def state(self) -> int:
"""Return the state."""
return self._device.humidity
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return '%'
@ -165,17 +169,17 @@ class HomematicipHumiditySensor(HomematicipGenericDevice):
class HomematicipTemperatureSensor(HomematicipGenericDevice):
"""Representation of a HomematicIP Cloud thermometer device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the thermometer device."""
super().__init__(home, device, 'Temperature')
@property
def device_class(self):
def device_class(self) -> str:
"""Return the device class of the sensor."""
return DEVICE_CLASS_TEMPERATURE
@property
def state(self):
def state(self) -> float:
"""Return the state."""
if hasattr(self._device, 'valveActualTemperature'):
return self._device.valveActualTemperature
@ -183,7 +187,7 @@ class HomematicipTemperatureSensor(HomematicipGenericDevice):
return self._device.actualTemperature
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return TEMP_CELSIUS
@ -200,17 +204,17 @@ class HomematicipTemperatureSensor(HomematicipGenericDevice):
class HomematicipIlluminanceSensor(HomematicipGenericDevice):
"""Represenation of a HomematicIP Illuminance device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the device."""
super().__init__(home, device, 'Illuminance')
@property
def device_class(self):
def device_class(self) -> str:
"""Return the device class of the sensor."""
return DEVICE_CLASS_ILLUMINANCE
@property
def state(self):
def state(self) -> float:
"""Return the state."""
if hasattr(self._device, 'averageIllumination'):
return self._device.averageIllumination
@ -218,7 +222,7 @@ class HomematicipIlluminanceSensor(HomematicipGenericDevice):
return self._device.illumination
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return 'lx'
@ -226,22 +230,22 @@ class HomematicipIlluminanceSensor(HomematicipGenericDevice):
class HomematicipPowerSensor(HomematicipGenericDevice):
"""Represenation of a HomematicIP power measuring device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the device."""
super().__init__(home, device, 'Power')
@property
def device_class(self):
def device_class(self) -> str:
"""Return the device class of the sensor."""
return DEVICE_CLASS_POWER
@property
def state(self):
def state(self) -> float:
"""Represenation of the HomematicIP power comsumption value."""
return self._device.currentPowerConsumption
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return POWER_WATT
@ -249,17 +253,17 @@ class HomematicipPowerSensor(HomematicipGenericDevice):
class HomematicipWindspeedSensor(HomematicipGenericDevice):
"""Represenation of a HomematicIP wind speed sensor."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the device."""
super().__init__(home, device, 'Windspeed')
@property
def state(self):
def state(self) -> float:
"""Represenation of the HomematicIP wind speed value."""
return self._device.windSpeed
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return 'km/h'
@ -281,22 +285,22 @@ class HomematicipWindspeedSensor(HomematicipGenericDevice):
class HomematicipTodayRainSensor(HomematicipGenericDevice):
"""Represenation of a HomematicIP rain counter of a day sensor."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the device."""
super().__init__(home, device, 'Today Rain')
@property
def state(self):
def state(self) -> float:
"""Represenation of the HomematicIP todays rain value."""
return round(self._device.todayRainCounter, 2)
@property
def unit_of_measurement(self):
def unit_of_measurement(self) -> str:
"""Return the unit this state is expressed in."""
return 'mm'
def _get_wind_direction(wind_direction_degree) -> str:
def _get_wind_direction(wind_direction_degree: float) -> str:
"""Convert wind direction degree to named direction."""
if 11.25 <= wind_direction_degree < 33.75:
return 'NNE'

View File

@ -6,8 +6,11 @@ from homematicip.aio.device import (
AsyncOpenCollector8Module, AsyncPlugableSwitch,
AsyncPlugableSwitchMeasuring)
from homematicip.aio.group import AsyncSwitchingGroup
from homematicip.aio.home import AsyncHome
from homeassistant.components.switch import SwitchDevice
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
from .device import ATTR_GROUP_MEMBER_UNREACHABLE
@ -21,7 +24,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP switch from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
@ -55,12 +59,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class HomematicipSwitch(HomematicipGenericDevice, SwitchDevice):
"""representation of a HomematicIP Cloud switch device."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the switch device."""
super().__init__(home, device)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if device is on."""
return self._device.on
@ -76,18 +80,18 @@ class HomematicipSwitch(HomematicipGenericDevice, SwitchDevice):
class HomematicipGroupSwitch(HomematicipGenericDevice, SwitchDevice):
"""representation of a HomematicIP switching group."""
def __init__(self, home, device, post='Group'):
def __init__(self, home: AsyncHome, device, post: str = 'Group') -> None:
"""Initialize switching group."""
device.modelType = 'HmIP-{}'.format(post)
super().__init__(home, device, post)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if group is on."""
return self._device.on
@property
def available(self):
def available(self) -> bool:
"""Switch-Group available."""
# A switch-group must be available, and should not be affected by the
# individual availability of group members.
@ -116,12 +120,12 @@ class HomematicipSwitchMeasuring(HomematicipSwitch):
"""Representation of a HomematicIP measuring switch device."""
@property
def current_power_w(self):
def current_power_w(self) -> float:
"""Return the current power usage in W."""
return self._device.currentPowerConsumption
@property
def today_energy_kwh(self):
def today_energy_kwh(self) -> int:
"""Return the today total energy usage in kWh."""
if self._device.energyCounter is None:
return 0
@ -131,19 +135,19 @@ class HomematicipSwitchMeasuring(HomematicipSwitch):
class HomematicipMultiSwitch(HomematicipGenericDevice, SwitchDevice):
"""Representation of a HomematicIP Cloud multi switch device."""
def __init__(self, home, device, channel):
def __init__(self, home: AsyncHome, device, channel: int):
"""Initialize the multi switch device."""
self.channel = channel
super().__init__(home, device, 'Channel{}'.format(channel))
@property
def unique_id(self):
def unique_id(self) -> str:
"""Return a unique ID."""
return "{}_{}_{}".format(self.__class__.__name__,
self.post, self._device.id)
@property
def is_on(self):
def is_on(self) -> bool:
"""Return true if device is on."""
return self._device.functionalChannels[self.channel].on

View File

@ -4,9 +4,12 @@ import logging
from homematicip.aio.device import (
AsyncWeatherSensor, AsyncWeatherSensorPlus, AsyncWeatherSensorPro)
from homematicip.aio.home import AsyncHome
from homeassistant.components.weather import WeatherEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import TEMP_CELSIUS
from homeassistant.core import HomeAssistant
from . import DOMAIN as HMIPC_DOMAIN, HMIPC_HAPID, HomematicipGenericDevice
@ -19,7 +22,8 @@ async def async_setup_platform(
pass
async def async_setup_entry(hass, config_entry, async_add_entities):
async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry,
async_add_entities) -> None:
"""Set up the HomematicIP weather sensor from a config entry."""
home = hass.data[HMIPC_DOMAIN][config_entry.data[HMIPC_HAPID]].home
devices = []
@ -36,42 +40,42 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class HomematicipWeatherSensor(HomematicipGenericDevice, WeatherEntity):
"""representation of a HomematicIP Cloud weather sensor plus & basic."""
def __init__(self, home, device):
def __init__(self, home: AsyncHome, device) -> None:
"""Initialize the weather sensor."""
super().__init__(home, device)
@property
def name(self):
def name(self) -> str:
"""Return the name of the sensor."""
return self._device.label
@property
def temperature(self):
def temperature(self) -> float:
"""Return the platform temperature."""
return self._device.actualTemperature
@property
def temperature_unit(self):
def temperature_unit(self) -> str:
"""Return the unit of measurement."""
return TEMP_CELSIUS
@property
def humidity(self):
def humidity(self) -> int:
"""Return the humidity."""
return self._device.humidity
@property
def wind_speed(self):
def wind_speed(self) -> float:
"""Return the wind speed."""
return self._device.windSpeed
@property
def attribution(self):
def attribution(self) -> str:
"""Return the attribution."""
return "Powered by Homematic IP"
@property
def condition(self):
def condition(self) -> str:
"""Return the current condition."""
if hasattr(self._device, "raining") and self._device.raining:
return 'rainy'
@ -86,6 +90,6 @@ class HomematicipWeatherSensorPro(HomematicipWeatherSensor):
"""representation of a HomematicIP weather sensor pro."""
@property
def wind_bearing(self):
def wind_bearing(self) -> float:
"""Return the wind bearing."""
return self._device.windDirection