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):