From 2f2067d2b940e1705b2ee504039367fa753ca6ab Mon Sep 17 00:00:00 2001 From: Jens Ahrensfeld Date: Thu, 25 Jun 2026 20:19:33 +0200 Subject: [PATCH] Add set_model_power no-op stub to TempControllerBase The Normal controller had no set_model_power(), causing callers to guard with hasattr() instead of relying on a stable interface. Adding a no-op stub to the base class means all controllers have the method; TempControllerSmith overrides it to actually update its internal model. Remove the now-redundant hasattr guards at both call sites. Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01Tqxrk8uj4M3w3d3eXm3xK8 --- components/pid/temp_controller_base.py | 3 +++ components/sud_forecast.py | 3 +-- server/brewpi.py | 4 +--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/pid/temp_controller_base.py b/components/pid/temp_controller_base.py index 0437b6a..4233acc 100644 --- a/components/pid/temp_controller_base.py +++ b/components/pid/temp_controller_base.py @@ -89,6 +89,9 @@ class TempControllerBase(APid): def post_pid(self): pass + def set_model_power(self, power): + pass + def set_theta_ist(self, value): self.theta_ist_set = value if self.is_startup: diff --git a/components/sud_forecast.py b/components/sud_forecast.py index c988f1a..680e7f6 100644 --- a/components/sud_forecast.py +++ b/components/sud_forecast.py @@ -181,8 +181,7 @@ class SudForecastEstimator: tc.process() power = actuate(tc.get_power()) pot.set_power(power) - if hasattr(tc, 'set_model_power'): - tc.set_model_power(power) + tc.set_model_power(power) if sud.state == SudState.RAMPING: if tc.is_holding(): diff --git a/server/brewpi.py b/server/brewpi.py index b4ac96f..a1ba51e 100755 --- a/server/brewpi.py +++ b/server/brewpi.py @@ -148,9 +148,7 @@ if __name__ == '__main__': # Assign temp. sensor readings to tc sensor_task.set_on_changed("temp", ChangedFloat(tc.set_theta_ist, prec=2).set) - # Assign heater power set to tc model - "Normal" has no internal model - if hasattr(tc, "set_model_power"): - heater.set_on_changed("power_set", tc.set_model_power) + heater.set_on_changed("power_set", tc.set_model_power) # For simulation - the sim sensor has no real plant to read, so it # just reports back whatever the modeled Pot's own temperature is.