class SelfLearning433Mhz(ActorBase):

    oncode = Property.Text("Switch ON code",
                           configurable=True,
                           default_value="")
    offcode = Property.Text("Switch OFF code",
                            configurable=True,
                            default_value="")

    def send(self, code):
        try:
            call([
                "sudo /home/pi/433Utils/RPi_utils/./codesend %s 4 355" % (code)
            ],
                 shell=True)
        except Exception as e:
            self.api.app.logger.error("FAILED to switch 433Mhz Code: %s" %
                                      (code))
        self.api.app.logger.info("SWITCHED Selflearning 433Mhz Code: %s" %
                                 (code))

    def on(self, power=100):
        self.send(self.oncode)
        self.api.app.logger.info("SWITCHED Selflearning 433Mhz Socket: %s" %
                                 (self.oncode))

    def off(self):
        self.send(self.offcode)
        self.api.app.logger.info("SWITCHED Selflearning 433Mhz Socket: %s" %
                                 (self.offcode))
class MQTT_SENSOR(SensorActive):
    a_topic = Property.Text("Topic", configurable=True,
                            default_value="", description="MQTT Topic")
    b_payload = Property.Text("Payload Directory", configurable=True, default_value="",
                              description="Where to find the message in the payload, leave blank for raw payload")
    c_unit = Property.Text("Unit", configurable=True,
                           default_value="", description="Displayed Unit")
    d_offset = Property.Number("Offset", configurable=True,
                               default_value="0", description="Offset relative to sensor data")

    last_value = None
    send_value = 0

    def init(self):
        self.topic = self.a_topic
        if self.b_payload == "":
            self.payload_text = None
        else:
            self.payload_text = self.b_payload.split('.')
        self.unit = self.c_unit[0:3]

        SensorActive.init(self)
        def on_message(client, userdata, msg):

            try:
                json_data = json.loads(msg.payload)
                val = json_data
                if self.payload_text is not None:
                    for key in self.payload_text:
                        val = val.get(key, None)
                if isinstance(val, (int, float, basestring)):
                    q.put({"id": on_message.sensorid, "value": val})
            except Exception as e:
                print e
        on_message.sensorid = self.id
        self.api.cache["mqtt"].client.subscribe(self.topic)
        self.api.cache["mqtt"].client.message_callback_add(
            self.topic, on_message)

    def get_value(self):
        try:
            self.send_value = round(
                float(self.last_value) + float(self.d_offset), 2)
        except Exception as e:
            pass
        return {"value": self.send_value, "unit": self.unit}

    def get_unit(self):
        return self.unit

    def stop(self):
        self.api.cache["mqtt"].client.unsubscribe(self.topic)
        SensorActive.stop(self)

    def execute(self):
        '''
        Active sensor has to handle his own loop
        :return:
        '''
        self.sleep(5)
Example #3
0
class GPIOPWM(ActorBase):

    gpio = Property.Select("GPIO",
                           options=[
                               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                               14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
                               26, 27
                           ])
    duty_cylce = Property.Number("Duty Cycle", configurable=True)

    p = None
    power = 100

    def init(self):
        GPIO.setup(int(self.gpio), GPIO.OUT)
        GPIO.output(int(self.gpio), 0)

    def on(self, power=None):
        if power is not None:
            self.power = int(power)

        if self.duty_cylce is None:
            duty_cylce = 50

        self.p = GPIO.PWM(int(self.gpio), int(self.duty_cylce))
        self.p.start(int(self.power))

    def set_power(self, power):
        if power is not None:
            self.power = int(power)
        self.p.ChangeDutyCycle(self.power)

    def off(self):
        print "GPIO OFF"
        self.p.stop()
