MQTT andmekäsitlusrakendus

Selleks, et MQTT protokolli järgi saadetavaid andmeid käsitleda, näiteks logida, andmeanalüüsi teha või ka visualiseerida on vaja andmekäsitlusskripti, mis saab andmed kätte, on võimeline kirjutama failidesse ja edastama infot omakorda edasi järgnevatele rakendustele, näiteks brauseripõhisele kasutajaliidesele.

MQTT andmekäsitlusrakendus

MQTT olemust ja kasutusvõimalusi on varem kirjeldatud juba artiklis "Mis on MQTT"

 

Nüüd vaatame lähemalt, kuidas saaks Mosquito poolt edastatud andmevoost vajalikud andmd kätte ja neid täpsemalt edasi töödelda. Selleks loome Python skripti, milles on omakorda mitu tegumilõime (ingl. threading), toome esmase näite puhul neist välja kolm peamist

mqtt.client võtab andmeid vastu, et need oleksid teistele tegumitele kättesaadavad

teises tegumis toimub andmete logimine tavatekstilisel kujul .txt faili

kolmandaks käsitleb ja serveerib Flask veebiserver kasutajaliidese poolt tehtud päringuid

 

Failistruktuur on järgnev
/mqtt_projekt

├── app.py              # Flask põhifail ja MQTT loogika
├── plabAndmeteLogi.txt  # Logifail (tekitatakse automaatselt)
├── static/
│   ├── css/
│   │   └── style.css   # Kujundus
│   └── js/
│       └── script.js  # jQuery/AJAX loogika
└── templates/
    └── index.html      # Veebilehe mall
Milles on Python skript app.py järgneva sisuga

from flask import Flask, render_template, jsonify
import paho.mqtt.client as mqtt
import threading
import json
import os

 

app = Flask(__name__)

 

# Globaalne muutuja viimaste andmete hoidmiseks mälus
viimased_andmed = "Ootame andmeid..."
logi_fail = "plabAndmeteLogi.txt"

 

# MQTT seaded
MQTT_BROKER = "localhost" # Kuna Mosquitto on samas laptopis
MQTT_PORT = 1883
MQTT_TOPIC = "plab/stend1/rakendus"

 

def on_message(client, userdata, msg):
    global viimased_andmed
    payload = msg.payload.decode("utf-8")
    viimased_andmed = payload
    
    # Kirjutame andmed tekstifaili
    with open(logi_fail, "a", encoding="utf-8") as f:
        f.write(payload + "n")

 

def start_mqtt():
    client = mqtt.Client()
    client.on_message = on_message
    client.connect(MQTT_BROKER, MQTT_PORT, 60)
    client.subscribe(MQTT_TOPIC)
    client.loop_forever()

 

# Käivitame MQTT kliendi eraldi lõimes, et Flask saaks töötada
mqtt_thread = threading.Thread(target=start_mqtt, daemon=True)
mqtt_thread.start()

 

@app.route('/')
def index():
    return render_template('index.html')

 

@app.route('/get_data')
def get_data():
    # AJAX päringu sihtkoht
    return jsonify(andmed=viimased_andmed)

 

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)

 
Kasutajaliides templates/index.html sisaldab lihtsat tekstilist vaadet, mis teeb Flask veebiserverile päringuid, saab sellest vastu andmed ja kuvab neid brauseripõhiselt kasutajale nähtavas formaadis.

<!DOCTYPE html>
<html lang="et">
<head>
    <meta charset="UTF-8">
    <title>MQTT Stendi Monitor</title>
    <link rel="stylesheet" href="{{url_for('static', filename='css/style.css')}}">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
    <div class="container">
        <h1>Stendi andmed reaalajas</h1>
        <div id="andme-kast">
            <p>Viimane info: <span id="mqtt-info">Laen...</span></p>
        </div>
        <p><small>Värskendus: 0.5s | Fail: plabAndmeteLogi.txt</small></p>
    </div>

    <script>
        function uuendaAndmeid(){
            $.getJSON('/get_data', function(data){
                $('#mqtt-info').text(data.andmed);
           });
       }
        // Kutsume funktsiooni välja iga 500 millisekundi järel
        setInterval(uuendaAndmeid, 500);
    </script>
</body>
</html>

 
Projektis kasutatava html malli puhtuse ja parema ülevaatlikkuse huvides on visuaalstiilid eraldi CSS failis static/css/style.css, võimalus on eraldi salvestada ka Javaskript, praegu on see html faili lõpus

body{
    font-family: Arial, sans-serif;
    background-color: #f4f4f4;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
}

.container{
    background: white;
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 4px 6px rgba(0,0,0,0.1);
    text-align: center;
}

#andme-kast{
    font-size: 1.5rem;
    color: #2c3e50;
    margin: 20px 0;
    padding: 15px;
    border: 2px solid #3498db;
    border-radius: 5px;
    background: #ecf0f1;
}

#mqtt-info{
    font-weight: bold;
    color: #e74c3c;
}

 

Kuidas süsteem töötab:

  • Arhitektuur: Pythoni skriptis töötab kaks "mootorit" korraga. threading moodul hoiab MQTT ühendust üleval, et ükski ESP32 saadetud pakett kaduma ei läheks.
  • Andmete logimine: Iga kord, kui on_message funktsioon käivitub, lisatakse rida plabAndmeteLogi.txt faili lõppu ("a" re¾iim).
  • Frontend: Brauser laeb index.html lehe. Seal olev jQuery kood teeb päringuid Flaski /get_data aadressile iga 0.5 sekundi järel.
Dünaamiline lehesisene värskendus: Kuna kasutame AJAX-it ($.getJSON), siis brauser ei lae andmeuuendusteks mitte igakorselt kogu lehte uuesti, vaid muudab ainult ühte väikest "infoaknakest", tekstielemendi sees.

Monteeri lihtsalt ja kiiresti

Riistvara montaa¾ on jaotatud etappideks ja toetatud õppevideodega. Vaata lähemalt.

 

Tarkvaratugi

Loe riistvaralist portide lugemist ja muutujate defineerimist toetava tarkvarateegi kohta