Skip to content

Commit

Permalink
feat: Added two new attributes to various sensors determining when th…
Browse files Browse the repository at this point in the history
…e underlying data was last retrieved and when the value was last evaluated. These will slowly be added to other entities.
  • Loading branch information
BottlecapDave committed Nov 18, 2023
1 parent 02ef313 commit 11f8878
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self, hass: HomeAssistant, coordinator, meter, point):
self._latest_date = None
self._previous_total_consumption = None
self._attributes = {
"last_updated_timestamp": None
"last_evaluated": None
}

@property
Expand Down Expand Up @@ -88,11 +88,11 @@ def state(self):
total_consumption = get_total_consumption(consumption_result)
self._state = get_current_consumption_delta(current_date,
total_consumption,
self._attributes["last_updated_timestamp"] if self._attributes["last_updated_timestamp"] is not None else current_date,
self._attributes["last_evaluated"] if self._attributes["last_evaluated"] is not None else current_date,
self._previous_total_consumption)
if (self._state is not None):
self._latest_date = current_date
self._attributes["last_updated_timestamp"] = current_date
self._attributes["last_evaluated"] = current_date

# Store the total consumption ready for the next run
self._previous_total_consumption = total_consumption
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def __init__(self, hass: HomeAssistant, coordinator, meter, point):
self._state = None
self._latest_date = None
self._attributes = {
"last_updated_timestamp": None
"last_evaluated": None
}

@property
Expand Down Expand Up @@ -74,7 +74,7 @@ def state(self):

if (consumption_result is not None):
self._state = consumption_result[-1]["demand"]
self._attributes["last_updated_timestamp"] = now()
self._attributes["last_evaluated"] = now()

return self._state

Expand Down
16 changes: 11 additions & 5 deletions custom_components/octopus_energy/electricity/current_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from homeassistant.core import HomeAssistant

from homeassistant.util.dt import (now)
from homeassistant.util.dt import (utcnow)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
)
Expand All @@ -15,6 +15,7 @@

from .base import (OctopusEnergyElectricitySensor)
from ..utils.attributes import dict_to_typed_dict
from ..coordinators.electricity_rates import ElectricityRatesCoordinatorResult

from ..utils.rate_information import (get_current_rate_information)

Expand Down Expand Up @@ -88,12 +89,12 @@ def extra_state_attributes(self):
def state(self):
"""Retrieve the current rate for the sensor."""
# Find the current rate. We only need to do this every half an hour
current = now()
rates = self.coordinator.data.rates if self.coordinator is not None and self.coordinator.data is not None else None
if (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0):
current = utcnow()
rates_result: ElectricityRatesCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if (rates_result is not None and (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0)):
_LOGGER.debug(f"Updating OctopusEnergyElectricityCurrentRate for '{self._mpan}/{self._serial_number}'")

rate_information = get_current_rate_information(rates, current)
rate_information = get_current_rate_information(rates_result.rates, current)

if rate_information is not None:
self._attributes = {
Expand Down Expand Up @@ -135,6 +136,11 @@ def state(self):

self._last_updated = current

if rates_result is not None:
self._attributes["data_last_retrieved"] = rates_result.last_retrieved

self._attributes["last_evaluated"] = current

return self._state

async def async_added_to_hass(self):
Expand Down
16 changes: 11 additions & 5 deletions custom_components/octopus_energy/electricity/next_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from homeassistant.core import HomeAssistant

from homeassistant.util.dt import (now)
from homeassistant.util.dt import (utcnow)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity
)
Expand All @@ -16,6 +16,7 @@
from .base import (OctopusEnergyElectricitySensor)
from ..utils.attributes import dict_to_typed_dict
from ..utils.rate_information import (get_next_rate_information)
from ..coordinators.electricity_rates import ElectricityRatesCoordinatorResult

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -79,13 +80,13 @@ def extra_state_attributes(self):
def state(self):
"""Retrieve the next rate for the sensor."""
# Find the next rate. We only need to do this every half an hour
current = now()
rates = self.coordinator.data.rates if self.coordinator is not None and self.coordinator.data is not None else None
if (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0):
current = utcnow()
rates_result: ElectricityRatesCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if (rates_result is not None and (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0)):
_LOGGER.debug(f"Updating OctopusEnergyElectricityNextRate for '{self._mpan}/{self._serial_number}'")

target = current
rate_information = get_next_rate_information(rates, target)
rate_information = get_next_rate_information(rates_result.rates, target)