Example #4
0
class iSpindel(SensorActive):
	key = Property.Text(label="iSpindel Name", configurable=True, description="Enter the name of your iSpindel")
	sensorType = Property.Select("Data Type", options=["Temperature", "Gravity", "Battery"], description="Select which type of data to register for this sensor")
	tuningPolynom = Property.Text(label="Tuning Polynomial", configurable=True, default_value="tilt", description="Enter your iSpindel polynomial. Use the variable tilt for the angle reading from iSpindel. Does not support ^ character.")
	unitsGravity = Property.Select("Gravity Units", options=["SG", "Brix", "°P"], description="Displays gravity reading with this unit if the Data Type is set to Gravity. Does not convert between units, to do that modify your polynomial.")

	def get_unit(self):
		if self.sensorType == "Temperature":
			return "°C" if self.get_config_parameter("unit", "C") == "C" else "°F"
		elif self.sensorType == "Gravity":
			return self.unitsGravity
		elif self.sensorType == "Battery":
			return "V"
		else:
			return " "

	def stop(self):
		pass

	def execute(self):
		global cache
		while self.is_running():
			try:				
				if cache[self.key] is not None:
					if self.sensorType == "Gravity":
						reading = calcGravity(self.tuningPolynom, cache[self.key]['Angle'], self.unitsGravity)
					else:
						reading = cache[self.key][self.sensorType]
					self.data_received(reading)
			except:
				pass
			self.api.socketio.sleep(1) 
Example #5
0
class WiiSensor(SensorPassive):

    offset = Property.Number('Offset', True, 0)
    unit_of_measure = Property.Select('Unit of measure', ['KG', 'LBS'])

    def init(self):
        self.t = WiiThread()

        def shudown():
            shudown.cb.shutdown()

        shudown.cb = self.t

        self.t.start()

    def stop(self):
        try:
            self.t.stop()
        except:
            pass

    def get_unit(self):
        if self.unit_of_measure == 'KG':
            return 'KG'
        else:
            return 'LBS'

    def read(self):
        if self.unit_of_measure == 'KG':
            self.data_received(round(self.t.value + float(self.offset), 2))
        else:
            self.data_received(
                round(self.t.value * 2.20462262185 + float(self.offset), 2))
Example #6
0
class PIDArduino(KettleController):

    a_p = Property.Number("P", True, 0)
    b_i = Property.Number("I", True, 0)
    c_d = Property.Number("D", True, 0)
    d_max_out = Property.Number("max. output %", True, 100)

    def run(self):
        sampleTime = 5
        wait_time = 5
        p = float(self.a_p)
        i = float(self.b_i)
        d = float(self.c_d)
        maxout = float(self.d_max_out)
        pid = PIDArduino(sampleTime, p, i, d, 0, maxout)

        while self.is_running():
            heat_percent = pid.calc(self.get_temp(), self.get_target_temp())
            heating_time = sampleTime * heat_percent / 100
            wait_time = sampleTime - heating_time
            if heating_time == sampleTime:
                self.heater_on(100)
                self.sleep(heating_time)
            elif wait_time == sampleTime:
                self.heater_off()
                self.sleep(wait_time)
            else:
                self.heater_on(100)
                self.sleep(heating_time)
                self.heater_off()
                self.sleep(wait_time)
Example #7
0
class eManometer(SensorActive):
    key = Property.Text(label="eManometer Name",
                        configurable=True,
                        description="Enter the name of your eManometer")
    sensorType = Property.Select(
        "Data Type",
        options=["Temperature", "Pressure", "CO2"],
        description="Select which type of data to register for this sensor")

    def get_unit(self):
        if self.sensorType == "Temperature":
            return "°C" if self.get_config_parameter("unit",
                                                     "C") == "C" else "°F"
        elif self.sensorType == "Pressure":
            return "bar"
        elif self.sensorType == "CO2":
            return "g/l"
        else:
            return " "

    def stop(self):
        pass

    def execute(self):
        global cache
        while self.is_running():
            try:
                if cache[self.key] is not None:
                    reading = cache[self.key][self.sensorType]
                    self.data_received(reading)
            except:
                pass
            self.api.socketio.sleep(1)
