def configure(self, config): from kiota.Configurator import Configurator Configurator.apply(self, config["gateway"]) # if self.id is None: # try: # import ubinascii # except ImportError: # import binascii as ubinascii # try: # import uhashlib # except ImportError: # import hashlib as uhashlib # self.id = ubinascii.hexlify(uhashlib.sha256(machine.unique_id()).digest()).decode() self.topic = "/kiota/{}".format(self.id) self.last_ping = 0 self.client = MQTTClient(self.topic, self.mqtt_server.server, self.mqtt_server.port, self.mqtt_server.username, self.mqtt_server.password, self.mqtt_server.keep_alive) self.client.set_callback(self.do_message_callback) self.exit_topic = "{}/exit".format(self.topic) self.devices = [] for d in config["devices"]: try: class_name = d["type"] module_name = class_name try: module_name = d["module"] except (KeyError): pass package_name = "kiota" try: package_name = d["package"] except (KeyError): pass package = __import__("{}.{}".format(package_name, module_name), class_name) # print(package) module = getattr(package, module_name) # print(module) klass = getattr(module, class_name) # print(klass) device = klass(d) self.devices.append(device) except ImportError as e: Util.log(self, "error: '{}' config: '{}'".format(e, d))
def write(self, payload): start_value = self.start_value pattern = self.pattern if payload is not None: p = None try: import ujson as json p = json.loads(payload) except (OSError, ValueError): import kiota.Util as Util Util.log(self, "Can parse payload: '{}'".format(payload)) else: try: start_value = p["start_value"] except (KeyError): pass try: pattern = p["pattern"] except (KeyError): pass return { "transmission": bool( TransmitterDevice.transmit(self.pin, self.retries, start_value, pattern)) }
def configure(self, config): super().configure(config) import ssd1306 self.display = None try: if self.display_type == "SSD1306_I2C": i2c = machine.I2C(self.i2c.bus, scl=machine.Pin(self.i2c.gpio_scl), sda=machine.Pin(self.i2c.gpio_sda) # freq=self.i2c.max_freq ) # addrs = i2c.scan() # print("Scanning I2C devices:", [hex(x) for x in addrs]) # if self.sla not in addrs: # import ubinascii # print("ICT device not detected on address", ubinascii.hexlify(device_addr)) self.display = ssd1306.SSD1306_I2C(self.width, self.height, i2c) self.display.poweron() elif self.display_type == "SSD1306_SPI": spi = None if self.bitbanging_mode: spi = machine.SPI(self.spi.id, baudrate=self.spi.baudrate, polarity=self.spi.polarity, phase=self.spi.phase, sck=machine.Pin(self.spi.gpio_sck), mosi=machine.Pin(self.spi.gpio_mosi), miso=machine.Pin(self.spi.gpio_miso)) else: spi = machine.SPI(self.spi.id, baudrate=self.spi.baudrate, polarity=self.spi.polarity, phase=self.spi.phase) self.display = ssd1306.SSD1306_SPI( self.width, self.height, spi, machine.Pin(self.spi.gpio_dc), machine.Pin(self.spi.gpio_res), machine.Pin(self.spi.gpio_cs)) except OSError as e: import kiota.Util as Util Util.log(self, "failed to configure display", e)
def connect(self): self.client.connect() Util.log( self, "connect to MQTT server on {}:{} as {}".format( self.mqtt_server.server, self.mqtt_server.port, self.mqtt_server.username)) self.subscribe(self.exit_topic) for device in self.devices: device.connect(self)
def write(self, payload): ok = False try: ok = bool(self.update_display_function(self.display, payload)) except Exception as e: import kiota.Util as Util Util.log(self, "failed to update display", e) return {"display": ok}
def do_message_callback(self, b_topic, payload): topic = b_topic.decode() #convert to string import gc, micropython gc.collect() gc.threshold(gc.mem_free() // 4 + gc.mem_alloc()) micropython.mem_info() Util.log(self, "received: topic '{}' payload: '{}'".format(topic, payload)) if topic == self.exit_topic: raise ExitGatewayException() for device in self.devices: if device.do_message(topic, payload): # Util.log(self,"consumed: topic '{}' payload: '{}' by device {}".format(topic,payload,json.dumps(device.config))) # break return
def start(self): while True: try: self.connect() while True: #time.sleep(0.01) # attempt to reduce number of OSError: [Errno 104] ECONNRESET self.client.check_msg() #time.sleep(0.01) # attempt to reduce number of OSError: [Errno 104] ECONNRESET self.push() time.sleep(0.01) except OSError as e: Util.log(self, "failed to connect, retrying....", e) time.sleep(self.mqtt_server.wait_to_reconnect) except IndexError as e: Util.log(self, "failed to connect, retrying....", e) time.sleep(self.mqtt_server.wait_to_reconnect) self.client.disconnect()
def read(self): d = None if self.dht_type == 22: d = dht.DHT22(machine.Pin(self.gpio)) else: d = dht.DHT11(machine.Pin(self.gpio)) try: d.measure() payload = { 'temperature': str(d.temperature()), "humidity": str(d.humidity()) } return payload except Exception as e: import kiota.Util as Util Util.log( self, "DHT type: {}, failed to measure pin: '{}'".format( self.dht_type, self.gpio)) import sys sys.print_exception(e)
def update_display(display, payload): def calculate_width(font, text): w = 0 for c in text: glyph, char_height, char_width = font.get_ch(c) w += char_width return w try: command = {} if payload is None: # An example command for testing command = { "heating_state": True, "msg": "auto", "inside_temp": 23.456, "outside_temp": -9.876 } else: try: import ujson as json command = json.loads(payload) except (OSError, ValueError): import kiota.Util as Util Util.log(update_display, "Can't parse payload: '{}'".format(payload)) display.fill(0) ink = 1 heating_state = command["heating_state"] if heating_state: ink = 0 display.fill_rect(0, 0, 128, 14, 1) if command["msg"] is not None: display.text(str(command["msg"]), 0, 1, ink) if command["heating_state"]: display.text("ON", 104, 1, ink) else: display.text("OFF", 104, 1, ink) import KameronRegularNumbers25 as font from Writer import Writer writer = Writer(display, font) writer.set_clip(True, True) inside_temp = "--" try: inside_temp = str(int(round(float(command["inside_temp"])))) except: pass writer.set_textpos(23, int((64 - calculate_width(font, inside_temp)) / 2)) display.fill_rect(0, 15, 64, 41, 0) writer.printstring(inside_temp) outside_temp = "--" try: outside_temp = str(int(round(float(command["outside_temp"])))) except: pass writer.set_textpos( 23, 64 + int((64 - calculate_width(font, outside_temp)) / 2)) display.fill_rect(64, 15, 64, 41, 0) writer.printstring(outside_temp) display.text("inside", 0, 56) display.text("outside", 72, 56) display.show() except Exception as e: display.text("ERROR", 0, 0) display.show() import sys sys.print_exception(e) return True
def publish(self, topic, payload): Util.log(self, "sent: topic '{}' payload: '{}'".format(topic, payload)) # self.client.publish(topic.encode('utf-8'), payload) self.client.publish(topic.encode(), payload)