university-final-iot-backend/app/devices/mqtt_client.py

85 lines
2.9 KiB
Python
Raw Normal View History

import sys
import json
2018-04-27 09:15:44 +00:00
from flask_mqtt import Mqtt
from .models import Recording
2018-05-08 14:45:09 +00:00
from app import app
2018-05-04 06:35:26 +00:00
2018-05-08 14:45:09 +00:00
class MqttClient:
__initialized = False
mqtt = Mqtt()
2018-05-03 20:30:34 +00:00
# Mqtt setup
2018-05-08 14:45:09 +00:00
@staticmethod
def setup(app):
if not MqttClient.__initialized:
MqttClient.mqtt.init_app(app)
MqttClient.mqtt.client.on_message = MqttClient.handle_mqtt_message
MqttClient.mqtt.client.on_subscribe = MqttClient.handle_subscribe
MqttClient.__initialized = True
@MqttClient.mqtt.on_connect()
2018-05-03 20:30:34 +00:00
def handle_connect(client, userdata, flags, rc):
print('MQTT client connected')
2018-05-08 14:45:09 +00:00
MqttClient.mqtt.subscribe('device/+')
2018-05-03 20:30:34 +00:00
2018-05-08 14:45:09 +00:00
@MqttClient.mqtt.on_disconnect()
2018-05-03 20:30:34 +00:00
def handle_disconnect():
print('MQTT client disconnected')
print('MQTT client initialized')
2018-05-08 14:45:09 +00:00
@staticmethod
def tear_down():
if MqttClient.__initialized:
MqttClient.mqtt.unsubscribe_all()
if (hasattr(MqttClient.mqtt, 'client') and
MqttClient.mqtt.client is not None):
MqttClient.mqtt.client.disconnect()
print('MQTT client destroyed')
@staticmethod
def handle_subscribe(client, userdata, mid, granted_qos):
2018-05-03 20:30:34 +00:00
print('MQTT client subscribed')
2018-05-08 14:45:09 +00:00
@staticmethod
def handle_mqtt_message(client, userdata, message):
2018-05-03 20:30:34 +00:00
print("Received message!")
print("Topic: " + message.topic)
print("Payload: " + message.payload.decode())
try:
# If type is JSON
2018-05-08 14:45:09 +00:00
recording = MqttClient.parse_json_message(
message.topic, message.payload.decode())
2018-05-03 20:30:34 +00:00
with app.app_context():
recording.save()
except ValueError:
print("ERROR!")
error_type, error_instance, traceback = sys.exc_info()
print("Type: " + str(error_type))
print("Instance: " + str(error_instance))
return
2018-05-08 14:45:09 +00:00
@staticmethod
def parse_json_message(topic, payload) -> Recording:
2018-05-03 20:30:34 +00:00
try:
json_msg = json.loads(payload)
2018-05-08 14:45:09 +00:00
device_id = MqttClient.get_device_id(topic)
2018-05-03 20:30:34 +00:00
return Recording(device_id=device_id,
record_type=json_msg["record_type"],
record_value=json_msg["record_value"],
recorded_at=json_msg["recorded_at"],
raw_json=json_msg)
except KeyError:
error_type, error_instance, traceback = sys.exc_info()
raise ValueError("JSON parsing failed! Key error: "
+ str(error_instance))
2018-05-08 14:45:09 +00:00
@staticmethod
def get_device_id(topic) -> int:
2018-05-03 20:30:34 +00:00
device_token, device_id = topic.split("/")
if device_token == "device":
return int(device_id)
else:
raise ValueError("Topic is in invalid format")