Example #8
0
class Hysteresis(FermenterController):

    heater_offset_min = Property.Number("Heater Offset min", True, 0)
    heater_offset_max = Property.Number("Heater Offset max", True, 0)
    cooler_offset_min = Property.Number("Cooler Offset min", True, 0)
    cooler_offset_max = Property.Number("Cooler Offset max", True, 0)

    def stop(self):
        super(FermenterController, self).stop()

        self.heater_off()
        self.cooler_off()

    def run(self):
        while self.is_running():

            target_temp = self.get_target_temp()
            temp = self.get_temp()

            if temp + int(self.heater_offset_min) < target_temp:
                self.heater_on(100)

            if temp + int(self.heater_offset_max) > target_temp:
                self.heater_off()

            if temp > target_temp + int(self.cooler_offset_min):
                self.cooler_on(100)

            if temp < target_temp + int(self.cooler_offset_max):
                self.cooler_off()

            self.sleep(1)
Example #9
0
class PIDPWM(KettleController):

    a_p = Property.Number("P", True, 0)
    b_i = Property.Number("I", True, 0)
    c_d = Property.Number("D", True, 0)
    d_max_out = Property.Number("max. output %", True, 100)

    def run(self):
        sampleTime = 5
        p = float(self.a_p)
        i = float(self.b_i)
        d = float(self.c_d)
        maxout = float(self.d_max_out)
        pid = PIDArduino(sampleTime, p, i, d, 0, maxout)
        self.heater_on(0)

        while self.is_running():
            heat_percent = pid.calc(self.get_temp(), self.get_target_temp())
            print(heat_percent)
            self.actor_power(round(heat_percent))
            self.sleep(sampleTime)

    def stop(self):

        super(KettleController, self).stop()
        self.heater_off()
Example #10
0
class brewBubbles(SensorActive):
    log("cbpi_brewbubbles Start Instancing")
    key = Property.Text(label="BrewBubbles Name",
                        configurable=True,
                        description="Enter the name of your BrewBubbles")
    sensorType = Property.Select(
        "Data Type",
        options=["BPM", "Room Temp.", "Vessel Temp."],
        description="Select which type of data to register for this sensor")

    log("cbpi_brewbubbles continue Instancing")

    def get_unit(self):
        if self.sensorType == "Temperature":
            if self.get_config_parameter("unit", "C") == "C":
                return "°C"
            else:
                return "°F"
        else:
            return " "

    def stop(self):
        pass

    def execute(self):
        global cache
        while self.is_running():
            try:
                if cache[self.key] is not None:
                    reading = cache[self.key][self.sensorType]
                    self.data_received(reading)
            except:
                pass
            self.api.socketio.sleep(1)
Example #11
0
class LauteringAutomation(KettleController):

    minSensorDistance = Property.Number(
        "Minimum Distance to Sensor (High Fill Level)", True, 0)
    maxSensorDistance = Property.Number(
        "Maximum Distance to Sensor (Low Fill Level)", True, 0)
    pumping = False
    currentFillLevel = 0

    def stop(self):
        super(KettleController, self).stop()
        self.heater_off()

    def run(self):
        self.sleep(1)
        while self.is_running():
            self.currentFillLevel = self.get_temp()
            if bool(self.pumping):
                if self.currentFillLevel >= float(self.maxSensorDistance):
                    self.heater_off()
                    self.pumping = False
                else:
                    self.heater_on(100)
            else:
                if self.currentFillLevel <= float(self.minSensorDistance):
                    self.heater_on(100)
                    self.pumping = True
                else:
                    self.heater_off()
            self.sleep(1)
