Use attributes in zoneminder (#77895)

This commit is contained in:
epenet 2022-09-19 15:05:29 +02:00 committed by GitHub
parent ecef755217
commit d83e9072e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 91 deletions

View File

@ -1,6 +1,8 @@
"""Support for ZoneMinder binary sensors.""" """Support for ZoneMinder binary sensors."""
from __future__ import annotations from __future__ import annotations
from zoneminder.zm import ZoneMinder
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass, BinarySensorDeviceClass,
BinarySensorEntity, BinarySensorEntity,
@ -28,27 +30,13 @@ async def async_setup_platform(
class ZMAvailabilitySensor(BinarySensorEntity): class ZMAvailabilitySensor(BinarySensorEntity):
"""Representation of the availability of ZoneMinder as a binary sensor.""" """Representation of the availability of ZoneMinder as a binary sensor."""
def __init__(self, host_name, client): _attr_device_class = BinarySensorDeviceClass.CONNECTIVITY
def __init__(self, host_name: str, client: ZoneMinder) -> None:
"""Initialize availability sensor.""" """Initialize availability sensor."""
self._state = None self._attr_name = host_name
self._name = host_name
self._client = client self._client = client
@property
def name(self):
"""Return the name of this binary sensor."""
return self._name
@property
def is_on(self):
"""Return true if the binary sensor is on."""
return self._state
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return BinarySensorDeviceClass.CONNECTIVITY
def update(self) -> None: def update(self) -> None:
"""Update the state of this sensor (availability of ZoneMinder).""" """Update the state of this sensor (availability of ZoneMinder)."""
self._state = self._client.is_available self._attr_is_on = self._client.is_available

View File

@ -3,6 +3,9 @@ from __future__ import annotations
import logging import logging
from zoneminder.monitor import Monitor
from zoneminder.zm import ZoneMinder
from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -22,6 +25,7 @@ def setup_platform(
"""Set up the ZoneMinder cameras.""" """Set up the ZoneMinder cameras."""
filter_urllib3_logging() filter_urllib3_logging()
cameras = [] cameras = []
zm_client: ZoneMinder
for zm_client in hass.data[ZONEMINDER_DOMAIN].values(): for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
if not (monitors := zm_client.get_monitors()): if not (monitors := zm_client.get_monitors()):
_LOGGER.warning("Could not fetch monitors from ZoneMinder host: %s") _LOGGER.warning("Could not fetch monitors from ZoneMinder host: %s")
@ -38,7 +42,7 @@ class ZoneMinderCamera(MjpegCamera):
_attr_should_poll = True # Cameras default to False _attr_should_poll = True # Cameras default to False
def __init__(self, monitor, verify_ssl): def __init__(self, monitor: Monitor, verify_ssl: bool) -> None:
"""Initialize as a subclass of MjpegCamera.""" """Initialize as a subclass of MjpegCamera."""
super().__init__( super().__init__(
name=monitor.name, name=monitor.name,
@ -46,22 +50,12 @@ class ZoneMinderCamera(MjpegCamera):
still_image_url=monitor.still_image_url, still_image_url=monitor.still_image_url,
verify_ssl=verify_ssl, verify_ssl=verify_ssl,
) )
self._is_recording = None self._attr_is_recording = False
self._is_available = None self._attr_available = False
self._monitor = monitor self._monitor = monitor
def update(self) -> None: def update(self) -> None:
"""Update our recording state from the ZM API.""" """Update our recording state from the ZM API."""
_LOGGER.debug("Updating camera state for monitor %i", self._monitor.id) _LOGGER.debug("Updating camera state for monitor %i", self._monitor.id)
self._is_recording = self._monitor.is_recording self._attr_is_recording = self._monitor.is_recording
self._is_available = self._monitor.is_available self._attr_available = self._monitor.is_available
@property
def is_recording(self):
"""Return whether the monitor is in alarm mode."""
return self._is_recording
@property
def available(self):
"""Return True if entity is available."""
return self._is_available

View File

@ -4,7 +4,8 @@ from __future__ import annotations
import logging import logging
import voluptuous as vol import voluptuous as vol
from zoneminder.monitor import TimePeriod from zoneminder.monitor import Monitor, TimePeriod
from zoneminder.zm import ZoneMinder
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
@ -73,6 +74,7 @@ def setup_platform(
monitored_conditions = config[CONF_MONITORED_CONDITIONS] monitored_conditions = config[CONF_MONITORED_CONDITIONS]
sensors: list[SensorEntity] = [] sensors: list[SensorEntity] = []
zm_client: ZoneMinder
for zm_client in hass.data[ZONEMINDER_DOMAIN].values(): for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
if not (monitors := zm_client.get_monitors()): if not (monitors := zm_client.get_monitors()):
_LOGGER.warning("Could not fetch any monitors from ZoneMinder") _LOGGER.warning("Could not fetch any monitors from ZoneMinder")
@ -95,34 +97,19 @@ def setup_platform(
class ZMSensorMonitors(SensorEntity): class ZMSensorMonitors(SensorEntity):
"""Get the status of each ZoneMinder monitor.""" """Get the status of each ZoneMinder monitor."""
def __init__(self, monitor): def __init__(self, monitor: Monitor) -> None:
"""Initialize monitor sensor.""" """Initialize monitor sensor."""
self._monitor = monitor self._monitor = monitor
self._state = None self._attr_available = False
self._is_available = None self._attr_name = f"{self._monitor.name} Status"
@property
def name(self):
"""Return the name of the sensor."""
return f"{self._monitor.name} Status"
@property
def native_value(self):
"""Return the state of the sensor."""
return self._state
@property
def available(self):
"""Return True if Monitor is available."""
return self._is_available
def update(self) -> None: def update(self) -> None:
"""Update the sensor.""" """Update the sensor."""
if not (state := self._monitor.function): if not (state := self._monitor.function):
self._state = None self._attr_native_value = None
else: else:
self._state = state.value self._attr_native_value = state.value
self._is_available = self._monitor.is_available self._attr_available = self._monitor.is_available
class ZMSensorEvents(SensorEntity): class ZMSensorEvents(SensorEntity):
@ -130,18 +117,19 @@ class ZMSensorEvents(SensorEntity):
_attr_native_unit_of_measurement = "Events" _attr_native_unit_of_measurement = "Events"
def __init__(self, monitor, include_archived, description: SensorEntityDescription): def __init__(
self,
monitor: Monitor,
include_archived: bool,
description: SensorEntityDescription,
) -> None:
"""Initialize event sensor.""" """Initialize event sensor."""
self.entity_description = description self.entity_description = description
self._monitor = monitor self._monitor = monitor
self._include_archived = include_archived self._include_archived = include_archived
self.time_period = TimePeriod.get_time_period(description.key) self.time_period = TimePeriod.get_time_period(description.key)
self._attr_name = f"{monitor.name} {self.time_period.title}"
@property
def name(self):
"""Return the name of the sensor."""
return f"{self._monitor.name} {self.time_period.title}"
def update(self) -> None: def update(self) -> None:
"""Update the sensor.""" """Update the sensor."""
@ -153,28 +141,14 @@ class ZMSensorEvents(SensorEntity):
class ZMSensorRunState(SensorEntity): class ZMSensorRunState(SensorEntity):
"""Get the ZoneMinder run state.""" """Get the ZoneMinder run state."""
def __init__(self, client): _attr_name = "Run State"
def __init__(self, client: ZoneMinder) -> None:
"""Initialize run state sensor.""" """Initialize run state sensor."""
self._state = None self._attr_available = False
self._is_available = None
self._client = client self._client = client
@property
def name(self):
"""Return the name of the sensor."""
return "Run State"
@property
def native_value(self):
"""Return the state of the sensor."""
return self._state
@property
def available(self):
"""Return True if ZoneMinder is available."""
return self._is_available
def update(self) -> None: def update(self) -> None:
"""Update the sensor.""" """Update the sensor."""
self._state = self._client.get_active_state() self._attr_native_value = self._client.get_active_state()
self._is_available = self._client.is_available self._attr_available = self._client.is_available

View File

@ -5,7 +5,8 @@ import logging
from typing import Any from typing import Any
import voluptuous as vol import voluptuous as vol
from zoneminder.monitor import MonitorState from zoneminder.monitor import Monitor, MonitorState
from zoneminder.zm import ZoneMinder
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
from homeassistant.const import CONF_COMMAND_OFF, CONF_COMMAND_ON from homeassistant.const import CONF_COMMAND_OFF, CONF_COMMAND_ON
@ -38,6 +39,7 @@ def setup_platform(
off_state = MonitorState(config.get(CONF_COMMAND_OFF)) off_state = MonitorState(config.get(CONF_COMMAND_OFF))
switches = [] switches = []
zm_client: ZoneMinder
for zm_client in hass.data[ZONEMINDER_DOMAIN].values(): for zm_client in hass.data[ZONEMINDER_DOMAIN].values():
if not (monitors := zm_client.get_monitors()): if not (monitors := zm_client.get_monitors()):
_LOGGER.warning("Could not fetch monitors from ZoneMinder") _LOGGER.warning("Could not fetch monitors from ZoneMinder")
@ -53,24 +55,20 @@ class ZMSwitchMonitors(SwitchEntity):
icon = "mdi:record-rec" icon = "mdi:record-rec"
def __init__(self, monitor, on_state, off_state): def __init__(self, monitor: Monitor, on_state: str, off_state: str) -> None:
"""Initialize the switch.""" """Initialize the switch."""
self._monitor = monitor self._monitor = monitor
self._on_state = on_state self._on_state = on_state
self._off_state = off_state self._off_state = off_state
self._state = None self._state: bool | None = None
self._attr_name = f"{monitor.name} State"
@property
def name(self):
"""Return the name of the switch."""
return f"{self._monitor.name} State"
def update(self) -> None: def update(self) -> None:
"""Update the switch value.""" """Update the switch value."""
self._state = self._monitor.function == self._on_state self._state = self._monitor.function == self._on_state
@property @property
def is_on(self): def is_on(self) -> bool | None:
"""Return True if entity is on.""" """Return True if entity is on."""
return self._state return self._state