if rate_information is not None:
self._attributes = {
Expand All @@ -112,6 +113,11 @@ def state(self):

self._last_updated = current

if rates_result is not None:
self._attributes["data_last_retrieved"] = rates_result.last_retrieved

self._attributes["last_evaluated"] = current

return self._state

async def async_added_to_hass(self):
Expand Down
16 changes: 11 additions & 5 deletions custom_components/octopus_energy/electricity/previous_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from homeassistant.core import HomeAssistant

from homeassistant.util.dt import (now)
from homeassistant.util.dt import (utcnow)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity
)
Expand All @@ -16,6 +16,7 @@
from .base import (OctopusEnergyElectricitySensor)
from ..utils.attributes import dict_to_typed_dict
from ..utils.rate_information import (get_previous_rate_information)
from ..coordinators.electricity_rates import ElectricityRatesCoordinatorResult

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -79,13 +80,13 @@ def extra_state_attributes(self):
def state(self):
"""Retrieve the previous rate."""
# Find the previous rate. We only need to do this every half an hour
current = now()
rates = self.coordinator.data.rates if self.coordinator is not None and self.coordinator.data is not None else None
if (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0):
current = utcnow()
rates_result: ElectricityRatesCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if (rates_result is not None and (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0)):
_LOGGER.debug(f"Updating OctopusEnergyElectricityPreviousRate for '{self._mpan}/{self._serial_number}'")

target = current
rate_information = get_previous_rate_information(rates, target)
rate_information = get_previous_rate_information(rates_result.rates, target)

if rate_information is not None:
self._attributes = {
Expand All @@ -112,6 +113,11 @@ def state(self):

self._last_updated = current

if rates_result is not None:
self._attributes["data_last_retrieved"] = rates_result.last_retrieved

self._attributes["last_evaluated"] = current

return self._state

async def async_added_to_hass(self):
Expand Down
6 changes: 3 additions & 3 deletions custom_components/octopus_energy/gas/current_consumption.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self, hass: HomeAssistant, coordinator, meter, point):
self._latest_date = None
self._previous_total_consumption = None
self._attributes = {
"last_updated_timestamp": None
"last_evaluated": None
}

@property
Expand Down Expand Up @@ -88,11 +88,11 @@ def state(self):
total_consumption = get_total_consumption(consumption_result)
self._state = get_current_consumption_delta(current_date,
total_consumption,
self._attributes["last_updated_timestamp"] if self._attributes["last_updated_timestamp"] is not None else current_date,
self._attributes["last_evaluated"] if self._attributes["last_evaluated"] is not None else current_date,
self._previous_total_consumption)
if (self._state is not None):
self._latest_date = current_date
self._attributes["last_updated_timestamp"] = current_date
self._attributes["last_evaluated"] = current_date

# Store the total consumption ready for the next run
self._previous_total_consumption = total_consumption
Expand Down
16 changes: 11 additions & 5 deletions custom_components/octopus_energy/gas/current_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from homeassistant.core import HomeAssistant

from homeassistant.util.dt import (now)
from homeassistant.util.dt import (utcnow)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
)
Expand All @@ -16,6 +16,7 @@
from .base import (OctopusEnergyGasSensor)
from ..utils.attributes import dict_to_typed_dict
from ..utils.rate_information import get_current_rate_information
from ..coordinators.gas_rates import GasRatesCoordinatorResult

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -81,12 +82,12 @@ def extra_state_attributes(self):
@property
def state(self):
"""Retrieve the current rate for the sensor."""
current = now()
rates = self.coordinator.data.rates if self.coordinator is not None and self.coordinator.data is not None else None
if (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0):
current = utcnow()
rates_result: GasRatesCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if (rates_result is not None and (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0)):
_LOGGER.debug(f"Updating OctopusEnergyGasCurrentRate for '{self._mprn}/{self._serial_number}'")

rate_information = get_current_rate_information(rates, current)
rate_information = get_current_rate_information(rates_result.rates, current)