class Message_CG(StepBase):

    messagetodisplay = Property.Text("Message To Display", configurable=True, default_value="Message you want to display", description="Message to be displayed")
    timer = Property.Number("Seconds to wait for next step (use 0 to wait for user)?", configurable=True, default_value=1, description="How long should the brew session wait before continuing? If you select 0 then it will wait for user to click Start Next Step.")
    s = False

    @cbpi.action("Start Timer")
    def start(self):
        self.s = False
        if self.is_timer_finished() is None:
            self.start_timer(int(self.timer)+1)

    def reset(self):
        self.stop_timer()

    def execute(self):
        if self.is_timer_finished() is None:
            self.start_timer(int(self.timer)+1)
        if self.s == False:
            self.s = True
            if int(self.timer) == 0:
                self.notify(self.messagetodisplay, "Please select \"Next Step\" to continue", type="warning", timeout=None)
            else:
                self.notify(self.messagetodisplay, "Brewing will continue automatically when the timer completes.", type="info", timeout=((int(self.timer)-1)*1000))
        if self.is_timer_finished() == True:
            if int(self.timer) == 0:
                pass
            else:
                self.next()
Example #13
0
class MQTTActor_Compressor(ActorBase):
    topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC")
    delay = Property.Number("Compressor Delay", configurable=True, default_value=10, description="minutes")
    on_payload = Property.Text("On Payload", configurable=True, default_value='{"state": "on"}', description="Payload to send to turn the actor on")
    off_payload = Property.Text("Off Payload", configurable=True, default_value='{"state": "off"}', description="Payload to send to turn the actor off")

    compressor_on = False
    compressor_wait = datetime.utcnow()
    delayed = False

    def init(self):
        super(MQTTActor_Compressor, self).init()
        cbpi.MQTTActor_Compressors += [self]

    def on(self, power=100):
        if datetime.utcnow() >= self.compressor_wait:
            self.compressor_on = True
            self.api.cache["mqtt"].client.publish(self.topic, payload=self.on_payload, qos=2, retain=True)
            self.delayed = False
        else:
            print "Delaying Turing on Compressor"
            cbpi.app.logger.info("Delaying Turing on Compressor")
            self.delayed = True

    def off(self):
        if self.compressor_on:
            self.compressor_on = False
            self.compressor_wait = datetime.utcnow() + timedelta(minutes=int(self.delay))
        self.delayed = False
        self.api.cache["mqtt"].client.publish(self.topic, payload=self.off_payload, qos=2, retain=True)
Example #14
0
class OnAtStartup(ActorBase):
    actor_setting = Property.Actor(
        "Actor",
        description="Select the actor you would like to have ON at startup")
    power_setting = Property.Number(
        "Power",
        True,
        100,
        description="Select the power of the actor at startup")

    def init(self):
        if not 0 <= int(self.power_setting) <= 100:
            self.api.notify(headline="OnAtStartup Error",
                            message="Power must be between 0 and 100",
                            timeout=None,
                            type="danger")
            raise ValueError("Power must be between 0 and 100")
        else:
            self.api.switch_actor_on(int(self.actor_setting),
                                     power=int(self.power_setting))

    def set_power(self, power):
        pass

    def off(self):
        pass

    def on(self, power=None):
        pass
Example #15
0
class MQTTActor_Compressor(ActorBase):
    topic = Property.Text("Topic", configurable=True,
                          default_value="", description="MQTT TOPIC")
    delay = Property.Number(
        "Compressor Delay", configurable=True, default_value=10, description="minutes")
    compressor_on = False
    compressor_wait = datetime.utcnow()
    delayed = False

    def init(self):
        super(MQTTActor_Compressor, self).init()
        cbpi.MQTTActor_Compressors += [self]
        print "Initially setting MQTT Actor Compressor to off.."
        self.off()

    def on(self, power=100):
        if datetime.utcnow() >= self.compressor_wait:
            self.compressor_on = True
            self.api.cache["mqtt"].client.publish(self.topic, payload=json.dumps(
                {"on": True, "power": 100}), qos=2, retain=True)
            self.delayed = False
        else:
            cbpi.app.logger.info("Delaying Turing on Compressor")
            self.delayed = True

    def off(self):
        if self.compressor_on:
            self.compressor_on = False
            self.compressor_wait = datetime.utcnow() + timedelta(minutes=int(self.delay))
        self.delayed = False
        self.api.cache["mqtt"].client.publish(
            self.topic, payload=json.dumps({"on": False}), qos=2, retain=True)
