Add Reolink hdd/sd card storage sensor (#110961)

This commit is contained in:
starkillerOG 2024-03-21 11:41:32 +01:00 committed by GitHub
parent 25fe74aec5
commit cd934c21f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 73 additions and 3 deletions

View file

@ -202,6 +202,12 @@
}, },
"wifi_signal": { "wifi_signal": {
"default": "mdi:wifi" "default": "mdi:wifi"
},
"hdd_storage": {
"default": "mdi:harddisk"
},
"sd_storage": {
"default": "mdi:micro-sd"
} }
}, },
"siren": { "siren": {

View file

@ -15,7 +15,7 @@ from homeassistant.components.sensor import (
SensorStateClass, SensorStateClass,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import EntityCategory from homeassistant.const import PERCENTAGE, EntityCategory
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import StateType from homeassistant.helpers.typing import StateType
@ -37,7 +37,7 @@ class ReolinkSensorEntityDescription(
): ):
"""A class that describes sensor entities for a camera channel.""" """A class that describes sensor entities for a camera channel."""
value: Callable[[Host, int], int] value: Callable[[Host, int], int | float]
@dataclass(frozen=True, kw_only=True) @dataclass(frozen=True, kw_only=True)
@ -75,6 +75,19 @@ HOST_SENSORS = (
), ),
) )
HDD_SENSORS = (
ReolinkSensorEntityDescription(
key="storage",
cmd_key="GetHddInfo",
native_unit_of_measurement=PERCENTAGE,
state_class=SensorStateClass.MEASUREMENT,
entity_category=EntityCategory.DIAGNOSTIC,
entity_registry_enabled_default=False,
value=lambda api, idx: api.hdd_storage(idx),
supported=lambda api, idx: api.supported(None, "hdd"),
),
)
async def async_setup_entry( async def async_setup_entry(
hass: HomeAssistant, hass: HomeAssistant,
@ -84,7 +97,9 @@ async def async_setup_entry(
"""Set up a Reolink IP Camera.""" """Set up a Reolink IP Camera."""
reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id] reolink_data: ReolinkData = hass.data[DOMAIN][config_entry.entry_id]
entities: list[ReolinkSensorEntity | ReolinkHostSensorEntity] = [ entities: list[
ReolinkSensorEntity | ReolinkHostSensorEntity | ReolinkHddSensorEntity
] = [
ReolinkSensorEntity(reolink_data, channel, entity_description) ReolinkSensorEntity(reolink_data, channel, entity_description)
for entity_description in SENSORS for entity_description in SENSORS
for channel in reolink_data.host.api.channels for channel in reolink_data.host.api.channels
@ -97,6 +112,14 @@ async def async_setup_entry(
if entity_description.supported(reolink_data.host.api) if entity_description.supported(reolink_data.host.api)
] ]
) )
entities.extend(
[
ReolinkHddSensorEntity(reolink_data, hdd_index, entity_description)
for entity_description in HDD_SENSORS
for hdd_index in reolink_data.host.api.hdd_list
if entity_description.supported(reolink_data.host.api, hdd_index)
]
)
async_add_entities(entities) async_add_entities(entities)
@ -139,3 +162,38 @@ class ReolinkHostSensorEntity(ReolinkHostCoordinatorEntity, SensorEntity):
def native_value(self) -> StateType | date | datetime | Decimal: def native_value(self) -> StateType | date | datetime | Decimal:
"""Return the value reported by the sensor.""" """Return the value reported by the sensor."""
return self.entity_description.value(self._host.api) return self.entity_description.value(self._host.api)
class ReolinkHddSensorEntity(ReolinkHostCoordinatorEntity, SensorEntity):
"""Base sensor class for Reolink host sensors."""
entity_description: ReolinkSensorEntityDescription
def __init__(
self,
reolink_data: ReolinkData,
hdd_index: int,
entity_description: ReolinkSensorEntityDescription,
) -> None:
"""Initialize Reolink host sensor."""
self.entity_description = entity_description
super().__init__(reolink_data)
self._hdd_index = hdd_index
self._attr_translation_placeholders = {"hdd_index": str(hdd_index)}
self._attr_unique_id = (
f"{self._host.unique_id}_{hdd_index}_{entity_description.key}"
)
if self._host.api.hdd_type(hdd_index) == "HDD":
self._attr_translation_key = "hdd_storage"
else:
self._attr_translation_key = "sd_storage"
@property
def native_value(self) -> StateType | date | datetime | Decimal:
"""Return the value reported by the sensor."""
return self.entity_description.value(self._host.api, self._hdd_index)
@property
def available(self) -> bool:
"""Return True if entity is available."""
return self._host.api.hdd_available(self._hdd_index) and super().available

View file

@ -396,6 +396,12 @@
}, },
"ptz_pan_position": { "ptz_pan_position": {
"name": "PTZ pan position" "name": "PTZ pan position"
},
"hdd_storage": {
"name": "HDD {hdd_index} storage"
},
"sd_storage": {
"name": "SD {hdd_index} storage"
} }
}, },
"siren": { "siren": {