diff --git a/src/apps/powerwall/__init__.py b/src/apps/powerwall/__init__.py index 0b4b9f7..81b7f05 100644 --- a/src/apps/powerwall/__init__.py +++ b/src/apps/powerwall/__init__.py @@ -192,15 +192,27 @@ def _update_powerwall_tariff(): debug("Powerwall updated") status_msg = f"Tariff data updated at {dt.datetime.now()}" if import_schedules or export_schedules: - status_msg += "(" + status_msg += " (" sep = "" if import_schedules: - import_breaks = [s.upper_bound for s in import_schedules if s.upper_bound is not None] - status_msg += f"{sep}import breaks: {import_breaks}" + status_msg += f"{sep}import: " + for i, schedule in enumerate(import_schedules): + status_msg += f"{schedule.get_value():.2f}" + if i < len(import_schedules) - 1: + if hasattr(schedule.assigner_func, "upper_bound"): + status_msg += f" |{schedule.assigner_func.upper_bound:.2f}| " + else: + status_msg += "|" sep = ", " if export_schedules: - export_breaks = [s.upper_bound for s in export_schedules if s.upper_bound is not None] - status_msg += f"{sep}export breaks: {export_breaks}" + status_msg += f"{sep}export: " + for i, schedule in enumerate(export_schedules): + status_msg += f"{schedule.get_value():.2f}" + if i < len(export_schedules) - 1: + if hasattr(schedule.assigner_func, "upper_bound"): + status_msg += f" |{schedule.assigner_func.upper_bound:.2f}| " + else: + status_msg += "|" sep = ", " status_msg += ")" set_status_message(status_msg) diff --git a/src/modules/powerwall_tariff.py b/src/modules/powerwall_tariff.py index 4c85235..366ef0c 100644 --- a/src/modules/powerwall_tariff.py +++ b/src/modules/powerwall_tariff.py @@ -120,10 +120,9 @@ def reset(self): class Schedule: - def __init__(self, charge_name, lower_bound, upper_bound, pricing_func, pricing_key): + def __init__(self, charge_name, assigner_func, pricing_func, pricing_key): self.charge_name = charge_name - self.lower_bound = lower_bound - self.upper_bound = upper_bound + self.assigner_func = assigner_func self.pricing_func = pricing_func self.pricing_key = pricing_key self._periods = [] @@ -131,8 +130,8 @@ def __init__(self, charge_name, lower_bound, upper_bound, pricing_func, pricing_ self._start = None self._end = None - def is_in(self, cost): - return (self.lower_bound is None or cost >= self.lower_bound) and (self.upper_bound is None or cost < self.upper_bound) + def is_in(self, rate): + return self.assigner_func.is_in(rate) def add(self, rate): if self._start is None: @@ -205,7 +204,17 @@ def highest_rates(rates, hrs): } -class AveragePricing(): +class PriceBandAssigner: + def __init__(self, lower_bound, upper_bound): + self.lower_bound = lower_bound + self.upper_bound = upper_bound + + def is_in(self, rate): + cost = rate[PRICE_KEY] + return (self.lower_bound is None or cost >= self.lower_bound) and (self.upper_bound is None or cost < self.upper_bound) + + +class AveragePricing: def __init__(self): self.sum = 0 self.count = 0 @@ -224,7 +233,7 @@ def get_value(self): return 0.0 -class MinimumPricing(): +class MinimumPricing: def __init__(self): self.min = PRICE_CAP @@ -239,7 +248,7 @@ def get_value(self): return v -class MaximumPricing(): +class MaximumPricing: def __init__(self): self.max = 0 @@ -305,12 +314,21 @@ def get_breaks(break_config, rates): return breaks +def get_tariff_assigners(break_config, rates): + breaks = get_breaks(break_config, rates) + funcs = [] + for i in range(len(breaks)+1): + lower_bound = breaks[i-1] if i > 0 else None + upper_bound = breaks[i] if i < len(breaks) else None + funcs.append(PriceBandAssigner(lower_bound, upper_bound)) + return funcs + + def populate_schedules(schedules, day_rates): for rate in day_rates: - cost = rate[PRICE_KEY] schedule = None for s in schedules: - if s.is_in(cost): + if s.is_in(rate): schedule = s break schedule.add(rate) @@ -331,14 +349,12 @@ def get_schedules(breaks_config, plunge_pricing_breaks_config, tariff_pricing_co else: configured_breaks = breaks_config - breaks = get_breaks(configured_breaks, day_rates) + assigner_funcs = get_tariff_assigners(configured_breaks, day_rates) schedules = [] for i, charge_name in enumerate(CHARGE_NAMES): - lower_bound = breaks[i-1] if i > 0 else None - upper_bound = breaks[i] if i < len(breaks) else None pricing_func = create_pricing(tariff_pricing_config[i]) - schedules.append(Schedule(charge_name, lower_bound, upper_bound, pricing_func, pricing_key)) + schedules.append(Schedule(charge_name, assigner_funcs[i], pricing_func, pricing_key)) populate_schedules(schedules, day_rates)