Example #16
0
class Hysteresis(KettleController):

    # Custom Properties

    on = Property.Number("Offset On", True, 0, description="Offset below target temp when heater should switched on. Should be bigger then Offset Off")
    off = Property.Number("Offset Off", True, 0, description="Offset below target temp when heater should switched off. Should be smaller then Offset Off")

    def stop(self):
        '''
        Invoked when the automatic is stopped.
        Normally you switch off the actors and clean up everything
        :return: None
        '''
        super(KettleController, self).stop()
        self.heater_off()




    def run(self):
        '''
        Each controller is exectuted in its own thread. The run method is the entry point
        :return: 
        '''
        while self.is_running():

            if self.get_temp() < self.get_target_temp() - float(self.on):
                self.heater_on(100)
            elif self.get_temp() >= self.get_target_temp() - float(self.off):
                self.heater_off()
            else:
                self.heater_off()
            self.sleep(1)
Example #17
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)
Example #18
0
class Socket433MHz(ActorBase):
    code_on = Property.Text(
        "ON Code",
        configurable=True,
        description="Enter the code for turning the 433Hz socket on")
    code_off = Property.Text(
        "OFF Code",
        configurable=True,
        description="Enter the code for turning the 433Hz socket off")
    pin = Property.Text(
        "GPIO PIN",
        configurable=True,
        description="Enter the code GPIO PIN for the rf transmitter")

    def on(self, power=100):
        logging.basicConfig(
            level=logging.INFO,
            datefmt='%Y-%m-%d %H:%M:%S',
            format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s',
        )
        rfdevice = RFDevice(int(self.pin))
        rfdevice.enable_tx()
        rfdevice.tx_code(int(self.code_on), None, None)
        rfdevice.cleanup()

    def off(self):
        logging.basicConfig(
            level=logging.INFO,
            datefmt='%Y-%m-%d %H:%M:%S',
            format='%(asctime)-15s - [%(levelname)s] %(module)s: %(message)s',
        )
        rfdevice = RFDevice(int(self.pin))
        rfdevice.enable_tx()
        rfdevice.tx_code(int(self.code_off), None, None)
        rfdevice.cleanup()
Example #19
0
class SimpleManualStep(StepBase):
    # Properties
    heading = Property.Text("Heading",
                            configurable=True,
                            default_value="Step Alert",
                            description="First line of notification.")
    message = Property.Text("Message",
                            configurable=True,
                            default_value="Press next button to continue",
                            description="Second line of notification.")
    notifyType = Property.Select(
        "Type", options=["success", "info", "warning", "danger"])
    proceed = Property.Select(
        "Next Step",
        options=["Pause", "Continue"],
        description=
        "Whether or not to automatically continue to the next brew step.")

    #-------------------------------------------------------------------------------
    def init(self):
        if self.notifyType not in ["success", "info", "warning", "danger"]:
            self.notifyType = "info"
        self.notify(self.heading,
                    self.message,
                    type=self.notifyType,
                    timeout=None)
        if self.proceed == "Continue":
            next(self)
Example #20
0
class HeadsStep(StepBase, BaseColletingStep):
    collectingSpeed = Property.Number("Скорость отбора, мл/ч",
                                      configurable=True,
                                      default_value=100)
    headsTotal = Property.Number("Объем голов для отбора, мл",
                                 configurable=True,
                                 default_value=100)

    total = 0
    time = datetime.utcnow()

    def finish(self):
        self.actor_off(int(self.collectingActor))
        self.notify("", "Отбор голов завершен", type="success", timeout=2000)

    def execute(self):
        self.updateMaxCollectingSpeed()
        self.calculateActorPower()
        self.manageActor()
        self.checkTotalCollecting()
        self.notifySensor()

    def checkTotalCollecting(self):
        time = datetime.utcnow()
        if (time - self.time).total_seconds() >= 10:
            self.time = time
            self.total += float(self.collectingSpeed) / 360.0

        if self.total >= int(self.headsTotal):
            next(self)
