示例#1
0
class MQTTDevice:
    def __init__(self,
                 topic_online,
                 true_message="true",
                 false_message="false"):
        self.true_message = true_message
        self.false_message = false_message
        self.client = MQTTClient(MQTT_CLIENT_ID_RANDOM,
                                 MQTT_BROKER_ADDRESS,
                                 port=MQTT_PORT,
                                 keepalive=KEEP_ALIVE_TIME_SEC)
        self.next_scheduled_ping_time = 0
        self._client_setup(topic_online)

    def _client_setup(self, topic_online):
        self.client.set_last_will(topic_online, self.false_message)
        self.client.connect()
        self.client.publish(topic_online, self.true_message)
        self.setup_subscriptions()

    # override this method in subclass
    # set callback and subscriptions
    def setup_subscriptions(self):
        pass

    def _ping(self):
        if (self.next_scheduled_ping_time < utime.time()):
            self.client.ping()
            self.next_scheduled_ping_time = utime.time() + PING_EVERY_SEC

    #run method has to be called every execution cycle
    def run(self):
        self._ping()
        self.client.check_msg()
class Device(object):
    def __init__(self, device_token):
        self.__device_token = bytes(device_token, 'utf-8')
        self.__variables = None
        self.__diag_variables = None
        self.__mqtt = None
        self.__bindings = dict()
        self.next_ping_time = time()

    def __publish(self, topic, payload=None):
        if payload is None:
            return
        msg = json.dumps({'payload': payload})
        self.__mqtt.publish(C4R_TOPIC_FORMAT %
                            (self.__device_token, topic), msg, qos=1)
        print(topic, "<--", msg)
        self.mqtt_ping_reset()

    def __on_message(self, topic, msg):
        print(topic.decode().rsplit('/')[-1], "-->", msg.decode())
        data = json.loads(msg)
        for var_name, callback in self.__bindings.items():
            if var_name in data.keys():
                ret = callback(data[var_name])
                self.__variables[var_name]['value'] = ret
                self.__publish('data', {var_name: ret})

    def connect(self):
        self.__mqtt = MQTTClient(client_id=self.__device_token,
                                 server=C4R_BROKER_HOST,
                                 port=C4R_BROKER_PORT)

        self.__mqtt.set_callback(self.__on_message)
        try:
            self.__mqtt.connect()
            self.__mqtt.subscribe(C4R_TOPIC_FORMAT %
                                  (self.__device_token, 'commands'), qos=1)
        except Exception as e:
            print("[Exception] %s: %s" % (type(e).__name__, e))
            return False
        self.mqtt_ping_reset()
        return True

    def ping(self):
        self.__mqtt.ping()
        self.mqtt_ping_reset()

    def mqtt_ping_reset(self):
        self.next_ping_time = time() + PING_INTERVAL
        print("Next MQTT ping at", self.next_ping_time)

    def declare(self, variables):
        self.__variables = variables

    def declare_diag(self, diag_variables):
        self.__diag_variables = diag_variables

    def publish_config(self):
        cfg = []
        for var_name, var_config in self.__variables.items():
            cfg.append({'name': var_name, 'type': var_config['type']})
            self.__bindings[var_name] = var_config['bind']
        self.__publish('config', cfg)

    def publish_diag(self):
        self.__publish('diagnostics', self.__diag_variables)

    def publish_data(self):
        for var_name, callback in self.__bindings.items():
            self.__variables[var_name]['value'] = \
                                callback(self.__variables[var_name]['value'])

        cfg = {var_name: var_config['value']
               for var_name, var_config in self.__variables.items()}
        self.__publish('data', cfg)

    def check_commands(self):
        """Call me at least once per 55s"""
        self.__mqtt.check_msg()
        if time() >= self.next_ping_time:
            print("MQTT ping at", time())
            self.ping()
示例#3
0
client.publish(topic=LOG_TOPIC, msg=id + b' is up')

last_message = time.time()

while True:
    client.check_msg()

    if button_changed == True:
        button_changed = False

        if button() == 0:
            msg = "ON"
        else:
            msg = "OFF"

        last_message = time.time()

        # Note: The retain flag is not supported by Adafruit IO!
        # https://io.adafruit.com/blog/#mqtt-get-and-the-case-of-the-missing-retain-flag
        client.publish(topic=LED_STATE_TOPIC,
                       msg=msg.encode(),
                       retain=True,
                       qos=MQTT_QoS.AT_LEASE_ONCE)

    time.sleep(.1)

    if time.time() > last_message + keepalive / 2:
        last_message = time.time()
        client.ping()
示例#4
0
                    debug("slave: ampsMax=%2.2f, ampsActual=%2.2f" % (ourSlave['ampsMax'], ourSlave['ampsActual']), 1)
                else:
                    rgbled(0xFF, 0x00, 0x00)
                    debug("recv: unknown message type %d:%d" % (slaveMsg[0], slaveMsg[1]), 1)
            except InvalidMessage as e:
                rgbled(0xFF, 0x00, 0x00)
                debug("slave message failed checks: %s" % e, 0)
            except ValueError as e:
                rgbled(0xFF, 0x00, 0x00)
                debug("recv: garbled message: %s" % e, 0)
                ERRORS += 1

        if (time.time() > PING):
            rgbled(0x0F, 0x0F, 0x00)
            try:
                mqtt_client.ping()
            except:
                debug("mqtt ping failure", 0)
                time.sleep(1)
                machine.reset()
            PING = time.time() + 30

        # If we have a slave talk to it every second
        if (time.time() >= HEARTBEAT):
            HEARTBEAT = time.time() + 1
            rgbled(0x0F, 0x00, 0x0F)

            debug("mem_free: %d" % gc.mem_free(), 1)
            if (ourSlave['twcid'] != None):
                send_master_heartbeat("limit", ourSlave['charge_rate'])
                # send_master_heartbeat("limit", 15)