from mqtt import MqttMessage from workers.base import BaseWorker import logger import traceback import time REQUIREMENTS = ['pyserial'] _LOGGER = logger.get(__name__) class MsgwWorker(BaseWorker): LOGNAME = "mysensors-nrf24" def _setup(self): _LOGGER.debug("Setting up " + self.LOGNAME) import serial self.ser = serial.Serial(self.port, self.baudrate, timeout=10) if not hasattr(self, 'encoding'): self.encoding = 'utf-8' if not hasattr(self, 'timezone'): self.timezone = 1 def config(self): return [] def run(self, mqtt): _LOGGER.debug("Starting " + self.LOGNAME + " at: %s" % self.ser.name) while True: try: line = self.ser.readline() if not line: continue _LOGGER.debug(self.LOGNAME + ": Serial.read: %s" % line) splited_line = line.decode(self.encoding).strip().split(';', 5) if len(splited_line) < 5: raise Exception("protocol error: too few values") # node-id ; child-sensor-id ; command ; ack ; type ; payload #nodeid = int(splited_line[0]) #childid = int(splited_line[1]) command = int(splited_line[2]) #ack = int(splited_line[3]) ctype = int(splited_line[4]) payload = splited_line[5] if len(splited_line) > 5 else '' topic = self.format_topic(*splited_line[0:5]) # Internal if command == 3: # I_TIME if ctype == 1: tm = time.localtime() offset = self.timezone if tm.tm_isdst == 1: offset += 1 timevalue = str(offset*60*60+int(time.mktime(tm))) resp = str.encode(splited_line[0]+";"+splited_line[1]+";3;0;1;"+timevalue+"\n") self.ser.write(resp) _LOGGER.error(self.LOGNAME + ": time request received, sending back %s" % resp) continue # I_CONFIG elif ctype == 6: resp = str.encode(splited_line[0]+";"+splited_line[1]+";3;0;6;M\n") self.ser.write(resp) _LOGGER.error(self.LOGNAME + ": config request received, sending back %s" % resp) continue mqtt.publish([MqttMessage(topic=topic, payload=payload)]) except Exception as e: _LOGGER.error(self.LOGNAME + ": Caught exception in MsgwWorker.run(): {}".format(e)) traceback.print_exc(); except serial.serialutil.SerialException as e: _LOGGER.error(self.LOGNAME + ": Caught exception in MsgwWorker.run(): {}".format(e)) traceback.print_exc(); self.ser = serial.Serial(self.port, self.baudrate, timeout=10) def on_command(self, topic, value): _LOGGER.debug(self.LOGNAME + ": on_command({}, {})".format(topic, value)) try: splited_topic = topic.split('/') line = str.encode(splited_topic[-5]+";"+splited_topic[-4]+";"+splited_topic[-3]+";"+splited_topic[-2]+";"+splited_topic[-1]+";")+value+b'\n' _LOGGER.debug(self.LOGNAME + ": Serial.write: %s" % line) self.ser.write(line) except Exception as e: _LOGGER.error(self.LOGNAME + ": Caught exception in MsgwWorker.on_command(): {}".format(e)) traceback.print_exc() return []