Files
controller-data-analysis/mqtt.py
T
2021-12-24 10:56:22 +08:00

84 lines
2.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import time, random, threading
import multiprocessing as mp
import json
class MqttThread(threading.Thread):
def __init__(self, callback_API, controller_id: str, url: str, port: int, client_id: str, name='thread-1', alive=60):
super(MqttThread, self).__init__(name = name)
self.__controller_ID = controller_id
self._mqtt_url = url
self._mqtt_port = port
self._mqtt_alive = alive
self._client_id = client_id
self._mqtt_client = None
self._connected = False
self._handler = callback_API
@property
def mqtt_url(self) -> str:
return self._mqtt_url
@property
def mqtt_port(self) -> int:
return self._mqtt_port
@property
def connected(self) -> bool:
return self._connected
def run(self) -> None:
print('use controller ID', self.__controller_ID)
self._mqtt_client = mqtt.Client(self.__controller_ID + '_' + self._client_id)
self._mqtt_client.connect(self._mqtt_url, self._mqtt_port)
self._mqtt_client.on_connect = self.on_connect
self._mqtt_client.on_disconnect = self.on_disconnect
self._mqtt_client.on_message = self.on_message
self.routine()
def shutdown(self) -> None:
if self._mqtt_client != None:
self._mqtt_client.loop_stop()
self._mqtt_client.disconnect()
def routine(self) -> None:
self._mqtt_client.loop_start()
def on_connect(self, client: mqtt.Client, user_data, flags, rc: int):
topic = self.__controller_ID + '_user'
# print('cloud-server subscribe', topic)
# self._mqtt_client.subscribe(topic)
self._mqtt_client.subscribe(self.__controller_ID + '/+/+')
self._connected = True
def on_disconnect(self, client: mqtt.Client, user_data, rc):
print('cloud-server disconnected')
time.sleep(3)
self._connected = False
self._mqtt_client.reconnect()
def publish(self, payload: str, wait_for_ack = False) -> int:
QoS = 2 if wait_for_ack else 0
message_info = self._mqtt_client.publish(self.__controller_ID + '_user', json.dumps(payload), QoS)
print(self.__controller_ID + '_user', payload)
if wait_for_ack:
print(" > awaiting ACK for {}".format(message_info.mid))
message_info.wait_for_publish()
print(" < received ACK for {}".format(message_info.mid))
def on_message(self, client: mqtt.Client, user_data, message):
topic = message.topic.split('/')[1]
payload = json.loads(message.payload.decode('utf-8'))
func = getattr(self._handler, topic, None)
if func != None:
return func(payload)