Use EntityDescription - amcrest (#54998)

This commit is contained in:
Marc Mueller 2021-08-23 22:32:01 +02:00 committed by GitHub
parent e5a350e786
commit 1f6a70bafd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 51 deletions

View File

@ -48,7 +48,7 @@ from .const import (
SERVICE_UPDATE, SERVICE_UPDATE,
) )
from .helpers import service_signal from .helpers import service_signal
from .sensor import SENSORS from .sensor import SENSOR_KEYS
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -102,7 +102,7 @@ AMCREST_SCHEMA = vol.Schema(
cv.ensure_list, [vol.In(BINARY_SENSORS)], vol.Unique(), check_binary_sensors cv.ensure_list, [vol.In(BINARY_SENSORS)], vol.Unique(), check_binary_sensors
), ),
vol.Optional(CONF_SENSORS): vol.All( vol.Optional(CONF_SENSORS): vol.All(
cv.ensure_list, [vol.In(SENSORS)], vol.Unique() cv.ensure_list, [vol.In(SENSOR_KEYS)], vol.Unique()
), ),
vol.Optional(CONF_CONTROL_LIGHT, default=True): cv.boolean, vol.Optional(CONF_CONTROL_LIGHT, default=True): cv.boolean,
} }

View File

@ -1,10 +1,12 @@
"""Support for Amcrest IP camera sensors.""" """Support for Amcrest IP camera sensors."""
from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
from amcrest import AmcrestError from amcrest import AmcrestError
from homeassistant.components.sensor import SensorEntity from homeassistant.components.sensor import SensorEntity, SensorEntityDescription
from homeassistant.const import CONF_NAME, CONF_SENSORS, PERCENTAGE from homeassistant.const import CONF_NAME, CONF_SENSORS, PERCENTAGE
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
@ -17,11 +19,22 @@ SCAN_INTERVAL = timedelta(seconds=SENSOR_SCAN_INTERVAL_SECS)
SENSOR_PTZ_PRESET = "ptz_preset" SENSOR_PTZ_PRESET = "ptz_preset"
SENSOR_SDCARD = "sdcard" SENSOR_SDCARD = "sdcard"
# Sensor types are defined like: Name, units, icon
SENSORS = { SENSOR_TYPES: tuple[SensorEntityDescription, ...] = (
SENSOR_PTZ_PRESET: ["PTZ Preset", None, "mdi:camera-iris"], SensorEntityDescription(
SENSOR_SDCARD: ["SD Used", PERCENTAGE, "mdi:sd"], key=SENSOR_PTZ_PRESET,
} name="PTZ Preset",
icon="mdi:camera-iris",
),
SensorEntityDescription(
key=SENSOR_SDCARD,
name="SD Used",
native_unit_of_measurement=PERCENTAGE,
icon="mdi:sd",
),
)
SENSOR_KEYS: list[str] = [desc.key for desc in SENSOR_TYPES]
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None): async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
@ -31,10 +44,12 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
name = discovery_info[CONF_NAME] name = discovery_info[CONF_NAME]
device = hass.data[DATA_AMCREST][DEVICES][name] device = hass.data[DATA_AMCREST][DEVICES][name]
sensors = discovery_info[CONF_SENSORS]
async_add_entities( async_add_entities(
[ [
AmcrestSensor(name, device, sensor_type) AmcrestSensor(name, device, description)
for sensor_type in discovery_info[CONF_SENSORS] for description in SENSOR_TYPES
if description.key in sensors
], ],
True, True,
) )
@ -43,42 +58,14 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
class AmcrestSensor(SensorEntity): class AmcrestSensor(SensorEntity):
"""A sensor implementation for Amcrest IP camera.""" """A sensor implementation for Amcrest IP camera."""
def __init__(self, name, device, sensor_type): def __init__(self, name, device, description: SensorEntityDescription):
"""Initialize a sensor for Amcrest camera.""" """Initialize a sensor for Amcrest camera."""
self._name = f"{name} {SENSORS[sensor_type][0]}" self.entity_description = description
self._signal_name = name self._signal_name = name
self._api = device.api self._api = device.api
self._sensor_type = sensor_type
self._state = None
self._attrs = {}
self._unit_of_measurement = SENSORS[sensor_type][1]
self._icon = SENSORS[sensor_type][2]
self._unsub_dispatcher = None self._unsub_dispatcher = None
@property self._attr_name = f"{name} {description.name}"
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def native_value(self):
"""Return the state of the sensor."""
return self._state
@property
def extra_state_attributes(self):
"""Return the state attributes."""
return self._attrs
@property
def icon(self):
"""Icon to use in the frontend, if any."""
return self._icon
@property
def native_unit_of_measurement(self):
"""Return the units of measurement."""
return self._unit_of_measurement
@property @property
def available(self): def available(self):
@ -89,32 +76,35 @@ class AmcrestSensor(SensorEntity):
"""Get the latest data and updates the state.""" """Get the latest data and updates the state."""
if not self.available: if not self.available:
return return
_LOGGER.debug("Updating %s sensor", self._name) _LOGGER.debug("Updating %s sensor", self.name)
sensor_type = self.entity_description.key
try: try:
if self._sensor_type == SENSOR_PTZ_PRESET: if sensor_type == SENSOR_PTZ_PRESET:
self._state = self._api.ptz_presets_count self._attr_native_value = self._api.ptz_presets_count
elif self._sensor_type == SENSOR_SDCARD: elif sensor_type == SENSOR_SDCARD:
storage = self._api.storage_all storage = self._api.storage_all
try: try:
self._attrs[ self._attr_extra_state_attributes[
"Total" "Total"
] = f"{storage['total'][0]:.2f} {storage['total'][1]}" ] = f"{storage['total'][0]:.2f} {storage['total'][1]}"
except ValueError: except ValueError:
self._attrs[ self._attr_extra_state_attributes[
"Total" "Total"
] = f"{storage['total'][0]} {storage['total'][1]}" ] = f"{storage['total'][0]} {storage['total'][1]}"
try: try:
self._attrs[ self._attr_extra_state_attributes[
"Used" "Used"
] = f"{storage['used'][0]:.2f} {storage['used'][1]}" ] = f"{storage['used'][0]:.2f} {storage['used'][1]}"
except ValueError: except ValueError:
self._attrs["Used"] = f"{storage['used'][0]} {storage['used'][1]}" self._attr_extra_state_attributes[
"Used"
] = f"{storage['used'][0]} {storage['used'][1]}"
try: try:
self._state = f"{storage['used_percent']:.2f}" self._attr_native_value = f"{storage['used_percent']:.2f}"
except ValueError: except ValueError:
self._state = storage["used_percent"] self._attr_native_value = storage["used_percent"]
except AmcrestError as error: except AmcrestError as error:
log_update_error(_LOGGER, "update", self.name, "sensor", error) log_update_error(_LOGGER, "update", self.name, "sensor", error)