1 """Component to make instant statistics about your history."""
3 from __future__
import annotations
5 from abc
import abstractmethod
9 import voluptuous
as vol
12 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
36 from .
import HistoryStatsConfigEntry
50 from .coordinator
import HistoryStatsUpdateCoordinator
51 from .data
import HistoryStats
52 from .helpers
import pretty_ratio
54 UNITS: dict[str, str] = {
55 CONF_TYPE_TIME: UnitOfTime.HOURS,
56 CONF_TYPE_RATIO: PERCENTAGE,
59 ICON =
"mdi:chart-line"
62 def exactly_two_period_keys[_T: dict[str, Any]](conf: _T) -> _T:
63 """Ensure exactly 2 of CONF_PERIOD_KEYS are provided."""
64 if sum(param
in conf
for param
in CONF_PERIOD_KEYS) != 2:
66 "You must provide exactly 2 of the following: start, end, duration"
71 PLATFORM_SCHEMA = vol.All(
72 SENSOR_PLATFORM_SCHEMA.extend(
74 vol.Required(CONF_ENTITY_ID): cv.entity_id,
75 vol.Required(CONF_STATE): vol.All(cv.ensure_list, [cv.string]),
76 vol.Optional(CONF_START): cv.template,
77 vol.Optional(CONF_END): cv.template,
78 vol.Optional(CONF_DURATION): cv.time_period,
79 vol.Optional(CONF_TYPE, default=CONF_TYPE_TIME): vol.In(CONF_TYPE_KEYS),
80 vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
81 vol.Optional(CONF_UNIQUE_ID): cv.string,
84 exactly_two_period_keys,
91 async_add_entities: AddEntitiesCallback,
92 discovery_info: DiscoveryInfoType |
None =
None,
94 """Set up the History Stats sensor."""
97 entity_id: str = config[CONF_ENTITY_ID]
98 entity_states: list[str] = config[CONF_STATE]
99 start: Template |
None = config.get(CONF_START)
100 end: Template |
None = config.get(CONF_END)
101 duration: datetime.timedelta |
None = config.get(CONF_DURATION)
102 sensor_type: str = config[CONF_TYPE]
103 name: str = config[CONF_NAME]
104 unique_id: str |
None = config.get(CONF_UNIQUE_ID)
106 history_stats =
HistoryStats(hass, entity_id, entity_states, start, end, duration)
108 await coordinator.async_refresh()
109 if not coordinator.last_update_success:
110 raise PlatformNotReady
from coordinator.last_exception
118 entry: HistoryStatsConfigEntry,
119 async_add_entities: AddEntitiesCallback,
121 """Set up the History stats sensor entry."""
123 sensor_type: str = entry.options[CONF_TYPE]
124 coordinator = entry.runtime_data
125 entity_id: str = entry.options[CONF_ENTITY_ID]
129 hass, coordinator, sensor_type, entry.title, entry.entry_id, entity_id
136 CoordinatorEntity[HistoryStatsUpdateCoordinator], SensorEntity
138 """Base class for a HistoryStats sensor."""
144 coordinator: HistoryStatsUpdateCoordinator,
147 """Initialize the HistoryStats sensor base class."""
152 """Entity has been added to hass."""
157 """Set attrs from value and count."""
164 """Process an update from the coordinator."""
167 class HistoryStatsSensor(HistoryStatsSensorBase):
168 """A HistoryStats sensor."""
170 _attr_state_class = SensorStateClass.MEASUREMENT
175 coordinator: HistoryStatsUpdateCoordinator,
178 unique_id: str |
None,
179 source_entity_id: str,
181 """Initialize the HistoryStats sensor."""
191 if self.
_type_type == CONF_TYPE_TIME:
197 """Process an update from the coordinator."""
198 state = self.coordinator.data
199 if state
is None or state.seconds_matched
is None:
203 if self.
_type_type == CONF_TYPE_TIME:
204 value = state.seconds_matched / 3600
206 value = round(value, 2)
208 elif self.
_type_type == CONF_TYPE_RATIO:
210 elif self.
_type_type == CONF_TYPE_COUNT:
CALLBACK_TYPE async_setup_state_listener(self)
None _process_update(self)
None _handle_coordinator_update(self)
None async_added_to_hass(self)
None __init__(self, HistoryStatsUpdateCoordinator coordinator, str name)
None __init__(self, HomeAssistant hass, HistoryStatsUpdateCoordinator coordinator, str sensor_type, str name, str|None unique_id, str source_entity_id)
None _process_update(self)
_attr_suggested_display_precision
_attr_native_unit_of_measurement
None async_on_remove(self, CALLBACK_TYPE func)
float pretty_ratio(float value, tuple[datetime.datetime, datetime.datetime] period)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
None async_setup_entry(HomeAssistant hass, HistoryStatsConfigEntry entry, AddEntitiesCallback async_add_entities)
dr.DeviceInfo|None async_device_info_to_link_from_entity(HomeAssistant hass, str entity_id_or_uuid)
None async_setup_reload_service(HomeAssistant hass, str domain, Iterable[str] platforms)