if rate_information is not None:
self._attributes = {
Expand Down Expand Up @@ -118,6 +119,11 @@ def state(self):

self._last_updated = current

if rates_result is not None:
self._attributes["data_last_retrieved"] = rates_result.last_retrieved

self._attributes["last_evaluated"] = current

return self._state

async def async_added_to_hass(self):
Expand Down
16 changes: 11 additions & 5 deletions custom_components/octopus_energy/gas/next_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from homeassistant.core import HomeAssistant

from homeassistant.util.dt import (now)
from homeassistant.util.dt import (utcnow)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
)
Expand All @@ -16,6 +16,7 @@
from .base import (OctopusEnergyGasSensor)
from ..utils.attributes import dict_to_typed_dict
from ..utils.rate_information import get_next_rate_information
from ..coordinators.gas_rates import GasRatesCoordinatorResult

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -76,12 +77,12 @@ def extra_state_attributes(self):
@property
def state(self):
"""Retrieve the next rate for the sensor."""
current = now()
rates = self.coordinator.data.rates if self.coordinator is not None and self.coordinator.data is not None else None
if (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0):
current = utcnow()
rates_result: GasRatesCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if (rates_result is not None and (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0)):
_LOGGER.debug(f"Updating OctopusEnergyGasNextRate for '{self._mprn}/{self._serial_number}'")

rate_information = get_next_rate_information(rates, current)
rate_information = get_next_rate_information(rates_result.rates, current)

if rate_information is not None:
self._attributes = {
Expand All @@ -106,6 +107,11 @@ def state(self):

self._last_updated = current

if rates_result is not None:
self._attributes["data_last_retrieved"] = rates_result.last_retrieved

self._attributes["last_evaluated"] = current

return self._state

async def async_added_to_hass(self):
Expand Down
16 changes: 11 additions & 5 deletions custom_components/octopus_energy/gas/previous_rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from homeassistant.core import HomeAssistant

from homeassistant.util.dt import (now)
from homeassistant.util.dt import (utcnow)
from homeassistant.helpers.update_coordinator import (
CoordinatorEntity,
)
Expand All @@ -16,6 +16,7 @@
from .base import (OctopusEnergyGasSensor)
from ..utils.attributes import dict_to_typed_dict
from ..utils.rate_information import get_previous_rate_information
from ..coordinators.gas_rates import GasRatesCoordinatorResult

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -76,12 +77,12 @@ def extra_state_attributes(self):
@property
def state(self):
"""Retrieve the previous rate for the sensor."""
current = now()
rates = self.coordinator.data.rates if self.coordinator is not None and self.coordinator.data is not None else None
if (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0):
current = utcnow()
rates_result: GasRatesCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if (rates_result is not None and (self._last_updated is None or self._last_updated < (current - timedelta(minutes=30)) or (current.minute % 30) == 0)):
_LOGGER.debug(f"Updating OctopusEnergyGasPreviousRate for '{self._mprn}/{self._serial_number}'")

rate_information = get_previous_rate_information(rates, current)
rate_information = get_previous_rate_information(rates_result.rates, current)

if rate_information is not None:
self._attributes = {
Expand All @@ -106,6 +107,11 @@ def state(self):

self._last_updated = current

if rates_result is not None:
self._attributes["data_last_retrieved"] = rates_result.last_retrieved

self._attributes["last_evaluated"] = current

return self._state

async def async_added_to_hass(self):
Expand Down
7 changes: 6 additions & 1 deletion custom_components/octopus_energy/intelligent/bump_charge.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,13 @@ def is_on(self):
result: IntelligentDispatchesCoordinatorResult = self.coordinator.data if self.coordinator is not None else None
if result is None or (self._last_updated is not None and self._last_updated > result.last_retrieved):
return self._state

if result is not None:
self._attributes["data_last_retrieved"] = result.last_retrieved

self._state = is_in_bump_charge(utcnow(), result.dispatches.planned)
current_date = utcnow()
self._state = is_in_bump_charge(current_date, result.dispatches.planned)
self._attributes["last_evaluated"] = current_date

return self._state

Expand Down
6 changes: 4 additions & 2 deletions custom_components/octopus_energy/intelligent/charge_limit.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@ def native_value(self) -> float:
"""The value of the charge limit."""
settings_result: IntelligentCoordinatorResult = self.coordinator.data if self.coordinator is not None and self.coordinator.data is not None else None
if settings_result is None or (self._last_updated is not None and self._last_updated > settings_result.last_retrieved):
self._attributes["last_updated_timestamp"] = self._last_updated
return self._state

self._attributes["last_updated_timestamp"] = settings_result.last_retrieved
if settings_result is not None:
self._attributes["data_last_retrieved"] = settings_result.last_retrieved

self._state = settings_result.settings.charge_limit_weekday
self._attributes["last_evaluated"] = utcnow()

return self._state

Expand Down

0 comments on commit 11f8878

Please sign in to comment.