From 94a03fbf53e2b8539982517d66e84eba8ccb6553 Mon Sep 17 00:00:00 2001 From: BottlecapDave Date: Wed, 19 Jul 2023 19:41:58 +0100 Subject: [PATCH] fix(sensors): Fixed issue with saving session evaluating incorrectly when data is unavailable --- .../octopus_energy/binary_sensor.py | 6 ++-- .../saving_sessions/__init__.py | 34 +++++++++++-------- .../octopus_energy/saving_sessions/points.py | 14 +++----- .../saving_sessions/saving_sessions.py | 15 +++----- .../test_current_saving_sessions_event.py | 12 +++++++ .../test_get_next_saving_sessions_event.py | 12 +++++++ 6 files changed, 56 insertions(+), 37 deletions(-) diff --git a/custom_components/octopus_energy/binary_sensor.py b/custom_components/octopus_energy/binary_sensor.py index d2f3205e..969b14b0 100644 --- a/custom_components/octopus_energy/binary_sensor.py +++ b/custom_components/octopus_energy/binary_sensor.py @@ -34,7 +34,7 @@ async def async_setup_entry(hass, entry, async_add_entities): """Setup sensors based on our entry""" if CONFIG_MAIN_API_KEY in entry.data: - await async_setup_season_sensors(hass, entry, async_add_entities) + await async_setup_saving_session_sensors(hass, entry, async_add_entities) await async_setup_intelligent_sensors(hass, async_add_entities) elif CONFIG_TARGET_NAME in entry.data: await async_setup_target_sensors(hass, entry, async_add_entities) @@ -61,8 +61,8 @@ async def async_setup_entry(hass, entry, async_add_entities): return True -async def async_setup_season_sensors(hass, entry, async_add_entities): - _LOGGER.debug('Setting up Season Saving entity') +async def async_setup_saving_session_sensors(hass, entry, async_add_entities): + _LOGGER.debug('Setting up Saving Session entities') config = dict(entry.data) if entry.options: diff --git a/custom_components/octopus_energy/saving_sessions/__init__.py b/custom_components/octopus_energy/saving_sessions/__init__.py index 1c4d7fb4..7ecf5681 100644 --- a/custom_components/octopus_energy/saving_sessions/__init__.py +++ b/custom_components/octopus_energy/saving_sessions/__init__.py @@ -1,24 +1,28 @@ def current_saving_sessions_event(current_date, events): current_event = None - for event in events: - if (event["start"] <= current_date and event["end"] >= current_date): - current_event = { - "start": event["start"], - "end": event["end"], - "duration_in_minutes": (event["end"] - event["start"]).total_seconds() / 60 - } - break + + if events is not None: + for event in events: + if (event["start"] <= current_date and event["end"] >= current_date): + current_event = { + "start": event["start"], + "end": event["end"], + "duration_in_minutes": (event["end"] - event["start"]).total_seconds() / 60 + } + break return current_event def get_next_saving_sessions_event(current_date, events): next_event = None - for event in events: - if event["start"] > current_date and (next_event == None or event["start"] < next_event["start"]): - next_event = { - "start": event["start"], - "end": event["end"], - "duration_in_minutes": (event["end"] - event["start"]).total_seconds() / 60 - } + + if events is not None: + for event in events: + if event["start"] > current_date and (next_event == None or event["start"] < next_event["start"]): + next_event = { + "start": event["start"], + "end": event["end"], + "duration_in_minutes": (event["end"] - event["start"]).total_seconds() / 60 + } return next_event \ No newline at end of file diff --git a/custom_components/octopus_energy/saving_sessions/points.py b/custom_components/octopus_energy/saving_sessions/points.py index 6342f972..c6f5af28 100644 --- a/custom_components/octopus_energy/saving_sessions/points.py +++ b/custom_components/octopus_energy/saving_sessions/points.py @@ -1,6 +1,6 @@ import logging -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.update_coordinator import ( @@ -51,20 +51,16 @@ def extra_state_attributes(self): def state_class(self): """The state class of sensor""" return SensorStateClass.TOTAL_INCREASING - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" + + @property + def state(self): + """Update the points based on data.""" saving_session = self.coordinator.data if (saving_session is not None and "points" in saving_session): self._state = saving_session["points"] else: self._state = 0 - self.async_write_ha_state() - @property - def state(self): - """Retrieve the previously calculated state""" return self._state async def async_added_to_hass(self): diff --git a/custom_components/octopus_energy/saving_sessions/saving_sessions.py b/custom_components/octopus_energy/saving_sessions/saving_sessions.py index 304a4530..da0cdd14 100644 --- a/custom_components/octopus_energy/saving_sessions/saving_sessions.py +++ b/custom_components/octopus_energy/saving_sessions/saving_sessions.py @@ -1,6 +1,6 @@ import logging -from homeassistant.core import HomeAssistant, callback +from homeassistant.core import HomeAssistant from homeassistant.helpers.entity import generate_entity_id from homeassistant.util.dt import (now) @@ -55,10 +55,10 @@ def icon(self): def extra_state_attributes(self): """Attributes of the sensor.""" return self._attributes - - @callback - def _handle_coordinator_update(self) -> None: - """Handle updated data from the coordinator.""" + + @property + def is_on(self): + """Determine if the user is in a saving session.""" saving_session = self.coordinator.data if (saving_session is not None and "events" in saving_session): self._events = saving_session["events"] @@ -88,11 +88,6 @@ def _handle_coordinator_update(self) -> None: self._attributes["next_joined_event_end"] = next_event["end"] self._attributes["next_joined_event_duration_in_minutes"] = next_event["duration_in_minutes"] - self.async_write_ha_state() - - @property - def is_on(self): - """The state of the sensor.""" return self._state async def async_added_to_hass(self): diff --git a/tests/unit/saving_sessions/test_current_saving_sessions_event.py b/tests/unit/saving_sessions/test_current_saving_sessions_event.py index 8a992da9..241a70da 100644 --- a/tests/unit/saving_sessions/test_current_saving_sessions_event.py +++ b/tests/unit/saving_sessions/test_current_saving_sessions_event.py @@ -52,4 +52,16 @@ async def test_when_no_active_event_present_then_false_is_returned(current_date) events, ) + assert result is None + +@pytest.mark.asyncio +async def test_when_events_is_none_then_none_returned(): + events = None + current_date = datetime.strptime("2022-12-08T17:00:00Z", "%Y-%m-%dT%H:%M:%S%z") + + result = current_saving_sessions_event( + current_date, + events, + ) + assert result is None \ No newline at end of file diff --git a/tests/unit/saving_sessions/test_get_next_saving_sessions_event.py b/tests/unit/saving_sessions/test_get_next_saving_sessions_event.py index 59c78327..ca84279b 100644 --- a/tests/unit/saving_sessions/test_get_next_saving_sessions_event.py +++ b/tests/unit/saving_sessions/test_get_next_saving_sessions_event.py @@ -55,4 +55,16 @@ async def test_when_no_future_events_present_then_none_returned(): events, ) + assert result is None + +@pytest.mark.asyncio +async def test_when_events_is_none_then_none_returned(): + events = None + current_date = datetime.strptime("2022-12-08T17:00:00Z", "%Y-%m-%dT%H:%M:%S%z") + + result = get_next_saving_sessions_event( + current_date, + events, + ) + assert result is None \ No newline at end of file