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()
Exemple #3
0
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)
Exemple #4
0
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()
Exemple #5
0
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)
Exemple #6
0
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 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()
Exemple #8
0
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)
Exemple #9
0
class KRimsMashStep(StepBase):
    '''
    Just put the decorator @cbpi.step on top of a method
    '''
    # Properties
    temp = Property.Number("Kettle Temperature",
                           configurable=True,
                           description="Target Temperature of the Kettle")
    mash_temp = Property.Number(
        "Mash Temperature",
        configurable=True,
        description="Target Temperature of the 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")
    sensor = StepProperty.Sensor("Sensor",
                                 description="Selectable secondary sensor")
    pump = StepProperty.Actor("Pump, etc.")
    mode = Property.Select("Mode", ["Timer", "User input"],
                           "Selects how the step operates")

    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)
        self.actor_on(int(self.pump))

    @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)
        self.actor_off(int(self.pump))

    def execute(self):
        '''
        This method is execute in an interval
        :return:
        '''

        # Check if Target Temp is reached
        if self.mode == "Timer":
            if cbpi.get_sensor_value(int(self.sensor)) >= float(
                    self.mash_temp):
                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)
                self.next()

        if self.mode == "User input":
            if cbpi.get_sensor_value(int(self.sensor)) >= float(
                    self.mash_temp):
                self.notify("Mash Temp reached!",
                            "User input needed to proceed to next step",
                            timeout=None)
                self.mode = "All done. Wait for user"
Exemple #10
0
class SpargeStep(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("Boil Kettle")
    kettle2 = StepProperty.Kettle("HLT Kettle")
    actor1 = StepProperty.Actor("Wort Pump")
    actor2 = StepProperty.Actor("Water Pump")
    sensor1 = StepProperty.Sensor("BK Volume Sensor")
    sensor2 = StepProperty.Sensor("HLT Volume Sensor")
    volume1 = Property.Number("BK Volume Target", configurable=True)
    volume2 = Property.Number("HLT Volume Min", configurable=True)
    volumeStart = Property.Number("HLT Volume Start", configurable=True)
    volumeDiff = Property.Number("Volume Difference", configurable=True)
    timer = Property.Number("Timer in Minutes", configurable=True)
    temp = Property.Number("BK Temp", configurable=True)
    volumeBoil = Property.Number("BK Boil Volume", configurable=True)

    volumeState1 = 0
    volumeState2 = 0

    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.kettle2)

    def execute(self):
        '''
        This method is execute in an interval
        :return: 
        '''
        sensorValue1 = cbpi.get_sensor_value(int(self.sensor1))
        sensorValue2 = cbpi.get_sensor_value(int(self.sensor2))
        volumeChange1 = float(sensorValue1) - float(self.volumeState1)
        volumeChange2 = float(self.volumeState2) - float(sensorValue2)
        kettle1_state = cbpi.cache.get("kettle")[int(self.kettle1)].state
        kettle2_state = cbpi.cache.get("kettle")[int(self.kettle2)].state

        for key, value in cbpi.cache["actors"].iteritems():
            if key == int(self.actor1):
                actorState1 = value.state
            if key == int(self.actor2):
                actorState2 = value.state

        if float(sensorValue1) >= float(
                self.volumeBoil) and kettle1_state is False:
            Kettle2View().toggle(int(self.kettle1))
            self.notify("Kettle Update", "Kettle 1 Auto is on.", timeout=None)
            self.set_target_temp(self.temp, self.kettle1)

        # Check if kettle2 volume limit reached
        if float(sensorValue2) <= float(self.volume2):
            if kettle2_state is True:
                self.set_target_temp(0, self.kettle2)
                Kettle2View().toggle(int(self.kettle2))
                self.notify("Kettle Update",
                            "Kettle 2 Auto is off.",
                            timeout=None)
            if self.is_timer_finished() is None:
                self.start_timer(int(self.timer) * 60)
            # Make sure kettle1 hasn't reached target
            if float(sensorValue1) < float(self.volume1):
                self.actor_on(int(self.actor1))
                if self.is_timer_finished() == True:
                    self.actor_off(int(self.actor2))
                else:
                    self.actor_on(int(self.actor2))
        else:
            if self.volumeState1 > 0:
                totalDiff = float(volumeChange2) - float(volumeChange1)
                if totalDiff > 0:
                    if abs(totalDiff) > float(self.volumeDiff):
                        self.actor_off(int(self.actor2))
                        self.actor_on(int(self.actor1))
                    else:
                        self.actor_on(int(self.actor2))
                else:
                    if abs(totalDiff) > float(self.volumeDiff):
                        self.actor_off(int(self.actor1))
                        self.actor_on(int(self.actor2))
                    else:
                        self.actor_on(int(self.actor1))
            else:
                if volumeChange >= 10:
                    self.volumeState2 = sensorValue2
                    self.volumeState1 = sensorValue1

        # Check if kettle1 target volume has been reached
        if float(sensorValue1) >= float(self.volume1):
            self.set_target_temp(0, self.kettle2)
            self.stop_timer()
            self.start_timer(0)
            self.notify("Sparge Complete!",
                        "Starting the next step.",
                        timeout=None)
            self.next()
