Skip to content

Commit

Permalink
#93
Browse files Browse the repository at this point in the history
  • Loading branch information
magnuselden authored and magnuselden committed Nov 30, 2023
1 parent c678cf9 commit 3fb37dc
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,23 +54,30 @@ def get_demand(temp) -> Demand:
return Demand.ErrorDemand




@dataclass
class NextWaterBoostModel:
prices: list = field(default_factory=lambda: [])
min_price: float = None # type: ignore
groups: list = field(default_factory=lambda: [])
non_hours: set = field(default_factory=lambda: [])
demand_hours: set = field(default_factory=lambda: {})

preset: HvacPresets = HvacPresets.Normal
now_dt: datetime = None # type: ignore
latest_boost: datetime = None # type: ignore
floating_mean: float = None # type: ignore

temp_trend: float = None # type: ignore
current_temp: float = None # type: ignore
target_temp: float = None # type: ignore

floating_mean: float = field(default=None, init=False)
groups: list = field(default_factory=lambda: [], init=False)
non_hours: set = field(default_factory=lambda: [], init=False)
demand_hours: set = field(default_factory=lambda: {}, init=False)

non_hours_raw: list[int] = field(default_factory=lambda: [], repr=False, compare=False)
demand_hours_raw: list[int] = field(default_factory=lambda: [], repr=False, compare=False)

latest_calculation: datetime = field(default=None, init=False)
should_update: bool = field(default=True, init=False)

@property
def cold_limit(self) -> datetime:
if self.is_cold:
Expand Down Expand Up @@ -102,22 +109,33 @@ def price_dt(self) -> dict[datetime, float]:
return ret

def init_vars(self, temp, temp_trend, target_temp, prices_today: list, prices_tomorrow: list, preset: HvacPresets,
min_price: float, non_hours: list = None, high_demand_hours: dict = None, now_dt=None,
latest_boost: datetime = None) -> None:
if non_hours is None:
non_hours = []
if high_demand_hours is None:
high_demand_hours = []
self.min_price = min_price
self.prices = prices_today + prices_tomorrow
now_dt=None, latest_boost: datetime = None) -> None:
new_prices = prices_today + prices_tomorrow
new_non_hours = self._set_hours(self.non_hours_raw)
new_demand_hours = self._set_hours(self.demand_hours_raw)
new_temp_trend = DEFAULT_TEMP_TREND if temp_trend > DEFAULT_TEMP_TREND else temp_trend

if any([
self.prices != new_prices,
self.latest_boost != latest_boost,
self.non_hours != new_non_hours,
self.demand_hours != new_demand_hours,
self.preset != preset,
self.temp_trend != new_temp_trend,
self.current_temp != temp,
self.target_temp != target_temp
]):
self.should_update = True

self.prices = new_prices
self.set_now_dt(now_dt)
self.latest_boost = latest_boost
self.non_hours = self._set_hours(non_hours)
self.demand_hours = self._set_hours(high_demand_hours)
self.non_hours = new_non_hours
self.demand_hours = new_demand_hours
self.set_floating_mean()
self._group_prices(prices_today, prices_tomorrow)
self.preset = preset
self.temp_trend = DEFAULT_TEMP_TREND if temp_trend > DEFAULT_TEMP_TREND else temp_trend
self.temp_trend = new_temp_trend
self.current_temp = temp
self.target_temp = target_temp

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@ def __init__(self, hvac, hub):
max_age=3600, max_samples=50, precision=1, ignore=0, outlier=20
)
self.model = WaterBoosterModel(self._hub.state_machine)
self.booster = NextWaterBoost()
self.booster = NextWaterBoost(
min_price = self._hub.sensors.peaqev_facade.min_price,
non_hours = self._hub.options.heating_options.non_hours_water_boost,
demand_hours = self._hub.options.heating_options.demand_hours_water_boost
)

self._hub.observer.add(ObserverTypes.OffsetsChanged, self._update_operation)
self._hub.observer.add("water boost done", self.async_reset_water_boost)
async_track_time_interval(
Expand Down Expand Up @@ -119,13 +124,10 @@ def _get_next_start(self, target_temp: int) -> tuple[datetime, int|None]:
ret, override_demand = self.booster.next_predicted_demand(
prices_today=self._hub.spotprice.model.prices,
prices_tomorrow=self._hub.spotprice.model.prices_tomorrow,
min_price=self._hub.sensors.peaqev_facade.min_price,
preset=preset,
temp=self.current_temperature,
temp_trend=self.temp_trend.gradient_raw,
target_temp=target_temp,
non_hours=self._hub.options.heating_options.non_hours_water_boost,
high_demand_hours=self._hub.options.heating_options.demand_hours_water_boost,
latest_boost=datetime.fromtimestamp(self.model.latest_boost_call),
)
if ret != self.model.next_water_heater_start:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,31 +13,31 @@


class NextWaterBoost:
def __init__(self):
self.model = NextWaterBoostModel()

def __init__(self, min_price: float = None, non_hours: list[int] = None, demand_hours: list[int] = None):
self.model = NextWaterBoostModel(min_price=min_price, non_hours_raw=non_hours, demand_hours_raw=demand_hours)
def next_predicted_demand(
self,
prices_today: list,
prices_tomorrow: list,
min_price: float,
temp: float,
temp_trend: float,
target_temp: float,
preset: HvacPresets = HvacPresets.Normal,
now_dt=None,
non_hours=None,
high_demand_hours=None,
latest_boost: datetime = None,
) -> tuple[datetime, int | None]:
if len(prices_today) < 1:
return datetime.max, None
self.model.init_vars(temp, temp_trend, target_temp, prices_today, prices_tomorrow, preset, min_price, non_hours,
high_demand_hours, now_dt, latest_boost)
self.model.init_vars(temp, temp_trend, target_temp, prices_today, prices_tomorrow, preset, now_dt, latest_boost)

return self._get_next_start(
delay_dt=None if self.model.cold_limit == now_dt else self.model.cold_limit
)
next_start = self.model.latest_calculation
if self.model.should_update:
next_start = self._get_next_start(
delay_dt=None if self.model.cold_limit == now_dt else self.model.cold_limit
)
self.model.latest_calculation = next_start
self.model.should_update = False
return next_start

def _get_next_start(self, delay_dt=None) -> tuple[datetime, int | None]:
last_known = self._last_known_price()
Expand Down Expand Up @@ -67,7 +67,7 @@ def _get_next_start(self, delay_dt=None) -> tuple[datetime, int | None]:
new_demand=self.model.get_demand_minutes(expected_temp)
), None

def _check_intersecting(self, next_dt, last_known) -> datetime | None:
def _check_intersecting(self, next_dt, last_known) -> tuple[datetime, int | None]:
intersecting_non_hours = self._intersecting_special_hours(self.model.non_hours, min(next_dt, last_known))
intersecting_demand_hours = self._intersecting_special_hours(self.model.demand_hours, min(next_dt, last_known))
if intersecting_demand_hours:
Expand Down

0 comments on commit 3fb37dc

Please sign in to comment.