diff --git a/components/actor/heater_hendi.py b/components/actor/heater_hendi.py index aae2b9f..8454b11 100755 --- a/components/actor/heater_hendi.py +++ b/components/actor/heater_hendi.py @@ -34,28 +34,49 @@ class HeaterHendi(AHeater): def activate(self, enable): if not self.connected: return - if enable: - self.hendi.remoteEnable(1) - else: - self.hendi.setSwitch(0) + try: + if enable: + self.hendi.remoteEnable(1) + else: + self.hendi.setSwitch(0) + except Exception as e: + # A device that was connected can still fail a live command (the + # hendi's own idle-timeout auto-suspend, a cable pulled mid-run, + # ...) - treat that the same as a disconnect rather than letting + # it escape uncaught, since this is called both from HeaterTask's + # tick loop (with self.device.open(): activate(True)/(False)) and + # from a client's Connect/Disconnect command, neither of which + # expect activate() itself to ever raise. + print(f"HeaterHendi: comm error in activate({enable}): {e}") + self.disconnect() def is_activated(self): if not self.connected: return False - s = self.hendi.isRemoteEnable() - return '1' in s + try: + s = self.hendi.isRemoteEnable() + return '1' in s + except Exception as e: + print(f"HeaterHendi: comm error in is_activated: {e}") + self.disconnect() + return False 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 + try: + 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 + except Exception as e: + print(f"HeaterHendi: comm error in process: {e}") + self.disconnect() + self.power_eff = 0 def set_power(self, power): self.power_set = min(self.get_power_max(), power) diff --git a/components/actor/stirrerpololu1376.py b/components/actor/stirrerpololu1376.py index 7f76902..b809740 100644 --- a/components/actor/stirrerpololu1376.py +++ b/components/actor/stirrerpololu1376.py @@ -47,27 +47,45 @@ class StirrerPololu1376(AStirrer): def activate(self, enable): if not self.connected: return - print("activate {}".format(enable)) - if enable: - self.drv.go() - else: - self.drv.stop() + try: + print("activate {}".format(enable)) + if enable: + self.drv.go() + else: + self.drv.stop() + except Exception as e: + # See HeaterHendi.activate()'s own comment: a device that was + # connected can still fail a live command (cable pulled + # mid-run, ...) - this is called both from StirrerTask's tick + # loop (with self.device.open(): activate(True)/(False)) and + # from a client's Connect/Disconnect command, neither of which + # expect activate() itself to ever raise. + print(f"StirrerPololu1376: comm error in activate({enable}): {e}") + self.disconnect() def _on_set_speed(self, speed): if not self.connected: return - self.drv.motor_forward(speed) - print("Set speed to {} %".format(speed)) + try: + self.drv.motor_forward(speed) + print("Set speed to {} %".format(speed)) + except Exception as e: + print(f"StirrerPololu1376: comm error in _on_set_speed: {e}") + self.disconnect() def _on_process(self): if not self.connected: return - status = self.drv.get_variable(Varid.STATUS) - limit_status = self.drv.get_variable(Varid.STATUS_LIMIT_STATUS) - if status & 0x01 == 0x01: - if limit_status & 0x01 == 0x01: - print("Recover after motor error!") - self.drv.go() + try: + status = self.drv.get_variable(Varid.STATUS) + limit_status = self.drv.get_variable(Varid.STATUS_LIMIT_STATUS) + if status & 0x01 == 0x01: + if limit_status & 0x01 == 0x01: + print("Recover after motor error!") + self.drv.go() + except Exception as e: + print(f"StirrerPololu1376: comm error in _on_process: {e}") + self.disconnect() if __name__ == '__main__':