1 """Support for showing the date and the time."""
3 from __future__
import annotations
5 from collections.abc
import Callable, Mapping
6 from datetime
import datetime, timedelta
10 import voluptuous
as vol
14 PLATFORM_SCHEMA
as SENSOR_PLATFORM_SCHEMA,
26 from .const
import OPTION_TYPES
28 _LOGGER = logging.getLogger(__name__)
30 TIME_STR_FORMAT =
"%H:%M"
33 PLATFORM_SCHEMA = SENSOR_PLATFORM_SCHEMA.extend(
35 vol.Optional(CONF_DISPLAY_OPTIONS, default=[
"time"]): vol.All(
36 cv.ensure_list, [vol.In(OPTION_TYPES)]
45 async_add_entities: AddEntitiesCallback,
46 discovery_info: DiscoveryInfoType |
None =
None,
48 """Set up the Time and Date sensor."""
49 if hass.config.time_zone
is None:
50 _LOGGER.error(
"Timezone is not set in Home Assistant configuration")
54 [
TimeDateSensor(variable)
for variable
in config[CONF_DISPLAY_OPTIONS]]
59 hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
61 """Set up the Time & Date sensor."""
64 [
TimeDateSensor(entry.options[CONF_DISPLAY_OPTIONS], entry.entry_id)]
69 """Implementation of a Time and Date sensor."""
71 _attr_should_poll =
False
72 _attr_has_entity_name =
True
73 _state: str |
None =
None
74 unsub: CALLBACK_TYPE |
None =
None
76 def __init__(self, option_type: str, entry_id: str |
None =
None) ->
None:
77 """Initialize the sensor."""
79 self.
typetype = option_type
87 """Return the state of the sensor."""
92 """Icon to use in the frontend, if any."""
93 if "date" in self.
typetype
and "time" in self.
typetype:
94 return "mdi:calendar-clock"
95 if "date" in self.
typetype:
102 preview_callback: Callable[[str, Mapping[str, Any]],
None],
104 """Render a preview."""
108 """Update preview."""
110 now = dt_util.utcnow()
116 preview_callback(calculated_state.state, calculated_state.attributes)
119 def async_stop_preview() -> None:
123 self.
unsubunsub =
None
126 return async_stop_preview
129 """Set up first update."""
131 async
def async_update_config(event: Event) ->
None:
132 """Handle core config update."""
137 self.
hasshass.bus.async_listen(EVENT_CORE_CONFIG_UPDATE, async_update_config)
142 """Cancel next update."""
145 self.
unsubunsub =
None
148 """Compute next time an update should occur."""
149 if self.
typetype ==
"date":
150 tomorrow = dt_util.as_local(time_date) +
timedelta(days=1)
151 return dt_util.start_of_local_day(tomorrow)
153 timestamp = dt_util.as_timestamp(time_date)
156 delta = interval - (timestamp % interval)
157 next_interval = time_date +
timedelta(seconds=delta)
158 _LOGGER.debug(
"%s + %s -> %s (%s)", time_date, delta, next_interval, self.
typetype)
163 time = dt_util.as_local(time_date).strftime(TIME_STR_FORMAT)
164 time_utc = time_date.strftime(TIME_STR_FORMAT)
165 date = dt_util.as_local(time_date).
date().isoformat()
166 date_utc = time_date.date().isoformat()
168 if self.
typetype ==
"time":
170 elif self.
typetype ==
"date":
172 elif self.
typetype ==
"date_time":
173 self.
_state_state = f
"{date}, {time}"
174 elif self.
typetype ==
"date_time_utc":
175 self.
_state_state = f
"{date_utc}, {time_utc}"
176 elif self.
typetype ==
"time_date":
177 self.
_state_state = f
"{time}, {date}"
178 elif self.
typetype ==
"time_utc":
179 self.
_state_state = time_utc
180 elif self.
typetype ==
"date_time_iso":
181 self.
_state_state = dt_util.parse_datetime(
182 f
"{date} {time}", raise_on_error=
True
186 """Update state and setup listener for next interval."""
187 now = dt_util.utcnow()
195 """Get the latest data and update state."""
str|None native_value(self)
None _update_state_and_setup_listener(self)
None async_added_to_hass(self)
None __init__(self, str option_type, str|None entry_id=None)
CALLBACK_TYPE async_start_preview(self, Callable[[str, Mapping[str, Any]], None] preview_callback)
None _update_internal_state(self, datetime time_date)
None point_in_time_listener(self, datetime time_date)
datetime get_next_interval(self, datetime time_date)
None async_will_remove_from_hass(self)
None async_write_ha_state(self)
CalculatedState _async_calculate_state(self)
None async_on_remove(self, CALLBACK_TYPE func)
None async_setup_entry(HomeAssistant hass, ConfigEntry entry, AddEntitiesCallback async_add_entities)
None async_setup_platform(HomeAssistant hass, ConfigType config, AddEntitiesCallback async_add_entities, DiscoveryInfoType|None discovery_info=None)
CALLBACK_TYPE async_track_point_in_utc_time(HomeAssistant hass, HassJob[[datetime], Coroutine[Any, Any, None]|None]|Callable[[datetime], Coroutine[Any, Any, None]|None] action, datetime point_in_time)