Use SensorEntityDescription for arlo (#54223)
* Use SensorEntityDescription.
This commit is contained in:
parent
e7f0768ae6
commit
6ea50823c1
2 changed files with 75 additions and 57 deletions
|
@ -1,13 +1,19 @@
|
|||
"""Sensor support for Netgear Arlo IP cameras."""
|
||||
from dataclasses import replace
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import PLATFORM_SCHEMA, SensorEntity
|
||||
from homeassistant.components.sensor import (
|
||||
PLATFORM_SCHEMA,
|
||||
SensorEntity,
|
||||
SensorEntityDescription,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION,
|
||||
CONCENTRATION_PARTS_PER_MILLION,
|
||||
CONF_MONITORED_CONDITIONS,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
PERCENTAGE,
|
||||
|
@ -22,17 +28,43 @@ from . import ATTRIBUTION, DATA_ARLO, DEFAULT_BRAND, SIGNAL_UPDATE_ARLO
|
|||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
# sensor_type [ description, unit, icon ]
|
||||
SENSOR_TYPES = {
|
||||
"last_capture": ["Last", None, "run-fast"],
|
||||
"total_cameras": ["Arlo Cameras", None, "video"],
|
||||
"captured_today": ["Captured Today", None, "file-video"],
|
||||
"battery_level": ["Battery Level", PERCENTAGE, "battery-50"],
|
||||
"signal_strength": ["Signal Strength", None, "signal"],
|
||||
"temperature": ["Temperature", TEMP_CELSIUS, "thermometer"],
|
||||
"humidity": ["Humidity", PERCENTAGE, "water-percent"],
|
||||
"air_quality": ["Air Quality", CONCENTRATION_PARTS_PER_MILLION, "biohazard"],
|
||||
}
|
||||
SENSOR_TYPES = (
|
||||
SensorEntityDescription(key="last_capture", name="Last", icon="mdi:run-fast"),
|
||||
SensorEntityDescription(key="total_cameras", name="Arlo Cameras", icon="mdi:video"),
|
||||
SensorEntityDescription(
|
||||
key="captured_today", name="Captured Today", icon="mdi:file-video"
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="battery_level",
|
||||
name="Battery Level",
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:battery-50",
|
||||
device_class=DEVICE_CLASS_BATTERY,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="signal_strength", name="Signal Strength", icon="mdi:signal"
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="temperature",
|
||||
name="Temperature",
|
||||
unit_of_measurement=TEMP_CELSIUS,
|
||||
icon="mdi:thermometer",
|
||||
device_class=DEVICE_CLASS_TEMPERATURE,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="humidity",
|
||||
name="Humidity",
|
||||
unit_of_measurement=PERCENTAGE,
|
||||
icon="mdi:water-percent",
|
||||
device_class=DEVICE_CLASS_HUMIDITY,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key="air_quality",
|
||||
name="Air Quality",
|
||||
unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
icon="mdi:biohazard",
|
||||
),
|
||||
)
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
|
@ -50,24 +82,27 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
return
|
||||
|
||||
sensors = []
|
||||
for sensor_type in config[CONF_MONITORED_CONDITIONS]:
|
||||
if sensor_type == "total_cameras":
|
||||
sensors.append(ArloSensor(SENSOR_TYPES[sensor_type][0], arlo, sensor_type))
|
||||
for sensor_original in SENSOR_TYPES:
|
||||
if sensor_original.key not in config[CONF_MONITORED_CONDITIONS]:
|
||||
continue
|
||||
sensor_entry = replace(sensor_original)
|
||||
if sensor_entry.key == "total_cameras":
|
||||
sensors.append(ArloSensor(arlo, sensor_entry))
|
||||
else:
|
||||
for camera in arlo.cameras:
|
||||
if sensor_type in ("temperature", "humidity", "air_quality"):
|
||||
if sensor_entry.key in ("temperature", "humidity", "air_quality"):
|
||||
continue
|
||||
|
||||
name = f"{SENSOR_TYPES[sensor_type][0]} {camera.name}"
|
||||
sensors.append(ArloSensor(name, camera, sensor_type))
|
||||
sensor_entry.name = f"{sensor_entry.name} {camera.name}"
|
||||
sensors.append(ArloSensor(camera, sensor_entry))
|
||||
|
||||
for base_station in arlo.base_stations:
|
||||
if (
|
||||
sensor_type in ("temperature", "humidity", "air_quality")
|
||||
sensor_entry.key in ("temperature", "humidity", "air_quality")
|
||||
and base_station.model_id == "ABC1000"
|
||||
):
|
||||
name = f"{SENSOR_TYPES[sensor_type][0]} {base_station.name}"
|
||||
sensors.append(ArloSensor(name, base_station, sensor_type))
|
||||
sensor_entry.name = f"{sensor_entry.name} {base_station.name}"
|
||||
sensors.append(ArloSensor(base_station, sensor_entry))
|
||||
|
||||
add_entities(sensors, True)
|
||||
|
||||
|
@ -75,19 +110,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
class ArloSensor(SensorEntity):
|
||||
"""An implementation of a Netgear Arlo IP sensor."""
|
||||
|
||||
def __init__(self, name, device, sensor_type):
|
||||
def __init__(self, device, sensor_entry):
|
||||
"""Initialize an Arlo sensor."""
|
||||
_LOGGER.debug("ArloSensor created for %s", name)
|
||||
self._name = name
|
||||
self.entity_description = sensor_entry
|
||||
self._data = device
|
||||
self._sensor_type = sensor_type
|
||||
self._state = None
|
||||
self._icon = f"mdi:{SENSOR_TYPES.get(self._sensor_type)[2]}"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of this camera."""
|
||||
return self._name
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
"""Register callbacks."""
|
||||
|
@ -110,36 +137,22 @@ class ArloSensor(SensorEntity):
|
|||
@property
|
||||
def icon(self):
|
||||
"""Icon to use in the frontend, if any."""
|
||||
if self._sensor_type == "battery_level" and self._state is not None:
|
||||
if self.entity_description.key == "battery_level" and self._state is not None:
|
||||
return icon_for_battery_level(
|
||||
battery_level=int(self._state), charging=False
|
||||
)
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the units of measurement."""
|
||||
return SENSOR_TYPES.get(self._sensor_type)[1]
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device class of the sensor."""
|
||||
if self._sensor_type == "temperature":
|
||||
return DEVICE_CLASS_TEMPERATURE
|
||||
if self._sensor_type == "humidity":
|
||||
return DEVICE_CLASS_HUMIDITY
|
||||
return None
|
||||
return self.entity_description.icon
|
||||
|
||||
def update(self):
|
||||
"""Get the latest data and updates the state."""
|
||||
_LOGGER.debug("Updating Arlo sensor %s", self.name)
|
||||
if self._sensor_type == "total_cameras":
|
||||
if self.entity_description.key == "total_cameras":
|
||||
self._state = len(self._data.cameras)
|
||||
|
||||
elif self._sensor_type == "captured_today":
|
||||
elif self.entity_description.key == "captured_today":
|
||||
self._state = len(self._data.captured_today)
|
||||
|
||||
elif self._sensor_type == "last_capture":
|
||||
elif self.entity_description.key == "last_capture":
|
||||
try:
|
||||
video = self._data.last_video
|
||||
self._state = video.created_at_pretty("%m-%d-%Y %H:%M:%S")
|
||||
|
@ -151,31 +164,31 @@ class ArloSensor(SensorEntity):
|
|||
_LOGGER.debug(error_msg)
|
||||
self._state = None
|
||||
|
||||
elif self._sensor_type == "battery_level":
|
||||
elif self.entity_description.key == "battery_level":
|
||||
try:
|
||||
self._state = self._data.battery_level
|
||||
except TypeError:
|
||||
self._state = None
|
||||
|
||||
elif self._sensor_type == "signal_strength":
|
||||
elif self.entity_description.key == "signal_strength":
|
||||
try:
|
||||
self._state = self._data.signal_strength
|
||||
except TypeError:
|
||||
self._state = None
|
||||
|
||||
elif self._sensor_type == "temperature":
|
||||
elif self.entity_description.key == "temperature":
|
||||
try:
|
||||
self._state = self._data.ambient_temperature
|
||||
except TypeError:
|
||||
self._state = None
|
||||
|
||||
elif self._sensor_type == "humidity":
|
||||
elif self.entity_description.key == "humidity":
|
||||
try:
|
||||
self._state = self._data.ambient_humidity
|
||||
except TypeError:
|
||||
self._state = None
|
||||
|
||||
elif self._sensor_type == "air_quality":
|
||||
elif self.entity_description.key == "air_quality":
|
||||
try:
|
||||
self._state = self._data.ambient_air_quality
|
||||
except TypeError:
|
||||
|
@ -189,7 +202,7 @@ class ArloSensor(SensorEntity):
|
|||
attrs[ATTR_ATTRIBUTION] = ATTRIBUTION
|
||||
attrs["brand"] = DEFAULT_BRAND
|
||||
|
||||
if self._sensor_type != "total_cameras":
|
||||
if self.entity_description.key != "total_cameras":
|
||||
attrs["model"] = self._data.model_id
|
||||
|
||||
return attrs
|
||||
|
|
|
@ -5,6 +5,7 @@ from unittest.mock import patch
|
|||
import pytest
|
||||
|
||||
from homeassistant.components.arlo import DATA_ARLO, sensor as arlo
|
||||
from homeassistant.components.arlo.sensor import SENSOR_TYPES
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
|
@ -20,7 +21,11 @@ def _get_named_tuple(input_dict):
|
|||
def _get_sensor(name="Last", sensor_type="last_capture", data=None):
|
||||
if data is None:
|
||||
data = {}
|
||||
return arlo.ArloSensor(name, data, sensor_type)
|
||||
sensor_entry = next(
|
||||
sensor_entry for sensor_entry in SENSOR_TYPES if sensor_entry.key == sensor_type
|
||||
)
|
||||
sensor_entry.name = name
|
||||
return arlo.ArloSensor(data, sensor_entry)
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
|
|
Loading…
Add table
Reference in a new issue