Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions homeassistant/components/duco/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
"iaq_rh": {
"default": "mdi:water-percent"
},
"target_flow_level": {
"default": "mdi:gauge"
},
Comment thread
ronaldvdmeer marked this conversation as resolved.
"time_state_end": {
"default": "mdi:timer-outline"
},
"ventilation_state": {
"default": "mdi:tune-variant"
}
Expand Down
30 changes: 28 additions & 2 deletions homeassistant/components/duco/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from collections.abc import Callable
from dataclasses import dataclass
from datetime import datetime
import logging

from duco.models import Node, NodeType, VentilationState
Expand All @@ -24,6 +25,7 @@
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from homeassistant.util import dt as dt_util

from .const import DOMAIN
from .coordinator import DucoConfigEntry, DucoCoordinator
Expand All @@ -38,7 +40,7 @@
class DucoSensorEntityDescription(SensorEntityDescription):
"""Duco sensor entity description."""

value_fn: Callable[[Node], int | float | str | None]
value_fn: Callable[[Node], datetime | int | float | str | None]
node_types: tuple[NodeType, ...]


Expand Down Expand Up @@ -68,6 +70,30 @@ class DucoBoxSensorEntityDescription(SensorEntityDescription):
value_fn=lambda node: node.sensor.temp if node.sensor else None,
node_types=(NodeType.UCCO2, NodeType.BSRH, NodeType.UCRH),
),
DucoSensorEntityDescription(
key="target_flow_level",
translation_key="target_flow_level",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
suggested_display_precision=0,
value_fn=lambda node: (
node.ventilation.flow_lvl_tgt if node.ventilation else None
),
node_types=(NodeType.BOX,),
),
DucoSensorEntityDescription(
key="time_state_end",
translation_key="time_state_end",
device_class=SensorDeviceClass.TIMESTAMP,
value_fn=lambda node: (
dt_util.utc_from_timestamp(node.ventilation.time_state_end).replace(
second=0, microsecond=0
)
Comment thread
ronaldvdmeer marked this conversation as resolved.
if node.ventilation and node.ventilation.time_state_end != 0
else None
),
node_types=(NodeType.BOX,),
),
Comment thread
ronaldvdmeer marked this conversation as resolved.
Comment thread
ronaldvdmeer marked this conversation as resolved.
DucoSensorEntityDescription(
key="box_temperature",
translation_key="box_temperature",
Expand Down Expand Up @@ -210,7 +236,7 @@ def __init__(
)

@property
def native_value(self) -> int | float | str | None:
def native_value(self) -> datetime | int | float | str | None:
"""Return the sensor value."""
return self.entity_description.value_fn(self._node)

Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/duco/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@
"iaq_rh": {
"name": "Humidity air quality index"
},
"target_flow_level": {
"name": "Target flow level"
},
"time_state_end": {
"name": "Mode end time"
},
Comment thread
ronaldvdmeer marked this conversation as resolved.
"ventilation_state": {
"name": "Ventilation state",
"state": {
Expand Down
108 changes: 108 additions & 0 deletions tests/components/duco/snapshots/test_sensor.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,57 @@
'state': '27.9',
})
# ---
# name: test_sensor_entities_state[sensor.living_mode_end_time-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
]),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.living_mode_end_time',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Mode end time',
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TIMESTAMP: 'timestamp'>,
'original_icon': None,
'original_name': 'Mode end time',
'platform': 'duco',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'time_state_end',
'unique_id': 'aa:bb:cc:dd:ee:ff_1_time_state_end',
'unit_of_measurement': None,
})
# ---
# name: test_sensor_entities_state[sensor.living_mode_end_time-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'timestamp',
'friendly_name': 'Living Mode end time',
}),
'context': <ANY>,
'entity_id': 'sensor.living_mode_end_time',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': 'unknown',
})
# ---
# name: test_sensor_entities_state[sensor.living_signal_strength-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
Expand Down Expand Up @@ -446,6 +497,63 @@
'state': '-60',
})
# ---
# name: test_sensor_entities_state[sensor.living_target_flow_level-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
None,
]),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'config_subentry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.living_target_flow_level',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'labels': set({
}),
'name': None,
'object_id_base': 'Target flow level',
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Target flow level',
'platform': 'duco',
'previous_unique_id': None,
'suggested_object_id': None,
'supported_features': 0,
'translation_key': 'target_flow_level',
'unique_id': 'aa:bb:cc:dd:ee:ff_1_target_flow_level',
'unit_of_measurement': '%',
})
# ---
# name: test_sensor_entities_state[sensor.living_target_flow_level-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Living Target flow level',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.living_target_flow_level',
'last_changed': <ANY>,
'last_reported': <ANY>,
'last_updated': <ANY>,
'state': '0',
})
# ---
# name: test_sensor_entities_state[sensor.living_ventilation_state-entry]
EntityRegistryEntrySnapshot({
'aliases': list([
Expand Down
Loading