Example #21
0
class Hysteresis(KettleController):

    # Custom Properties

    on = Property.Number("Offset On", True, 0)
    off = Property.Number("Offset Off", True, 0)

    def stop(self):
        '''
        Invoked when the automatic is stopped.
        Normally you switch off the actors and clean up everything
        :return: None
        '''
        super(KettleController, self).stop()
        self.heater_off()

    def run(self):
        '''
        Each controller is exectuted in its own thread. The run method is the entry point
        :return: 
        '''
        while self.is_running():

            self.actor_power(50)

            if self.get_temp() < self.get_target_temp() - int(self.on):
                self.heater_on(100)
            elif self.get_temp() >= self.get_target_temp() - int(self.off):
                self.heater_off()
            else:
                self.heater_off()
            self.sleep(1)
Example #22
0
class HopDropperActor(ActorBase):
    gpio = Property.Select("GPIO",
                           options=[
                               0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
                               14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
                               26, 27
                           ],
                           description="GPIO to which the actor is connected")
    timeout = Property.Number(
        "Timeout",
        configurable=True,
        default_value=2,
        description="After how many seconds the actor should switch off again")

    def init(self):
        GPIO.setup(int(self.gpio), GPIO.OUT)
        GPIO.output(int(self.gpio), 0)

    def on(self, power=0):
        def toggleTimeJob(id, t):
            self.api.socketio.sleep(t)
            self.api.switch_actor_off(int(id))

        if self.timeout:
            t = self.api.socketio.start_background_task(target=toggleTimeJob,
                                                        id=self.id,
                                                        t=int(self.timeout))
        GPIO.output(int(self.gpio), 1)

    def off(self):

        GPIO.output(int(self.gpio), 0)
Example #23
0
class Mod_PWM(ActorBase):

    gpio = Property.Select("GPIO", options=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27])
    frequency = Property.Number("Cycles Per Second", configurable=True)
    
    power = 100
    p = None
    stopped = True
    
    def init(self):
        GPIO.setup(int(self.gpio), GPIO.OUT)
        GPIO.output(int(self.gpio), 0)

    def on(self, power):
        self.stopped = False
        if self.p is None:
            if self.frequency is None:
                self.frequency = 50
            self.p = GPIO.PWM(int(self.gpio), int(self.frequency))
            self.p.start(int(Mod_PWM.power))
        if power is not None:
            self.p.ChangeDutyCycle(int(power))
        else:
            self.p.ChangeDutyCycle(int(Mod_PWM.power))
    
    def set_power(self, power):
        if power is not None:
            Mod_PWM.power = power
        if self.stopped is False:
            self.p.ChangeDutyCycle(int(Mod_PWM.power))

    def off(self):
        self.stopped = True
        self.p.ChangeDutyCycle(0)
Example #24
0
class HTTPActor(ActorBase):

    a_url = Property.Text("Controller Address", configurable=True, default_value="http://<ipaddress>:<port>", description="Address of the controller. Do not add a trailing slash (ex: http://192.168.0.10)")
    b_on = Property.Text("On Command", configurable=True, default_value="control?cmd=GPIO,<pin>,1", description="Command to turn actor on")
    c_off = Property.Text("Off Command", configurable=True, default_value="control?cmd=GPIO,<pin>,0", description="Command to turn actor off")
    d_pow = Property.Text("Power Command", configurable=True, default_value="control?cmd=PWM,<pin>,", description="Command to set actor power level. Power level will be added to the end of the command. If device does not support this, make this field blank.")
    
    power = 100
    
    def send(self, command):
        try:
            h = httplib2.Http(".cache")
            ## Sending http command ""
            (resp, content) = h.request("%s/%s" % (self.a_url, command), "GET", headers={'cache-control':'no-cache'})
        except Exception as e:
            self.api.app.logger.error("FAILED to switch HTTP actor: %s/%s" % (self.a_url, command))

    def on(self, power=None):
        self.send(self.b_on)
        if power is not None:
            self.set_power(power)

    def off(self):
        self.send(self.c_off)
        
    def set_power(self, power):
        if power is not None and self.d_pow is not None and self.d_pow:
            if power != self.power:
                self.power = int(power)
                self.send("%s%s" % (self.d_pow, power))
