From 599fa4aae5b113d2af6daf1f5575527934dffcc8 Mon Sep 17 00:00:00 2001 From: thdfw Date: Sat, 11 Jan 2025 19:58:54 +0100 Subject: [PATCH 1/3] Gamma multiplies (55-oat)*ws, not ws --- gw_spaceheat/actors/flo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gw_spaceheat/actors/flo.py b/gw_spaceheat/actors/flo.py index 3313aa75..7cc36f69 100644 --- a/gw_spaceheat/actors/flo.py +++ b/gw_spaceheat/actors/flo.py @@ -68,7 +68,7 @@ def COP(self, oat, lwt): return self.config.CopIntercept + self.config.CopOatCoeff*oat + self.config.CopLwtCoeff*lwt def required_heating_power(self, oat, ws): - r = self.alpha + self.beta*oat + self.gamma*ws + r = self.alpha + self.beta*oat + self.gamma*((55-oat)*ws) return r if r>0 else 0 def delivered_heating_power(self, swt): From f37f235e24eadbe0892177ceb9c5d49d3b56069a Mon Sep 17 00:00:00 2001 From: thdfw Date: Sat, 11 Jan 2025 19:59:22 +0100 Subject: [PATCH 2/3] Post-process clustering when top Optional[Tuple[float, int]]: bottom_centroid_f = round(sum(cluster_bottom) / len(cluster_bottom), 3) else: bottom_centroid_f = min(cluster_top) - self.log( - f"Thermocline {thermocline}, top: {top_centroid_f} F, bottom: {bottom_centroid_f} F" - ) + # Process clustering + # Find RSWT in first hour + self.log(f"Thermocline {thermocline}, top: {top_centroid_f} F, bottom: {bottom_centroid_f} F") + try: + alpha = self.ha1_params.AlphaTimes10 / 10 + beta = self.ha1_params.BetaTimes100 / 100 + gamma = self.ha1_params.GammaEx6 / 1e6 + oat = self.weather_forecast["oat"][0], + ws = self.weather_forecast["ws"][0] + r = alpha + beta*oat + gamma*ws + rhp= r if r>0 else 0 + intermediate_rswt = self.ha1_params.IntermediateRswtF + dd_rswt = self.ha1_params.DdRswtF + intermediate_power = self.ha1_params.IntermediatePowerKw + dd_power = self.ha1_params.DdPowerKw + no_power_rswt = -alpha/beta + x_rswt = np.array([no_power_rswt, intermediate_rswt, dd_rswt]) + y_hpower = np.array([0, intermediate_power, dd_power]) + A = np.vstack([x_rswt**2, x_rswt, np.ones_like(x_rswt)]).T + a, b, c = np.linalg.solve(A, y_hpower) + c2 = c - rhp + rswt = round((-b + (b**2-4*a*c2)**0.5)/(2*a),2) + self.log(f"RSWT = {rswt} F") + if top_centroid_f < rswt and max(processed_temps) >= rswt: + print("There is water available above RSWT, changing the clustering result") + top_cluster = [x for x in processed_temps if x>=rswt] + bottom_cluster = [x for x in processed_temps if x Date: Sat, 11 Jan 2025 20:14:51 +0100 Subject: [PATCH 3/3] get_forecasts() when received new params, debugged --- gw_spaceheat/actors/synth_generator.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/gw_spaceheat/actors/synth_generator.py b/gw_spaceheat/actors/synth_generator.py index f62c6e1b..ea09ffd9 100644 --- a/gw_spaceheat/actors/synth_generator.py +++ b/gw_spaceheat/actors/synth_generator.py @@ -37,6 +37,7 @@ def __init__(self, name: str, services: ServicesInterface): self.elec_assigned_amount = None self.previous_time = None self.temperatures_available = False + self.received_new_params: bool = False # House parameters in the .env file self.is_simulated = self.settings.is_simulated @@ -113,8 +114,9 @@ async def main_loop(self, session: aiohttp.ClientSession) -> None: while not self._stop_requested: self._send(PatInternalWatchdogMessage(src=self.name)) - if self.forecasts is None or time.time()>self.forecasts.Time[0]: + if self.forecasts is None or time.time()>self.forecasts.Time[0] or self.received_new_params: await self.get_forecasts(session) + self.received_new_params = False self.get_latest_temperatures() if self.temperatures_available: @@ -139,7 +141,7 @@ def process_message(self, message: Message) -> Result[bool, BaseException]: self.previous_watts = message.Payload.Watts case ScadaParams(): self.log("Received new parameters, time to recompute forecasts!") - self.get_forecasts() + self.received_new_params = True return Ok(True) def fill_missing_store_temps(self):