Add devolo binary_sensor devices (#36370)

* initial commit

* small corrections

* fix linting error

* add new files to coveragerc

* rename devolo_sensor to devolo_device

* use correct import

* use binary_switch platform

* use binary_switch platform

* add binary_sensor to coverage

* adjustments according PR review

* make super call easier to read

* use f-string instead of concatenating

* update docstrings - remove device_id property

* add will_remove_from_hass
This commit is contained in:
Markus Bong 2020-06-06 17:10:05 +02:00 committed by GitHub
parent d73a4e1ed5
commit 3495932eb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 179 additions and 1 deletions

View File

@ -157,7 +157,10 @@ omit =
homeassistant/components/denonavr/media_player.py
homeassistant/components/deutsche_bahn/sensor.py
homeassistant/components/devolo_home_control/__init__.py
homeassistant/components/devolo_home_control/binary_sensor.py
homeassistant/components/devolo_home_control/const.py
homeassistant/components/devolo_home_control/devolo_device.py
homeassistant/components/devolo_home_control/subscriber.py
homeassistant/components/devolo_home_control/switch.py
homeassistant/components/dht/sensor.py
homeassistant/components/digital_ocean/*

View File

@ -0,0 +1,72 @@
"""Platform for binary sensor integration."""
import logging
from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.typing import HomeAssistantType
from .const import DOMAIN
from .devolo_device import DevoloDeviceEntity
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
) -> None:
"""Get all binary sensor and multi level sensor devices and setup them via config entry."""
entities = []
for device in hass.data[DOMAIN]["homecontrol"].binary_sensor_devices:
for binary_sensor in device.binary_sensor_property:
entities.append(
DevoloBinaryDeviceEntity(
homecontrol=hass.data[DOMAIN]["homecontrol"],
device_instance=device,
element_uid=binary_sensor,
)
)
async_add_entities(entities, False)
class DevoloBinaryDeviceEntity(DevoloDeviceEntity, BinarySensorEntity):
"""Representation of a binary sensor within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid):
"""Initialize a devolo binary sensor."""
if device_instance.binary_sensor_property.get(element_uid).sub_type != "":
name = f"{device_instance.itemName} {device_instance.binary_sensor_property.get(element_uid).sub_type}"
else:
name = f"{device_instance.itemName} {device_instance.binary_sensor_property.get(element_uid).sensor_type}"
super().__init__(
homecontrol=homecontrol,
device_instance=device_instance,
element_uid=element_uid,
name=name,
sync=self._sync,
)
self._binary_sensor_property = self._device_instance.binary_sensor_property.get(
self._unique_id
)
self._state = self._binary_sensor_property.state
self._subscriber = None
@property
def is_on(self):
"""Return the state."""
return self._state
def _sync(self, message=None):
"""Update the binary sensor state."""
if message[0].startswith("devolo.BinarySensor"):
self._state = self._device_instance.binary_sensor_property[message[0]].state
elif message[0].startswith("hdm"):
self._available = self._device_instance.is_online()
else:
_LOGGER.debug("No valid message received: %s", message)
self.schedule_update_ha_state()

View File

@ -3,6 +3,6 @@
DOMAIN = "devolo_home_control"
DEFAULT_MYDEVOLO = "https://www.mydevolo.com"
DEFAULT_MPRM = "https://homecontrol.mydevolo.com"
PLATFORMS = ["switch"]
PLATFORMS = ["binary_sensor", "switch"]
CONF_MYDEVOLO = "mydevolo_url"
CONF_HOMECONTROL = "home_control_url"

View File

@ -0,0 +1,84 @@
"""Base class for a device entity integrated in devolo Home Control."""
import logging
from homeassistant.helpers.entity import Entity
from .const import DOMAIN
from .subscriber import Subscriber
_LOGGER = logging.getLogger(__name__)
ATTR_BATTERY_LEVEL = "battery_level"
class DevoloDeviceEntity(Entity):
"""Representation of a sensor within devolo Home Control."""
def __init__(self, homecontrol, device_instance, element_uid, name, sync):
"""Initialize a devolo device entity."""
self._device_instance = device_instance
self._name = name
self._unique_id = element_uid
self._homecontrol = homecontrol
self._available = device_instance.is_online()
# Get the brand and model information
self._brand = device_instance.brand
self._model = device_instance.name
self._state_attrs = {}
if hasattr(self._device_instance, "batteryLevel"):
self._state_attrs = {ATTR_BATTERY_LEVEL: self._device_instance.batteryLevel}
self.subscriber = None
self.sync_callback = sync
async def async_added_to_hass(self) -> None:
"""Call when entity is added to hass."""
self.subscriber = Subscriber(
self._device_instance.itemName, callback=self.sync_callback
)
self._homecontrol.publisher.register(
self._device_instance.uid, self.subscriber, self.sync_callback
)
async def async_will_remove_from_hass(self) -> None:
"""Call when entity is removed or disabled."""
self._homecontrol.publisher.unregister(
self._device_instance.uid, self.subscriber
)
@property
def unique_id(self):
"""Return the unique ID of the entity."""
return self._unique_id
@property
def device_info(self):
"""Return the device info."""
return {
"identifiers": {(DOMAIN, self._device_instance.uid)},
"name": self._device_instance.itemName,
"manufacturer": self._brand,
"model": self._model,
}
@property
def device_state_attributes(self):
"""Return the state attributes of the device."""
return self._state_attrs
@property
def should_poll(self):
"""Return the polling state."""
return False
@property
def name(self):
"""Return the display name of this entity."""
return self._name
@property
def available(self) -> bool:
"""Return the online state."""
return self._available

View File

@ -0,0 +1,19 @@
"""Subscriber for devolo home control API publisher."""
import logging
_LOGGER = logging.getLogger(__name__)
class Subscriber:
"""Subscriber class for the publisher in mprm websocket class."""
def __init__(self, name, callback):
"""Initiate the subscriber."""
self.name = name
self.callback = callback
def update(self, message):
"""Trigger hass to update the device."""
_LOGGER.debug('%s got message "%s"', self.name, message)
self.callback(message)