Add devices to Verisure integration (#47913)

Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
Franck Nijhof 2021-03-15 23:59:41 +01:00 committed by GitHub
parent 9fd973d8e8
commit 5f627df6f8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 163 additions and 21 deletions

View file

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
from typing import Callable, Iterable from typing import Any, Callable, Iterable
from homeassistant.components.alarm_control_panel import ( from homeassistant.components.alarm_control_panel import (
FORMAT_NUMBER, FORMAT_NUMBER,
@ -56,6 +56,16 @@ class VerisureAlarm(CoordinatorEntity, AlarmControlPanelEntity):
"""Return the unique ID for this alarm control panel.""" """Return the unique ID for this alarm control panel."""
return self.coordinator.entry.data[CONF_GIID] return self.coordinator.entry.data[CONF_GIID]
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
return {
"name": "Verisure Alarm",
"manufacturer": "Verisure",
"model": "VBox",
"identifiers": {(DOMAIN, self.coordinator.entry.data[CONF_GIID])},
}
@property @property
def state(self) -> str | None: def state(self) -> str | None:
"""Return the state of the device.""" """Return the state of the device."""

View file

@ -1,7 +1,7 @@
"""Support for Verisure binary sensors.""" """Support for Verisure binary sensors."""
from __future__ import annotations from __future__ import annotations
from typing import Callable, Iterable from typing import Any, Callable, Iterable
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
DEVICE_CLASS_CONNECTIVITY, DEVICE_CLASS_CONNECTIVITY,
@ -13,7 +13,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import DOMAIN from .const import CONF_GIID, DOMAIN
from .coordinator import VerisureDataUpdateCoordinator from .coordinator import VerisureDataUpdateCoordinator
@ -57,6 +57,19 @@ class VerisureDoorWindowSensor(CoordinatorEntity, BinarySensorEntity):
"""Return the unique ID for this alarm control panel.""" """Return the unique ID for this alarm control panel."""
return f"{self.serial_number}_door_window" return f"{self.serial_number}_door_window"
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
area = self.coordinator.data["door_window"][self.serial_number]["area"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": "Shock Sensor Detector",
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
@property @property
def device_class(self) -> str: def device_class(self) -> str:
"""Return the class of this device, from component DEVICE_CLASSES.""" """Return the class of this device, from component DEVICE_CLASSES."""
@ -88,6 +101,21 @@ class VerisureEthernetStatus(CoordinatorEntity, BinarySensorEntity):
"""Return the name of the binary sensor.""" """Return the name of the binary sensor."""
return "Verisure Ethernet status" return "Verisure Ethernet status"
@property
def unique_id(self) -> str:
"""Return the unique ID for this binary sensor."""
return f"{self.coordinator.entry.data[CONF_GIID]}_ethernet"
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
return {
"name": "Verisure Alarm",
"manufacturer": "Verisure",
"model": "VBox",
"identifiers": {(DOMAIN, self.coordinator.entry.data[CONF_GIID])},
}
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return the state of the sensor.""" """Return the state of the sensor."""

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import errno import errno
import os import os
from typing import Callable, Iterable from typing import Any, Callable, Iterable
from verisure import Error as VerisureError from verisure import Error as VerisureError
@ -15,7 +15,7 @@ from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_platform import current_platform from homeassistant.helpers.entity_platform import current_platform
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN, LOGGER, SERVICE_CAPTURE_SMARTCAM from .const import CONF_GIID, DOMAIN, LOGGER, SERVICE_CAPTURE_SMARTCAM
from .coordinator import VerisureDataUpdateCoordinator from .coordinator import VerisureDataUpdateCoordinator
@ -62,6 +62,29 @@ class VerisureSmartcam(CoordinatorEntity, Camera):
self._image_id = None self._image_id = None
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self.delete_image) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, self.delete_image)
@property
def name(self) -> str:
"""Return the name of this camera."""
return self.coordinator.data["cameras"][self.serial_number]["area"]
@property
def unique_id(self) -> str:
"""Return the unique ID for this camera."""
return self.serial_number
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
area = self.coordinator.data["cameras"][self.serial_number]["area"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": "SmartCam",
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
def camera_image(self) -> bytes | None: def camera_image(self) -> bytes | None:
"""Return image response.""" """Return image response."""
self.check_imagelist() self.check_imagelist()
@ -115,16 +138,6 @@ class VerisureSmartcam(CoordinatorEntity, Camera):
if error.errno != errno.ENOENT: if error.errno != errno.ENOENT:
raise raise
@property
def name(self) -> str:
"""Return the name of this camera."""
return self.coordinator.data["cameras"][self.serial_number]["area"]
@property
def unique_id(self) -> str:
"""Return the unique ID for this camera."""
return self.serial_number
def capture_smartcam(self) -> None: def capture_smartcam(self) -> None:
"""Capture a new picture from a smartcam.""" """Capture a new picture from a smartcam."""
try: try:

View file

@ -17,6 +17,20 @@ SERVICE_CAPTURE_SMARTCAM = "capture_smartcam"
SERVICE_DISABLE_AUTOLOCK = "disable_autolock" SERVICE_DISABLE_AUTOLOCK = "disable_autolock"
SERVICE_ENABLE_AUTOLOCK = "enable_autolock" SERVICE_ENABLE_AUTOLOCK = "enable_autolock"
# Mapping of device types to a human readable name
DEVICE_TYPE_NAME = {
"CAMERAPIR2": "Camera detector",
"HOMEPAD1": "VoiceBox",
"HUMIDITY1": "Climate sensor",
"PIR2": "Camera detector",
"SIREN1": "Siren",
"SMARTCAMERA1": "SmartCam",
"SMOKE2": "Smoke detector",
"SMOKE3": "Smoke detector",
"VOICEBOX1": "VoiceBox",
"WATER1": "Water detector",
}
# Legacy; to remove after YAML removal # Legacy; to remove after YAML removal
CONF_CODE_DIGITS = "code_digits" CONF_CODE_DIGITS = "code_digits"
CONF_DEFAULT_LOCK_CODE = "default_lock_code" CONF_DEFAULT_LOCK_CODE = "default_lock_code"

View file

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
import asyncio import asyncio
from typing import Callable, Iterable from typing import Any, Callable, Iterable
from verisure import Error as VerisureError from verisure import Error as VerisureError
@ -15,6 +15,7 @@ from homeassistant.helpers.entity_platform import current_platform
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import ( from .const import (
CONF_GIID,
CONF_LOCK_CODE_DIGITS, CONF_LOCK_CODE_DIGITS,
CONF_LOCK_DEFAULT_CODE, CONF_LOCK_DEFAULT_CODE,
DEFAULT_LOCK_CODE_DIGITS, DEFAULT_LOCK_CODE_DIGITS,
@ -73,6 +74,24 @@ class VerisureDoorlock(CoordinatorEntity, LockEntity):
"""Return the name of the lock.""" """Return the name of the lock."""
return self.coordinator.data["locks"][self.serial_number]["area"] return self.coordinator.data["locks"][self.serial_number]["area"]
@property
def unique_id(self) -> str:
"""Return the unique ID for this entity."""
return self.serial_number
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
area = self.coordinator.data["locks"][self.serial_number]["area"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": "Lockguard Smartlock",
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
@property @property
def available(self) -> bool: def available(self) -> bool:
"""Return True if entity is available.""" """Return True if entity is available."""

View file

@ -1,7 +1,7 @@
"""Support for Verisure sensors.""" """Support for Verisure sensors."""
from __future__ import annotations from __future__ import annotations
from typing import Callable, Iterable from typing import Any, Callable, Iterable
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import PERCENTAGE, TEMP_CELSIUS from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
@ -9,7 +9,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import CONF_GIID, DEVICE_TYPE_NAME, DOMAIN
from .coordinator import VerisureDataUpdateCoordinator from .coordinator import VerisureDataUpdateCoordinator
@ -64,6 +64,22 @@ class VerisureThermometer(CoordinatorEntity, Entity):
"""Return the unique ID for this entity.""" """Return the unique ID for this entity."""
return f"{self.serial_number}_temperature" return f"{self.serial_number}_temperature"
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
device_type = self.coordinator.data["climate"][self.serial_number].get(
"deviceType"
)
area = self.coordinator.data["climate"][self.serial_number]["deviceArea"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": DEVICE_TYPE_NAME.get(device_type, device_type),
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
@property @property
def state(self) -> str | None: def state(self) -> str | None:
"""Return the state of the entity.""" """Return the state of the entity."""
@ -107,6 +123,22 @@ class VerisureHygrometer(CoordinatorEntity, Entity):
"""Return the unique ID for this entity.""" """Return the unique ID for this entity."""
return f"{self.serial_number}_humidity" return f"{self.serial_number}_humidity"
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
device_type = self.coordinator.data["climate"][self.serial_number].get(
"deviceType"
)
area = self.coordinator.data["climate"][self.serial_number]["deviceArea"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": DEVICE_TYPE_NAME.get(device_type, device_type),
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
@property @property
def state(self) -> str | None: def state(self) -> str | None:
"""Return the state of the entity.""" """Return the state of the entity."""
@ -150,6 +182,19 @@ class VerisureMouseDetection(CoordinatorEntity, Entity):
"""Return the unique ID for this entity.""" """Return the unique ID for this entity."""
return f"{self.serial_number}_mice" return f"{self.serial_number}_mice"
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
area = self.coordinator.data["mice"][self.serial_number]["area"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": "Mouse detector",
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
@property @property
def state(self) -> str | None: def state(self) -> str | None:
"""Return the state of the device.""" """Return the state of the device."""

View file

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
from time import monotonic from time import monotonic
from typing import Callable, Iterable from typing import Any, Callable, Iterable
from homeassistant.components.switch import SwitchEntity from homeassistant.components.switch import SwitchEntity
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
@ -10,7 +10,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import CONF_GIID, DOMAIN
from .coordinator import VerisureDataUpdateCoordinator from .coordinator import VerisureDataUpdateCoordinator
@ -48,9 +48,22 @@ class VerisureSmartplug(CoordinatorEntity, SwitchEntity):
@property @property
def unique_id(self) -> str: def unique_id(self) -> str:
"""Return the unique ID for this alarm control panel.""" """Return the unique ID for this entity."""
return self.serial_number return self.serial_number
@property
def device_info(self) -> dict[str, Any]:
"""Return device information about this entity."""
area = self.coordinator.data["smart_plugs"][self.serial_number]["area"]
return {
"name": area,
"suggested_area": area,
"manufacturer": "Verisure",
"model": "SmartPlug",
"identifiers": {(DOMAIN, self.serial_number)},
"via_device": (DOMAIN, self.coordinator.entry.data[CONF_GIID]),
}
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return true if on.""" """Return true if on."""