Example #25
0
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()
Example #26
0
class PIDHendi(KettleController):

    P = Property.Number("P", configurable=True, default_value=40, unit="")
    I = Property.Number("I", configurable=True, default_value=140, unit="")
    D = Property.Number("D", configurable=True, default_value=0, unit="")
    Pmax = Property.Number("Max Power", configurable=True, default_value=100, unit="%")

    def run(self):
        p = float(self.P)
        i = float(self.I)
        d = float(self.D)
        pmax = int(self.Pmax)
        ts = 5

        print((p, i, d, pmax))
        pid = PID(ts, p, i, d, pmax)

        while self.is_running():
            heat_percent = pid.calc(self.get_sensor_value(), self.get_target_temp())
            if heat_percent == 0:
                self.actor_power(heat_percent)
                self.heater_off()
                cbpi.log_action("PIDHendi OFF {}")
            else:
                self.actor_power(heat_percent)
                self.heater_on(power=heat_percent)

                cbpi.log_action("PIDHendi calling heater_on(power={})".format(heat_percent))

            self.sleep(ts)

        self.heater_off()
Example #27
0
class SimpleBoilLogic(KettleController):

    ramp_power = Property.Number("Ramp Up Power %", True, 100)
    boil_power = Property.Number("Boil Power %", True, 70)

    def stop(self):

        super(KettleController, self).stop()
        self.heater_off()

    def run(self):

        r_power = int(self.ramp_power)
        b_power = int(self.boil_power)

        while self.is_running():
            temp = self.get_temp()
            r_limit = self.get_target_temp()
            if temp < r_limit and r_limit > 0:
                self.heater_on(r_power)
                self.actor_power(r_power)
            if temp >= r_limit and r_limit > 0:
                self.heater_on(b_power)
                self.actor_power(b_power)
            self.sleep(1)
Example #28
0
class TrailingAverageSensor(SensorPassive):
    sensor_prop = Property.Sensor("Sensor", description="Select a sensor to average readings of.")
    count_prop = Property.Number("Count", configurable=True, default_value=12, description="Number of readings to average.")
    decimals_prop = Property.Number("Decimals", configurable=True, default_value=1, description="How many decimals to round the average to.")

    #-------------------------------------------------------------------------------
    def init(self):
        self.values = list()
        self.sensor_id = int(self.sensor_prop)
        self.count = int(self.count_prop)
        self.weight = 1.0/self.count
        self.decimals = int(self.decimals_prop)

    #-------------------------------------------------------------------------------
    def read(self):
        self.values.append(float(cbpi.cache.get("sensors")[int(self.sensor_id)].instance.last_value))
        while len(self.values) > self.count:
            self.values.pop(0)
        numerator = 0.0
        denominator = 0.0
        weight = 1.0
        for value in reversed(self.values):
            numerator += value * weight
            denominator += weight
            weight = weight - self.weight
        self.data_received(round(numerator/denominator, self.decimals))

    #-------------------------------------------------------------------------------
    def get_unit(self):
        return cbpi.cache.get("sensors")[int(self.sensor_id)].instance.get_unit()

    #-------------------------------------------------------------------------------
    def stop(self):
        pass
