mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 05:07:41 +00:00
parent
032940f1a9
commit
fb96ef99d0
@ -14,7 +14,7 @@ from .const import DOMAIN
|
|||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
PLATFORMS = [Platform.COVER]
|
PLATFORMS = [Platform.COVER, Platform.SENSOR]
|
||||||
|
|
||||||
type HomeeConfigEntry = ConfigEntry[Homee]
|
type HomeeConfigEntry = ConfigEntry[Homee]
|
||||||
|
|
||||||
|
@ -1,4 +1,60 @@
|
|||||||
"""Constants for the homee integration."""
|
"""Constants for the homee integration."""
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
LIGHT_LUX,
|
||||||
|
PERCENTAGE,
|
||||||
|
UnitOfElectricCurrent,
|
||||||
|
UnitOfElectricPotential,
|
||||||
|
UnitOfEnergy,
|
||||||
|
UnitOfPower,
|
||||||
|
UnitOfSpeed,
|
||||||
|
UnitOfTemperature,
|
||||||
|
UnitOfTime,
|
||||||
|
UnitOfVolume,
|
||||||
|
)
|
||||||
|
|
||||||
# General
|
# General
|
||||||
DOMAIN = "homee"
|
DOMAIN = "homee"
|
||||||
|
|
||||||
|
# Sensor mappings
|
||||||
|
HOMEE_UNIT_TO_HA_UNIT = {
|
||||||
|
"": None,
|
||||||
|
"n/a": None,
|
||||||
|
"text": None,
|
||||||
|
"%": PERCENTAGE,
|
||||||
|
"lx": LIGHT_LUX,
|
||||||
|
"klx": LIGHT_LUX,
|
||||||
|
"A": UnitOfElectricCurrent.AMPERE,
|
||||||
|
"V": UnitOfElectricPotential.VOLT,
|
||||||
|
"kWh": UnitOfEnergy.KILO_WATT_HOUR,
|
||||||
|
"W": UnitOfPower.WATT,
|
||||||
|
"m/s": UnitOfSpeed.METERS_PER_SECOND,
|
||||||
|
"km/h": UnitOfSpeed.KILOMETERS_PER_HOUR,
|
||||||
|
"°F": UnitOfTemperature.FAHRENHEIT,
|
||||||
|
"°C": UnitOfTemperature.CELSIUS,
|
||||||
|
"K": UnitOfTemperature.KELVIN,
|
||||||
|
"s": UnitOfTime.SECONDS,
|
||||||
|
"min": UnitOfTime.MINUTES,
|
||||||
|
"h": UnitOfTime.HOURS,
|
||||||
|
"L": UnitOfVolume.LITERS,
|
||||||
|
}
|
||||||
|
OPEN_CLOSE_MAP = {
|
||||||
|
0.0: "open",
|
||||||
|
1.0: "closed",
|
||||||
|
2.0: "partial",
|
||||||
|
3.0: "opening",
|
||||||
|
4.0: "closing",
|
||||||
|
}
|
||||||
|
OPEN_CLOSE_MAP_REVERSED = {
|
||||||
|
0.0: "closed",
|
||||||
|
1.0: "open",
|
||||||
|
2.0: "partial",
|
||||||
|
3.0: "cosing",
|
||||||
|
4.0: "opening",
|
||||||
|
}
|
||||||
|
WINDOW_MAP = {
|
||||||
|
0.0: "closed",
|
||||||
|
1.0: "open",
|
||||||
|
2.0: "tilted",
|
||||||
|
}
|
||||||
|
WINDOW_MAP_REVERSED = {0.0: "open", 1.0: "closed", 2.0: "tilted"}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"""Base Entities for Homee integration."""
|
"""Base Entities for Homee integration."""
|
||||||
|
|
||||||
from pyHomee.const import AttributeType, NodeProfile, NodeState
|
from pyHomee.const import AttributeState, AttributeType, NodeProfile, NodeState
|
||||||
from pyHomee.model import HomeeAttribute, HomeeNode
|
from pyHomee.model import HomeeAttribute, HomeeNode
|
||||||
|
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo
|
from homeassistant.helpers.device_registry import DeviceInfo
|
||||||
@ -11,6 +11,56 @@ from .const import DOMAIN
|
|||||||
from .helpers import get_name_for_enum
|
from .helpers import get_name_for_enum
|
||||||
|
|
||||||
|
|
||||||
|
class HomeeEntity(Entity):
|
||||||
|
"""Represents a Homee entity consisting of a single HomeeAttribute."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
_attr_should_poll = False
|
||||||
|
|
||||||
|
def __init__(self, attribute: HomeeAttribute, entry: HomeeConfigEntry) -> None:
|
||||||
|
"""Initialize the wrapper using a HomeeAttribute and target entity."""
|
||||||
|
self._attribute = attribute
|
||||||
|
self._attr_unique_id = (
|
||||||
|
f"{entry.runtime_data.settings.uid}-{attribute.node_id}-{attribute.id}"
|
||||||
|
)
|
||||||
|
self._entry = entry
|
||||||
|
self._attr_device_info = DeviceInfo(
|
||||||
|
identifiers={
|
||||||
|
(DOMAIN, f"{entry.runtime_data.settings.uid}-{attribute.node_id}")
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
self._host_connected = entry.runtime_data.connected
|
||||||
|
|
||||||
|
async def async_added_to_hass(self) -> None:
|
||||||
|
"""Add the homee attribute entity to home assistant."""
|
||||||
|
self.async_on_remove(
|
||||||
|
self._attribute.add_on_changed_listener(self._on_node_updated)
|
||||||
|
)
|
||||||
|
self.async_on_remove(
|
||||||
|
await self._entry.runtime_data.add_connection_listener(
|
||||||
|
self._on_connection_changed
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def available(self) -> bool:
|
||||||
|
"""Return the availability of the underlying node."""
|
||||||
|
return (self._attribute.state == AttributeState.NORMAL) and self._host_connected
|
||||||
|
|
||||||
|
async def async_update(self) -> None:
|
||||||
|
"""Update entity from homee."""
|
||||||
|
homee = self._entry.runtime_data
|
||||||
|
await homee.update_attribute(self._attribute.node_id, self._attribute.id)
|
||||||
|
|
||||||
|
def _on_node_updated(self, attribute: HomeeAttribute) -> None:
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
async def _on_connection_changed(self, connected: bool) -> None:
|
||||||
|
self._host_connected = connected
|
||||||
|
self.schedule_update_ha_state()
|
||||||
|
|
||||||
|
|
||||||
class HomeeNodeEntity(Entity):
|
class HomeeNodeEntity(Entity):
|
||||||
"""Representation of an Entity that uses more than one HomeeAttribute."""
|
"""Representation of an Entity that uses more than one HomeeAttribute."""
|
||||||
|
|
||||||
@ -20,7 +70,7 @@ class HomeeNodeEntity(Entity):
|
|||||||
def __init__(self, node: HomeeNode, entry: HomeeConfigEntry) -> None:
|
def __init__(self, node: HomeeNode, entry: HomeeConfigEntry) -> None:
|
||||||
"""Initialize the wrapper using a HomeeNode and target entity."""
|
"""Initialize the wrapper using a HomeeNode and target entity."""
|
||||||
self._node = node
|
self._node = node
|
||||||
self._attr_unique_id = f"{entry.runtime_data.settings.uid}-{node.id}"
|
self._attr_unique_id = f"{entry.unique_id}-{node.id}"
|
||||||
self._entry = entry
|
self._entry = entry
|
||||||
|
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
@ -41,6 +91,23 @@ class HomeeNodeEntity(Entity):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def device_info(self) -> DeviceInfo:
|
||||||
|
"""Return the device info."""
|
||||||
|
# Homee hub has id -1, but is identified only by the UID.
|
||||||
|
if self._node.id == -1:
|
||||||
|
return DeviceInfo(
|
||||||
|
identifiers={(DOMAIN, self._entry.runtime_data.settings.uid)},
|
||||||
|
)
|
||||||
|
|
||||||
|
return DeviceInfo(
|
||||||
|
identifiers={(DOMAIN, f"{self._entry.unique_id}-{self._node.id}")},
|
||||||
|
name=self._node.name,
|
||||||
|
model=get_name_for_enum(NodeProfile, self._node.profile),
|
||||||
|
sw_version=self._get_software_version(),
|
||||||
|
via_device=(DOMAIN, self._entry.runtime_data.settings.uid),
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def available(self) -> bool:
|
def available(self) -> bool:
|
||||||
"""Return the availability of the underlying node."""
|
"""Return the availability of the underlying node."""
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
"""Helper functions for the homee custom component."""
|
"""Helper functions for the homee custom component."""
|
||||||
|
|
||||||
|
from enum import IntEnum
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_name_for_enum(att_class, att_id) -> str:
|
def get_name_for_enum(att_class: type[IntEnum], att_id: int) -> str | None:
|
||||||
"""Return the enum item name for a given integer."""
|
"""Return the enum item name for a given integer."""
|
||||||
try:
|
try:
|
||||||
attribute_name = att_class(att_id).name
|
item = att_class(att_id)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
_LOGGER.warning("Value %s does not exist in %s", att_id, att_class.__name__)
|
_LOGGER.warning("Value %s does not exist in %s", att_id, att_class.__name__)
|
||||||
return "Unknown"
|
return None
|
||||||
|
return item.name.lower()
|
||||||
return attribute_name
|
|
||||||
|
12
homeassistant/components/homee/icons.json
Normal file
12
homeassistant/components/homee/icons.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"link_quality": {
|
||||||
|
"default": "mdi:signal"
|
||||||
|
},
|
||||||
|
"window_position": {
|
||||||
|
"default": "mdi:window-closed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
303
homeassistant/components/homee/sensor.py
Normal file
303
homeassistant/components/homee/sensor.py
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
"""The homee sensor platform."""
|
||||||
|
|
||||||
|
from collections.abc import Callable
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from pyHomee.const import AttributeType, NodeState
|
||||||
|
from pyHomee.model import HomeeAttribute, HomeeNode
|
||||||
|
|
||||||
|
from homeassistant.components.sensor import (
|
||||||
|
SensorDeviceClass,
|
||||||
|
SensorEntity,
|
||||||
|
SensorEntityDescription,
|
||||||
|
SensorStateClass,
|
||||||
|
)
|
||||||
|
from homeassistant.const import EntityCategory
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
|
from . import HomeeConfigEntry
|
||||||
|
from .const import (
|
||||||
|
HOMEE_UNIT_TO_HA_UNIT,
|
||||||
|
OPEN_CLOSE_MAP,
|
||||||
|
OPEN_CLOSE_MAP_REVERSED,
|
||||||
|
WINDOW_MAP,
|
||||||
|
WINDOW_MAP_REVERSED,
|
||||||
|
)
|
||||||
|
from .entity import HomeeEntity, HomeeNodeEntity
|
||||||
|
from .helpers import get_name_for_enum
|
||||||
|
|
||||||
|
|
||||||
|
def get_open_close_value(attribute: HomeeAttribute) -> str | None:
|
||||||
|
"""Return the open/close value."""
|
||||||
|
vals = OPEN_CLOSE_MAP if not attribute.is_reversed else OPEN_CLOSE_MAP_REVERSED
|
||||||
|
return vals.get(attribute.current_value)
|
||||||
|
|
||||||
|
|
||||||
|
def get_window_value(attribute: HomeeAttribute) -> str | None:
|
||||||
|
"""Return the states of a window open sensor."""
|
||||||
|
vals = WINDOW_MAP if not attribute.is_reversed else WINDOW_MAP_REVERSED
|
||||||
|
return vals.get(attribute.current_value)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class HomeeSensorEntityDescription(SensorEntityDescription):
|
||||||
|
"""A class that describes Homee sensor entities."""
|
||||||
|
|
||||||
|
value_fn: Callable[[HomeeAttribute], str | float | None] = (
|
||||||
|
lambda value: value.current_value
|
||||||
|
)
|
||||||
|
native_unit_of_measurement_fn: Callable[[str], str | None] = (
|
||||||
|
lambda homee_unit: HOMEE_UNIT_TO_HA_UNIT[homee_unit]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
SENSOR_DESCRIPTIONS: dict[AttributeType, HomeeSensorEntityDescription] = {
|
||||||
|
AttributeType.ACCUMULATED_ENERGY_USE: HomeeSensorEntityDescription(
|
||||||
|
key="energy",
|
||||||
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
|
),
|
||||||
|
AttributeType.BATTERY_LEVEL: HomeeSensorEntityDescription(
|
||||||
|
key="battery",
|
||||||
|
device_class=SensorDeviceClass.BATTERY,
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.BRIGHTNESS: HomeeSensorEntityDescription(
|
||||||
|
key="brightness",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
value_fn=(
|
||||||
|
lambda attribute: attribute.current_value * 1000
|
||||||
|
if attribute.unit == "klx"
|
||||||
|
else attribute.current_value
|
||||||
|
),
|
||||||
|
),
|
||||||
|
AttributeType.CURRENT: HomeeSensorEntityDescription(
|
||||||
|
key="current",
|
||||||
|
device_class=SensorDeviceClass.CURRENT,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.CURRENT_ENERGY_USE: HomeeSensorEntityDescription(
|
||||||
|
key="power",
|
||||||
|
device_class=SensorDeviceClass.POWER,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.CURRENT_VALVE_POSITION: HomeeSensorEntityDescription(
|
||||||
|
key="valve_position",
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.DAWN: HomeeSensorEntityDescription(
|
||||||
|
key="dawn",
|
||||||
|
device_class=SensorDeviceClass.ILLUMINANCE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.DEVICE_TEMPERATURE: HomeeSensorEntityDescription(
|
||||||
|
key="device_temperature",
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.LEVEL: HomeeSensorEntityDescription(
|
||||||
|
key="level",
|
||||||
|
device_class=SensorDeviceClass.VOLUME,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.LINK_QUALITY: HomeeSensorEntityDescription(
|
||||||
|
key="link_quality",
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.POSITION: HomeeSensorEntityDescription(
|
||||||
|
key="position",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.RAIN_FALL_LAST_HOUR: HomeeSensorEntityDescription(
|
||||||
|
key="rainfall_hour",
|
||||||
|
device_class=SensorDeviceClass.PRECIPITATION,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.RAIN_FALL_TODAY: HomeeSensorEntityDescription(
|
||||||
|
key="rainfall_day",
|
||||||
|
device_class=SensorDeviceClass.PRECIPITATION,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.RELATIVE_HUMIDITY: HomeeSensorEntityDescription(
|
||||||
|
key="humidity",
|
||||||
|
device_class=SensorDeviceClass.HUMIDITY,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.TEMPERATURE: HomeeSensorEntityDescription(
|
||||||
|
key="temperature",
|
||||||
|
device_class=SensorDeviceClass.TEMPERATURE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.TOTAL_ACCUMULATED_ENERGY_USE: HomeeSensorEntityDescription(
|
||||||
|
key="total_energy",
|
||||||
|
device_class=SensorDeviceClass.ENERGY,
|
||||||
|
state_class=SensorStateClass.TOTAL_INCREASING,
|
||||||
|
),
|
||||||
|
AttributeType.TOTAL_CURRENT: HomeeSensorEntityDescription(
|
||||||
|
key="total_current",
|
||||||
|
device_class=SensorDeviceClass.CURRENT,
|
||||||
|
),
|
||||||
|
AttributeType.TOTAL_CURRENT_ENERGY_USE: HomeeSensorEntityDescription(
|
||||||
|
key="total_power",
|
||||||
|
device_class=SensorDeviceClass.POWER,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.TOTAL_VOLTAGE: HomeeSensorEntityDescription(
|
||||||
|
key="total_voltage",
|
||||||
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.UP_DOWN: HomeeSensorEntityDescription(
|
||||||
|
key="up_down",
|
||||||
|
device_class=SensorDeviceClass.ENUM,
|
||||||
|
options=[
|
||||||
|
"open",
|
||||||
|
"closed",
|
||||||
|
"partial",
|
||||||
|
"opening",
|
||||||
|
"closing",
|
||||||
|
],
|
||||||
|
value_fn=get_open_close_value,
|
||||||
|
),
|
||||||
|
AttributeType.UV: HomeeSensorEntityDescription(
|
||||||
|
key="uv",
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.VOLTAGE: HomeeSensorEntityDescription(
|
||||||
|
key="voltage",
|
||||||
|
device_class=SensorDeviceClass.VOLTAGE,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.WIND_SPEED: HomeeSensorEntityDescription(
|
||||||
|
key="wind_speed",
|
||||||
|
device_class=SensorDeviceClass.WIND_SPEED,
|
||||||
|
state_class=SensorStateClass.MEASUREMENT,
|
||||||
|
),
|
||||||
|
AttributeType.WINDOW_POSITION: HomeeSensorEntityDescription(
|
||||||
|
key="window_position",
|
||||||
|
device_class=SensorDeviceClass.ENUM,
|
||||||
|
options=["closed", "open", "tilted"],
|
||||||
|
value_fn=get_window_value,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True, kw_only=True)
|
||||||
|
class HomeeNodeSensorEntityDescription(SensorEntityDescription):
|
||||||
|
"""Describes Homee node sensor entities."""
|
||||||
|
|
||||||
|
value_fn: Callable[[HomeeNode], str | None]
|
||||||
|
|
||||||
|
|
||||||
|
NODE_SENSOR_DESCRIPTIONS: tuple[HomeeNodeSensorEntityDescription, ...] = (
|
||||||
|
HomeeNodeSensorEntityDescription(
|
||||||
|
key="state",
|
||||||
|
device_class=SensorDeviceClass.ENUM,
|
||||||
|
options=[
|
||||||
|
"available",
|
||||||
|
"unavailable",
|
||||||
|
"update_in_progress",
|
||||||
|
"waiting_for_attributes",
|
||||||
|
"initializing",
|
||||||
|
"user_interaction_required",
|
||||||
|
"password_required",
|
||||||
|
"host_unavailable",
|
||||||
|
"delete_in_progress",
|
||||||
|
"cosi_connected",
|
||||||
|
"blocked",
|
||||||
|
"waiting_for_wakeup",
|
||||||
|
"remote_node_deleted",
|
||||||
|
"firmware_update_in_progress",
|
||||||
|
],
|
||||||
|
entity_category=EntityCategory.DIAGNOSTIC,
|
||||||
|
entity_registry_enabled_default=False,
|
||||||
|
value_fn=lambda node: get_name_for_enum(NodeState, node.state),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_entry(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: HomeeConfigEntry,
|
||||||
|
async_add_devices: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Add the homee platform for the sensor components."""
|
||||||
|
|
||||||
|
devices: list[HomeeSensor | HomeeNodeSensor] = []
|
||||||
|
for node in config_entry.runtime_data.nodes:
|
||||||
|
# Node properties that are sensors.
|
||||||
|
devices.extend(
|
||||||
|
HomeeNodeSensor(node, config_entry, description)
|
||||||
|
for description in NODE_SENSOR_DESCRIPTIONS
|
||||||
|
)
|
||||||
|
|
||||||
|
# Node attributes that are sensors.
|
||||||
|
devices.extend(
|
||||||
|
HomeeSensor(attribute, config_entry, SENSOR_DESCRIPTIONS[attribute.type])
|
||||||
|
for attribute in node.attributes
|
||||||
|
if attribute.type in SENSOR_DESCRIPTIONS and not attribute.editable
|
||||||
|
)
|
||||||
|
|
||||||
|
if devices:
|
||||||
|
async_add_devices(devices)
|
||||||
|
|
||||||
|
|
||||||
|
class HomeeSensor(HomeeEntity, SensorEntity):
|
||||||
|
"""Representation of a homee sensor."""
|
||||||
|
|
||||||
|
entity_description: HomeeSensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
attribute: HomeeAttribute,
|
||||||
|
entry: HomeeConfigEntry,
|
||||||
|
description: HomeeSensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize a homee sensor entity."""
|
||||||
|
super().__init__(attribute, entry)
|
||||||
|
self.entity_description = description
|
||||||
|
self._attr_translation_key = description.key
|
||||||
|
if attribute.instance > 0:
|
||||||
|
self._attr_translation_key = f"{description.translation_key}_instance"
|
||||||
|
self._attr_translation_placeholders = {"instance": str(attribute.instance)}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_value(self) -> float | str | None:
|
||||||
|
"""Return the native value of the sensor."""
|
||||||
|
return self.entity_description.value_fn(self._attribute)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_unit_of_measurement(self) -> str | None:
|
||||||
|
"""Return the native unit of the sensor."""
|
||||||
|
return self.entity_description.native_unit_of_measurement_fn(
|
||||||
|
self._attribute.unit
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class HomeeNodeSensor(HomeeNodeEntity, SensorEntity):
|
||||||
|
"""Represents a sensor based on a node's property."""
|
||||||
|
|
||||||
|
entity_description: HomeeNodeSensorEntityDescription
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
node: HomeeNode,
|
||||||
|
entry: HomeeConfigEntry,
|
||||||
|
description: HomeeNodeSensorEntityDescription,
|
||||||
|
) -> None:
|
||||||
|
"""Initialize a homee node sensor entity."""
|
||||||
|
super().__init__(node, entry)
|
||||||
|
self.entity_description = description
|
||||||
|
self._attr_translation_key = f"node_{description.key}"
|
||||||
|
self._node = node
|
||||||
|
self._attr_unique_id = f"{self._attr_unique_id}-{description.key}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def native_value(self) -> str | None:
|
||||||
|
"""Return the sensors value."""
|
||||||
|
return self.entity_description.value_fn(self._node)
|
@ -24,5 +24,84 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"entity": {
|
||||||
|
"sensor": {
|
||||||
|
"brightness_instance": {
|
||||||
|
"name": "Illuminance {instance}"
|
||||||
|
},
|
||||||
|
"current_instance": {
|
||||||
|
"name": "Current {instance}"
|
||||||
|
},
|
||||||
|
"dawn": {
|
||||||
|
"name": "Dawn"
|
||||||
|
},
|
||||||
|
"device_temperature": {
|
||||||
|
"name": "Device temperature"
|
||||||
|
},
|
||||||
|
"energy_instance": {
|
||||||
|
"name": "Energy {instance}"
|
||||||
|
},
|
||||||
|
"level": {
|
||||||
|
"name": "Level"
|
||||||
|
},
|
||||||
|
"link_quality": {
|
||||||
|
"name": "Link quality"
|
||||||
|
},
|
||||||
|
"node_state": {
|
||||||
|
"name": "Node state"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"name": "Position"
|
||||||
|
},
|
||||||
|
"power_instance": {
|
||||||
|
"name": "Power {instance}"
|
||||||
|
},
|
||||||
|
"rainfall_hour": {
|
||||||
|
"name": "Rainfall last hour"
|
||||||
|
},
|
||||||
|
"rainfall_day": {
|
||||||
|
"name": "Rainfall today"
|
||||||
|
},
|
||||||
|
"total_current": {
|
||||||
|
"name": "Total current"
|
||||||
|
},
|
||||||
|
"total_energy": {
|
||||||
|
"name": "Total energy"
|
||||||
|
},
|
||||||
|
"total_power": {
|
||||||
|
"name": "Total power"
|
||||||
|
},
|
||||||
|
"total_voltage": {
|
||||||
|
"name": "Total voltage"
|
||||||
|
},
|
||||||
|
"up_down": {
|
||||||
|
"name": "State",
|
||||||
|
"state": {
|
||||||
|
"open": "[%key:common::state::open%]",
|
||||||
|
"closed": "[%key:common::state::closed%]",
|
||||||
|
"partial": "Partially open",
|
||||||
|
"opening": "Opening",
|
||||||
|
"closing": "Closing"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uv": {
|
||||||
|
"name": "Ultraviolet"
|
||||||
|
},
|
||||||
|
"valve_position": {
|
||||||
|
"name": "Valve position"
|
||||||
|
},
|
||||||
|
"voltage_instance": {
|
||||||
|
"name": "Voltage {instance}"
|
||||||
|
},
|
||||||
|
"window_position": {
|
||||||
|
"name": "Window position",
|
||||||
|
"state": {
|
||||||
|
"closed": "[%key:common::state::closed%]",
|
||||||
|
"open": "[%key:common::state::open%]",
|
||||||
|
"tilted": "Tilted"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user