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)
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)
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)
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()
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 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))
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)
class HTTPActor_Compressor(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_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(HTTPActor_Compressor, self).init() cbpi.HTTPActor_compressors += [self] 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): if datetime.utcnow() >= self.compressor_wait: self.compressor_on = True self.send(self.b_on) 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.d_delay)) self.delayed = False self.send(self.c_off)
class IFTTTWebhookProActor(ActorBase): ifttt_url = "https://maker.ifttt.com/trigger/{}/with/key/{}?value1={}" api_key = Property.Text( "1. Maker Webhook Key", configurable=True, default_value="", description="The key to be able to use this webhook") hook_name = Property.Text("2. Webhook Name", configurable=True, default_value="", description="The webhook name") on_payload = Property.Text( "3. On Payload", configurable=True, default_value="ON", description="The value to send for the on command") zoff_payload = Property.Text( "4. Off Payload", configurable=True, default_value="OFF", description="The value to send for the off command") power = 100 def send(self, value): print(self.api_key) if self.api_key is None or self.api_key == '': cbpi.notify("IFTTT Key Error", "The IFTTT maker key must be set", type="warning", timeout=None) url = self.ifttt_url.format(self.hook_name, self.api_key, value) try: response = requests.get(url) response.raise_for_status() except requests.exceptions.RequestException as err: cbpi.notify( "IFTTT Send Error", "There was an error sending the request to IFTTT. Please check your key", type="danger", timeout=20000) self.api.app.logger.error( "FAILED to switch IFTTT actor: {}".format(self.hook_name)) def on(self, power=None): self.send(self.on_payload) if power is not None: self.set_power(power) def off(self): self.send(self.zoff_payload) def set_power(self, power): power = 100
class PauseStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method. The class name must be unique in the system ''' # Properties timer = Property.Number("Timer in Minutes", configurable=True) titleOfInitialMessage = Property.Text( "Title of instruction message", configurable=True, default_value="Pause instruction", description="Title to show above the instruction messge") initialMessage = Property.Text( "Instruction message", configurable=True, description="Message to show on begining of the Step.") def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' if not self.initialMessage == u'': self.initialMessage = self.initialMessage.encode("utf-8") self.titleOfInitialMessage = self.titleOfInitialMessage.encode( "utf-8") self.notify(self.titleOfInitialMessage, self.initialMessage, timeout=int(self.timer) * 1000 * 60) @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: ''' self.stop_timer() self.start_timer(int(self.timer) * 60) def reset(self): self.stop_timer() # def finish(self): # pass def execute(self): 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("End of Pause!", "Starting the next step", timeout=10000) self.next()
class MQTTActor(ActorBase): topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC") 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") def on(self, power=100): self.api.cache["mqtt"].client.publish(self.topic, payload=self.on_payload, qos=2, retain=True) def off(self): self.api.cache["mqtt"].client.publish(self.topic, payload=self.off_payload, qos=2, retain=True)
class MQTT_SENSOR(SensorActive): a_topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC") b_payload = Property.Text("Payload Dictioanry", configurable=True, default_value="", description="Where to find msg in patload, leave blank for raw payload") c_unit = Property.Text("Unit", configurable=True, default_value="", description="Units to display") offset = Property.Number("Offset", True, 0, description="Offset which is added to the received sensor data. Positive and negative values are both allowed.") last_value = None 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: print "payload " + msg.payload json_data = json.loads(msg.payload) #print json_data val = json_data if self.payload_text is not None: for key in self.payload_text: val = val.get(key, None) #print val 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): return {"value": self.last_value+self.offset, "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)
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)
class MQTTActor(ActorBase): topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT Topic") pPower = 100 def init(self): super(MQTTActor, self).init() print "Initially setting MQTT Actor to off.." self.off() def on(self, power): if power is not None: if power != self.pPower: power = min(100, power) power = max(0, power) self.pPower = int(power) self.api.cache["mqtt"].client.publish(self.topic, payload=json.dumps( {"on": True, "power": self.pPower}), qos=2, retain=True) def off(self): self.api.cache["mqtt"].client.publish( self.topic, payload=json.dumps({"on": False}), qos=2, retain=True) def set_power(self, power): self.on(power)
class MQTTActor(ActorBase): topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC") pPower = 100 def on(self, power): if power is not None: if power != self.pPower: power = min(100, power) power = max(0, power) self.pPower = int(power) self.api.cache["mqtt"].client.publish(self.topic, payload=json.dumps({ "state": "on", "power": self.pPower }), qos=2, retain=True) def off(self): self.api.cache["mqtt"].client.publish(self.topic, payload=json.dumps( {"state": "off"}), qos=2, retain=True) def set_power(self, power): self.on(power)
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)
class TasmotaSocket(ActorBase): host = Property.Text("IP or DNS Name", configurable=True, default_value="10.0.2.153") # Command so swtich wifi socket on onCommand = "cm?cmnd=Power%20On" # Command so swtich wifi socket off offCommand = "cm?cmnd=Power%20Off" def send(self, command): try: h = httplib2.Http() ## Sending http command "" content = h.request("http://%s/%s" % (self.host, command), "GET")[1] except Exception as e: self.api.app.logger.error( "FAILED to switch Tasmota socket %s Command: %s" % (self.host, command)) def on(self, power=100): self.send(self.onCommand) def off(self): self.send(self.offCommand)
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)
class SampleActor(ActorBase): #custom property prop1 = Property.Text("Property1", True, "1") def on(self, power=0): ''' Code to switch on the actor :param power: int value between 0 - 100 :return: ''' print "SWITCH ON %s" % (self.prop1) def off(self): ''' Code to switch off the actor :return: ''' print "SWITCH OFF" def set_power(self, power): ''' Optional: Set the power of your actor :param power: int value between 0 - 100 :return: ''' pass
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()
class PT100(SensorPassive): sensor_name = Property.Text("SensorPT100") 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(round(self.t.value, 2)) else: self.data_received(round(9.0 / 5.0 * self.t.value + 32, 2)) @classmethod def init_global(cls): '''
class ESPEasyMQTT(ActorBase): """ ESPEasy MQTT Actor """ topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC") def on(self, # pylint: disable=invalid-name power=100): # pylint: disable=unused-argument """ turn actor on """ self.api.cache["mqtt"].client.publish(self.topic, payload=1, qos=2, retain=True) def off(self): """ turn actor off """ self.api.cache["mqtt"].client.publish(self.topic, payload=0, qos=2, retain=True)
class BroadlinkActor(ActorBase): # custom property ip = Property.Text("IP", True, None) def state(self): """ Retrive device state :return: """ device = get_device(self.ip) return device.check_power() def on(self, power=0): """ Code to switch on the actor :param power: int value between 0 - 100 :return: """ device = get_device(self.ip) device.set_power(True) def off(self): """ Code to switch off the actor :return: """ device = get_device(self.ip) device.set_power(False)
class ESPEasyMQTT(ActorBase): topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC") def on(self, power=100): self.api.cache["mqtt"].client.publish(self.topic, payload=1, qos=2, retain=True) def off(self): self.api.cache["mqtt"].client.publish(self.topic, payload=0, qos=2, retain=True)
class MQTTActor(ActorBase): topic = Property.Text("Topic", configurable=True, default_value="", description="MQTT TOPIC") def on(self, power=100): self.api.cache["mqtt"].client.publish(self.topic, payload=json.dumps({"state": "on"}), qos=2, retain=True) def off(self): self.api.cache["mqtt"].client.publish(self.topic, payload=json.dumps({"state": "off"}), qos=2, retain=True)
class PlaatoSensor(SensorActive): pins = [] for key in PINS.keys(): pins.append(key) api_key = Property.Text("Api Key", configurable=True) pin = Property.Select( "Pin", options=pins, description="Select which metric you want to listen for") refresh_time = Property.Text("Refresh Time", default_value="5", configurable=True) def get_unit(self): if self.pin == "Temperature": return self.get("v108") elif self.pin == "Volume": return self.get("v109") elif self.pin == "Bubbles per minute": return "bpm" elif self.pin == "ABV": return "%" elif self.pin == "Percent of beer left": return "%" else: return "" def execute(self): while self.is_running(): pin_value = PINS[self.pin] refresh = float(self.refresh_time) response = self.get(pin_value) rounded_response = str(round(float(response), 2)) self.data_received(rounded_response) self.api.socketio.sleep(refresh) def get(self, pin): url = "{0}/{1}/get/{2}".format(plaato_base_url, self.api_key, pin) try: response = urllib2.urlopen(url) except urllib2.HTTPError, error: err = error.read() print err else:
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
class SampleActor(ActorBase): #custom property prop1 = Property.Text("Property1", True, "1") def on(self, power=0): print("SWITCH ON %s" % (self.prop1)) def off(self, power=0): print("SWITCH OFF")
class WaitOnTimeStep(StepBase): ''' Just put the decorator @cbpi.step on top of a method ''' # Properties user_start_time = Property.Text("Start Time", configurable=True, default_value="00:00", description="Time at which this step completes in 24 hour format") target_start_time = datetime.datetime.now() def init(self): ''' Initialize Step. This method is called once at the beginning of the step :return: ''' # get the current time curr_time = datetime.datetime.now() # import time from user input in to datetime object self.target_start_time = datetime.datetime.strptime(self.user_start_time, "%H:%M") # replace the hour and minute with the user input self.target_start_time = self.target_start_time.replace(year=curr_time.year) self.target_start_time = self.target_start_time.replace(month=curr_time.month) self.target_start_time = self.target_start_time.replace(day=curr_time.day) # if target is in the past, add a day if (curr_time > self.target_start_time): self.target_start_time += datetime.timedelta(days=1) start_msg = "Configured start time & date is : {0:%H}:{0:%M} {0:%B} {0:%d}, {0:%Y}".format(self.target_start_time) self.notify("Setting start time!", start_msg, timeout=None) 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: ''' def reset(self): pass def finish(self): pass def execute(self): ''' This method is execute in an interval :return: ''' curr_time = datetime.datetime.now() if (curr_time > self.target_start_time): self.notify("Time to start!", "Starting the next step", timeout=None) self.next()
class UbidotsTempSensor(SensorActive): temp = Property.Number("Temperature", configurable=True, default_value=5) API_KEY = Property.Text('API KEY', configurable=True, description='Enter your Ubidots API KEY') sensorType = Property.Select( "Data Type", options=["Temperature", "Gravity", "Battery"], description="Select which type of data to register for this sensor") UNIT_KEY = Property.Text('UNIT KEY', configurable=True, description='Enter your Variable KEY') 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): ''' Stop the sensor. Is called when the sensor config is updated or the sensor is deleted :return: ''' pass def execute(self): ''' Active sensor has to handle its own loop :return: ''' while self.is_running(): self.data_received( ubidots_get_value(api_key=self.API_KEY, variable_key=self.UNIT_KEY)) self.sleep(30)