mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 04:07:08 +00:00
Fix bug in google calendar offset calculation (#70024)
Move the offset reached computation outside of the update method so that it is computed when state updates occur rather than when data refreshes happen (which are throttled and happen at most every 15 minutes). Issue #69892
This commit is contained in:
parent
c00e226b2a
commit
36bb947cdf
@ -120,13 +120,22 @@ class GoogleCalendarEntity(CalendarEntity):
|
||||
self._event: CalendarEvent | None = None
|
||||
self._name: str = data[CONF_NAME]
|
||||
self._offset = data.get(CONF_OFFSET, DEFAULT_CONF_OFFSET)
|
||||
self._offset_reached = False
|
||||
self._offset_value: timedelta | None = None
|
||||
self.entity_id = entity_id
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, bool]:
|
||||
"""Return the device state attributes."""
|
||||
return {"offset_reached": self._offset_reached}
|
||||
return {"offset_reached": self.offset_reached}
|
||||
|
||||
@property
|
||||
def offset_reached(self) -> bool:
|
||||
"""Return whether or not the event offset was reached."""
|
||||
if self._event and self._offset_value:
|
||||
return is_offset_reached(
|
||||
self._event.start_datetime_local, self._offset_value
|
||||
)
|
||||
return False
|
||||
|
||||
@property
|
||||
def event(self) -> CalendarEvent | None:
|
||||
@ -187,9 +196,7 @@ class GoogleCalendarEntity(CalendarEntity):
|
||||
(summary, offset) = extract_offset(event.get("summary", ""), self._offset)
|
||||
event["summary"] = summary
|
||||
self._event = _get_calendar_event(event)
|
||||
self._offset_reached = is_offset_reached(
|
||||
self._event.start_datetime_local, offset
|
||||
)
|
||||
self._offset_value = offset
|
||||
else:
|
||||
self._event = None
|
||||
|
||||
|
@ -505,3 +505,77 @@ async def test_scan_calendar_error(
|
||||
assert await component_setup()
|
||||
|
||||
assert not hass.states.get(TEST_ENTITY)
|
||||
|
||||
|
||||
async def test_future_event_update_behavior(
|
||||
hass, mock_events_list_items, component_setup
|
||||
):
|
||||
"""Test an future event that becomes active."""
|
||||
now = dt_util.now()
|
||||
now_utc = dt_util.utcnow()
|
||||
one_hour_from_now = now + datetime.timedelta(minutes=60)
|
||||
end_event = one_hour_from_now + datetime.timedelta(minutes=90)
|
||||
event = {
|
||||
**TEST_EVENT,
|
||||
"start": {"dateTime": one_hour_from_now.isoformat()},
|
||||
"end": {"dateTime": end_event.isoformat()},
|
||||
}
|
||||
mock_events_list_items([event])
|
||||
assert await component_setup()
|
||||
|
||||
# Event has not started yet
|
||||
state = hass.states.get(TEST_ENTITY)
|
||||
assert state.name == TEST_ENTITY_NAME
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
# Advance time until event has started
|
||||
now += datetime.timedelta(minutes=60)
|
||||
now_utc += datetime.timedelta(minutes=30)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=now_utc), patch(
|
||||
"homeassistant.util.dt.now", return_value=now
|
||||
):
|
||||
async_fire_time_changed(hass, now)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Event has started
|
||||
state = hass.states.get(TEST_ENTITY)
|
||||
assert state.state == STATE_ON
|
||||
|
||||
|
||||
async def test_future_event_offset_update_behavior(
|
||||
hass, mock_events_list_items, component_setup
|
||||
):
|
||||
"""Test an future event that becomes active."""
|
||||
now = dt_util.now()
|
||||
now_utc = dt_util.utcnow()
|
||||
one_hour_from_now = now + datetime.timedelta(minutes=60)
|
||||
end_event = one_hour_from_now + datetime.timedelta(minutes=90)
|
||||
event_summary = "Test Event in Progress"
|
||||
event = {
|
||||
**TEST_EVENT,
|
||||
"start": {"dateTime": one_hour_from_now.isoformat()},
|
||||
"end": {"dateTime": end_event.isoformat()},
|
||||
"summary": f"{event_summary} !!-15",
|
||||
}
|
||||
mock_events_list_items([event])
|
||||
assert await component_setup()
|
||||
|
||||
# Event has not started yet
|
||||
state = hass.states.get(TEST_ENTITY)
|
||||
assert state.name == TEST_ENTITY_NAME
|
||||
assert state.state == STATE_OFF
|
||||
assert not state.attributes["offset_reached"]
|
||||
|
||||
# Advance time until event has started
|
||||
now += datetime.timedelta(minutes=45)
|
||||
now_utc += datetime.timedelta(minutes=45)
|
||||
with patch("homeassistant.util.dt.utcnow", return_value=now_utc), patch(
|
||||
"homeassistant.util.dt.now", return_value=now
|
||||
):
|
||||
async_fire_time_changed(hass, now)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Event has not started, but the offset was reached
|
||||
state = hass.states.get(TEST_ENTITY)
|
||||
assert state.state == STATE_OFF
|
||||
assert state.attributes["offset_reached"]
|
||||
|
Loading…
x
Reference in New Issue
Block a user