class PressureSensor(StepBase): volume = Property.Number("volume", configurable=True) sensor = StepProperty.Sensor("Sensor") actor = StepProperty.Actor("Actor") def init(self): if self.actor is not None: self.actor_on(int(self.actor)) @cbpi.action("Turn Actor OFF") def start(self): if self.actor is not None: self.actor_off(int(self.actor)) def reset(self): if self.actor is not None: self.actor_off(int(self.actor)) def finish(self): if self.actor is not None: self.actor_off(int(self.actor)) def execute(self): for key, value in cbpi.cache.get("sensors").iteritems(): if key == int(self.sensor): sensorValue = value.instance.last_value if float(sensorValue) >= float(self.volume): self.next()
class Chill_CG(StepBase): kettle = StepProperty.Kettle("Kettle", description="Kettle in which the chilling takes place") chiller = StepProperty.Actor("Chiller", description="Actor that controls the Chiller") chillerPump = StepProperty.Actor("chillerPump", description="Actor that controls the chillerPump") chillerTemp = StepProperty.Sensor("Chiller Temp", description="Sensor that shows the chiller temperature") cutoutvariance = Property.Number("Variance between kettle and chiller for end", configurable=True, default_value=0.3, description="The step will end when the kettle temp falls to within this much of the chiller temp.") def init(self): self.actor_on(int(self.chillerPump)) self.actor_on(int(self.chiller)) self.set_target_temp(0, self.kettle) def start(self): pass def reset(self): pass def finish(self): self.actor_off(int(self.chillerPump)) self.actor_off(int(self.chiller)) def execute(self): if self.get_kettle_temp(self.kettle) <= (self.get_sensor_value(self.chillerTemp)+float(self.cutoutvariance)): self.notify("Chill Stage Complete", "Kettle reached: " + str(self.get_kettle_temp(self.kettle)), type="success", timeout=None) self.actor_off(int(self.chiller)) self.actor_off(int(self.chillerPump)) self.next()
class BaseColletingStep(object): collectingActor = StepProperty.Actor( "Устройство отбора", description="Исполнительное устройство отбора") collectingSensor = StepProperty.Sensor( "Индикатор отбора", description="Индикатор скорости отбора") isPaused = False power = 0 maxSpeed = 0 @cbpi.action("Начать отбор") def start(self): if self.isPaused: self.time = datetime.utcnow() self.notify("", "Отбор продолжен", type="success", timeout=2000) self.isPaused = False @cbpi.action("Остановить отбор") def stop(self): if not self.isPaused: self.notify("", "Отбор приостановлен", type="success", timeout=2000) self.isPaused = True def notifySensor(self): try: sensor = self.api.cache.get("sensors").get( int(self.collectingSensor)).instance sensor.collecting = int(self.collectingSpeed) except: pass def updateMaxCollectingSpeed(self): try: actor = self.api.cache.get("actors").get(int( self.collectingActor)).instance self.maxSpeed = actor.get_max_speed() except: self.maxSpeed = 0 def manageActor(self): actorId = int(self.collectingActor) self.actor_power(power=self.power, id=actorId) if self.isPaused: self.actor_off(actorId) else: self.actor_on(power=self.power, id=actorId) def calculateActorPower(self): if self.maxSpeed > 0: self.power = min( round(float(self.collectingSpeed) / self.maxSpeed * 100), 100)
class KettleVolumeStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method. The class name must be unique in the system ''' # Properties temp = Property.Number("Temperature", configurable=True) kettle = StepProperty.Kettle("Kettle") timer = Property.Number("Timer in Minutes", configurable=True) sensor = StepProperty.Sensor("Sensor") volume = Property.Number("Volume", configurable=True) def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep #self.set_target_temp(self.temp, self.kettle) def finish(self): self.set_target_temp(0, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' for key, value in cbpi.cache.get("sensors").iteritems(): if key == int(self.sensor): sensorValue = value.instance.last_value # Check if timer finished and go to next step if float(sensorValue) <= float(self.volume): self.set_target_temp(self.temp, self.kettle) kettle_state = cbpi.cache.get("kettle")[int(self.kettle)].state if kettle_state is True: Kettle2View().toggle(int(self.kettle)) self.notify("Kettle Update", "Auto is off. Timer started.", timeout=None) if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) if self.is_timer_finished() == True: self.notify("Mash-in Complete!", "Starting the next step.", timeout=None) self.next()
class MashInStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperature", configurable=True, description="Target Temperature of Mash Step") kettle = StepProperty.Kettle("Kettle", description="Kettle in which the mashing takes place") s = False @cbpi.action("Change Power") def change_power(self): self.actor_power(1, 50) def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target step self.s = False self.set_target_temp(self.temp, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached if self.get_kettle_temp(self.kettle) >= float(self.temp) and self.s is False: self.s = True #DBK_added self.actor_off(1) self.notify("Step Temp Reached!", "Please press the next button to continue", timeout=None)
class PumpStep(StepBase): pump = StepProperty.Actor("Pump") timer = Property.Number("Timer in Minutes", configurable=True, default_value=0) @cbpi.action("Stat Timer") def start(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) def reset(self): self.stop_timer() def finish(self): self.actor_off(int(self.pump)) def init(self): self.actor_on(int(self.pump)) def execute(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) if self.is_timer_finished() == True: self.next()
class PumpStep(StepBase): pump = StepProperty.Actor("Pump", description="Pump actor gets toogled") timer = Property.Number("Timer in Minutes", configurable=True, default_value=0, description="Timer is started immediately") @cbpi.action("Stat Timer") def start(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) def reset(self): self.stop_timer() def finish(self): self.actor_off(int(self.pump)) def init(self): self.actor_on(int(self.pump)) def execute(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) if self.is_timer_finished() == True: # if you dont want a beep sound comment out like : # cbpi.PumpStepEndBeep() cbpi.PumpStepEndBeep() self.next()
class HeartsStep(StepBase, BaseColletingStep): temperatureSensor = StepProperty.Sensor( "Датчик температуры", description="Датчик температуры в кубе") initialCollecting = Property.Number("Стартовая скорость отбора, мл/ч", configurable=True, default_value=1000) endTemp = Property.Number("Температура завершения отбора", configurable=True, default_value=93) collectingSpeed = 0.0 temperature = 0 def finish(self): self.actor_off(int(self.collectingActor)) self.notify("", "Отбор тела завершен", type="success", timeout=2000) def execute(self): self.updateAndCheckTemperature() self.recountCollecting() self.notifySensor() self.updateMaxCollectingSpeed() self.calculateActorPower() self.manageActor() def recountCollecting(self): self.collectingSpeed = int( self.initialCollecting) * (6.04 - 0.06 * float(self.temperature)) def updateAndCheckTemperature(self): self.temperature = float( self.get_sensor_value(int(self.temperatureSensor))) if self.temperature >= int(self.endTemp): next(self)
class AutoSwitch(StepBase): # Properties a_id = StepProperty.Kettle("Kettle") b_auto = Property.Select("Auto Setting", options=["On", "Off"]) def init(self): if isinstance(self.a_id, unicode) and self.a_id: self.id = (int(self.a_id)) self.auto_type = self.b_auto try: kettle = cbpi.cache.get("kettle").get(self.id) if (kettle.state is False) and (self.auto_type = "On"): # Start controller if kettle.logic is not None: cfg = kettle.config.copy() cfg.update(dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor)) instance = cbpi.get_controller(kettle.logic).get("class")(**cfg) instance.init() kettle.instance = instance def run(instance): instance.run() t = self.api.socketio.start_background_task(target=run, instance=instance) kettle.state = True cbpi.emit("UPDATE_KETTLE", kettle) else (kettle.state is True) and (self.auto_type = "Off"): # Stop controller kettle.instance.stop() kettle.state = False cbpi.emit("UPDATE_KETTLE", kettle)
class PumpStep(StepBase): pump = StepProperty.Actor("Pump", description="Pump actor gets toogled") timer = Property.Number("Timer in Minutes", configurable=True, default_value=0, description="Timer is started immediately") @cbpi.action("Start Timer") def start(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) #self.start_stopwatch() def reset(self): self.stop_timer() #self.stop_stopwatch() def finish(self): self.actor_off(int(self.pump)) #self.stop_stopwatch() def init(self): self.actor_on(int(self.pump)) def execute(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) if self.is_timer_finished() == True: self.next()
class MashInStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperature", configurable=True) kettle = StepProperty.Kettle("Kettle") s = False def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.s = False self.set_target_temp(self.temp, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached if self.get_kettle_temp(self.kettle) >= int( self.temp) and self.s is False: self.s = True self.notify("Step Temp Reached!", "Please press the next button to continue", timeout=None)
class MashStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperature", configurable=True, description="Target Temperature of Mash Step") kettle = StepProperty.Kettle( "Kettle", description="Kettle in which the mashing takes place") timer = Property.Number( "Timer in Minutes", configurable=True, description="Timer is started when the target temperature is reached") def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.set_target_temp(self.temp, self.kettle) @cbpi.action("Start Timer Now") def start(self): ''' Custom Action which can be execute form the brewing dashboard. All method with decorator @cbpi.action("YOUR CUSTOM NAME") will be available in the user interface :return: ''' if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) def reset(self): self.stop_timer() self.set_target_temp(self.temp, self.kettle) def finish(self): self.set_target_temp(0, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached if self.get_kettle_temp(self.kettle) >= float(self.temp): # Check if Timer is Running if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) # Check if timer finished and go to next step if self.is_timer_finished() == True: self.notify("Mash Step Completed!", "Starting the next step", timeout=None) # if you dont want a beep sound comment out like : # cbpi.MashStepEndBeep() cbpi.MashStepEndBeep() self.next()
class Cooling(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperature", configurable=True, description="Target Temperature") kettle = StepProperty.Kettle( "Kettle", description="Kettle in which the Chilling takes place") timer = Property.Number( "Timer in Seconds", configurable=True, description="Timer is started when the target temperature is reached") def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.set_target_temp(self.temp, self.kettle) @cbpi.action("Start Timer Now") def start(self): ''' Custom Action which can be execute form the brewing dashboard. All method with decorator @cbpi.action("YOUR CUSTOM NAME") will be available in the user interface :return: ''' if self.is_timer_finished() is None: self.start_timer(int(self.timer)) def reset(self): self.stop_timer() self.set_target_temp(self.temp, self.kettle) def finish(self): self.set_target_temp(0, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached if self.get_kettle_temp(self.kettle) <= float(self.temp): # Check if Timer is Running if self.is_timer_finished() is None: self.start_timer(int(self.timer)) # Check if timer finished and go to next step if self.is_timer_finished() == True: self.notify( "Cooling Step Completed! Target temp is: %s C" % (self.temp), "Current temp is: %s C" % (self.get_kettle_temp(self.kettle)), timeout=10000) self.next()
class FlowSensorReset(StepBase): sensor_prop = StepProperty.Sensor("Sensor") #------------------------------------------------------------------------------- def init(self): self.sensor = cbpi.cache.get("sensors")[int(self.sensor_prop)].instance self.sensor.reset_volume() self.next()
class SimpleActorTimer(StepBase): # Properties actor1 = StepProperty.Actor("Actor 1") actor2 = StepProperty.Actor("Actor 2") timer = Property.Number("Timer in Minutes", configurable=True, description="Timer is started immediately.") #------------------------------------------------------------------------------- def init(self): self.actors = [self.actor1, self.actor2] self.actors_on() #------------------------------------------------------------------------------- def finish(self): self.actors_off() #------------------------------------------------------------------------------- def execute(self): # Check if Timer is Running if self.is_timer_finished() is None: self.start_timer(float(self.timer) * 60) # Check if timer finished and go to next step if self.is_timer_finished() == True: self.notify("{} complete".format(self.name), "Starting the next step", timeout=None) next(self) #------------------------------------------------------------------------------- def actors_on(self): for actor in self.actors: try: self.actor_on(int(actor)) except: pass def actors_off(self): for actor in self.actors: try: self.actor_off(int(actor)) except: pass
class SimpleTargetStep(StepBase): # Properties auto_mode = Property.Select( "Auto Mode", options=["Set to ON", "Set to OFF", "No Change"]) kettle = StepProperty.Kettle("Kettle") target = Property.Number("Target Temp", configurable=True) #------------------------------------------------------------------------------- def init(self): self.set_target_temp(float(self.target), int(self.kettle)) if self.auto_mode == "Set to ON": self.setAutoMode(True) elif self.auto_mode == "Set to OFF": self.setAutoMode(False) next(self) #------------------------------------------------------------------------------- def setAutoMode(self, auto_state): try: kettle = cbpi.cache.get("kettle")[int(self.kettle)] if (kettle.state is False) and (auto_state is True): # turn on if kettle.logic is not None: cfg = kettle.config.copy() cfg.update( dict(api=cbpi, kettle_id=kettle.id, heater=kettle.heater, sensor=kettle.sensor)) instance = cbpi.get_controller( kettle.logic).get("class")(**cfg) instance.init() kettle.instance = instance def run(instance): instance.run() t = cbpi.socketio.start_background_task(target=run, instance=instance) kettle.state = not kettle.state cbpi.emit("UPDATE_KETTLE", cbpi.cache.get("kettle")[int(self.kettle)]) elif (kettle.state is True) and (auto_state is False): # turn off kettle.instance.stop() kettle.state = not kettle.state cbpi.emit("UPDATE_KETTLE", cbpi.cache.get("kettle")[int(self.kettle)]) except Exception as e: cbpi.notify("Error", "Failed to set Auto mode {}".format(["OFF", "ON" ][auto_state]), type="danger", timeout=None) cbpi.app.logger.error(e)
class Rast(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperatur", configurable=True, description="Zieltemperatur des Schritts") kettle = StepProperty.Kettle("Kessel", description="Auswahl des Braukessels") timer = Property.Number( "Timer in Minuten", configurable=True, description="Timer startet, wenn die Zieltemperatur erreicht wurde") def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.set_target_temp(self.temp, self.kettle) # @cbpi.action("Timer manuell starten") # def start(self): # if self.is_timer_finished() is None: # self.start_timer(int(self.timer) * 60) def reset(self): self.stop_timer() self.set_target_temp(self.temp, self.kettle) def finish(self): pass def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached if self.get_kettle_temp(self.kettle) >= float(self.temp): # Check if Timer is Running if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) # Check if timer finished and go to next step if self.is_timer_finished() == True: self.notify("Rast beendet!", "Beginne nächsten Schritt", timeout=None) self.next()
class StartStopStep(StepBase, BaseColletingStep): temperatureSensor = StepProperty.Sensor( "Датчик температуры", description="Датчик температуры в царге") initialCollecting = Property.Number("Стартовая скорость отбора, мл/ч", configurable=True, default_value=1000) deltaTemp = Property.Number("Разрешенный залет температуры, °C", configurable=True, default_value=0.3) decrement = Property.Number("Уменьшение отбора при залете температуры, %", configurable=True, default_value=10) endTemp = Property.Number("Температура завершения отбора", configurable=True, default_value=93) initialTemp = None currentCollecting = None collectingSpeed = 0.0 temperature = 0 stopped = False def finish(self): self.actor_off(int(self.collectingActor)) self.notify("", "Отбор тела завершен", type="success", timeout=2000) def execute(self): self.updateAndCheckTemperature() self.recountCollecting() self.notifySensor() self.updateMaxCollectingSpeed() self.calculateActorPower() self.manageActor() def recountCollecting(self): if not self.currentCollecting: self.currentCollecting = int(initialCollecting) if not self.initialTemp: self.initialTemp = float(self.temperature) excess = float(self.temperature) - self.initialTemp > float( self.deltaTemp) if excess and not self.stopped: self.currentCollecting = self.currentCollecting * ( 100 - int(decrement)) / 100 self.stopped = excess self.collectingSpeed = 0 if self.stopped else self.currentCollecting def updateAndCheckTemperature(self): self.temperature = float( self.get_sensor_value(int(self.temperatureSensor))) if self.temperature >= int(self.endTemp): next(self)
class ChangeKettleTargetTemp(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperature", configurable=True, description="Target Temperature") kettle = StepProperty.Kettle( "Kettle", description="Kettle in which the target temperature will change") def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target temp self.set_target_temp(self.temp, self.kettle) @cbpi.action("Start Timer Now") def start(self): ''' Custom Action which can be execute form the brewing dashboard. All method with decorator @cbpi.action("YOUR CUSTOM NAME") will be available in the user interface :return: ''' if self.is_timer_finished() is None: self.start_timer(int(self.timer)) def reset(self): self.stop_timer() self.set_target_temp(self.temp, self.kettle) def finish(self): self.set_target_temp(self.temp, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' kettles = cbpi.cache["kettle"] kettle_name = kettles[int(self.kettle)].name self.notify("Changed target temp for %s " % (kettle_name), "New target temp is: %s C" % (self.temp), timeout=10000) self.next()
class BoilStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties power = Property.Number("Power", configurable=True) kettle = StepProperty.Kettle("Kettle") timer = Property.Number("Timer in Minutes", configurable=True) def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep print(("class BoilStep(StepBase): power = {}".format(self.kettle))) self.actor_power(1, self.power) #self.set_target_temp(self.power, self.kettle) @cbpi.action("Start Timer Now") def start(self): ''' Custom Action which can be execute form the brewing dashboard. All method with decorator @cbpi.action("YOUR CUSTOM NAME") will be available in the user interface :return: ''' if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) def reset(self): self.stop_timer() self.actor_power(0, self.power) #self.set_target_temp(self.temp, self.kettle) def finish(self): self.actor_power(0, 0) self.set_target_temp(0, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Timer is Running if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) # Check if timer finished and go to next step if self.is_timer_finished() == True: next(self)
class Flowmeter(StepBase): sensor = StepProperty.Sensor("Sensor") actorA = StepProperty.Actor("Actor") volume = Property.Number("Volume", configurable=True) resetFlowmeter = Property.Number( "Reset flowmeter when done. 1 = Yes 0 = No", configurable=True, default_value="1") def init(self): if int(self.actorA) is not None: self.actor_on(int(self.actorA)) @cbpi.action("Turn Actor OFF") def start(self): if self.actorA is not None: self.actor_off(int(self.actorA)) def reset(self): if self.actorA is not None: self.actor_off(int(self.actorA)) def finish(self): if self.actorA is not None: self.actor_off(int(self.actorA)) if self.resetFlowmeter == "1": for key, value in list(cbpi.cache.get("sensors").items()): if key == int(self.sensor): value.instance.reset() def execute(self): for key, value in list(cbpi.cache.get("sensors").items()): if key == int(self.sensor): sensorValue = value.instance.getValue() if float(sensorValue) >= float(self.volume): next(self)
class TwoKettleLogic(StepBase): ''' Just put the decorator @cbpi.step on top of a method. The class name must be unique in the system ''' # Properties kettle1 = StepProperty.Kettle("Kettle 1") temp1 = Property.Number("Temperature 1", configurable=True) kettle2 = StepProperty.Kettle("Kettle 2") temp2 = Property.Number("Temperature 2", configurable=True) def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.set_target_temp(self.temp1, self.kettle1) self.set_target_temp(self.temp2, self.kettle2) def finish(self): pass def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached for both kettles if self.get_kettle_temp(self.kettle1) >= int( self.temp1) and self.get_kettle_temp(self.kettle2) >= int( self.temp2): self.notify("Kettle Temps Reached!", "Starting the next step.", timeout=None) self.next()
class SimpleMashInStep(StepBase): # Properties a_kettle_prop = StepProperty.Kettle( "Kettle", description="Kettle in which the mashing takes place") b_target_prop = Property.Number( "Temperature", configurable=True, description="Target Temperature of Mash Step") c_agitator_prop = Property.Select("Run agitator while heating?", options=["Yes", "No"]) d_kill_heat_prop = Property.Select("Turn off heater when target reached?", options=["Yes", "No"]) #------------------------------------------------------------------------------- def init(self): self.kettle = int(self.a_kettle_prop) self.target = float(self.b_target_prop) self.agitator_run = self.c_agitator_prop == "Yes" self.kill_heat = self.d_kill_heat_prop == "Yes" self.done = False self.agitator = getAgitator( cbpi.cache.get("kettle")[self.kettle].agitator) # set target temp self.set_target_temp(self.target, self.kettle) if self.agitator and self.agitator_run: self.actor_on(self.agitator) #------------------------------------------------------------------------------- def finish(self): self.set_target_temp(0, self.kettle) #------------------------------------------------------------------------------- def execute(self): # Check if Target Temp is reached if (self.get_kettle_temp(self.kettle) >= self.target) and (self.done is False): self.done = True if self.kill_heat: self.set_target_temp(0, self.kettle) if self.agitator: self.actor_off(self.agitator) self.notify("{} complete".format(self.name), "Press next button to continue", type='warning', timeout=None)
class ToggleAuto(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Temperature", configurable=True, description="Target Temperature of HLT") kettle = StepProperty.Kettle("Kettle", description="Set this to your HLT") toggle_type = Property.Select("Toggle Type", options=["On", "Off"]) def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' #self.notify("props", cbpi.cache.get("kettle")[int(self.kettle)].state, timeout=None) self.set_target_temp(self.temp, self.kettle) kettle_state = kettle = cbpi.cache.get("kettle")[int( self.kettle)].state if kettle_state is False and self.toggle_type == "On": Kettle2View().toggle(int(self.kettle)) self.notify("Kettle Update", "Auto is on. Starting the next step.", timeout=None) self.next() else: if kettle_state is False and self.toggle_type == "Off": self.notify( "Kettle Error", "Auto is already off, please adjust your brew step!", type="danger", timeout=None) else: if kettle_state is True: if self.toggle_type == "On": self.notify( "Kettle Error", "Auto is already on, please adjust your brew step!", type="danger", timeout=None) else: Kettle2View().toggle(int(self.kettle)) self.notify("Kettle Update", "Auto is Off. Starting the next step.", timeout=None) self.next()
class Maischen(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number( "Temperatur", configurable=True, description="Benachrichtigung bei Erreichen der Ein/Abmaischtemperatur." ) kettle = StepProperty.Kettle("Kessel", description="Auswahl des Braukessels") s = False @cbpi.action("Weiter") def next_step(self): self.set_target_temp(0, self.kettle) self.next() def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.s = False self.set_target_temp(self.temp, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached if self.get_kettle_temp(self.kettle) >= float( self.temp) and self.s is False: self.s = True self.notify( "Maischtemperatur erreicht!", "Bitte maischen und anschließend bestätigen, um fortzufahren.", timeout=None)
class SimpleCoolToTemp(StepBase): kettle = StepProperty.Kettle("Kettle", description="Kettle") c_target = Property.Number("Target", configurable=True) c_offset = Property.Number("Offset", configurable=True) def init(self): self.target = float(self.c_target) self.offset = float(self.c_offset) self.set_target_temp(self.target, self.kettle) def reset(self): self.set_target_temp(self.target, self.kettle) def finish(self): self.set_target_temp(0, self.kettle) def execute(self): if abs(self.get_kettle_temp(self.kettle) - self.target) <= self.offset: next(self)
class ToBoilStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties temp = Property.Number("Power", configurable=True) kettle = StepProperty.Kettle("Kettle") s = False def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # set target tep self.s = False print(("ToBoilStep init: {}".format(int(self.temp)))) self.set_target_temp(self.temp, self.kettle) def reset(self): self.stop_timer() self.set_target_temp(self.temp, self.kettle) def finish(self): self.set_target_temp(0, self.kettle) def execute(self): ''' This method is execute in an interval :return: ''' # Check if Target Temp is reached #if self.get_kettle_temp(self.kettle) >= int(self.temp) and self.s is False: # self.s = True # self.notify("Step Temp Reached!", "Please press the next button to continue", timeout=None) #self.actor_power(self.get_target_temp) pass
class SimpleToggleStep(StepBase): # Properties actor = StepProperty.Actor("Actor") power = Property.Number("Power", configurable=True) toggle_type = Property.Select("Toggle Type", options=["On", "Off", "Power Only"]) def init(self): if self.toggle_type == "On": if self.power is not None and self.power: self.actor_on(int(self.actor), int(self.power)) else: self.actor_on(int(self.actor)) if self.toggle_type == "Off": self.actor_off(int(self.actor)) if self.toggle_type == "Power Only" and self.power is not None and self.power: self.actor_power(int(self.actor), int(self.power)) def finish(self): pass def execute(self): next(self)
class SimpleMashOutStep(StepBase): kettle = StepProperty.Kettle( "Kettle", description="Kettle in which the chilling takes place") temp = Property.Number("MashOut Temperature", configurable=True, default_value=76.7, description="Target Temperature of Mashout") timer = Property.Number("MashOut Timer in Minutes", configurable=True, default_value=10, description="Time to be held at Mashout temp") stage = "init" #This process goes through the following stages: init, mashout, sparge, preboil, hotbreak preboiltemp = 90 hotbreaktemp = 99 wait_user = False def init(self): self.stage = "init" self.wait_user = False self.set_target_temp(self.temp, self.kettle) # self.preboiltemp = self.api.cache.get("kettle").get(self.kettle).get_config_parameter("e_max_temp_pid") # self.hotbreaktemp = 99 def start(self): pass def reset(self): pass def finish(self): pass @cbpi.action("Sparge Complete") def sparge_complete(self): if self.stage == "sparge": self.stage = "preboil" self.wait_user = False self.set_target_temp(self.preboiltemp, self.kettle) else: self.notify( "No Action Taken", "Function only works in \"sparge\" sub-stage. Current stage: " + self.stage, type="info", timeout=5000) @cbpi.action("Removed Lid") def lid_removed(self): if self.stage == "preboil": self.stage = "hotbreak" self.wait_user = False self.set_target_temp(self.hotbreaktemp, self.kettle) else: self.notify( "No Action Taken", "Function only works in \"preboil\" sub-stage. Current stage: " + self.stage, type="info", timeout=5000) @cbpi.action("Hotbreak Finished") def hotbreak_finished(self): if self.stage == "hotbreak": self.wait_user = False next(self) else: self.notify( "No Action Taken", "Function only works in \"hotbreak\" sub-stage. Current stage: " + self.stage, type="info", timeout=5000) def execute(self): if self.stage == "init": #let the kettle heat to mash out temp if self.get_kettle_temp(self.kettle) >= self.temp: self.stage = "mashout" elif self.stage == "mashout": #run the mash timer if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) if self.is_timer_finished() == True: self.stage = "sparge" elif self.stage == "sparge": #wait for user confirmation to continue if self.wait_user == False: self.notify( "MASH OUT COMPLETE", "Sparge and then select \"Sparge Complete\" to continue.", type="warning", timeout=None) self.wait_user = True elif self.stage == "preboil": #let the kettle heat to pre-boil, then wait for user to remove lid if self.get_kettle_temp(self.kettle) >= self.preboiltemp: if self.wait_user == False: self.notify( "REMOVE THE LID", "Heated to Pre-Boil. Remove the lid and click \"Removed Lid\" to continue.", type="warning", timeout=None) self.wait_user = True elif self.stage == "hotbreak": #heat kettle to boil, then wait for user for user to go to boil stage if self.get_kettle_temp(self.kettle) >= self.hotbreaktemp: if self.wait_user == False: self.notify( "WATCH FOR HOTBREAK", "When hotbreak is complete click \"Hotbreak Finished\" to continue.", type="warning", timeout=None) self.wait_user = True else: #An error has occured! Not in a valid status self.notify("INVALID STAGE", "An invalid stage has been returned. Current stage: " + self.stage, type="dangar", timeout=None)
class SimpleWhirlpoolStep(StepBase): kettle = StepProperty.Kettle( "Kettle", description="Kettle in which the chilling takes place") chiller = StepProperty.Actor("Chiller", description="Actor that controls the Chiller") chillerPump = StepProperty.Actor( "chillerPump", description="Actor that controls the chillerPump") temp = Property.Number("Whirlpool Temperature", configurable=True, default_value=80, description="Target Temperature of Whirlpool") timer = Property.Number( "Total Whirlpool Timer in Minutes (incl. Santise Time)", configurable=True, default_value=30, description="Timer is started immediately") sanitiseTimer = Property.Number("Sanitise Timer in Minutes", configurable=True, default_value=5, description="Time at sanitisation temp") sanitiseTemp = Property.Number( "Sanitise Temperature", configurable=True, default_value=95, description="Target Temperature for sanitisation") s_end = 1 stage = "init" #This process goes through the following stages: init, waithookup, sanitise, whirlpool c_cut = 0 def init(self): self.stage = "init" self.actor_off(int(self.chillerPump)) self.actor_off(int(self.chiller)) self.set_target_temp(self.sanitiseTemp, self.kettle) self.s_end = 1 self.c_cut = 0 def start(self): pass def reset(self): self.stop_timer() def finish(self): self.actor_off(int(self.chillerPump)) self.actor_off(int(self.chiller)) @cbpi.action("Chiller Connected") def chiller_connected(self): if self.stage == "waithookup": self.stage = "sanitise" self.actor_on(int(self.chillerPump)) self.s_end = (self.timer_remaining() - (60 * int(self.sanitiseTimer))) else: self.notify( "No Action Taken", "Function only works in \"waithookup\" sub-stage. Current stage: " + self.stage, type="info", timeout=5000) def execute(self): if self.is_timer_finished() is None: self.start_timer(int(self.timer) * 60) if self.is_timer_finished() == True: if self.stage != "whirlpool": self.notify( "ERROR - Whirlpool incomplete", "Step completed without reaching internal whirlpool stage", type="danger", timeout=None) self.actor_off(int(self.chiller)) self.actor_off(int(self.chillerPump)) next(self) else: if self.get_kettle_temp(self.kettle) >= ( self.get_target_temp(self.kettle) + 10): #This option determines when the chiller is full on self.actor_on(int(self.chiller)) elif self.get_kettle_temp(self.kettle) >= self.get_target_temp( self.kettle ): #This option specifies partial activation - alternate 3secs on and off self.c_cut = int((self.timer_remaining() / 3)) if self.c_cut % 2: self.actor_on(int(self.chiller)) else: self.actor_off(int(self.chiller)) else: self.actor_off(int(self.chiller)) if self.stage == "init": self.notify("Put on the lid and connect the chiller", "Please select \"Chiller Connected\" to continue", type="warning", timeout=None) self.stage = "waithookup" elif self.stage == "sanitise": if self.s_end >= self.timer_remaining(): self.stage = "whirlpool" self.set_target_temp(self.temp, self.kettle)