1 """Support for iammeter via local API."""
3 from __future__
import annotations
5 from asyncio
import timeout
6 from collections.abc
import Callable
7 from dataclasses
import dataclass
8 from datetime
import datetime, timedelta
11 from iammeter.client
import IamMeter
12 import voluptuous
as vol
15 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
18 SensorEntityDescription,
27 UnitOfElectricCurrent,
28 UnitOfElectricPotential,
42 from .const
import DEVICE_3080, DOMAIN
44 _LOGGER = logging.getLogger(__name__)
47 DEFAULT_DEVICE_NAME =
"IamMeter"
49 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
51 vol.Required(CONF_HOST): cv.string,
52 vol.Optional(CONF_NAME, default=DEFAULT_DEVICE_NAME): cv.string,
53 vol.Optional(CONF_PORT, default=DEFAULT_PORT): cv.port,
62 hass: HomeAssistant, model: str, serial_number: str
64 """Migrate old unique ids to new unique ids."""
65 ent_reg = er.async_get(hass)
75 phase_list = [
"A",
"B",
"C",
"NET"]
76 id_phase_range = 1
if model == DEVICE_3080
else 4
77 id_name_range = 5
if model == DEVICE_3080
else 7
78 for row
in range(id_phase_range):
79 for idx
in range(id_name_range):
80 old_unique_id = f
"{serial_number}-{row}-{idx}"
82 f
"{serial_number}_{name_list[idx]}"
83 if model == DEVICE_3080
84 else f
"{serial_number}_{name_list[idx]}_{phase_list[row]}"
86 entity_id = ent_reg.async_get_entity_id(
87 Platform.SENSOR, DOMAIN, old_unique_id
89 if entity_id
is not None:
91 ent_reg.async_update_entity(entity_id, new_unique_id=new_unique_id)
94 "Skip migration of id [%s] to [%s] because it already exists",
100 "Migrating unique_id from [%s] to [%s]",
109 async_add_entities: AddEntitiesCallback,
110 discovery_info: DiscoveryInfoType |
None =
None,
112 """Platform setup."""
113 config_host = config[CONF_HOST]
114 config_port = config[CONF_PORT]
115 config_name = config[CONF_NAME]
117 api = await hass.async_add_executor_job(
118 IamMeter, config_host, config_port, config_name
120 except TimeoutError
as err:
121 _LOGGER.error(
"Device is not ready")
122 raise PlatformNotReady
from err
124 async
def async_update_data():
126 async
with timeout(PLATFORM_TIMEOUT):
127 return await hass.async_add_executor_job(api.client.get_data)
128 except TimeoutError
as err:
129 raise UpdateFailed
from err
135 update_method=async_update_data,
136 update_interval=SCAN_INTERVAL,
137 request_refresh_debouncer=debounce.Debouncer(
138 hass, _LOGGER, cooldown=0.3, immediate=
True
141 await coordinator.async_refresh()
142 model = coordinator.data[
"Model"]
143 serial_number = coordinator.data[
"sn"]
145 if model == DEVICE_3080:
148 for description
in SENSOR_TYPES_3080
153 for description
in SENSOR_TYPES_3080T
158 """Representation of a Sensor."""
160 entity_description: IammeterSensorEntityDescription
161 _attr_has_entity_name =
True
166 coordinator: DataUpdateCoordinator,
167 description: IammeterSensorEntityDescription,
169 """Initialize the sensor."""
174 identifiers={(DOMAIN, coordinator.data[
"sn"])},
175 manufacturer=
"IamMeter",
176 name=coordinator.name,
181 """Return the native sensor value."""
182 raw_attr = self.coordinator.data.get(self.
entity_descriptionentity_description.key,
None)
188 @dataclass(frozen=True)
190 """Describes Iammeter sensor entity."""
192 value: Callable[[float | int], float] | Callable[[datetime], datetime] |
None =
None
195 SENSOR_TYPES_3080: tuple[IammeterSensorEntityDescription, ...] = (
198 icon=
"mdi:solar-power",
199 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
200 device_class=SensorDeviceClass.VOLTAGE,
201 state_class=SensorStateClass.MEASUREMENT,
202 entity_registry_enabled_default=
False,
206 icon=
"mdi:solar-power",
207 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
208 state_class=SensorStateClass.MEASUREMENT,
209 device_class=SensorDeviceClass.CURRENT,
210 entity_registry_enabled_default=
False,
214 icon=
"mdi:solar-power",
215 native_unit_of_measurement=UnitOfPower.WATT,
216 device_class=SensorDeviceClass.POWER,
217 state_class=SensorStateClass.MEASUREMENT,
221 icon=
"mdi:solar-power",
222 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
223 device_class=SensorDeviceClass.ENERGY,
224 state_class=SensorStateClass.TOTAL_INCREASING,
228 icon=
"mdi:solar-power",
229 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
230 device_class=SensorDeviceClass.ENERGY,
231 state_class=SensorStateClass.TOTAL_INCREASING,
234 SENSOR_TYPES_3080T: tuple[IammeterSensorEntityDescription, ...] = (
237 translation_key=
"voltage_a",
238 icon=
"mdi:solar-power",
239 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
240 device_class=SensorDeviceClass.VOLTAGE,
241 state_class=SensorStateClass.MEASUREMENT,
242 entity_registry_enabled_default=
False,
246 translation_key=
"current_a",
247 icon=
"mdi:solar-power",
248 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
249 state_class=SensorStateClass.MEASUREMENT,
250 device_class=SensorDeviceClass.CURRENT,
251 entity_registry_enabled_default=
False,
255 translation_key=
"power_a",
256 icon=
"mdi:solar-power",
257 native_unit_of_measurement=UnitOfPower.WATT,
258 device_class=SensorDeviceClass.POWER,
259 state_class=SensorStateClass.MEASUREMENT,
262 key=
"ImportEnergy_A",
263 translation_key=
"import_energy_a",
264 icon=
"mdi:solar-power",
265 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
266 device_class=SensorDeviceClass.ENERGY,
267 state_class=SensorStateClass.TOTAL_INCREASING,
271 translation_key=
"export_grid_a",
272 icon=
"mdi:solar-power",
273 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
274 device_class=SensorDeviceClass.ENERGY,
275 state_class=SensorStateClass.TOTAL_INCREASING,
279 translation_key=
"frequency_a",
280 icon=
"mdi:solar-power",
281 native_unit_of_measurement=UnitOfFrequency.HERTZ,
282 device_class=SensorDeviceClass.FREQUENCY,
283 state_class=SensorStateClass.MEASUREMENT,
284 entity_registry_enabled_default=
False,
288 translation_key=
"pf_a",
289 icon=
"mdi:solar-power",
290 native_unit_of_measurement=PERCENTAGE,
291 state_class=SensorStateClass.MEASUREMENT,
292 device_class=SensorDeviceClass.POWER_FACTOR,
293 value=
lambda value: value * 100,
294 entity_registry_enabled_default=
False,
298 translation_key=
"voltage_b",
299 icon=
"mdi:solar-power",
300 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
301 device_class=SensorDeviceClass.VOLTAGE,
302 state_class=SensorStateClass.MEASUREMENT,
303 entity_registry_enabled_default=
False,
307 translation_key=
"current_b",
308 icon=
"mdi:solar-power",
309 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
310 state_class=SensorStateClass.MEASUREMENT,
311 device_class=SensorDeviceClass.CURRENT,
312 entity_registry_enabled_default=
False,
316 translation_key=
"power_b",
317 icon=
"mdi:solar-power",
318 native_unit_of_measurement=UnitOfPower.WATT,
319 device_class=SensorDeviceClass.POWER,
320 state_class=SensorStateClass.MEASUREMENT,
323 key=
"ImportEnergy_B",
324 translation_key=
"import_energy_b",
325 icon=
"mdi:solar-power",
326 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
327 device_class=SensorDeviceClass.ENERGY,
328 state_class=SensorStateClass.TOTAL_INCREASING,
332 translation_key=
"export_grid_b",
333 icon=
"mdi:solar-power",
334 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
335 device_class=SensorDeviceClass.ENERGY,
336 state_class=SensorStateClass.TOTAL_INCREASING,
340 translation_key=
"frequency_b",
341 icon=
"mdi:solar-power",
342 native_unit_of_measurement=UnitOfFrequency.HERTZ,
343 device_class=SensorDeviceClass.FREQUENCY,
344 state_class=SensorStateClass.MEASUREMENT,
345 entity_registry_enabled_default=
False,
349 translation_key=
"pf_b",
350 icon=
"mdi:solar-power",
351 native_unit_of_measurement=PERCENTAGE,
352 state_class=SensorStateClass.MEASUREMENT,
353 device_class=SensorDeviceClass.POWER_FACTOR,
354 value=
lambda value: value * 100,
355 entity_registry_enabled_default=
False,
359 translation_key=
"voltage_c",
360 icon=
"mdi:solar-power",
361 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
362 device_class=SensorDeviceClass.VOLTAGE,
363 state_class=SensorStateClass.MEASUREMENT,
364 entity_registry_enabled_default=
False,
368 translation_key=
"current_c",
369 icon=
"mdi:solar-power",
370 native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
371 state_class=SensorStateClass.MEASUREMENT,
372 device_class=SensorDeviceClass.CURRENT,
373 entity_registry_enabled_default=
False,
377 translation_key=
"power_c",
378 icon=
"mdi:solar-power",
379 native_unit_of_measurement=UnitOfPower.WATT,
380 device_class=SensorDeviceClass.POWER,
381 state_class=SensorStateClass.MEASUREMENT,
384 key=
"ImportEnergy_C",
385 translation_key=
"import_energy_c",
386 icon=
"mdi:solar-power",
387 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
388 device_class=SensorDeviceClass.ENERGY,
389 state_class=SensorStateClass.TOTAL_INCREASING,
393 translation_key=
"export_grid_c",
394 icon=
"mdi:solar-power",
395 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
396 device_class=SensorDeviceClass.ENERGY,
397 state_class=SensorStateClass.TOTAL_INCREASING,
401 translation_key=
"frequency_c",
402 icon=
"mdi:solar-power",
403 native_unit_of_measurement=UnitOfFrequency.HERTZ,
404 device_class=SensorDeviceClass.FREQUENCY,
405 state_class=SensorStateClass.MEASUREMENT,
406 entity_registry_enabled_default=
False,
410 translation_key=
"pf_c",
411 icon=
"mdi:solar-power",
412 native_unit_of_measurement=PERCENTAGE,
413 state_class=SensorStateClass.MEASUREMENT,
414 device_class=SensorDeviceClass.POWER_FACTOR,
415 value=
lambda value: value * 100,
416 entity_registry_enabled_default=
False,
420 translation_key=
"voltage_net",
421 icon=
"mdi:solar-power",
422 native_unit_of_measurement=UnitOfElectricPotential.VOLT,
423 device_class=SensorDeviceClass.VOLTAGE,
424 state_class=SensorStateClass.MEASUREMENT,
425 entity_registry_enabled_default=
False,
429 icon=
"mdi:solar-power",
430 native_unit_of_measurement=UnitOfPower.WATT,
431 device_class=SensorDeviceClass.POWER,
432 state_class=SensorStateClass.MEASUREMENT,
433 entity_registry_enabled_default=
False,
436 key=
"ImportEnergy_Net",
437 translation_key=
"import_energy_net",
438 icon=
"mdi:solar-power",
439 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
440 device_class=SensorDeviceClass.ENERGY,
441 state_class=SensorStateClass.TOTAL_INCREASING,
442 entity_registry_enabled_default=
False,
445 key=
"ExportGrid_Net",
446 translation_key=
"export_grid_net",
447 icon=
"mdi:solar-power",
448 native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
449 device_class=SensorDeviceClass.ENERGY,
450 state_class=SensorStateClass.TOTAL_INCREASING,
451 entity_registry_enabled_default=
False,
455 translation_key=
"frequency_net",
456 icon=
"mdi:solar-power",
457 native_unit_of_measurement=UnitOfFrequency.HERTZ,
458 device_class=SensorDeviceClass.FREQUENCY,
459 state_class=SensorStateClass.MEASUREMENT,
460 entity_registry_enabled_default=
False,
464 translation_key=
"pf_net",
465 icon=
"mdi:solar-power",
466 native_unit_of_measurement=PERCENTAGE,
467 state_class=SensorStateClass.MEASUREMENT,
468 device_class=SensorDeviceClass.POWER_FACTOR,
469 value=
lambda value: value * 100,
470 entity_registry_enabled_default=
False,
None __init__(self, DataUpdateCoordinator coordinator, IammeterSensorEntityDescription description)
None _migrate_to_new_unique_id(HomeAssistant hass, str model, str serial_number)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)