Skip to content

Commit

Permalink
chore: Reduced reliance on get_tariff_parts (1 hour dev time)
Browse files Browse the repository at this point in the history
  • Loading branch information
BottlecapDave committed May 31, 2024
1 parent 96c3a4c commit 8ccf9b2
Show file tree
Hide file tree
Showing 19 changed files with 104 additions and 116 deletions.
3 changes: 3 additions & 0 deletions _docs/repairs/unknown_product.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Repairs - Unknown product

If you receive this error around one or more of your tariffs, it's because the Octopus Energy API can not find the product associated with your tariff. This usually occurs if you're on a tariff which is currently internal and has not been exposed. In this scenario, you should [raise an issue](https://github.com/BottlecapDave/HomeAssistant-OctopusEnergy/issues) with the tariff code and your meter information, which can be obtained by following the [FAQ](../faq.md#ive-been-asked-for-my-meter-information-in-a-bug-request-how-do-i-obtain-this).
3 changes: 0 additions & 3 deletions _docs/repairs/unknown_tariff.md

This file was deleted.

3 changes: 0 additions & 3 deletions _docs/repairs/unknown_tariff_format.md

This file was deleted.

4 changes: 2 additions & 2 deletions custom_components/octopus_energy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from .coordinators.saving_sessions import async_setup_saving_sessions_coordinators
from .coordinators.greenness_forecast import async_setup_greenness_forecast_coordinator
from .statistics import get_statistic_ids_to_remove
from .intelligent import async_mock_intelligent_data, get_intelligent_features, is_intelligent_tariff, mock_intelligent_device
from .intelligent import async_mock_intelligent_data, get_intelligent_features, is_intelligent_product, mock_intelligent_device

from .config.main import async_migrate_main_config
from .config.target_rates import async_migrate_target_config
Expand Down Expand Up @@ -243,7 +243,7 @@ async def async_setup_dependencies(hass, config):

if electricity_tariff is not None:
if meter["is_export"] == False:
if is_intelligent_tariff(electricity_tariff.code):
if is_intelligent_product(electricity_tariff.product):
intelligent_mpan = mpan
intelligent_serial_number = serial_number
has_intelligent_tariff = True
Expand Down
43 changes: 14 additions & 29 deletions custom_components/octopus_energy/coordinators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
from ..api_client import OctopusEnergyApiClient

from ..utils import (
get_active_tariff,
get_tariff_parts
get_active_tariff
)
from ..utils.rate_information import get_min_max_average_rates
from ..utils.requests import calculate_next_refresh
Expand Down Expand Up @@ -55,40 +54,26 @@ def __init__(self, last_retrieved: datetime, request_attempts: int, refresh_rate
self.next_refresh = calculate_next_refresh(last_retrieved, request_attempts, refresh_rate_in_minutes)
_LOGGER.debug(f'last_retrieved: {last_retrieved}; request_attempts: {request_attempts}; refresh_rate_in_minutes: {refresh_rate_in_minutes}; next_refresh: {self.next_refresh}')

async def async_check_valid_tariff(hass, account_id: str, client: OctopusEnergyApiClient, tariff_code: str, is_electricity: bool):
tariff_key = f'{DATA_KNOWN_TARIFF}_{tariff_code}'
if (tariff_key not in hass.data[DOMAIN][account_id]):
tariff_parts = get_tariff_parts(tariff_code)
if tariff_parts is None:
async def async_check_valid_product(hass, account_id: str, client: OctopusEnergyApiClient, product_code: str, is_electricity: bool):
tariff_key = f'{DATA_KNOWN_TARIFF}_{product_code}'
try:
_LOGGER.debug(f"Retrieving product information for '{product_code}'")
product = await client.async_get_product(product_code)
if product is None:
ir.async_create_issue(
hass,
DOMAIN,
f"unknown_tariff_format_{tariff_code}",
f"unknown_product_{product_code}",
is_fixable=False,
severity=ir.IssueSeverity.ERROR,
learn_more_url="https://bottlecapdave.github.io/HomeAssistant-OctopusEnergy/repairs/unknown_tariff_format",
translation_key="unknown_tariff_format",
translation_placeholders={ "type": "Electricity" if is_electricity else "Gas", "tariff_code": tariff_code },
learn_more_url="https://bottlecapdave.github.io/HomeAssistant-OctopusEnergy/repairs/unknown_product",
translation_key="unknown_product",
translation_placeholders={ "type": "Electricity" if is_electricity else "Gas", "product_code": product_code },
)
else:
try:
_LOGGER.debug(f"Retrieving product information for '{tariff_parts.product_code}'")
product = await client.async_get_product(tariff_parts.product_code)
if product is None:
ir.async_create_issue(
hass,
DOMAIN,
f"unknown_tariff_{tariff_code}",
is_fixable=False,
severity=ir.IssueSeverity.ERROR,
learn_more_url="https://bottlecapdave.github.io/HomeAssistant-OctopusEnergy/repairs/unknown_tariff",
translation_key="unknown_tariff",
translation_placeholders={ "type": "Electricity" if is_electricity else "Gas", "tariff_code": tariff_code },
)
else:
hass.data[DOMAIN][account_id][tariff_key] = True
except:
_LOGGER.debug(f"Failed to retrieve product info for '{tariff_parts.product_code}'")
hass.data[DOMAIN][account_id][tariff_key] = True
except:
_LOGGER.debug(f"Failed to retrieve product info for '{product_code}'")

def __raise_rate_event(event_key: str,
rates: list,
Expand Down
6 changes: 3 additions & 3 deletions custom_components/octopus_energy/coordinators/account.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import logging
from datetime import datetime, timedelta

from . import BaseCoordinatorResult, async_check_valid_tariff
from . import BaseCoordinatorResult, async_check_valid_product
from ..utils import get_active_tariff

from homeassistant.util.dt import (now)
Expand Down Expand Up @@ -64,12 +64,12 @@ async def async_refresh_account(
if account_info is not None and len(account_info["electricity_meter_points"]) > 0:
for point in account_info["electricity_meter_points"]:
active_tariff = get_active_tariff(current, point["agreements"])
await async_check_valid_tariff(hass, account_id, client, active_tariff.code, True)
await async_check_valid_product(hass, account_id, client, active_tariff.product, True)

if account_info is not None and len(account_info["gas_meter_points"]) > 0:
for point in account_info["gas_meter_points"]:
active_tariff = get_active_tariff(current, point["agreements"])
await async_check_valid_tariff(hass, account_id, client, active_tariff.code, False)
await async_check_valid_product(hass, account_id, client, active_tariff.product, False)

return AccountCoordinatorResult(current, 1, account_info)
except Exception as e:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
from ..coordinators.intelligent_dispatches import IntelligentDispatchesCoordinatorResult
from ..utils import private_rates_to_public_rates
from . import BaseCoordinatorResult, get_electricity_meter_tariff, raise_rate_events
from ..intelligent import adjust_intelligent_rates, is_intelligent_tariff
from ..intelligent import adjust_intelligent_rates, is_intelligent_product

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -63,7 +63,7 @@ async def async_refresh_electricity_rates_data(
return None

# We'll calculate the wrong value if we don't have our intelligent dispatches
if is_intelligent_tariff(tariff.code) and (dispatches_result is None or dispatches_result.dispatches is None):
if is_intelligent_product(tariff.product) and (dispatches_result is None or dispatches_result.dispatches is None):
return existing_rates_result

new_rates = None
Expand Down Expand Up @@ -144,7 +144,7 @@ async def async_refresh_electricity_rates_data(

raise_rate_events(current,
private_rates_to_public_rates(new_rates),
{ "mpan": target_mpan, "serial_number": target_serial_number, "tariff_code": tariff, "intelligent_dispatches_updated": True },
{ "mpan": target_mpan, "serial_number": target_serial_number, "tariff_code": tariff.code, "intelligent_dispatches_updated": True },
fire_event,
EVENT_ELECTRICITY_PREVIOUS_DAY_RATES,
EVENT_ELECTRICITY_CURRENT_DAY_RATES,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from ..api_client.intelligent_dispatches import IntelligentDispatches
from ..utils import Tariff, private_rates_to_public_rates

from ..intelligent import adjust_intelligent_rates, is_intelligent_tariff
from ..intelligent import adjust_intelligent_rates, is_intelligent_product
from ..coordinators.intelligent_dispatches import IntelligentDispatchesCoordinatorResult
from . import BaseCoordinatorResult, get_electricity_meter_tariff, get_gas_meter_tariff
from ..utils.rate_information import get_min_max_average_rates
Expand Down Expand Up @@ -84,7 +84,7 @@ async def async_fetch_consumption_and_rates(
return previous_data

# We'll calculate the wrong value if we don't have our intelligent dispatches
if is_intelligent_tariff(tariff.code) and intelligent_dispatches is None:
if is_intelligent_product(tariff.product) and intelligent_dispatches is None:
return previous_data

[consumption_data, latest_consumption_data, rate_data, standing_charge] = await asyncio.gather(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ async def _async_calculate_cost(self, event: Event[EventStateChangedData]):
new_last_reset,
old_last_reset,
self._config[CONFIG_COST_ENTITY_ACCUMULATIVE_VALUE],
self._attributes["is_tracking"],
self._attributes["is_tracking"] if "is_tracking" in self._attributes else True,
new_state.attributes["state_class"] if "state_class" in new_state.attributes else None)


Expand Down
16 changes: 7 additions & 9 deletions custom_components/octopus_energy/intelligent/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from homeassistant.helpers import storage

from ..utils import OffPeakTime, get_active_tariff, get_tariff_parts
from ..utils import get_active_tariff

from ..const import DOMAIN, INTELLIGENT_SOURCE_BUMP_CHARGE, INTELLIGENT_SOURCE_SMART_CHARGE, REFRESH_RATE_IN_MINUTES_INTELLIGENT

Expand Down Expand Up @@ -109,21 +109,19 @@ def mock_intelligent_device():
6.5
)

def is_intelligent_tariff(tariff_code: str):
parts = get_tariff_parts(tariff_code.upper())

def is_intelligent_product(product_code: str):
# Need to ignore Octopus Intelligent Go tariffs
return parts is not None and (
"INTELLI-BB-VAR" in parts.product_code or
"INTELLI-VAR" in parts.product_code or
re.search("INTELLI-[0-9]", parts.product_code) is not None
return product_code is not None and (
"INTELLI-BB-VAR" in product_code.upper() or
"INTELLI-VAR" in product_code.upper() or
re.search("INTELLI-[0-9]", product_code.upper()) is not None
)

def has_intelligent_tariff(current: datetime, account_info):
if account_info is not None and len(account_info["electricity_meter_points"]) > 0:
for point in account_info["electricity_meter_points"]:
tariff = get_active_tariff(current, point["agreements"])
if tariff is not None and is_intelligent_tariff(tariff.code):
if tariff is not None and is_intelligent_product(tariff.product):
return True

return False
Expand Down
6 changes: 3 additions & 3 deletions custom_components/octopus_energy/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,9 @@
"title": "Invalid format - {type} - {tariff_code}",
"description": "The tariff \"{tariff_code}\" associated with your {type} meter is not in an expected format. Click on \"Learn More\" with instructions on what to do next."
},
"unknown_tariff": {
"title": "Unknown tariff - {type} - {tariff_code}",
"description": "The tariff \"{tariff_code}\" associated with your {type} meter has not been found. Click on \"Learn More\" with instructions on what to do next."
"unknown_product": {
"title": "Unknown product - {type} - {product_code}",
"description": "The product \"{product_code}\" associated with your {type} meter has not been found. Click on \"Learn More\" with instructions on what to do next."
},
"invalid_target_rate": {
"title": "Invalid target rate \"{name}\"",
Expand Down
4 changes: 2 additions & 2 deletions custom_components/octopus_energy/utils/tariff_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ async def async_get_tariff_override(hass, mpan_mprn: str, serial_number: str):

try:
data = await store.async_load()
if data is not None and "tariff" in data:
if data is not None and "tariff_code" in data and "product_code" in data:
tariff = Tariff(data["product_code"], data["tariff_code"])
_LOGGER.info(f"Overriding tariff for {mpan_mprn}/{serial_number} with {tariff}")
_LOGGER.info(f"Overriding tariff for {mpan_mprn}/{serial_number} with {tariff.code}")
return tariff

except:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
mpan = "1234567890"
serial_number = "abcdefgh"

def get_account_info(is_active_agreement = True, tariff_code = "E-1R-SUPER-GREEN-24M-21-07-30-A"):
def get_account_info(is_active_agreement = True, tariff_code = "E-1R-SUPER-GREEN-24M-21-07-30-A", product_code = "SUPER-GREEN-24M-21-07-30"):
return {
"electricity_meter_points": [
{
Expand All @@ -39,7 +39,7 @@ def get_account_info(is_active_agreement = True, tariff_code = "E-1R-SUPER-GREEN
"start": "2023-07-01T00:00:00+01:00" if is_active_agreement else "2023-08-01T00:00:00+01:00",
"end": "2023-08-01T00:00:00+01:00" if is_active_agreement else "2023-09-01T00:00:00+01:00",
"tariff_code": tariff_code,
"product_code": "SUPER-GREEN-24M-21-07-30"
"product_code": product_code
}
]
}
Expand Down Expand Up @@ -813,7 +813,7 @@ def fire_event(name, metadata):
actual_fired_events[name] = metadata
return None

account_info = get_account_info(tariff_code="E-1R-INTELLI-VAR-22-10-14-C")
account_info = get_account_info(product_code="INTELLI-VAR-22-10-14")
existing_rates = ElectricityRatesCoordinatorResult(period_to - timedelta(days=60), 1, create_rate_data(period_from - timedelta(days=60), period_to - timedelta(days=60), [2, 4]))
dispatches_result = None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
current = datetime.strptime("2023-07-14T10:30:01+01:00", "%Y-%m-%dT%H:%M:%S%z")
last_retrieved = datetime.strptime("2023-07-14T00:00:00+01:00", "%Y-%m-%dT%H:%M:%S%z")

product_code = "INTELLI-VAR-22-10-14"
tariff_code = "E-1R-INTELLI-VAR-22-10-14-C"
mpan = "1234567890"
serial_number = "abcdefgh"

intelligent_device = IntelligentDevice("1", "2", "3", "4", 1, "5", "6", 2)

def get_account_info(is_active_agreement = True, active_tariff_code = tariff_code):
def get_account_info(is_active_agreement = True, active_product_code = product_code, active_tariff_code = tariff_code):
return {
"id": "A-XXXXXX",
"electricity_meter_points": [
Expand All @@ -40,7 +41,7 @@ def get_account_info(is_active_agreement = True, active_tariff_code = tariff_cod
"start": "2023-07-01T00:00:00+01:00" if is_active_agreement else "2023-08-01T00:00:00+01:00",
"end": "2023-08-01T00:00:00+01:00" if is_active_agreement else "2023-09-01T00:00:00+01:00",
"tariff_code": active_tariff_code,
"product_code": "SUPER-GREEN-24M-21-07-30"
"product_code": active_product_code
}
]
}
Expand Down Expand Up @@ -91,7 +92,7 @@ async def async_merge_dispatch_data(*args, **kwargs):
account_id, completed_dispatches = args
return completed_dispatches

account_info = get_account_info(True, "E-1R-GO-18-06-12-A")
account_info = get_account_info(True, active_product_code="GO-18-06-12")
existing_settings = None

with mock.patch.multiple(OctopusEnergyApiClient, async_get_intelligent_dispatches=async_mock_get_intelligent_dispatches):
Expand Down Expand Up @@ -123,7 +124,7 @@ async def async_merge_dispatch_data(*args, **kwargs):
account_id, completed_dispatches = args
return completed_dispatches

account_info = get_account_info(True, "E-1R-GO-18-06-12-A")
account_info = get_account_info(True, active_product_code="GO-18-06-12")
existing_settings = None

with mock.patch.multiple(OctopusEnergyApiClient, async_get_intelligent_dispatches=async_mock_get_intelligent_dispatches):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@
current = datetime.strptime("2023-07-14T10:30:01+01:00", "%Y-%m-%dT%H:%M:%S%z")
last_retrieved = datetime.strptime("2023-07-14T00:00:00+01:00", "%Y-%m-%dT%H:%M:%S%z")

product_code = "INTELLI-VAR-22-10-14"
tariff_code = "E-1R-INTELLI-VAR-22-10-14-C"
mpan = "1234567890"
serial_number = "abcdefgh"

def get_account_info(is_active_agreement = True, active_tariff_code = tariff_code):
def get_account_info(is_active_agreement = True, active_product_code = product_code, active_tariff_code = tariff_code):
return {
"id": "A-XXXXXX",
"electricity_meter_points": [
Expand All @@ -37,7 +38,7 @@ def get_account_info(is_active_agreement = True, active_tariff_code = tariff_cod
"start": "2023-07-01T00:00:00+01:00" if is_active_agreement else "2023-08-01T00:00:00+01:00",
"end": "2023-08-01T00:00:00+01:00" if is_active_agreement else "2023-09-01T00:00:00+01:00",
"tariff_code": active_tariff_code,
"product_code": "SUPER-GREEN-24M-21-07-30"
"product_code": active_product_code
}
]
}
Expand Down Expand Up @@ -90,7 +91,7 @@ async def async_mock_get_intelligent_settings(*args, **kwargs):
mock_api_called = True
return expected_settings

account_info = get_account_info(True, "E-1R-GO-18-06-12-A")
account_info = get_account_info(True, active_product_code="GO-18-06-12")
existing_settings = None

with mock.patch.multiple(OctopusEnergyApiClient, async_get_intelligent_settings=async_mock_get_intelligent_settings):
Expand Down
Loading

0 comments on commit 8ccf9b2

Please sign in to comment.