Skip to content

Commit

Permalink
Refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark Hale committed Mar 29, 2024
1 parent 5391a64 commit c25f0a7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 19 deletions.
22 changes: 17 additions & 5 deletions src/apps/powerwall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
44 changes: 30 additions & 14 deletions src/modules/powerwall_tariff.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,18 @@ 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 = []
self._value = None
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:
Expand Down Expand Up @@ -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
Expand All @@ -224,7 +233,7 @@ def get_value(self):
return 0.0


class MinimumPricing():
class MinimumPricing:
def __init__(self):
self.min = PRICE_CAP

Expand All @@ -239,7 +248,7 @@ def get_value(self):
return v


class MaximumPricing():
class MaximumPricing:
def __init__(self):
self.max = 0

Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down

0 comments on commit c25f0a7

Please sign in to comment.