mirror of
https://github.com/home-assistant/core.git
synced 2025-07-26 06:37:52 +00:00
Fix state update in time_date sensor (#106879)
This commit is contained in:
parent
513261baff
commit
03cbf8b28d
@ -86,8 +86,6 @@ class TimeDateSensor(SensorEntity):
|
|||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.unsub: CALLBACK_TYPE | None = None
|
self.unsub: CALLBACK_TYPE | None = None
|
||||||
|
|
||||||
self._update_internal_state(dt_util.utcnow())
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
"""Return the name of the sensor."""
|
"""Return the name of the sensor."""
|
||||||
@ -109,9 +107,7 @@ class TimeDateSensor(SensorEntity):
|
|||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
"""Set up first update."""
|
"""Set up first update."""
|
||||||
self.unsub = async_track_point_in_utc_time(
|
self._update_state_and_setup_listener()
|
||||||
self.hass, self.point_in_time_listener, self.get_next_interval()
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self) -> None:
|
async def async_will_remove_from_hass(self) -> None:
|
||||||
"""Cancel next update."""
|
"""Cancel next update."""
|
||||||
@ -119,25 +115,23 @@ class TimeDateSensor(SensorEntity):
|
|||||||
self.unsub()
|
self.unsub()
|
||||||
self.unsub = None
|
self.unsub = None
|
||||||
|
|
||||||
def get_next_interval(self) -> datetime:
|
def get_next_interval(self, time_date: datetime) -> datetime:
|
||||||
"""Compute next time an update should occur."""
|
"""Compute next time an update should occur."""
|
||||||
now = dt_util.utcnow()
|
|
||||||
|
|
||||||
if self.type == "date":
|
if self.type == "date":
|
||||||
tomorrow = dt_util.as_local(now) + timedelta(days=1)
|
tomorrow = dt_util.as_local(time_date) + timedelta(days=1)
|
||||||
return dt_util.start_of_local_day(tomorrow)
|
return dt_util.start_of_local_day(tomorrow)
|
||||||
|
|
||||||
if self.type == "beat":
|
if self.type == "beat":
|
||||||
# Add 1 hour because @0 beats is at 23:00:00 UTC.
|
# Add 1 hour because @0 beats is at 23:00:00 UTC.
|
||||||
timestamp = dt_util.as_timestamp(now + timedelta(hours=1))
|
timestamp = dt_util.as_timestamp(time_date + timedelta(hours=1))
|
||||||
interval = 86.4
|
interval = 86.4
|
||||||
else:
|
else:
|
||||||
timestamp = dt_util.as_timestamp(now)
|
timestamp = dt_util.as_timestamp(time_date)
|
||||||
interval = 60
|
interval = 60
|
||||||
|
|
||||||
delta = interval - (timestamp % interval)
|
delta = interval - (timestamp % interval)
|
||||||
next_interval = now + timedelta(seconds=delta)
|
next_interval = time_date + timedelta(seconds=delta)
|
||||||
_LOGGER.debug("%s + %s -> %s (%s)", now, delta, next_interval, self.type)
|
_LOGGER.debug("%s + %s -> %s (%s)", time_date, delta, next_interval, self.type)
|
||||||
|
|
||||||
return next_interval
|
return next_interval
|
||||||
|
|
||||||
@ -179,11 +173,16 @@ class TimeDateSensor(SensorEntity):
|
|||||||
f"{date} {time}", raise_on_error=True
|
f"{date} {time}", raise_on_error=True
|
||||||
).isoformat()
|
).isoformat()
|
||||||
|
|
||||||
|
def _update_state_and_setup_listener(self) -> None:
|
||||||
|
"""Update state and setup listener for next interval."""
|
||||||
|
now = dt_util.utcnow()
|
||||||
|
self._update_internal_state(now)
|
||||||
|
self.unsub = async_track_point_in_utc_time(
|
||||||
|
self.hass, self.point_in_time_listener, self.get_next_interval(now)
|
||||||
|
)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def point_in_time_listener(self, time_date: datetime) -> None:
|
def point_in_time_listener(self, time_date: datetime) -> None:
|
||||||
"""Get the latest data and update state."""
|
"""Get the latest data and update state."""
|
||||||
self._update_internal_state(time_date)
|
self._update_state_and_setup_listener()
|
||||||
self.async_write_ha_state()
|
self.async_write_ha_state()
|
||||||
self.unsub = async_track_point_in_utc_time(
|
|
||||||
self.hass, self.point_in_time_listener, self.get_next_interval()
|
|
||||||
)
|
|
||||||
|
@ -94,34 +94,32 @@ async def test_states(hass: HomeAssistant, freezer: FrozenDateTimeFactory) -> No
|
|||||||
state = hass.states.get("sensor.date_time_iso")
|
state = hass.states.get("sensor.date_time_iso")
|
||||||
assert state.state == "2017-05-18T00:54:00"
|
assert state.state == "2017-05-18T00:54:00"
|
||||||
|
|
||||||
|
# Time travel
|
||||||
now = dt_util.utc_from_timestamp(1602952963.2)
|
now = dt_util.utc_from_timestamp(1602952963.2)
|
||||||
freezer.move_to(now)
|
freezer.move_to(now)
|
||||||
async_fire_time_changed(hass, now)
|
async_fire_time_changed(hass, now)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# The time should be 2020-10-17 18:42 / @738, however the time_date sensor
|
|
||||||
# does not check the current time when calculating the state, it instead checks
|
|
||||||
# the time when it expected an update
|
|
||||||
state = hass.states.get("sensor.time")
|
state = hass.states.get("sensor.time")
|
||||||
assert state.state == "00:55"
|
assert state.state == "16:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date")
|
state = hass.states.get("sensor.date")
|
||||||
assert state.state == "2017-05-19"
|
assert state.state == "2020-10-17"
|
||||||
|
|
||||||
state = hass.states.get("sensor.time_utc")
|
state = hass.states.get("sensor.time_utc")
|
||||||
assert state.state == "00:55"
|
assert state.state == "16:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date_time")
|
state = hass.states.get("sensor.date_time")
|
||||||
assert state.state == "2017-05-18, 00:55"
|
assert state.state == "2020-10-17, 16:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date_time_utc")
|
state = hass.states.get("sensor.date_time_utc")
|
||||||
assert state.state == "2017-05-18, 00:55"
|
assert state.state == "2020-10-17, 16:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.internet_time")
|
state = hass.states.get("sensor.internet_time")
|
||||||
assert state.state == "@080"
|
assert state.state == "@738"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date_time_iso")
|
state = hass.states.get("sensor.date_time_iso")
|
||||||
assert state.state == "2017-05-18T00:55:00"
|
assert state.state == "2020-10-17T16:42:00"
|
||||||
|
|
||||||
|
|
||||||
async def test_states_non_default_timezone(
|
async def test_states_non_default_timezone(
|
||||||
@ -156,34 +154,32 @@ async def test_states_non_default_timezone(
|
|||||||
state = hass.states.get("sensor.date_time_iso")
|
state = hass.states.get("sensor.date_time_iso")
|
||||||
assert state.state == "2017-05-17T20:54:00"
|
assert state.state == "2017-05-17T20:54:00"
|
||||||
|
|
||||||
|
# Time travel
|
||||||
now = dt_util.utc_from_timestamp(1602952963.2)
|
now = dt_util.utc_from_timestamp(1602952963.2)
|
||||||
freezer.move_to(now)
|
freezer.move_to(now)
|
||||||
async_fire_time_changed(hass, now)
|
async_fire_time_changed(hass, now)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
# The time should be 2020-10-17 12:42 / @738, however the time_date sensor
|
|
||||||
# does not check the current time when calculating the state, it instead checks
|
|
||||||
# the time when it expected an update
|
|
||||||
state = hass.states.get("sensor.time")
|
state = hass.states.get("sensor.time")
|
||||||
assert state.state == "20:55"
|
assert state.state == "12:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date")
|
state = hass.states.get("sensor.date")
|
||||||
assert state.state == "2017-05-18"
|
assert state.state == "2020-10-17"
|
||||||
|
|
||||||
state = hass.states.get("sensor.time_utc")
|
state = hass.states.get("sensor.time_utc")
|
||||||
assert state.state == "00:55"
|
assert state.state == "16:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date_time")
|
state = hass.states.get("sensor.date_time")
|
||||||
assert state.state == "2017-05-17, 20:55"
|
assert state.state == "2020-10-17, 12:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date_time_utc")
|
state = hass.states.get("sensor.date_time_utc")
|
||||||
assert state.state == "2017-05-18, 00:55"
|
assert state.state == "2020-10-17, 16:42"
|
||||||
|
|
||||||
state = hass.states.get("sensor.internet_time")
|
state = hass.states.get("sensor.internet_time")
|
||||||
assert state.state == "@080"
|
assert state.state == "@738"
|
||||||
|
|
||||||
state = hass.states.get("sensor.date_time_iso")
|
state = hass.states.get("sensor.date_time_iso")
|
||||||
assert state.state == "2017-05-17T20:55:00"
|
assert state.state == "2020-10-17T12:42:00"
|
||||||
|
|
||||||
|
|
||||||
@patch(
|
@patch(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user