mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 11:17:21 +00:00
Reolink add pan position sensor (#98592)
* Add PTZ pan position sensor * fix typing * fix typing
This commit is contained in:
parent
66c10facfa
commit
39fc4b3d66
@ -21,14 +21,30 @@ from homeassistant.helpers.typing import StateType
|
|||||||
|
|
||||||
from . import ReolinkData
|
from . import ReolinkData
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN
|
||||||
from .entity import ReolinkHostCoordinatorEntity
|
from .entity import ReolinkChannelCoordinatorEntity, ReolinkHostCoordinatorEntity
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ReolinkSensorEntityDescriptionMixin:
|
||||||
|
"""Mixin values for Reolink sensor entities for a camera channel."""
|
||||||
|
|
||||||
|
value: Callable[[Host, int], int]
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ReolinkSensorEntityDescription(
|
||||||
|
SensorEntityDescription, ReolinkSensorEntityDescriptionMixin
|
||||||
|
):
|
||||||
|
"""A class that describes sensor entities for a camera channel."""
|
||||||
|
|
||||||
|
supported: Callable[[Host, int], bool] = lambda api, ch: True
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ReolinkHostSensorEntityDescriptionMixin:
|
class ReolinkHostSensorEntityDescriptionMixin:
|
||||||
"""Mixin values for Reolink host sensor entities."""
|
"""Mixin values for Reolink host sensor entities."""
|
||||||
|
|
||||||
value: Callable[[Host], bool]
|
value: Callable[[Host], int]
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -37,9 +53,21 @@ class ReolinkHostSensorEntityDescription(
|
|||||||
):
|
):
|
||||||
"""A class that describes host sensor entities."""
|
"""A class that describes host sensor entities."""
|
||||||
|
|
||||||
supported: Callable[[Host], bool] = lambda host: True
|
supported: Callable[[Host], bool] = lambda api: True
|
||||||
|
|
||||||
|
|
||||||
|
SENSORS = (
|
||||||
|
ReolinkSensorEntityDescription(
|
||||||
|
key="ptz_pan_position",
|
||||||
|
translation_key="ptz_pan_position",
|
||||||
|
icon="mdi:pan",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
value=lambda api, ch: api.ptz_pan_position(ch),
|
||||||
|
supported=lambda api, ch: api.supported(ch, "ptz_position"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
HOST_SENSORS = (
|
HOST_SENSORS = (
|
||||||
ReolinkHostSensorEntityDescription(
|
ReolinkHostSensorEntityDescription(
|
||||||
key="wifi_signal",
|
key="wifi_signal",
|
||||||
@ -62,11 +90,45 @@ 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]
|
||||||
|
|
||||||
async_add_entities(
|
entities: list[ReolinkSensorEntity | ReolinkHostSensorEntity] = [
|
||||||
ReolinkHostSensorEntity(reolink_data, entity_description)
|
ReolinkSensorEntity(reolink_data, channel, entity_description)
|
||||||
for entity_description in HOST_SENSORS
|
for entity_description in SENSORS
|
||||||
if entity_description.supported(reolink_data.host.api)
|
for channel in reolink_data.host.api.channels
|
||||||
|
if entity_description.supported(reolink_data.host.api, channel)
|
||||||
|
]
|
||||||
|
entities.extend(
|
||||||
|
[
|
||||||
|
ReolinkHostSensorEntity(reolink_data, entity_description)
|
||||||
|
for entity_description in HOST_SENSORS
|
||||||
|
if entity_description.supported(reolink_data.host.api)
|
||||||
|
]
|
||||||
)
|
)
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
|
||||||
|
class ReolinkSensorEntity(ReolinkChannelCoordinatorEntity, SensorEntity):
|
||||||
|
"""Base sensor class for Reolink IP camera sensors."""
|
||||||
|
|
||||||
|
entity_description: ReolinkSensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
reolink_data: ReolinkData,
|
||||||
|
channel: int,
|
||||||
|
entity_description: ReolinkSensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize Reolink sensor."""
|
||||||
|
super().__init__(reolink_data, channel)
|
||||||
|
self.entity_description = entity_description
|
||||||
|
|
||||||
|
self._attr_unique_id = (
|
||||||
|
f"{self._host.unique_id}_{channel}_{entity_description.key}"
|
||||||
|
)
|
||||||
|
|
||||||
|
@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._channel)
|
||||||
|
|
||||||
|
|
||||||
class ReolinkHostSensorEntity(ReolinkHostCoordinatorEntity, SensorEntity):
|
class ReolinkHostSensorEntity(ReolinkHostCoordinatorEntity, SensorEntity):
|
||||||
@ -79,7 +141,7 @@ class ReolinkHostSensorEntity(ReolinkHostCoordinatorEntity, SensorEntity):
|
|||||||
reolink_data: ReolinkData,
|
reolink_data: ReolinkData,
|
||||||
entity_description: ReolinkHostSensorEntityDescription,
|
entity_description: ReolinkHostSensorEntityDescription,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize Reolink binary sensor."""
|
"""Initialize Reolink host sensor."""
|
||||||
super().__init__(reolink_data)
|
super().__init__(reolink_data)
|
||||||
self.entity_description = entity_description
|
self.entity_description = entity_description
|
||||||
|
|
||||||
|
@ -102,6 +102,9 @@
|
|||||||
"sensor": {
|
"sensor": {
|
||||||
"wifi_signal": {
|
"wifi_signal": {
|
||||||
"name": "Wi-Fi signal"
|
"name": "Wi-Fi signal"
|
||||||
|
},
|
||||||
|
"ptz_pan_position": {
|
||||||
|
"name": "PTZ pan position"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user