Skip to content

Commit

Permalink
Merge branch 'main' of github.com:thegridelectric/gw-scada-spaceheat-…
Browse files Browse the repository at this point in the history
…python
  • Loading branch information
jessicamillar committed Jan 12, 2025
2 parents 75be066 + d506099 commit b802b57
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 6 deletions.
36 changes: 33 additions & 3 deletions gw_spaceheat/actors/atn.py
Original file line number Diff line number Diff line change
Expand Up @@ -979,10 +979,40 @@ async def get_thermocline_and_centroids(self) -> 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<rswt]
thermocline = len(top_cluster) #check this
top_centroid_f = round(sum(top_cluster)/len(top_cluster),3)
bottom_centroid_f = round(sum(bottom_cluster)/len(bottom_cluster),3)
except Exception as e:
self.log(f"Could not process clustering results! Error: {e}")
# TODO: post top_centroid, thermocline, bottom_centroid as synthetic channels
self.log(f"Thermocline {thermocline}, top: {top_centroid_f} F, bottom: {bottom_centroid_f} F")
return top_centroid_f, thermocline

def send_energy_instr(self, watthours: int, slot_minutes: int = 60):
Expand Down
2 changes: 1 addition & 1 deletion gw_spaceheat/actors/flo.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
6 changes: 4 additions & 2 deletions gw_spaceheat/actors/synth_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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):
Expand Down

0 comments on commit b802b57

Please sign in to comment.