Files
controller-data-analysis/mqtt.py
T
2022-12-02 11:24:21 +08:00

90 lines
2.6 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
import time, random
import json
class MqttThread():
def __init__(self, callback_API, controller_id: str, url: str, port: int, client_id: str, name='thread-1', alive=60):
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 = f'{self.__controller_ID }_data_analysis/#'
print('subscribe topic', topic)
self._mqtt_client.subscribe(topic)
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
topic = f'{self.__controller_ID}/data_analysis'
message = json.dumps(payload)
print('publish', topic, message)
message_info = self._mqtt_client.publish(topic, message, QoS)
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):
print('on_message', message.topic, message.payload)
topic = message.topic.split('/')[1]
payload = None
try:
payload = message.payload.decode('utf-8')
# print('callback from', topic, message.topic, payload)
except:
print('error')
func = getattr(self._handler, topic, None)
if func != None:
return func(payload)