Add sensors to the flexit_bacnet integration (#108297)

* Adds sensors to the flexit_bacnet integration

* Add one platform at a time

* Removes commented out code

And restores attributes that are needed

* Review changes

* More review fixes

* Adds translations for the flexit_bacnet sensors

* Review comments

* Adds test for flexit_bacnet sensor

* Refactors the sensor test

* Review comment

* Review comment

* Review comments
This commit is contained in:
Jonas Fors Lellky 2024-01-21 12:04:46 +01:00 committed by GitHub
parent d885bf886a
commit 7c86ea7e16
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 992 additions and 1 deletions

View File

@ -8,7 +8,7 @@ from homeassistant.core import HomeAssistant
from .const import DOMAIN
from .coordinator import FlexitCoordinator
PLATFORMS: list[Platform] = [Platform.CLIMATE]
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR]
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:

View File

@ -0,0 +1,186 @@
"""The Flexit Nordic (BACnet) integration."""
from collections.abc import Callable
from dataclasses import dataclass
from flexit_bacnet import FlexitBACnet
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
SensorStateClass,
StateType,
)
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
PERCENTAGE,
REVOLUTIONS_PER_MINUTE,
UnitOfPower,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import FlexitCoordinator
from .const import DOMAIN
from .entity import FlexitEntity
@dataclass(kw_only=True, frozen=True)
class FlexitSensorEntityDescription(SensorEntityDescription):
"""Describes a Flexit sensor entity."""
value_fn: Callable[[FlexitBACnet], float]
SENSOR_TYPES: tuple[FlexitSensorEntityDescription, ...] = (
FlexitSensorEntityDescription(
key="outside_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="outside_air_temperature",
value_fn=lambda data: data.outside_air_temperature,
),
FlexitSensorEntityDescription(
key="supply_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="supply_air_temperature",
value_fn=lambda data: data.supply_air_temperature,
),
FlexitSensorEntityDescription(
key="exhaust_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="exhaust_air_temperature",
value_fn=lambda data: data.exhaust_air_temperature,
),
FlexitSensorEntityDescription(
key="extract_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="extract_air_temperature",
value_fn=lambda data: data.extract_air_temperature,
),
FlexitSensorEntityDescription(
key="room_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
translation_key="room_temperature",
value_fn=lambda data: data.room_temperature,
),
FlexitSensorEntityDescription(
key="fireplace_ventilation_remaining_duration",
device_class=SensorDeviceClass.DURATION,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="fireplace_ventilation_remaining_duration",
value_fn=lambda data: data.fireplace_ventilation_remaining_duration,
suggested_display_precision=0,
),
FlexitSensorEntityDescription(
key="rapid_ventilation_remaining_duration",
device_class=SensorDeviceClass.DURATION,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=UnitOfTime.MINUTES,
translation_key="rapid_ventilation_remaining_duration",
value_fn=lambda data: data.rapid_ventilation_remaining_duration,
suggested_display_precision=0,
),
FlexitSensorEntityDescription(
key="supply_air_fan_control_signal",
state_class=SensorStateClass.MEASUREMENT,
translation_key="supply_air_fan_control_signal",
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda data: data.supply_air_fan_control_signal,
),
FlexitSensorEntityDescription(
key="supply_air_fan_rpm",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
translation_key="supply_air_fan_rpm",
value_fn=lambda data: data.supply_air_fan_rpm,
),
FlexitSensorEntityDescription(
key="exhaust_air_fan_control_signal",
state_class=SensorStateClass.MEASUREMENT,
translation_key="exhaust_air_fan_control_signal",
value_fn=lambda data: data.exhaust_air_fan_control_signal,
native_unit_of_measurement=PERCENTAGE,
),
FlexitSensorEntityDescription(
key="exhaust_air_fan_rpm",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=REVOLUTIONS_PER_MINUTE,
translation_key="exhaust_air_fan_rpm",
value_fn=lambda data: data.exhaust_air_fan_rpm,
),
FlexitSensorEntityDescription(
key="electric_heater_power",
device_class=SensorDeviceClass.POWER,
native_unit_of_measurement=UnitOfPower.KILO_WATT,
translation_key="electric_heater_power",
value_fn=lambda data: data.electric_heater_power,
suggested_display_precision=3,
),
FlexitSensorEntityDescription(
key="air_filter_operating_time",
state_class=SensorStateClass.TOTAL_INCREASING,
suggested_display_precision=0,
native_unit_of_measurement=UnitOfTime.HOURS,
translation_key="air_filter_operating_time",
value_fn=lambda data: data.air_filter_operating_time,
),
FlexitSensorEntityDescription(
key="heat_exchanger_efficiency",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
translation_key="heat_exchanger_efficiency",
value_fn=lambda data: data.heat_exchanger_efficiency,
),
FlexitSensorEntityDescription(
key="heat_exchanger_speed",
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
translation_key="heat_exchanger_speed",
value_fn=lambda data: data.heat_exchanger_speed,
),
)
async def async_setup_entry(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up Flexit (bacnet) sensor from a config entry."""
coordinator: FlexitCoordinator = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities(
FlexitSensor(coordinator, description) for description in SENSOR_TYPES
)
class FlexitSensor(FlexitEntity, SensorEntity):
"""Representation of a Flexit (bacnet) Sensor."""
entity_description: FlexitSensorEntityDescription
def __init__(
self,
coordinator: FlexitCoordinator,
entity_description: FlexitSensorEntityDescription,
) -> None:
"""Initialize Flexit (bacnet) sensor."""
super().__init__(coordinator)
self.entity_description = entity_description
self._attr_unique_id = (
f"{coordinator.device.serial_number}-{entity_description.key}"
)
@property
def native_value(self) -> StateType:
"""Return value of sensor."""
return self.entity_description.value_fn(self.coordinator.data)

View File

@ -15,5 +15,54 @@
"abort": {
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}
},
"entity": {
"sensor": {
"outside_air_temperature": {
"name": "Outside air temperature"
},
"supply_air_temperature": {
"name": "Supply air temperature"
},
"exhaust_air_temperature": {
"name": "Exhaust air temperature"
},
"extract_air_temperature": {
"name": "Extract air temperature"
},
"room_temperature": {
"name": "Room temperature"
},
"fireplace_ventilation_remaining_duration": {
"name": "Fireplace ventilation remaining duration"
},
"rapid_ventilation_remaining_duration": {
"name": "Rapid ventilation remaining duration"
},
"supply_air_fan_control_signal": {
"name": "Supply air fan control signal"
},
"supply_air_fan_rpm": {
"name": "Supply air fan"
},
"exhaust_air_fan_control_signal": {
"name": "Exhaust air fan control signal"
},
"exhaust_air_fan_rpm": {
"name": "Exhaust air fan"
},
"electric_heater_power": {
"name": "Electric heater power"
},
"air_filter_operating_time": {
"name": "Air filter operating time"
},
"heat_exchanger_efficiency": {
"name": "Heat exchanger efficiency"
},
"heat_exchanger_speed": {
"name": "Heat exchanger speed"
}
}
}
}

View File

@ -44,6 +44,21 @@ def mock_flexit_bacnet() -> Generator[AsyncMock, None, None]:
flexit_bacnet.air_temp_setpoint_away = 18.0
flexit_bacnet.air_temp_setpoint_home = 22.0
flexit_bacnet.ventilation_mode = 4
flexit_bacnet.air_filter_operating_time = 8000
flexit_bacnet.outside_air_temperature = -8.6
flexit_bacnet.supply_air_temperature = 19.1
flexit_bacnet.exhaust_air_temperature = -3.3
flexit_bacnet.extract_air_temperature = 19.0
flexit_bacnet.fireplace_ventilation_remaining_duration = 10.0
flexit_bacnet.rapid_ventilation_remaining_duration = 30.0
flexit_bacnet.supply_air_fan_control_signal = 74
flexit_bacnet.supply_air_fan_rpm = 2784
flexit_bacnet.exhaust_air_fan_control_signal = 70
flexit_bacnet.exhaust_air_fan_rpm = 2606
flexit_bacnet.electric_heater_power = 0.39636585116386414
flexit_bacnet.air_filter_operating_time = 8820.0
flexit_bacnet.heat_exchanger_efficiency = 81
flexit_bacnet.heat_exchanger_speed = 100
yield flexit_bacnet

View File

@ -0,0 +1,708 @@
# serializer version: 1
# name: test_sensors[sensor.device_name_air_filter_operating_time-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_air_filter_operating_time',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Air filter operating time',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'air_filter_operating_time',
'unique_id': '0000-0001-air_filter_operating_time',
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
})
# ---
# name: test_sensors[sensor.device_name_air_filter_operating_time-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Air filter operating time',
'state_class': <SensorStateClass.TOTAL_INCREASING: 'total_increasing'>,
'unit_of_measurement': <UnitOfTime.HOURS: 'h'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_air_filter_operating_time',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '8820.0',
})
# ---
# name: test_sensors[sensor.device_name_electric_heater_power-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_electric_heater_power',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 3,
}),
}),
'original_device_class': <SensorDeviceClass.POWER: 'power'>,
'original_icon': None,
'original_name': 'Electric heater power',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'electric_heater_power',
'unique_id': '0000-0001-electric_heater_power',
'unit_of_measurement': <UnitOfPower.KILO_WATT: 'kW'>,
})
# ---
# name: test_sensors[sensor.device_name_electric_heater_power-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'power',
'friendly_name': 'Device Name Electric heater power',
'unit_of_measurement': <UnitOfPower.KILO_WATT: 'kW'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_electric_heater_power',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '0.396365851163864',
})
# ---
# name: test_sensors[sensor.device_name_exhaust_air_fan-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_exhaust_air_fan',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Exhaust air fan',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'exhaust_air_fan_rpm',
'unique_id': '0000-0001-exhaust_air_fan_rpm',
'unit_of_measurement': 'rpm',
})
# ---
# name: test_sensors[sensor.device_name_exhaust_air_fan-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Exhaust air fan',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 'rpm',
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_exhaust_air_fan',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '2606',
})
# ---
# name: test_sensors[sensor.device_name_exhaust_air_fan_control_signal-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_exhaust_air_fan_control_signal',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Exhaust air fan control signal',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'exhaust_air_fan_control_signal',
'unique_id': '0000-0001-exhaust_air_fan_control_signal',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[sensor.device_name_exhaust_air_fan_control_signal-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Exhaust air fan control signal',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_exhaust_air_fan_control_signal',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '70',
})
# ---
# name: test_sensors[sensor.device_name_exhaust_air_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_exhaust_air_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Exhaust air temperature',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'exhaust_air_temperature',
'unique_id': '0000-0001-exhaust_air_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[sensor.device_name_exhaust_air_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Device Name Exhaust air temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_exhaust_air_temperature',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '-3.3',
})
# ---
# name: test_sensors[sensor.device_name_extract_air_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_extract_air_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Extract air temperature',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'extract_air_temperature',
'unique_id': '0000-0001-extract_air_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[sensor.device_name_extract_air_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Device Name Extract air temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_extract_air_temperature',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '19.0',
})
# ---
# name: test_sensors[sensor.device_name_fireplace_ventilation_remaining_duration-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_fireplace_ventilation_remaining_duration',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'Fireplace ventilation remaining duration',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'fireplace_ventilation_remaining_duration',
'unique_id': '0000-0001-fireplace_ventilation_remaining_duration',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensors[sensor.device_name_fireplace_ventilation_remaining_duration-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'Device Name Fireplace ventilation remaining duration',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_fireplace_ventilation_remaining_duration',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '10.0',
})
# ---
# name: test_sensors[sensor.device_name_heat_exchanger_efficiency-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_heat_exchanger_efficiency',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Heat exchanger efficiency',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heat_exchanger_efficiency',
'unique_id': '0000-0001-heat_exchanger_efficiency',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[sensor.device_name_heat_exchanger_efficiency-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Heat exchanger efficiency',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_heat_exchanger_efficiency',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '81',
})
# ---
# name: test_sensors[sensor.device_name_heat_exchanger_speed-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_heat_exchanger_speed',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Heat exchanger speed',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'heat_exchanger_speed',
'unique_id': '0000-0001-heat_exchanger_speed',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[sensor.device_name_heat_exchanger_speed-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Heat exchanger speed',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_heat_exchanger_speed',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '100',
})
# ---
# name: test_sensors[sensor.device_name_outside_air_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_outside_air_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Outside air temperature',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'outside_air_temperature',
'unique_id': '0000-0001-outside_air_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[sensor.device_name_outside_air_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Device Name Outside air temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_outside_air_temperature',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '-8.6',
})
# ---
# name: test_sensors[sensor.device_name_rapid_ventilation_remaining_duration-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_rapid_ventilation_remaining_duration',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 0,
}),
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'Rapid ventilation remaining duration',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'rapid_ventilation_remaining_duration',
'unique_id': '0000-0001-rapid_ventilation_remaining_duration',
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
})
# ---
# name: test_sensors[sensor.device_name_rapid_ventilation_remaining_duration-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'Device Name Rapid ventilation remaining duration',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfTime.MINUTES: 'min'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_rapid_ventilation_remaining_duration',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '30.0',
})
# ---
# name: test_sensors[sensor.device_name_room_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_room_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Room temperature',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'room_temperature',
'unique_id': '0000-0001-room_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[sensor.device_name_room_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Device Name Room temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_room_temperature',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '19.0',
})
# ---
# name: test_sensors[sensor.device_name_supply_air_fan-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_supply_air_fan',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Supply air fan',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'supply_air_fan_rpm',
'unique_id': '0000-0001-supply_air_fan_rpm',
'unit_of_measurement': 'rpm',
})
# ---
# name: test_sensors[sensor.device_name_supply_air_fan-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Supply air fan',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 'rpm',
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_supply_air_fan',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '2784',
})
# ---
# name: test_sensors[sensor.device_name_supply_air_fan_control_signal-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': dict({
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
}),
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_supply_air_fan_control_signal',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': None,
'original_icon': None,
'original_name': 'Supply air fan control signal',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'supply_air_fan_control_signal',
'unique_id': '0000-0001-supply_air_fan_control_signal',
'unit_of_measurement': '%',
})
# ---
# name: test_sensors[sensor.device_name_supply_air_fan_control_signal-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'friendly_name': 'Device Name Supply air fan control signal',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': '%',
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_supply_air_fan_control_signal',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '74',
})
# ---
# name: test_sensors[sensor.device_name_supply_air_temperature-entry]
EntityRegistryEntrySnapshot({
'aliases': set({
}),
'area_id': None,
'capabilities': None,
'config_entry_id': <ANY>,
'device_class': None,
'device_id': <ANY>,
'disabled_by': None,
'domain': 'sensor',
'entity_category': None,
'entity_id': 'sensor.device_name_supply_air_temperature',
'has_entity_name': True,
'hidden_by': None,
'icon': None,
'id': <ANY>,
'name': None,
'options': dict({
}),
'original_device_class': <SensorDeviceClass.TEMPERATURE: 'temperature'>,
'original_icon': None,
'original_name': 'Supply air temperature',
'platform': 'flexit_bacnet',
'previous_unique_id': None,
'supported_features': 0,
'translation_key': 'supply_air_temperature',
'unique_id': '0000-0001-supply_air_temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
})
# ---
# name: test_sensors[sensor.device_name_supply_air_temperature-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'temperature',
'friendly_name': 'Device Name Supply air temperature',
'unit_of_measurement': <UnitOfTemperature.CELSIUS: '°C'>,
}),
'context': <ANY>,
'entity_id': 'sensor.device_name_supply_air_temperature',
'last_changed': <ANY>,
'last_updated': <ANY>,
'state': '19.1',
})
# ---

View File

@ -0,0 +1,33 @@
"""Tests for the Flexit Nordic (BACnet) sensor entities."""
from unittest.mock import AsyncMock
from syrupy.assertion import SnapshotAssertion
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from tests.common import MockConfigEntry
from tests.components.flexit_bacnet import setup_with_selected_platforms
async def test_sensors(
hass: HomeAssistant,
snapshot: SnapshotAssertion,
entity_registry: er.EntityRegistry,
mock_flexit_bacnet: AsyncMock,
mock_config_entry: MockConfigEntry,
) -> None:
"""Test sensor states are correctly collected from library."""
await setup_with_selected_platforms(hass, mock_config_entry, [Platform.SENSOR])
entity_entries = er.async_entries_for_config_entry(
entity_registry, mock_config_entry.entry_id
)
assert entity_entries
for entity_entry in entity_entries:
assert entity_entry == snapshot(name=f"{entity_entry.entity_id}-entry")
assert hass.states.get(entity_entry.entity_id) == snapshot(
name=f"{entity_entry.entity_id}-state"
)