Home Assistant Unofficial Reference 2024.12.1
sensor.py
Go to the documentation of this file.
1 """Support for the Forecast.Solar sensor service."""
2 
3 from __future__ import annotations
4 
5 from collections.abc import Callable
6 from dataclasses import dataclass
7 from datetime import datetime, timedelta
8 from typing import Any
9 
10 from forecast_solar.models import Estimate
11 
13  DOMAIN as SENSOR_DOMAIN,
14  SensorDeviceClass,
15  SensorEntity,
16  SensorEntityDescription,
17  SensorStateClass,
18 )
19 from homeassistant.const import UnitOfEnergy, UnitOfPower
20 from homeassistant.core import HomeAssistant
21 from homeassistant.helpers.device_registry import DeviceEntryType, DeviceInfo
22 from homeassistant.helpers.entity_platform import AddEntitiesCallback
23 from homeassistant.helpers.typing import StateType
24 from homeassistant.helpers.update_coordinator import CoordinatorEntity
25 
26 from . import ForecastSolarConfigEntry
27 from .const import DOMAIN
28 from .coordinator import ForecastSolarDataUpdateCoordinator
29 
30 
31 @dataclass(frozen=True)
33  """Describes a Forecast.Solar Sensor."""
34 
35  state: Callable[[Estimate], Any] | None = None
36 
37 
38 SENSORS: tuple[ForecastSolarSensorEntityDescription, ...] = (
40  key="energy_production_today",
41  translation_key="energy_production_today",
42  state=lambda estimate: estimate.energy_production_today,
43  device_class=SensorDeviceClass.ENERGY,
44  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
45  suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
46  suggested_display_precision=1,
47  ),
49  key="energy_production_today_remaining",
50  translation_key="energy_production_today_remaining",
51  state=lambda estimate: estimate.energy_production_today_remaining,
52  device_class=SensorDeviceClass.ENERGY,
53  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
54  suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
55  suggested_display_precision=1,
56  ),
58  key="energy_production_tomorrow",
59  translation_key="energy_production_tomorrow",
60  state=lambda estimate: estimate.energy_production_tomorrow,
61  device_class=SensorDeviceClass.ENERGY,
62  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
63  suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
64  suggested_display_precision=1,
65  ),
67  key="power_highest_peak_time_today",
68  translation_key="power_highest_peak_time_today",
69  device_class=SensorDeviceClass.TIMESTAMP,
70  ),
72  key="power_highest_peak_time_tomorrow",
73  translation_key="power_highest_peak_time_tomorrow",
74  device_class=SensorDeviceClass.TIMESTAMP,
75  ),
77  key="power_production_now",
78  translation_key="power_production_now",
79  device_class=SensorDeviceClass.POWER,
80  state=lambda estimate: estimate.power_production_now,
81  state_class=SensorStateClass.MEASUREMENT,
82  native_unit_of_measurement=UnitOfPower.WATT,
83  ),
85  key="power_production_next_hour",
86  translation_key="power_production_next_hour",
87  state=lambda estimate: estimate.power_production_at_time(
88  estimate.now() + timedelta(hours=1)
89  ),
90  device_class=SensorDeviceClass.POWER,
91  entity_registry_enabled_default=False,
92  native_unit_of_measurement=UnitOfPower.WATT,
93  ),
95  key="power_production_next_12hours",
96  translation_key="power_production_next_12hours",
97  state=lambda estimate: estimate.power_production_at_time(
98  estimate.now() + timedelta(hours=12)
99  ),
100  device_class=SensorDeviceClass.POWER,
101  entity_registry_enabled_default=False,
102  native_unit_of_measurement=UnitOfPower.WATT,
103  ),
105  key="power_production_next_24hours",
106  translation_key="power_production_next_24hours",
107  state=lambda estimate: estimate.power_production_at_time(
108  estimate.now() + timedelta(hours=24)
109  ),
110  device_class=SensorDeviceClass.POWER,
111  entity_registry_enabled_default=False,
112  native_unit_of_measurement=UnitOfPower.WATT,
113  ),
115  key="energy_current_hour",
116  translation_key="energy_current_hour",
117  state=lambda estimate: estimate.energy_current_hour,
118  device_class=SensorDeviceClass.ENERGY,
119  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
120  suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
121  suggested_display_precision=1,
122  ),
124  key="energy_next_hour",
125  translation_key="energy_next_hour",
126  state=lambda estimate: estimate.sum_energy_production(1),
127  device_class=SensorDeviceClass.ENERGY,
128  native_unit_of_measurement=UnitOfEnergy.WATT_HOUR,
129  suggested_unit_of_measurement=UnitOfEnergy.KILO_WATT_HOUR,
130  suggested_display_precision=1,
131  ),
132 )
133 
134 
136  hass: HomeAssistant,
137  entry: ForecastSolarConfigEntry,
138  async_add_entities: AddEntitiesCallback,
139 ) -> None:
140  """Defer sensor setup to the shared sensor module."""
141  coordinator = entry.runtime_data
142 
145  entry_id=entry.entry_id,
146  coordinator=coordinator,
147  entity_description=entity_description,
148  )
149  for entity_description in SENSORS
150  )
151 
152 
154  CoordinatorEntity[ForecastSolarDataUpdateCoordinator], SensorEntity
155 ):
156  """Defines a Forecast.Solar sensor."""
157 
158  entity_description: ForecastSolarSensorEntityDescription
159  _attr_has_entity_name = True
160 
161  def __init__(
162  self,
163  *,
164  entry_id: str,
165  coordinator: ForecastSolarDataUpdateCoordinator,
166  entity_description: ForecastSolarSensorEntityDescription,
167  ) -> None:
168  """Initialize Forecast.Solar sensor."""
169  super().__init__(coordinator=coordinator)
170  self.entity_descriptionentity_description = entity_description
171  self.entity_identity_identity_id = f"{SENSOR_DOMAIN}.{entity_description.key}"
172  self._attr_unique_id_attr_unique_id = f"{entry_id}_{entity_description.key}"
173 
174  self._attr_device_info_attr_device_info = DeviceInfo(
175  entry_type=DeviceEntryType.SERVICE,
176  identifiers={(DOMAIN, entry_id)},
177  manufacturer="Forecast.Solar",
178  model=coordinator.data.account_type.value,
179  name="Solar production forecast",
180  configuration_url="https://forecast.solar",
181  )
182 
183  @property
184  def native_value(self) -> datetime | StateType:
185  """Return the state of the sensor."""
186  if self.entity_descriptionentity_description.state is None:
187  state: StateType | datetime = getattr(
188  self.coordinator.data, self.entity_descriptionentity_description.key
189  )
190  else:
191  state = self.entity_descriptionentity_description.state(self.coordinator.data)
192 
193  return state
None __init__(self, *str entry_id, ForecastSolarDataUpdateCoordinator coordinator, ForecastSolarSensorEntityDescription entity_description)
Definition: sensor.py:167
None async_setup_entry(HomeAssistant hass, ForecastSolarConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: sensor.py:139