Example #29
0
class Hysteresis(FermenterController):

    heater_offset_min = Property.Number("Heater Offset ON", True, 0, description="Offset as decimal number when the heater is switched on. Should be greater then 'Heater Offset OFF'. For example a value of 2 switches on the heater if the current temperature is 2 degrees below the target temperature")
    heater_offset_max = Property.Number("Heater Offset OFF", True, 0, description="Offset as decimal number when the heater is switched off. Should be smaller then 'Heater Offset ON'. For example a value of 1 switches off the heater if the current temperature is 1 degree below the target temperature")
    cooler_offset_min = Property.Number("Cooler Offset ON", True, 0, description="Offset as decimal number when the cooler is switched on. Should be greater then 'Cooler Offset OFF'. For example a value of 2 switches on the cooler if the current temperature is 2 degrees above the target temperature")
    cooler_offset_max = Property.Number("Cooler Offset OFF", True, 0, description="Offset as decimal number when the cooler is switched off. Should be less then 'Cooler Offset ON'. For example a value of 1 switches off the cooler if the current temperature is 1 degree above the target temperature")

    def stop(self):
        super(FermenterController, self).stop()

        self.heater_off()
        self.cooler_off()

    def run(self):
        while self.is_running():

            target_temp = self.get_target_temp()
            temp = self.get_temp()

            if temp + float(self.heater_offset_min) <= target_temp:
                self.heater_on(100)

            if temp + float(self.heater_offset_max) >= target_temp:
                self.heater_off()

            if temp >= target_temp + float(self.cooler_offset_min):
                self.cooler_on(100)

            if temp <= target_temp + float(self.cooler_offset_max):
                self.cooler_off()

            self.sleep(1)
Example #30
0
class GPIOinput(SensorActive):

    gpio = Property.Select("GPIO", options=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27])
    input_type = Property.Select("Input Type", options=["Momentary","Latch Rise", "Latch Fall"], description="Momentary - input high = high val. Latched - pulse on, pulse off")
    pud_type = Property.Select("Pull Up/Down", options=["Pull Up","Pull Down","Off"], description="Pull Up or down ressitor on input")

    on_val = Property.Number("High Value", configurable=True, default_value="0", description="Read value when input is high or Latch True(3.3V)")
    off_val = Property.Number("Low Value", configurable=True, default_value="100", description="Read value when sensor is low or Latch False (0V)")
    out_val = [0,1]

    input_on = False
    latch_val = False
    
    def init(self):
        self.input_on = False
        self.trigger_val = None
        try:                  
            GPIO.setup(int(self.gpio), GPIO.IN , pull_up_down = PUD_map[self.pud_type])
            GPIO.remove_event_detect(int(self.gpio))
            GPIO.add_event_detect(int(self.gpio), GPIO.BOTH, callback=self.IO_trigger, bouncetime=20)
            self.out_val = [self.off_val,self.on_val]
            self.latch_val = trig_level[self.input_type]
            super(GPIOinput,self).init()
            print "Init Complete"
            self.data_received(self.out_val[self.input_on])
        except Exception as e:
            print e

    def get_unit(self):
        unit = "NA"
        return unit
    
    def IO_trigger(self, channel):
        self.sleep(0.0005)
        self.trigger_val = GPIO.input(int(self.gpio))
        if self.input_type[0] == "L":
            if self.trigger_val != self.latch_val:
                self.trigger_val = None

    def execute(self): 
        while self.is_running():
            self.api.socketio.sleep(.1)
            #if GPIO.event_detected(int(self.gpio)):
            if self.trigger_val is not None:
                # if we're here, an edge was recognized
                #self.sleep(0.01) # debounce
                if self.input_type[0] == "M":
                    self.input_on = GPIO.input(int(self.gpio))
                else: #Latch
                    if self.trigger_val == self.latch_val:
                        self.input_on = not self.input_on
               
                self.data_received(self.out_val[self.input_on])
                self.trigger_val = None

    def stop(self):
        self.__running = False
        GPIO.cleanup([int(self.gpio)])
        GPIO.remove_event_detect(int(self.gpio))