Source code for mqttclient.mqttservice

import paho.mqtt.client as paho
import platform
import paho.mqtt.publish as publish
import requests
import socketio
from dotenv import load_dotenv
import os
import logging
import traceback
import json

base_dir = os.path.dirname(os.path.abspath(__file__))
dotenv_file = os.path.join(base_dir, "../.env")

load_dotenv(dotenv_file)


if platform.system() == "Linux":
    log_dir = "/var/log/pymqtt"
else:
    log_dir = os.path.join(base_dir, "../logs")


os.makedirs(log_dir, exist_ok=True)
logging.basicConfig(level=logging.INFO, filename=f"{log_dir}/mqtt.log",filemode="w")
#logging.basicConfig(level=logging.DEBUG, filename=f"{log_dir}/debug.log",filemode="w")
logger = logging.getLogger(__name__)

# Henter innloggingsdata for serverside MQTT-klient fra .env-fil 
username = os.getenv("MQTT_ADMIN_USERNAME")
password = os.getenv("MQTT_ADMIN_PASSWORD")

logger.info(f"got username {username}")

# TODO: implement database with known ids?
deviceIDs = ['1','2','3']

sio = socketio.Client()


[docs] @sio.event def connect(): """ Loggfører tilkobling til socket. """ logger.info("SocketIO from mqtt-client connected")
[docs] @sio.event def disconnect(): """ Loggfører avkobling til socket. """ logger.info("SocketIO from mqtt-client disconnected")
[docs] @sio.event def connect_error(data): """ Sier i fra om koblingen feiler. """ logger.info("Failed to connect to Flask Socket.IO server")
[docs] @sio.on("strength") def handle_strength(data): """ Returnerer styrke-koeffisient til mikrokontrolleren. """ logger.info("handle_strength triggered.") deviceid = data.get('device') if not deviceid: logger.info("Device ID not existing") return data.pop("device", None) #dev = "devices/2/data" try: payload = json.dumps(data) client.publish(f"devices/{deviceid}/data", payload=payload) logger.info(f"sending to {deviceid} with payload: {payload}") except: exc = traceback.print_exc() logger.info(f"!Sednging failed! Traceback: {exc}")
[docs] @sio.on("returnlocation") def return_location(data): """ Returnerer lokasjonsdata til MQTT-klienten. """ logger.info(f"received {data}") # could drop this deviceID = data.get("deviceID") if not deviceID: logger.info("Device ID not existing") return data.pop("deviceID", None) try: payload = json.dumps(data) client.publish(f"devices/{deviceID}/location", payload=payload) logger.info(f"return_location send on socket with payload {payload}") except: logger.info("return_location failed")
# connect socket #sio.connect("http://127.0.0.1:8000", transports=["websocket"])
[docs] def message_handler(client, msg, deviceID): """ Sender beskjeder til flask-appen. """ payload = { 'topic': msg.topic, 'device': deviceID, 'message': msg.payload.decode() } try: response = requests.post("http://127.0.0.1:8000/mqtt", json=payload) logger.info(f"POST request to /mqtt complete with {response.status_code}") except requests.exceptions.RequestException as e: logger.info(e)
[docs] def location_handler(client, msg, deviceID): """ Videresender lokasjonsinformasjon til flask-appen. """ payload = { 'nfctagID': msg.payload.decode(), 'devID': deviceID } logger.info(f"received payload: {payload}") try: response = requests.post("http://127.0.0.1:8000/mqtt/location", json=payload) logger.info(f"POST request to /mqtt/location complete with {response.status_code}") except requests.exceptions.RequestException as e: logger.info(e)
# enkel måte å implementere flere topics topics = { "message": message_handler, "location": location_handler } # connect mosquitto
[docs] def on_connect(client, userdata, flags, rc): """ Subscriber til følgende topics: Forklaring: - ``devices/+`` godtar alle int - ``/#`` godtar alle str-topics """ if rc == 0: logger.info("Connected to broker") client.subscribe('devices/+/#', qos=1) else: logger.info(f"Failed due to: {rc}")
[docs] def on_message(client, userdata, msg): """ Funksjon som sender forespørsel til server om lokasjonsdata. """ logger.info(f"topic: {msg.topic} qos: {str(msg.qos)} payload: {str(msg.payload)}") parts = msg.topic.split('/') deviceID = parts[1] logger.info(f"found device {deviceID}") if deviceID not in deviceIDs: logger.info(f"unkown device {deviceID} setting to unkown") deviceID = 'unkown' if parts[2] in topics: handler = topics.get(parts[2]) #call handler from topic handler(client, msg, deviceID) else: logger.info("{part} not in topic")
client = paho.Client(transport="websockets") client.on_connect = on_connect client.on_message = on_message client.username_pw_set(username, password) client.connect("mqtt.gruppe1.tech", 9002) if __name__ == "__main__": sio.connect("http://127.0.0.1:8000", transports=["websocket"]) client.loop_forever()