1 """Support for Iskra."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass, replace
8 from pyiskra.devices
import Device
9 from pyiskra.helper
import Counter, CounterType
14 SensorEntityDescription,
19 UnitOfElectricCurrent,
20 UnitOfElectricPotential,
29 from .
import IskraConfigEntry
32 ATTR_NON_RESETTABLE_COUNTER,
42 ATTR_RESETTABLE_COUNTER,
43 ATTR_TOTAL_ACTIVE_POWER,
44 ATTR_TOTAL_APPARENT_POWER,
45 ATTR_TOTAL_REACTIVE_POWER,
47 from .coordinator
import IskraDataUpdateCoordinator
48 from .entity
import IskraEntity
51 @dataclass(frozen=True, kw_only=True)
53 """Describes Iskra sensor entity."""
55 value_func: Callable[[Device], float |
None]
58 SENSOR_TYPES: tuple[IskraSensorEntityDescription, ...] = (
61 key=ATTR_TOTAL_ACTIVE_POWER,
62 translation_key=
"total_active_power",
63 device_class=SensorDeviceClass.POWER,
64 state_class=SensorStateClass.MEASUREMENT,
65 native_unit_of_measurement=UnitOfPower.WATT,
66 value_func=
lambda device: device.measurements.total.active_power.value,
69 key=ATTR_TOTAL_REACTIVE_POWER,
70 translation_key=
"total_reactive_power",
71 device_class=SensorDeviceClass.REACTIVE_POWER,
72 state_class=SensorStateClass.MEASUREMENT,
73 native_unit_of_measurement=UnitOfReactivePower.VOLT_AMPERE_REACTIVE,
74 value_func=
lambda device: device.measurements.total.reactive_power.value,
77 key=ATTR_TOTAL_APPARENT_POWER,
78 translation_key=
"total_apparent_power",
79 device_class=SensorDeviceClass.APPARENT_POWER,
80 state_class=SensorStateClass.MEASUREMENT,
81 native_unit_of_measurement=UnitOfApparentPower.VOLT_AMPERE,
82 value_func=
lambda device: device.measurements.total.apparent_power.value,
85 key=ATTR_PHASE1_POWER,
86 translation_key=
"phase1_power",
87 device_class=SensorDeviceClass.POWER,
88 state_class=SensorStateClass.MEASUREMENT,
89 native_unit_of_measurement=UnitOfPower.WATT,
90 value_func=
lambda device: device.measurements.phases[0].active_power.value,
93 key=ATTR_PHASE2_POWER,
94 translation_key=
"phase2_power",
95 device_class=SensorDeviceClass.POWER,
96 state_class=SensorStateClass.MEASUREMENT,
97 native_unit_of_measurement=UnitOfPower.WATT,
98 value_func=
lambda device: device.measurements.phases[1].active_power.value,
101 key=ATTR_PHASE3_POWER,
102 translation_key=
"phase3_power",
103 device_class=SensorDeviceClass.POWER,
104 state_class=SensorStateClass.MEASUREMENT,
105 native_unit_of_measurement=UnitOfPower.WATT,
106 value_func=
lambda device: device.measurements.phases[2].active_power.value,
110 key=ATTR_PHASE1_VOLTAGE,
111 translation_key=
"phase1_voltage",
112 device_class=SensorDeviceClass.VOLTAGE,
113 state_class=SensorStateClass.MEASUREMENT,
114 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
115 value_func=
lambda device: device.measurements.phases[0].voltage.value,
118 key=ATTR_PHASE2_VOLTAGE,
119 translation_key=
"phase2_voltage",
120 device_class=SensorDeviceClass.VOLTAGE,
121 state_class=SensorStateClass.MEASUREMENT,
122 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
123 value_func=
lambda device: device.measurements.phases[1].voltage.value,
126 key=ATTR_PHASE3_VOLTAGE,
127 translation_key=
"phase3_voltage",
128 device_class=SensorDeviceClass.VOLTAGE,
129 state_class=SensorStateClass.MEASUREMENT,
130 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
131 value_func=
lambda device: device.measurements.phases[2].voltage.value,
135 key=ATTR_PHASE1_CURRENT,
136 translation_key=
"phase1_current",
137 device_class=SensorDeviceClass.CURRENT,
138 state_class=SensorStateClass.MEASUREMENT,
139 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
140 value_func=
lambda device: device.measurements.phases[0].current.value,
143 key=ATTR_PHASE2_CURRENT,
144 translation_key=
"phase2_current",
145 device_class=SensorDeviceClass.CURRENT,
146 state_class=SensorStateClass.MEASUREMENT,
147 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
148 value_func=
lambda device: device.measurements.phases[1].current.value,
151 key=ATTR_PHASE3_CURRENT,
152 translation_key=
"phase3_current",
153 device_class=SensorDeviceClass.CURRENT,
154 state_class=SensorStateClass.MEASUREMENT,
155 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
156 value_func=
lambda device: device.measurements.phases[2].current.value,
161 translation_key=
"frequency",
162 device_class=SensorDeviceClass.FREQUENCY,
163 state_class=SensorStateClass.MEASUREMENT,
164 native_unit_of_measurement=UnitOfFrequency.HERTZ,
165 value_func=
lambda device: device.measurements.frequency.value,
174 ) -> IskraSensorEntityDescription:
175 """Dynamically create IskraSensor object as energy meter's counters are customizable."""
177 key = entity_name.format(index + 1)
179 if entity_name == ATTR_NON_RESETTABLE_COUNTER:
183 state_class=SensorStateClass.TOTAL_INCREASING,
184 value_func=
lambda device: device.counters.non_resettable[index].value,
185 native_unit_of_measurement=counter.units,
191 state_class=SensorStateClass.TOTAL_INCREASING,
192 value_func=
lambda device: device.counters.resettable[index].value,
193 native_unit_of_measurement=counter.units,
198 if counter.counter_type
in [CounterType.ACTIVE_IMPORT, CounterType.ACTIVE_EXPORT]:
199 entity_description = replace(
201 native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
202 device_class=SensorDeviceClass.ENERGY,
205 return entity_description
210 entry: IskraConfigEntry,
211 async_add_entities: AddEntitiesCallback,
213 """Set up Iskra sensors based on config_entry."""
216 coordinators = entry.runtime_data
218 entities: list[IskraSensor] = []
221 for coordinator
in coordinators:
222 device = coordinator.device
226 if device.supports_measurements:
227 sensors.append(ATTR_FREQUENCY)
228 sensors.append(ATTR_TOTAL_APPARENT_POWER)
229 sensors.append(ATTR_TOTAL_ACTIVE_POWER)
230 sensors.append(ATTR_TOTAL_REACTIVE_POWER)
231 if device.phases >= 1:
232 sensors.append(ATTR_PHASE1_VOLTAGE)
233 sensors.append(ATTR_PHASE1_POWER)
234 sensors.append(ATTR_PHASE1_CURRENT)
235 if device.phases >= 2:
236 sensors.append(ATTR_PHASE2_VOLTAGE)
237 sensors.append(ATTR_PHASE2_POWER)
238 sensors.append(ATTR_PHASE2_CURRENT)
239 if device.phases >= 3:
240 sensors.append(ATTR_PHASE3_VOLTAGE)
241 sensors.append(ATTR_PHASE3_POWER)
242 sensors.append(ATTR_PHASE3_CURRENT)
246 for description
in SENSOR_TYPES
247 if description.key
in sensors
250 if device.supports_counters:
251 for index, counter
in enumerate(device.counters.non_resettable[:4]):
253 counter, index, ATTR_NON_RESETTABLE_COUNTER
255 entities.append(
IskraSensor(coordinator, description))
257 for index, counter
in enumerate(device.counters.resettable[:8]):
259 counter, index, ATTR_RESETTABLE_COUNTER
261 entities.append(
IskraSensor(coordinator, description))
267 """Representation of a Sensor."""
269 entity_description: IskraSensorEntityDescription
273 coordinator: IskraDataUpdateCoordinator,
274 description: IskraSensorEntityDescription,
276 """Initialize the sensor."""
279 self.
_attr_unique_id_attr_unique_id = f
"{coordinator.device.serial}_{description.key}"
283 """Return the state of the sensor."""
None __init__(self, IskraDataUpdateCoordinator coordinator, IskraSensorEntityDescription description)
float|None native_value(self)
IskraSensorEntityDescription get_counter_entity_description(Counter counter, int index, str entity_name)
None async_setup_entry(HomeAssistant hass, IskraConfigEntry entry, AddEntitiesCallback async_add_entities)