Files
brewpi/components/actor/heater_hendi.py
T
jensandClaude Sonnet 5 f20e617d81 feat: add connect/disconnect status for real heater/stirrer hardware
Heater and Stirrer can be real serial hardware (hendi, Pololu1376), but
there was no connection concept at all - the constructors opened the
port and crashed the whole server if the device was missing, with no
way to see connection status or firmware version and no way to
reconnect without a restart.

Adds an observable Connectable mixin (components/connectable.py) shared
by AHeater/AStirrer; real devices defer opening the serial port to an
explicit connect(), auto-connect on server startup, and surface
Connected/FirmwareVersion/Simulated plus manual Connect/Disconnect over
the web GUI. Heating/stirring and Sud Start are all gated on connection
state, and a disconnect mid-brew force-stops the run via the same path
as a manual Stop.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YaPLuRPpyjWcwhMvCvpHCL
2026-07-03 19:18:59 +02:00

68 lines
1.4 KiB
Python
Executable File

from components.aheater import AHeater
from components.actor.hendiCtrl import HendiCtrl
class HeaterHendi(AHeater):
def __init__(self, params):
AHeater.__init__(self, simulated=False)
self.hendi = HendiCtrl(params['port'], params['speed'])
self.power_set = 0
self.power_eff = 0
def get_power_min(self):
return 0
def get_power_max(self):
caps = self.hendi.getCapabilties()
return caps['pwr_watts_max']
def get_powers(self):
caps = self.hendi.getCapabilties()
return [0] + caps['pwr_list']
def connect(self):
ok = self.hendi.connect()
self.connected = ok
self.firmware_version = self.hendi.sw_ver if ok else None
return ok
def disconnect(self):
self.hendi.disconnect()
self.connected = False
self.firmware_version = None
def activate(self, enable):
if not self.connected:
return
if enable:
self.hendi.remoteEnable(1)
else:
self.hendi.setSwitch(0)
def is_activated(self):
if not self.connected:
return False
s = self.hendi.isRemoteEnable()
return '1' in s
def process(self):
if not self.connected:
self.power_eff = 0
return
power = self.power_set
if power == 0:
self.hendi.setSwitch(0)
else:
self.hendi.setSwitch(1)
self.hendi.setPowerWatts(power)
self.power_eff = self.hendi.getPowerWatts() if power > 0 else 0
def set_power(self, power):
self.power_set = min(self.get_power_max(), power)
def get_power(self):
return self.power_eff
def close(self):
self.disconnect()