Exemple #11
0
class FlowSensorCalibrate(StepBase):
    # properties
    actor_prop = StepProperty.Actor("Actor")
    sensor_prop = StepProperty.Sensor("Sensor")
    timer_prop = Property.Number("Timer", configurable=True, default_value=10)
    threshold_prop = Property.Number(
        "Flow threshold",
        configurable=True,
        default_value=0.1,
        description="Value at which flow is considered stopped")

    #-------------------------------------------------------------------------------
    def init(self):
        # convert properties to usable attributes
        self.actor = int(self.actor_prop)
        self.sensor = cbpi.cache.get("sensors")[int(self.sensor_prop)].instance
        self.threshold = float(self.threshold_prop)
        self.flowing = False

        # reset sensor volume to start calibration
        self.sensor.reset_volume()
        # turn on actor
        self.actor_on(self.actor)
        # start timer
        if self.is_timer_finished() is None:
            self.start_timer(float(self.timer_prop) * 60)

    #-------------------------------------------------------------------------------
    def execute(self):
        sensor_data = self.sensor.read_sensor_data()
        if (not self.flowing) and (sensor_data['flow'] >= self.threshold):
            # flow has started
            cbpi.app.logger.info(
                "FlowSensor '{}' calibrate flow started".format(
                    self.sensor.name))
            self.flowing = True
        elif (self.flowing) and (sensor_data['flow'] <= self.threshold):
            # flow has stopped
            cbpi.app.logger.info(
                "FlowSensor '{}' calibrate flow stopped".format(
                    self.sensor.name))
            self.next()
        elif self.is_timer_finished() == True:
            # timer has expired
            cbpi.app.logger.info(
                "FlowSensor '{}' calibrate timer expired".format(
                    self.sensor.name))
            self.next()

    #-------------------------------------------------------------------------------
    def finish(self):
        # turn off actor
        self.actor_off(self.actor)

        # notify complete and total pulses
        sensor_data = self.sensor.read_sensor_data()
        self.notify("Flow Sensor Calibration Complete",
                    self.sensor.name,
                    type="success",
                    timeout=None)
        self.notify("Pulse Count: {}".format(sensor_data['count']),
                    self.sensor.name,
                    type="info",
                    timeout=None)

    #-------------------------------------------------------------------------------
    def reset(self):
        self.actor_off(self.actor)
Exemple #12
0
class FlowSensorTransfer(StepBase):
    a_sensor_prop = StepProperty.Sensor(
        "Flow Sensor", description="Sensor that contols this step")
    b_actor1_prop = StepProperty.Actor(
        "Actor 1",
        description="Actor to turn on for the duration of this step")
    c_actor2_prop = StepProperty.Actor(
        "Actor 2",
        description="Actor to turn on for the duration of this step")
    d_volume_prop = Property.Number(
        "Target Volume",
        configurable=True,
        description="Leave blank to continue until flow stops")
    e_reset_start_prop = Property.Select("Reset sensor at start?",
                                         options=["Yes", "No"])
    f_reset_finish_prop = Property.Select("Reset sensor at finish?",
                                          options=["Yes", "No"])
    g_threshold_prop = Property.Number(
        "Flow threshold",
        configurable=True,
        default_value=0.1,
        description="Value at which flow is considered stopped")

    #-------------------------------------------------------------------------------
    def init(self):
        # convert properties to usable attributes
        self.sensor = cbpi.cache.get("sensors")[int(
            self.a_sensor_prop)].instance
        self.actors = [self.b_actor1_prop, self.c_actor2_prop]
        try:
            self.target_volume = float(self.d_volume_prop)
        except:
            self.target_volume = 0.0
        self.reset_start = self.e_reset_start_prop == "Yes"
        self.reset_finish = self.f_reset_finish_prop == "Yes"
        try:
            self.threshold = float(self.g_threshold_prop)
        except:
            self.threshold = 0.1
        self.flowing = False

        # reset sensor volume if indicated
        if self.reset_start:
            self.sensor.reset_volume()
        # turn on actors
        self.actors_on()

    #-------------------------------------------------------------------------------
    def execute(self):
        sensor_data = self.sensor.read_sensor_data()
        if (not self.flowing) and (sensor_data['flow'] >= self.threshold):
            # flow has started
            cbpi.app.logger.info(
                "FlowSensor '{}' transfer flow started".format(
                    self.sensor.name))
            self.flowing = True
        elif (self.flowing) and (sensor_data['flow'] <= self.threshold):
            # flow has stopped
            cbpi.app.logger.info(
                "FlowSensor '{}' transfer flow stopped".format(
                    self.sensor.name))
            self.next()
        elif self.target_volume and (sensor_data['volume'] >=
                                     self.target_volume):
            # target volume reached
            cbpi.app.logger.info(
                "FlowSensor '{}' transfer target volume reached".format(
                    self.sensor.name))
            self.next()

    #-------------------------------------------------------------------------------
    def finish(self):
        # turn actors off
        self.actors_off()

        # notify complete and total volume
        sensor_data = self.sensor.read_sensor_data()
        self.notify("{} complete".format(self.name),
                    "Total Volume: {:.2f}{}".format(sensor_data['volume'],
                                                    self.sensor.volume_units),
                    timeout=None)

        # reset sensor volume if indicated
        if self.reset_finish:
            self.sensor.reset_volume()

    #-------------------------------------------------------------------------------
    def reset(self):
        self.actors_off()

    #-------------------------------------------------------------------------------
    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