Add devices to Verisure integration (#47913)
Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
9fd973d8e8
commit
5f627df6f8
7 changed files with 163 additions and 21 deletions
|
@ -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."""
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
|
@ -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."""
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue