예제 #1
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)
예제 #2
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) 
예제 #3
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))
예제 #4
0
class AtlasSensor(SensorActive):

    sensorSelect = Property.Select("Sensor Select",
                                   options=["0", "1", "2", "3"],
                                   description="Select available USB sensor")
    unitSelect = Property.Select("Unit Select",
                                 options=["Temp in F", "pH Value"],
                                 description="Select Unit")

    def get_unit(self):
        if self.unitSelect == "Temp in F":
            return " °F"
        elif self.unitSelect == "pH Value":
            return " pH"
        else:
            return "Select Data Type"

    def stop(self):
        '''
        Stop the sensor. Is called when the sensor config is updated or the sensor is deleted
        :return:
        '''
        print("Atlas Sensor Stopped")
        pass

    def execute(self):
        '''
        Active sensor has to handle its own loop
        :return: 
        '''
        #dev_active.send_cmd("C,0") # turn off continuous mode
        #dev_active.flush()
        #cbpi.app.logger.info("Device %s Flushed" % dev_active)

        while self.is_running():
            try:
                index = self.sensorSelect
                print("index = ", index)
                dev_active = get_sensor(index)
                #self.sleep(0.25)
                reading = run_Temp(dev_active)
                print("Sensor Reading = %s" % reading)

                self.data_received(reading)
                self.sleep(3)
            except:
                print("Error3: could not run execute loop.")
                self.sleep(2)

    #@classmethod
    #def init_global(self):
    #pass


#@cbpi.initalizer()
#def init(cbpi):
#pass
예제 #5
0
class PT100X(SensorPassive):
    # CONFIG PARAMETER & PROPERTIES
    csPin  = Property.Select("csPin", 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 Pin connected to the CS Pin of the MAX31865 - For MISO, MOSI, CLK no choice by default it's PIN 9, 10, 11")
    ResSens = Property.Select("Sensor Type", options=[100,1000],description="Select 100 for PT100 or 1000 for PT1000")
    RefRest = Property.Number("Reference Resistor", configurable=True, description="Reference Resistor of the MAX31865 board (it's written on the resistor: 430 or 4300,....)")
    offset = Property.Number("Offset", True, 0, description="Offset which is added to the received sensor data. Positive and negative values are both allowed.")
    ignore_below = Property.Number(ifelse_celcius("Low value filter threshold (°C)", "Low value filter threshold (°F)"), True, ifelse_celcius(0,32), description="Readings below this value will be ignored")
    ignore_above = Property.Number(ifelse_celcius("High value filter threshold (°C)", "High value filter threshold (°F)"), True,ifelse_celcius(100,212), description="Readings above this value will be ignored")
    misoPin = 9
    mosiPin = 10
    clkPin = 11
    ConfigText = Property.Select("Conversion Mode & Wires", options=["[0xB2] - 3 Wires Manual","[0xD2] - 3 Wires Auto","[0xA2] - 2 or 4 Wires Manual","[0xC2] - 2 or 4 Wires Auto"], description="Choose beetween 2, 3 or 4 wire PT100 & the Conversion mode at 60 Hz beetween Manual or Continuous Auto")

		#
		# Config Register
		# ---------------
		# bit 7: Vbias -> 1 (ON), 0 (OFF)
		# bit 6: Conversion Mode -> 0 (MANUAL), 1 (AUTO) !!don't change the noch fequency 60Hz when auto
		# bit5: 1-shot ->1 (ON)
		# bit4: 3-wire select -> 1 (3 wires config), 0 (2 or 4 wires)
		# bits 3-2: fault detection cycle -> 0 (none)
		# bit 1: fault status clear -> 1 (clear any fault)
		# bit 0: 50/60 Hz filter select -> 0 (60Hz - Faster converson), 1 (50Hz)
		#
		# 0b10110010 = 0xB2     (Manual conversion, 3 wires at 60Hz)
		# 0b10100010 = 0xA2     (Manual conversion, 2 or 4 wires at 60Hz)
		# 0b11010010 = 0xD2     (Continuous auto conversion, 3 wires at 60 Hz) 
		# 0b11000010 = 0xC2     (Continuous auto conversion, 2 or 4 wires at 60 Hz) 
		#


    def init(self):

        # INIT SENSOR
        self.ConfigReg = self.ConfigText[1:5]
        self.max = max31865.max31865(int(self.csPin),int(self.misoPin), int(self.mosiPin), int(self.clkPin), int(self.ResSens), int(self.RefRest), int(self.ConfigReg,16))

#        low_filter = float(self.ignore_below)
#        high_filter = float(self.ignore_above)  

    # READ SENSOR
    def read(self):
        low_filter = float(self.ignore_below)
        high_filter = float(self.ignore_above) 
        value = self.max.readTemp()

        if value < low_filter or value > high_filter:
            return

        if self.get_config_parameter("unit", "C") == "C":
            self.data_received(round(value + self.offset_value(), 2))
        else:
            self.data_received(round(9.0 / 5.0 * value + 32 + self.offset_value(), 2))

    @cbpi.try_catch(0)
    def offset_value(self):
        return float(self.offset)
예제 #6
0
class HendiControl(ActorBase):
    power_pin = Property.Select("Power control 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], )
    onoff_pin = Property.Select("On/Off control 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])
    freq = Property.Number("PWM frequency", configurable=True)
    Pmax = Property.Number("Max Power", configurable=True, default_value=100, unit="%")

    power = 0
    pwm = None
    stopped = True

    def init(self):
        GPIO.setmode(GPIO.BCM)
        # setup pins for power control
        GPIO.setup(int(self.power_pin), GPIO.OUT)
        # setup pins for on/off control
        GPIO.setup(int(self.onoff_pin), GPIO.OUT)
        GPIO.output(int(self.onoff_pin), 0)
        HendiControl.power =  int(self.Pmax)

    def on(self, power=None):
        HendiControl.stopped = False
        if HendiControl.pwm is None:
            if HendiControl.freq is None:
                HendiControl.freq = 100
            HendiControl.pwm = GPIO.PWM(int(self.power_pin), int(self.freq))
            HendiControl.pwm.start(int(HendiControl.power))
        if(0 == HendiControl.power):
            GPIO.output(int(self.onoff_pin), 0)
        else:
            GPIO.output(int(self.onoff_pin), 1)
            HendiControl.pwm.start(1)
            HendiControl.pwm.ChangeDutyCycle(int(HendiControl.power))
            cbpi.log_action("ON, Set power {}".format(HendiControl.power))

    def set_power(self, power):
        HendiControl.power = min(int(power), int(self.Pmax))
        cbpi.log_action("Set power {}".format(HendiControl.power))
        self.pwm.ChangeDutyCycle(HendiControl.power)



    def off(self):
        cbpi.log_action("off")
        self.stopped = True
        self.pwm.ChangeDutyCycle(0)
        self.pwm.stop()
        GPIO.output(int(self.onoff_pin), 0)
예제 #7
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))
예제 #8
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)
예제 #9
0
class RelayBoard(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")

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

    def on(self, power=0):

        GPIO.output(int(self.gpio), 0)
        state = "ON"
        filename = "./logs/%s_%s.log" % ("actor_gpio", int(self.gpio))
        formatted_time = strftime("%Y-%m-%d %H:%M:%S", localtime())
        msg = str(formatted_time) + "," + str(state) + "\n"
        with open(filename, "a") as file:
            file.write(msg)

    def off(self):

        GPIO.output(int(self.gpio), 1)
        state = "OFF"
        filename = "./logs/%s_%s.log" % ("actor_gpio", int(self.gpio))
        formatted_time = strftime("%Y-%m-%d %H:%M:%S", localtime())
        msg = str(formatted_time) + "," + str(state) + "\n"
        with open(filename, "a") as file:
            file.write(msg)
예제 #10
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)
예제 #11
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)
예제 #12
0
class ONE_WIRE_SENSOR(SensorPassive):

    sensor_name = Property.Select("Sensor", getSensors())

    def init(self):

        self.t = myThread(self.sensor_name)

        def shudown():
            shudown.cb.shutdown()
        shudown.cb = self.t

        self.t.start()

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

    def read(self):
        if self.get_config_parameter("unit", "C") == "C":
            self.data_received(self.t.value)
        else:
            self.data_received(format(9.0 / 5.0 * self.t.value + 32, '.2f'))

    @classmethod
    def init_global(self):
        try:
            call(["modprobe", "w1-gpio"])
            call(["modprobe", "w1-therm"])
        except Exception as e:
            pass
예제 #13
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()
예제 #14
0
class sense_emu(SensorPassive):
    type = Property.Select("TYPE", options=["humidity", "temperature"])

    def get_unit(self):
        '''
        :return: Unit of the sensor as string. Should not be longer than 3 characters
        '''

        if self.type == "humidity":
            return "%"
        if self.type == "temperature":
            return "°C" if self.get_config_parameter("unit",
                                                     "C") == "C" else "°F"

    def read(self):

        self.api.app.logger.info("Sense HAT Emulator")
        sensor = SenseHat()
        try:
            humidity = 64 * sensor.humidity / 100
            temperature = sensor.temp
            self.api.app.logger.info(humidity)
            self.api.app.logger.info(temperature)

            if self.type == "humidity":
                self.data_received(round(humidity, 2))
            if self.type == "temperature":
                if self.get_config_parameter("unit", "C") == "C":
                    self.data_received(round(temperature, 2))
                else:
                    self.data_received(round((9.0 / 5.0 * temperature) + 32,
                                             2))
        except Exception as e:
            self.api.app.logger.error("Sense Hat Emulator error")
예제 #15
0
class GembirdUSB(ActorBase):

    socket_no = Property.Select(label="Socket No", options=[1, 2, 3, 4, 5])

    def on(self, power=100):
        try:
            print((self.socket_no))
            command = "sudo sispmctl -o " + str(self.socket_no)
            subprocess.call(command, shell=True)
        except Exception as e:
            self.api.notify(
                "Gembird Actor Error",
                "Faied to switch socket. Please check configuration",
                type="danger",
                timeout=None)
            self.api.app.logger.error("Failed to switch Socket")

    def off(self):
        try:
            command = "sudo sispmctl -f " + str(self.socket_no)
            subprocess.call(command, shell=True)
        except Exception as e:
            self.api.notify(
                "Gembird Actor Error",
                "Faied to switch socket. Please check configuration",
                type="danger",
                timeout=None)
            self.api.app.logger.error("Failed to switch Socket")
예제 #16
0
class Silvercrest433Mhz(ActorBase):

    socket = Property.Select("socket", options=["A", "B", "C", "D"])

    on_codes = {'A': '1045296', 'B': '1045300', 'C': '1045308', 'D': '772370'}

    off_codes = {'A': '280608', 'B': '230816', 'C': '772380', 'D': '1045298'}

    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 Silvercrest 433Mhz Code: %s" % (code))

    def on(self, power=100):
        self.send(self.on_codes[self.socket])
        self.api.app.logger.info(
            "SWITCHED Silvercrest 433Mhz Socket: %s - %s" %
            (self.socket, self.on_codes[self.socket]))

    def off(self):
        self.send(self.off_codes[self.socket])
        self.api.app.logger.info(
            "SWITCHED Silvercrest 433Mhz Socket: %s - %s" %
            (self.socket, self.off_codes[self.socket]))
예제 #17
0
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)
예제 #18
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)
예제 #19
0
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)
예제 #20
0
class SensorGroup(SensorPassive):

    sensordesc = "Select a sensor to be included in this group."
    sensor01 = Property.Sensor("Sensor 1", description=sensordesc)
    sensor02 = Property.Sensor("Sensor 2", description=sensordesc)
    sensor03 = Property.Sensor("Sensor 3", description=sensordesc)
    sensor04 = Property.Sensor("Sensor 4", description=sensordesc)
    sensor05 = Property.Sensor("Sensor 5", description=sensordesc)
    sensor06 = Property.Sensor("Sensor 6", description=sensordesc)
    sensor07 = Property.Sensor("Sensor 7", description=sensordesc)
    sensor08 = Property.Sensor("Sensor 8", description=sensordesc)

    value_type = Property.Select(
        "Value",
        options=["Average", "Minimum", "Maximum"],
        description="Select what data to return from the group.")

    def init(self):
        self.sensors = []

        if isinstance(self.sensor01, unicode) and self.sensor01:
            self.sensors.append(int(self.sensor01))
        if isinstance(self.sensor02, unicode) and self.sensor02:
            self.sensors.append(int(self.sensor02))
        if isinstance(self.sensor03, unicode) and self.sensor03:
            self.sensors.append(int(self.sensor03))
        if isinstance(self.sensor04, unicode) and self.sensor04:
            self.sensors.append(int(self.sensor04))
        if isinstance(self.sensor05, unicode) and self.sensor05:
            self.sensors.append(int(self.sensor05))
        if isinstance(self.sensor06, unicode) and self.sensor06:
            self.sensors.append(int(self.sensor06))
        if isinstance(self.sensor07, unicode) and self.sensor07:
            self.sensors.append(int(self.sensor07))
        if isinstance(self.sensor08, unicode) and self.sensor08:
            self.sensors.append(int(self.sensor08))

    def stop(self):
        pass

    def read(self):
        values = [
            float(cbpi.cache.get("sensors")[sensor].instance.last_value)
            for sensor in self.sensors
        ]
        if self.value_type == "Minimum":
            temp = min(values)
        elif self.value_type == "Maximum":
            temp = max(values)
        else:
            temp = sum(values) / len(values)
        self.data_received(round(temp, 2))

    def get_unit(self):
        if len(self.sensors) > 0:
            return cbpi.cache.get("sensors")[
                self.sensors[0]].instance.get_unit()
        else:
            return super(SensorBase, self).get_unit()
예제 #21
0
class MCP23017_TestActor(ActorBase):
    a_busad = Property.Select("Bus Address", options=["0x20","0x21","0x22","0x23","0x24","0x25","0x26","0x27"], description="Bus address setting of MCP based on A0 A1 A2.")
    b_chan = Property.Text("Channel", configurable=True, default_value="100", description="MCP Output channel 0-128")
    #c_pud = Property.Select("Pull up", options=["Off","Up"], default_value = "Off", description="Pull Up or down resisitor")
    f_inv = Property.Select("Invert Output", options=["No","Yes"], description="Invert the output so on means output at 0V")

    #initiasliser called when an actor is created or changed
    def init(self):
        try:
            self.busad = self.a_busad
            self.chan = int(self.b_chan) + 500
            if self.f_inv == "Yes":
                self.on_pol = 0
                self.off_pol = 1
            else:
                self.on_pol = 1
                self.off_pol = 0
         
            #self.check_mcp()
                 
            self.is_on = False
        
            mcp.pinMode(chan,1)
            mcp.digitalWrite(self.chan,self.off_pol)
         
        except Exception as e:
            traceback.print_exc()
            raise

    def on(self, power=100):
        self.is_on = True
        if power != None:
            self.power = power
        mcp.digitalWrite(self.chan,self.on_pol)
        
    def off(self):
        self.is_on = False
        self.mcp.digitalWrite(self.chan,self.off_pol)
        
    def set_power(self, power):
        self.power = power 
        

    @cbpi.action("TODO: Reitialise MCP system")
    def recon(self):
        pass       
예제 #22
0
class BM_ManualStep(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.")
    s = False
    #-------------------------------------------------------------------------------

    @cbpi.action("Start Timer Now")
    def init(self):
        if self.notifyType not in ["success", "info", "warning", "danger"]:
            self.notifyType = "info"

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

        # Check if Target Temp is reached
        if self.s is False:
            self.s = True
            self.notify(self.heading,
                        self.message,
                        type=self.notifyType,
                        timeout=None)
            if self.proceed == "Continue":
                #Python 2
                try:
                    self.next()
                #Python3
                except:
                    next(self)
                pass
예제 #23
0
class SerialSensors(SensorPassive):
    sensor_name = Property.Select(
        "arduino's /dev/ttyACM?",
        getTTYACM(),
        description=
        "Possible devices where an arduino is connected; if empty, no arduino connected."
    )
    sensor_baud = Property.Select(
        "arduino's baud rate",
        getBaudRate(),
        description="Select the baud rate defined in your arduino program.")
    sensor_actv = Property.Select(
        "System Temperature",
        getYesNo(),
        description="Select to add CBP's system temperature or not.")
    sensor_strt = Property.Select(
        "Startup Message",
        getYesNo(),
        description=
        "Select to send the start up message: \"CBP3SerialSensors\"; to let arduino recognizing a starting point for data processing."
    )

    def init(self):

        self.t = myThread(self.id, self.sensor_name, self.sensor_baud,
                          self.sensor_actv, self.sensor_strt)

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

        shutdown.cb = self.t
        self.t.start()

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

    def read(self):
        if self.get_config_parameter("unit", "C") == "C":
            self.data_received(round(self.t.value, 2))
        else:
            self.data_received(round(9.0 / 5.0 * self.t.value + 32, 2))
class PT100(SensorPassive):
    # CONFIG PARAMETER & PROPERTIES
    csPin  = Property.Select("csPin", 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 Pin connected to the CS Pin of the MAX31865")
    RefRest = Property.Number("Reference Resistor", configurable=True, description="Reference Resistor of the MAX31865 board (it's written on the resistor: 400 or 430 or 431,....)")
    misoPin = 9
    mosiPin = 10
    clkPin = 11
    ConfigText = Property.Select("Conversion Mode & Wires", options=["[0xB2] Manual conversion, 3 wire @60Hz","[0xA2] Manual conversion, 2/4 wire @60Hz","[0xD2] Continuous (auto) conversion, 3 wire @60Hz","[0xC2] Continuous auto conversion, 2/4 wires @60Hz"], description="Select sensor conversion type")

		#
		# Config Register
		# ---------------
		# bit 7: Vbias -> 1 (ON), 0 (OFF)
		# bit 6: Conversion Mode -> 0 (MANUAL), 1 (AUTO) !!don't change the noch fequency 60Hz when auto
		# bit5: 1-shot ->1 (ON)
		# bit4: 3-wire select -> 1 (3 wires config), 0 (2 or 4 wires)
		# bits 3-2: fault detection cycle -> 0 (none)
		# bit 1: fault status clear -> 1 (clear any fault)
		# bit 0: 50/60 Hz filter select -> 0 (60Hz - Faster converson), 1 (50Hz)
		#
		# 0b10110010 = 0xB2     (Manual conversion, 3 wires at 60Hz)
		# 0b10100010 = 0xA2     (Manual conversion, 2 or 4 wires at 60Hz)
		# 0b11010010 = 0xD2     (Continuous auto conversion, 3 wires at 60 Hz) 
		# 0b11000010 = 0xC2     (Continuous auto conversion, 2 or 4 wires at 60 Hz) 
		#

  

    def init(self):

        # INIT SENSOR
	self.ConfigReg = self.ConfigText[1:5]
        print "Initialise MAX31865 at address"
        print hex(int(self.ConfigReg,16))
        self.max = max31865.max31865(int(self.csPin),int(self.misoPin), int(self.mosiPin), int(self.clkPin), int(self.RefRest), int(self.ConfigReg,16))

    def read(self):

        # READ SENSOR
        if self.get_config_parameter("unit", "C") == "C":
            self.data_received(round(self.max.readTemp(), 2))
        else:
            self.data_received(round(9.0 / 5.0 * self.max.readTemp() + 32, 2))
예제 #25
0
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)
예제 #26
0
class TPLinkPlug(ActorBase):
    plug_name = Property.Select("Plug", [1,2,3,4,5], description="TPLink Plug")
    plug_time = Property.Number("Publish stats every minute", configurable = True, unit="s", default_value=0, description="Time in minutes to publish voltage stats, 0 is off")
    plug_ip = Property.Text("TP-Link Plug Local IP", configurable = True, default_value="", description="Local IP address is used instead of Cloud service, leave blank to use cloud service.")
    c_off = 0
    d_on = 1
    cnt_timer = 0

    def on(self, power=100):
        try:
            send(command = self.d_on, plug = int(self.plug_name), ip = self.plug_ip)
        except:
            cbpi.notify("TPLinkPlug Error", "Device not correctly setup, go to Hardware settings and correct.", type="danger", timeout=10000) 

    def off(self):
        try:
            send(command = self.c_off, plug = int(self.plug_name), ip=self.plug_ip)
        except:
            cbpi.notify("TPLinkPlug Error", "Device not correctly setup, go to Hardware settings and correct.", type="danger", timeout=10000) 

    def set_power(self, power):
        pass

    def url(self):
        try:
            no = int(self.plug_name)-1
            url = TPplugs[no]["appServerUrl"]
        except:
            url = ""
        return url

    def device(self):
        try:
            no = int(self.plug_name)-1
            device = TPplugs[no]["deviceId"]
        except:
            device = ""
        return device

    def time(self):
        return self.plug_time

    def showstats(self):
        plug_time = int(self.plug_time)
        if plug_time == 0:
            return False
        self.cnt_timer += 1
        if (self.cnt_timer >= plug_time):
            self.cnt_timer = 0
            return True
        return False

    def ip(self):
        return self.plug_ip
예제 #27
0
class EnergenieSocket(ActorBase):
    socket = Property.Select("socket", options=[0,1,2,3,4])

    @classmethod
    def init_global(cls):
        pass

    def on(self, power=100):
        switch(int(self.socket), True, False)

    def off(self):
        switch(int(self.socket), False, True)
예제 #28
0
class GPIODelay(ActorBase):

    gpio = Property.Select("GPIO", options=range(28),
                           description="GPIO pin number")
    delay = Property.Number(
        "Minimum delay",
        configurable=True,
        default_value=300,
        unit="s",
        description="Minimum wait time before switching on (s)",
    )

    switched_off_at = None

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

    def on(self, power=0):
        gpio = int(self.gpio)
        cbpi.app.logger.info("Request to switch on GPIO %d" % gpio)
        if GPIO.input(gpio) == 1:
            cbpi.app.logger.info("GPIO %d already on" % gpio)
            return

        if self.switched_off_at is not None:
            since_last_off = time.time() - self.switched_off_at
            cbpi.app.logger.info(
                "GPIO %d last switched off %d seconds ago" %
                (gpio, since_last_off)
            )

            if since_last_off < float(self.delay):
                cbpi.app.logger.info(
                    "Not enough time since last switched off GPIO %d" % gpio
                )
                return

        cbpi.app.logger.info("Switching on GPIO %d" % gpio)
        GPIO.output(gpio, 1)

    def off(self):
        gpio = int(self.gpio)
        cbpi.app.logger.info("Request to switch off GPIO %d" % gpio)
        if GPIO.input(gpio) == 0:
            cbpi.app.logger.info("GPIO already off %d" % gpio)
            return

        cbpi.app.logger.info("Switching off GPIO %d" % gpio)
        self.switched_off_at = time.time()
        GPIO.output(gpio, 0)
예제 #29
0
class Mod_PWM_Logic(KettleController):

    TempDiff = Property.Number("Degrees from target to start Reduction", True,
                               2)
    PowDiff = Property.Number("Percent of power deduction", True, 50)
    RampUp = Property.Number("Percent of power increase per 1/10 sec", True, 2)
    Checking = Property.Select(
        "This logic only works with heater running Mod_PWM", options=["OK"])

    def stop(self):
        self.actor_power(int(Mod_PWM.power))
        super(KettleController, self).stop()
        self.heater_off()

    def run(self):
        x = Mod_PWM()
        top = x.power
        ramp = 0

        if self.TempDiff is None:
            self.TempDiff = 2
        if self.PowDiff is None:
            self.PowDiff = 50
        if self.RampUp is None:
            self.RampUp = 2

        while self.is_running():
            if self.get_temp() >= self.get_target_temp():
                ramp = 0
                self.heater_off()
            elif self.get_temp() < self.get_target_temp() - int(self.TempDiff):
                self.heater_on(0)
                while int(ramp) < int(top):
                    self.actor_power(int(ramp))
                    ramp = ramp + int(self.RampUp)
                    self.sleep(.1)
                self.actor_power(int(top))
            else:
                self.heater_on(0)
                while int(ramp) < int(top - (top * int(self.PowDiff) / 100)):
                    self.actor_power(int(ramp))
                    ramp = ramp + int(self.RampUp)
                    self.sleep(.1)
                self.actor_power(int(top - (top * int(self.PowDiff) / 100)))
                ramp = x.power
                Mod_PWM.power = top
            self.sleep(1)
            Ntop = x.power
            if int(Ntop) <> int(top):
                top = Ntop
            self.heater_off()
예제 #30
0
class GPIOSimple(ActorBase):
    """
    Simple GPIO Actor
    """
    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")
    mode = Property.Select(
        "Mode",
        options=["regular", "inverse"],
        description=
        "regular means 'ON' is GPIO 'High' and inverse means 'ON' is GPIO 'Low'"
    )

    def init(self):
        GPIO.setup(int(self.gpio), GPIO.OUT)
        if self.mode == "regular":
            GPIO.output(int(self.gpio), 0)
        else:
            GPIO.output(int(self.gpio), 1)

    def on(self, power=0):
        print(("GPIO ON %s" % str(self.gpio)))
        if self.mode == "regular":
            GPIO.output(int(self.gpio), 1)
        else:
            GPIO.output(int(self.gpio), 0)

    def off(self):
        print("GPIO OFF")
        if self.mode == "regular":
            GPIO.output(int(self.gpio), 0)
        else:
            GPIO.output(int(self.gpio), 1)