Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for Tibber sensors."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 import datetime
7 from datetime import timedelta
8 import logging
9 from random import randrange
10 from typing import Any
11 
12 import aiohttp
13 import tibber
14 
16  SensorDeviceClass,
17  SensorEntity,
18  SensorEntityDescription,
19  SensorStateClass,
20 )
21 from homeassistant.config_entries import ConfigEntry
22 from homeassistant.const import (
23  EVENT_HOMEASSISTANT_STOP,
24  PERCENTAGE,
25  SIGNAL_STRENGTH_DECIBELS,
26  EntityCategory,
27  UnitOfElectricCurrent,
28  UnitOfElectricPotential,
29  UnitOfEnergy,
30  UnitOfPower,
31 )
32 from homeassistant.core import Event, HomeAssistant, callback
33 from homeassistant.exceptions import PlatformNotReady
34 from homeassistant.helpers import device_registry as dr, entity_registry as er
35 from homeassistant.helpers.device_registry import DeviceInfo
36 from homeassistant.helpers.entity_platform import AddEntitiesCallback
37 from homeassistant.helpers.typing import StateType
39  CoordinatorEntity,
40  DataUpdateCoordinator,
41 )
42 from homeassistant.util import Throttle, dt as dt_util
43 
44 from .const import DOMAIN as TIBBER_DOMAIN, MANUFACTURER
45 from .coordinator import TibberDataCoordinator
46 
47 _LOGGER = logging.getLogger(__name__)
48 
49 ICON = "mdi:currency-usd"
50 SCAN_INTERVAL = timedelta(minutes=1)
51 MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=5)
52 PARALLEL_UPDATES = 0
53 TWENTY_MINUTES = 20 * 60
54 
55 RT_SENSORS_UNIQUE_ID_MIGRATION = {
56  "accumulated_consumption_last_hour": "accumulated consumption current hour",
57  "accumulated_production_last_hour": "accumulated production current hour",
58  "current_l1": "current L1",
59  "current_l2": "current L2",
60  "current_l3": "current L3",
61  "estimated_hour_consumption": "Estimated consumption current hour",
62 }
63 
64 RT_SENSORS_UNIQUE_ID_MIGRATION_SIMPLE = {
65  # simple migration can be done by replacing " " with "_"
66  "accumulated_consumption",
67  "accumulated_cost",
68  "accumulated_production",
69  "accumulated_reward",
70  "average_power",
71  "last_meter_consumption",
72  "last_meter_production",
73  "max_power",
74  "min_power",
75  "power_factor",
76  "power_production",
77  "signal_strength",
78  "voltage_phase1",
79  "voltage_phase2",
80  "voltage_phase3",
81 }
82 
83 
84 RT_SENSORS: tuple[SensorEntityDescription, ...] = (
86  key="averagePower",
87  translation_key="average_power",
88  device_class=SensorDeviceClass.POWER,
89  native_unit_of_measurement=UnitOfPower.WATT,
90  ),
92  key="power",
93  translation_key="power",
94  device_class=SensorDeviceClass.POWER,
95  state_class=SensorStateClass.MEASUREMENT,
96  native_unit_of_measurement=UnitOfPower.WATT,
97  ),
99  key="powerProduction",
100  translation_key="power_production",
101  device_class=SensorDeviceClass.POWER,
102  state_class=SensorStateClass.MEASUREMENT,
103  native_unit_of_measurement=UnitOfPower.WATT,
104  ),
106  key="minPower",
107  translation_key="min_power",
108  device_class=SensorDeviceClass.POWER,
109  native_unit_of_measurement=UnitOfPower.WATT,
110  ),
112  key="maxPower",
113  translation_key="max_power",
114  device_class=SensorDeviceClass.POWER,
115  native_unit_of_measurement=UnitOfPower.WATT,
116  ),
118  key="accumulatedConsumption",
119  translation_key="accumulated_consumption",
120  device_class=SensorDeviceClass.ENERGY,
121  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
122  state_class=SensorStateClass.TOTAL,
123  ),
125  key="accumulatedConsumptionLastHour",
126  translation_key="accumulated_consumption_last_hour",
127  device_class=SensorDeviceClass.ENERGY,
128  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
129  state_class=SensorStateClass.TOTAL_INCREASING,
130  ),
132  key="estimatedHourConsumption",
133  translation_key="estimated_hour_consumption",
134  device_class=SensorDeviceClass.ENERGY,
135  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
136  ),
138  key="accumulatedProduction",
139  translation_key="accumulated_production",
140  device_class=SensorDeviceClass.ENERGY,
141  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
142  state_class=SensorStateClass.TOTAL,
143  ),
145  key="accumulatedProductionLastHour",
146  translation_key="accumulated_production_last_hour",
147  device_class=SensorDeviceClass.ENERGY,
148  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
149  state_class=SensorStateClass.TOTAL_INCREASING,
150  ),
152  key="lastMeterConsumption",
153  translation_key="last_meter_consumption",
154  device_class=SensorDeviceClass.ENERGY,
155  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
156  state_class=SensorStateClass.TOTAL_INCREASING,
157  ),
159  key="lastMeterProduction",
160  translation_key="last_meter_production",
161  device_class=SensorDeviceClass.ENERGY,
162  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
163  state_class=SensorStateClass.TOTAL_INCREASING,
164  ),
166  key="voltagePhase1",
167  translation_key="voltage_phase1",
168  device_class=SensorDeviceClass.VOLTAGE,
169  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
170  state_class=SensorStateClass.MEASUREMENT,
171  ),
173  key="voltagePhase2",
174  translation_key="voltage_phase2",
175  device_class=SensorDeviceClass.VOLTAGE,
176  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
177  state_class=SensorStateClass.MEASUREMENT,
178  ),
180  key="voltagePhase3",
181  translation_key="voltage_phase3",
182  device_class=SensorDeviceClass.VOLTAGE,
183  native_unit_of_measurement=UnitOfElectricPotential.VOLT,
184  state_class=SensorStateClass.MEASUREMENT,
185  ),
187  key="currentL1",
188  translation_key="current_l1",
189  device_class=SensorDeviceClass.CURRENT,
190  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
191  state_class=SensorStateClass.MEASUREMENT,
192  ),
194  key="currentL2",
195  translation_key="current_l2",
196  device_class=SensorDeviceClass.CURRENT,
197  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
198  state_class=SensorStateClass.MEASUREMENT,
199  ),
201  key="currentL3",
202  translation_key="current_l3",
203  device_class=SensorDeviceClass.CURRENT,
204  native_unit_of_measurement=UnitOfElectricCurrent.AMPERE,
205  state_class=SensorStateClass.MEASUREMENT,
206  ),
208  key="signalStrength",
209  translation_key="signal_strength",
210  device_class=SensorDeviceClass.SIGNAL_STRENGTH,
211  native_unit_of_measurement=SIGNAL_STRENGTH_DECIBELS,
212  state_class=SensorStateClass.MEASUREMENT,
213  entity_category=EntityCategory.DIAGNOSTIC,
214  ),
216  key="accumulatedReward",
217  translation_key="accumulated_reward",
218  device_class=SensorDeviceClass.MONETARY,
219  state_class=SensorStateClass.TOTAL,
220  ),
222  key="accumulatedCost",
223  translation_key="accumulated_cost",
224  device_class=SensorDeviceClass.MONETARY,
225  state_class=SensorStateClass.TOTAL,
226  ),
228  key="powerFactor",
229  translation_key="power_factor",
230  device_class=SensorDeviceClass.POWER_FACTOR,
231  native_unit_of_measurement=PERCENTAGE,
232  state_class=SensorStateClass.MEASUREMENT,
233  ),
234 )
235 
236 SENSORS: tuple[SensorEntityDescription, ...] = (
238  key="month_cost",
239  translation_key="month_cost",
240  device_class=SensorDeviceClass.MONETARY,
241  ),
243  key="peak_hour",
244  translation_key="peak_hour",
245  device_class=SensorDeviceClass.ENERGY,
246  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
247  ),
249  key="peak_hour_time",
250  translation_key="peak_hour_time",
251  device_class=SensorDeviceClass.TIMESTAMP,
252  ),
254  key="month_cons",
255  translation_key="month_cons",
256  device_class=SensorDeviceClass.ENERGY,
257  native_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
258  state_class=SensorStateClass.TOTAL_INCREASING,
259  ),
260 )
261 
262 
264  hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
265 ) -> None:
266  """Set up the Tibber sensor."""
267 
268  tibber_connection = hass.data[TIBBER_DOMAIN]
269 
270  entity_registry = er.async_get(hass)
271  device_registry = dr.async_get(hass)
272 
273  coordinator: TibberDataCoordinator | None = None
274  entities: list[TibberSensor] = []
275  for home in tibber_connection.get_homes(only_active=False):
276  try:
277  await home.update_info()
278  except TimeoutError as err:
279  _LOGGER.error("Timeout connecting to Tibber home: %s ", err)
280  raise PlatformNotReady from err
281  except aiohttp.ClientError as err:
282  _LOGGER.error("Error connecting to Tibber home: %s ", err)
283  raise PlatformNotReady from err
284 
285  if home.has_active_subscription:
286  entities.append(TibberSensorElPrice(home))
287  if coordinator is None:
288  coordinator = TibberDataCoordinator(hass, tibber_connection)
289  entities.extend(
290  TibberDataSensor(home, coordinator, entity_description)
291  for entity_description in SENSORS
292  )
293 
294  if home.has_real_time_consumption:
295  entity_creator = TibberRtEntityCreator(
296  async_add_entities, home, entity_registry
297  )
298  await home.rt_subscribe(
300  entity_creator.add_sensors, home, hass
301  ).async_set_updated_data
302  )
303 
304  # migrate
305  old_id = home.info["viewer"]["home"]["meteringPointData"]["consumptionEan"]
306  if old_id is None:
307  continue
308 
309  # migrate to new device ids
310  old_entity_id = entity_registry.async_get_entity_id(
311  "sensor", TIBBER_DOMAIN, old_id
312  )
313  if old_entity_id is not None:
314  entity_registry.async_update_entity(
315  old_entity_id, new_unique_id=home.home_id
316  )
317 
318  # migrate to new device ids
319  device_entry = device_registry.async_get_device(
320  identifiers={(TIBBER_DOMAIN, old_id)}
321  )
322  if device_entry and entry.entry_id in device_entry.config_entries:
323  device_registry.async_update_device(
324  device_entry.id, new_identifiers={(TIBBER_DOMAIN, home.home_id)}
325  )
326 
327  async_add_entities(entities, True)
328 
329 
331  """Representation of a generic Tibber sensor."""
332 
333  _attr_has_entity_name = True
334 
335  def __init__(
336  self, *args: Any, tibber_home: tibber.TibberHome, **kwargs: Any
337  ) -> None:
338  """Initialize the sensor."""
339  super().__init__(*args, **kwargs)
340  self._tibber_home_tibber_home = tibber_home
341  self._home_name_home_name = tibber_home.info["viewer"]["home"]["appNickname"]
342  if self._home_name_home_name is None:
343  self._home_name_home_name = tibber_home.info["viewer"]["home"]["address"].get(
344  "address1", ""
345  )
346  self._device_name: str | None = None
347  self._model: str | None = None
348 
349  @property
350  def device_info(self) -> DeviceInfo:
351  """Return the device_info of the device."""
352  device_info = DeviceInfo(
353  identifiers={(TIBBER_DOMAIN, self._tibber_home_tibber_home.home_id)},
354  name=self._device_name,
355  manufacturer=MANUFACTURER,
356  )
357  if self._model is not None:
358  device_info["model"] = self._model
359  return device_info
360 
361 
363  """Representation of a Tibber sensor for el price."""
364 
365  _attr_state_class = SensorStateClass.MEASUREMENT
366  _attr_translation_key = "electricity_price"
367 
368  def __init__(self, tibber_home: tibber.TibberHome) -> None:
369  """Initialize the sensor."""
370  super().__init__(tibber_home=tibber_home)
371  self._last_updated: datetime.datetime | None = None
372  self._spread_load_constant_spread_load_constant = randrange(TWENTY_MINUTES)
373 
374  self._attr_available_attr_available = False
375  self._attr_extra_state_attributes_attr_extra_state_attributes = {
376  "app_nickname": None,
377  "grid_company": None,
378  "estimated_annual_consumption": None,
379  "price_level": None,
380  "max_price": None,
381  "avg_price": None,
382  "min_price": None,
383  "off_peak_1": None,
384  "peak": None,
385  "off_peak_2": None,
386  "intraday_price_ranking": None,
387  }
388  self._attr_icon_attr_icon = ICON
389  self._attr_unique_id_attr_unique_id = self._tibber_home_tibber_home.home_id
390  self._model_model = "Price Sensor"
391 
392  self._device_name_device_name = self._home_name_home_name
393 
394  async def async_update(self) -> None:
395  """Get the latest data and updates the states."""
396  now = dt_util.now()
397  if (
398  not self._tibber_home_tibber_home.last_data_timestamp
399  or (self._tibber_home_tibber_home.last_data_timestamp - now).total_seconds()
400  < 11 * 3600 + self._spread_load_constant_spread_load_constant
401  or not self.availableavailable
402  ):
403  _LOGGER.debug("Asking for new data")
404  await self._fetch_data_fetch_data()
405 
406  elif (
407  self._tibber_home_tibber_home.current_price_total
408  and self._last_updated
409  and self._last_updated.hour == now.hour
410  and self._tibber_home_tibber_home.last_data_timestamp
411  ):
412  return
413 
414  res = self._tibber_home_tibber_home.current_price_data()
415  self._attr_native_value, price_level, self._last_updated, price_rank = res
416  self._attr_extra_state_attributes_attr_extra_state_attributes["price_level"] = price_level
417  self._attr_extra_state_attributes_attr_extra_state_attributes["intraday_price_ranking"] = price_rank
418 
419  attrs = self._tibber_home_tibber_home.current_attributes()
420  self._attr_extra_state_attributes_attr_extra_state_attributes.update(attrs)
421  self._attr_available_attr_available = self._attr_native_value is not None
422  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = self._tibber_home_tibber_home.price_unit
423 
424  @Throttle(MIN_TIME_BETWEEN_UPDATES)
425  async def _fetch_data(self) -> None:
426  _LOGGER.debug("Fetching data")
427  try:
428  await self._tibber_home_tibber_home.update_info_and_price_info()
429  except (TimeoutError, aiohttp.ClientError):
430  return
431  data = self._tibber_home_tibber_home.info["viewer"]["home"]
432  self._attr_extra_state_attributes_attr_extra_state_attributes["app_nickname"] = data["appNickname"]
433  self._attr_extra_state_attributes_attr_extra_state_attributes["grid_company"] = data["meteringPointData"][
434  "gridCompany"
435  ]
436  self._attr_extra_state_attributes_attr_extra_state_attributes["estimated_annual_consumption"] = data[
437  "meteringPointData"
438  ]["estimatedAnnualConsumption"]
439 
440 
441 class TibberDataSensor(TibberSensor, CoordinatorEntity[TibberDataCoordinator]):
442  """Representation of a Tibber sensor."""
443 
444  def __init__(
445  self,
446  tibber_home: tibber.TibberHome,
447  coordinator: TibberDataCoordinator,
448  entity_description: SensorEntityDescription,
449  ) -> None:
450  """Initialize the sensor."""
451  super().__init__(coordinator=coordinator, tibber_home=tibber_home)
452  self.entity_descriptionentity_description = entity_description
453 
454  self._attr_unique_id_attr_unique_id = (
455  f"{self._tibber_home.home_id}_{self.entity_description.key}"
456  )
457  if entity_description.key == "month_cost":
458  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = self._tibber_home_tibber_home.currency
459 
460  self._device_name_device_name = self._home_name_home_name
461 
462  @property
463  def native_value(self) -> StateType:
464  """Return the value of the sensor."""
465  return getattr(self._tibber_home_tibber_home, self.entity_descriptionentity_description.key) # type: ignore[no-any-return]
466 
467 
468 class TibberSensorRT(TibberSensor, CoordinatorEntity["TibberRtDataCoordinator"]):
469  """Representation of a Tibber sensor for real time consumption."""
470 
471  def __init__(
472  self,
473  tibber_home: tibber.TibberHome,
474  description: SensorEntityDescription,
475  initial_state: float,
476  coordinator: TibberRtDataCoordinator,
477  ) -> None:
478  """Initialize the sensor."""
479  super().__init__(coordinator=coordinator, tibber_home=tibber_home)
480  self.entity_descriptionentity_description = description
481  self._model_model = "Tibber Pulse"
482  self._device_name_device_name = f"{self._model} {self._home_name}"
483 
484  self._attr_native_value_attr_native_value = initial_state
485  self._attr_unique_id_attr_unique_id = f"{self._tibber_home.home_id}_rt_{description.key}"
486 
487  if description.key in ("accumulatedCost", "accumulatedReward"):
488  self._attr_native_unit_of_measurement_attr_native_unit_of_measurement = tibber_home.currency
489 
490  @property
491  def available(self) -> bool:
492  """Return True if entity is available."""
493  return self._tibber_home_tibber_home.rt_subscription_running
494 
495  @callback
496  def _handle_coordinator_update(self) -> None:
497  if not (live_measurement := self.coordinator.get_live_measurement()):
498  return
499  state = live_measurement.get(self.entity_descriptionentity_description.key)
500  if state is None:
501  return
502  if self.entity_descriptionentity_description.key in (
503  "accumulatedConsumption",
504  "accumulatedProduction",
505  ):
506  # Value is reset to 0 at midnight, but not always strictly increasing
507  # due to hourly corrections.
508  # If device is offline, last_reset should be updated when it comes
509  # back online if the value has decreased
510  ts_local = dt_util.parse_datetime(live_measurement["timestamp"])
511  if ts_local is not None:
512  if self.last_resetlast_reset is None or (
513  # native_value is float
514  state < 0.5 * self.native_valuenative_value # type: ignore[operator]
515  and (
516  ts_local.hour == 0
517  or (ts_local - self.last_resetlast_reset) > timedelta(hours=24)
518  )
519  ):
520  self._attr_last_reset_attr_last_reset = dt_util.as_utc(
521  ts_local.replace(hour=0, minute=0, second=0, microsecond=0)
522  )
523  if self.entity_descriptionentity_description.key == "powerFactor":
524  state *= 100.0
525  self._attr_native_value_attr_native_value = state
526  self.async_write_ha_stateasync_write_ha_state()
527 
528 
530  """Create realtime Tibber entities."""
531 
532  def __init__(
533  self,
534  async_add_entities: AddEntitiesCallback,
535  tibber_home: tibber.TibberHome,
536  entity_registry: er.EntityRegistry,
537  ) -> None:
538  """Initialize the data handler."""
539  self._async_add_entities_async_add_entities = async_add_entities
540  self._tibber_home_tibber_home = tibber_home
541  self._added_sensors: set[str] = set()
542  self._entity_registry_entity_registry = entity_registry
543 
544  @callback
545  def _migrate_unique_id(self, sensor_description: SensorEntityDescription) -> None:
546  """Migrate unique id if needed."""
547  home_id = self._tibber_home_tibber_home.home_id
548  translation_key = sensor_description.translation_key
549  description_key = sensor_description.key
550  entity_id: str | None = None
551  if translation_key in RT_SENSORS_UNIQUE_ID_MIGRATION_SIMPLE:
552  entity_id = self._entity_registry_entity_registry.async_get_entity_id(
553  "sensor",
554  TIBBER_DOMAIN,
555  f"{home_id}_rt_{translation_key.replace('_', ' ')}",
556  )
557  elif translation_key in RT_SENSORS_UNIQUE_ID_MIGRATION:
558  entity_id = self._entity_registry_entity_registry.async_get_entity_id(
559  "sensor",
560  TIBBER_DOMAIN,
561  f"{home_id}_rt_{RT_SENSORS_UNIQUE_ID_MIGRATION[translation_key]}",
562  )
563  elif translation_key != description_key:
564  entity_id = self._entity_registry_entity_registry.async_get_entity_id(
565  "sensor",
566  TIBBER_DOMAIN,
567  f"{home_id}_rt_{translation_key}",
568  )
569 
570  if entity_id is None:
571  return
572 
573  new_unique_id = f"{home_id}_rt_{description_key}"
574 
575  _LOGGER.debug(
576  "Migrating unique id for %s to %s",
577  entity_id,
578  new_unique_id,
579  )
580  try:
581  self._entity_registry_entity_registry.async_update_entity(
582  entity_id, new_unique_id=new_unique_id
583  )
584  except ValueError as err:
585  _LOGGER.error(err)
586 
587  @callback
589  self, coordinator: TibberRtDataCoordinator, live_measurement: Any
590  ) -> None:
591  """Add sensor."""
592  new_entities = []
593  for sensor_description in RT_SENSORS:
594  if sensor_description.key in self._added_sensors:
595  continue
596  state = live_measurement.get(sensor_description.key)
597  if state is None:
598  continue
599 
600  self._migrate_unique_id_migrate_unique_id(sensor_description)
601  entity = TibberSensorRT(
602  self._tibber_home_tibber_home,
603  sensor_description,
604  state,
605  coordinator,
606  )
607  new_entities.append(entity)
608  self._added_sensors.add(sensor_description.key)
609  if new_entities:
610  self._async_add_entities_async_add_entities(new_entities)
611 
612 
613 class TibberRtDataCoordinator(DataUpdateCoordinator): # pylint: disable=hass-enforce-class-module
614  """Handle Tibber realtime data."""
615 
616  def __init__(
617  self,
618  add_sensor_callback: Callable[[TibberRtDataCoordinator, Any], None],
619  tibber_home: tibber.TibberHome,
620  hass: HomeAssistant,
621  ) -> None:
622  """Initialize the data handler."""
623  self._add_sensor_callback_add_sensor_callback = add_sensor_callback
624  super().__init__(
625  hass,
626  _LOGGER,
627  name=tibber_home.info["viewer"]["home"]["address"].get(
628  "address1", "Tibber"
629  ),
630  )
631 
632  self._async_remove_device_updates_handler_async_remove_device_updates_handler = self.async_add_listenerasync_add_listenerasync_add_listener(
633  self._data_updated_data_updated
634  )
635  hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, self._handle_ha_stop_handle_ha_stop)
636 
637  @callback
638  def _handle_ha_stop(self, _event: Event) -> None:
639  """Handle Home Assistant stopping."""
640  self._async_remove_device_updates_handler_async_remove_device_updates_handler()
641 
642  @callback
643  def _data_updated(self) -> None:
644  """Triggered when data is updated."""
645  if live_measurement := self.get_live_measurementget_live_measurement():
646  self._add_sensor_callback_add_sensor_callback(self, live_measurement)
647 
648  def get_live_measurement(self) -> Any:
649  """Get live measurement data."""
650  if errors := self.datadata.get("errors"):
651  _LOGGER.error(errors[0])
652  return None
653  return self.datadata.get("data", {}).get("liveMeasurement")
StateType|date|datetime|Decimal native_value(self)
Definition: __init__.py:460
None __init__(self, tibber.TibberHome tibber_home, TibberDataCoordinator coordinator, SensorEntityDescription entity_description)
Definition: sensor.py:449
None __init__(self, Callable[[TibberRtDataCoordinator, Any], None] add_sensor_callback, tibber.TibberHome tibber_home, HomeAssistant hass)
Definition: sensor.py:621
None _migrate_unique_id(self, SensorEntityDescription sensor_description)
Definition: sensor.py:545
None __init__(self, AddEntitiesCallback async_add_entities, tibber.TibberHome tibber_home, er.EntityRegistry entity_registry)
Definition: sensor.py:537
None add_sensors(self, TibberRtDataCoordinator coordinator, Any live_measurement)
Definition: sensor.py:590
None __init__(self, tibber.TibberHome tibber_home)
Definition: sensor.py:368
None __init__(self, tibber.TibberHome tibber_home, SensorEntityDescription description, float initial_state, TibberRtDataCoordinator coordinator)
Definition: sensor.py:477
None __init__(self, *Any args, tibber.TibberHome tibber_home, **Any kwargs)
Definition: sensor.py:337
Callable[[], None] async_add_listener(self, CALLBACK_TYPE update_callback, Any context=None)
Callable[[], None] async_add_listener(self, CALLBACK_TYPE update_callback, Any context=None)
bool add(self, _T matcher)
Definition: match.py:185
web.Response get(self, web.Request request, str config_key)
Definition: view.py:88
IssData update(pyiss.ISS iss)
Definition: __init__.py:33
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:265
None async_update_entity(HomeAssistant hass, str entity_id)