Try   HackMD

Using mqtt between Pycom and a Blazor webapp

By: Mats Lourenço (ml226ha)

Overview

The project goal is to monitor and control a PyCom from a Blazor webapp.

Objective

I want to be able to send an recieve messages between a PyCom and .Net6 Blazor webapp via MQTT. This will give me understanding how to setup a MQTT-broker and a MQTT-client in .Net and on the PyCom device. Transmition of data will be over WiFi, but it is of course possible to use other communication protocols like LoRa. The specific sensor is the built in Accelerometer (LIS2HH12)in the PySense, I planned to use other sensors but I did not get them delivered in time. The main thing for this tutorial is how to send and recive data via MQTT.
Estimated time for this project is about 3 days.

Material

For this tutorial I use:

  • Pycom FiPy, Electrokit
  • Pycom PySense, Electrokit

Total cost about: 1500SEK

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Computer setup

The PyCom is programmed with MicroPyton and developed in the Atom IDE.
You can install it by following this https://docs.pycom.io/gettingstarted/software/atom/
I flash the PyCom via Atom.

The webapp is developed in Visual Studio 2022 IDE with .Net6 and Blazor as Framework.
Follow this link to install and get started https://dotnet.microsoft.com/en-us/learn/aspnet/blazor-tutorial/intro

Putting everything together

In this case the PyCom FiPy is connected to the PySense so it is not so complicated.

Platform

I tried both Atom and Visual Studio Code. My tests where working with both IDE's but Atom was a little bit simpler and easier to use.

For the manager I choosed a Blazor WebApplication created in C# .Net6 on Visual Studio 2022.
First I tried Adafruit and it worked fine but I wanted to try to do the backend myself. Using MQTTnet library (https://github.com/dotnet/MQTTnet), I was able to get both a MQTT-broker and a MQTT-client running.

Currently its a localy hosted application, but it is possible to host in a cloud like Azure.

I choosed this platform since I work with C# development and wanted to explore the possibilitys to connect it to IOT-devices.

The code

Overview

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

PyCom built in MicroPython - Angle checker

The purpose of the code is to check the roll and pitch angle of the PySense and
publish a message whith the angles to the MQTT with the topic topic_data.
There are 2 different modes. One that publish every change in angle to MQTT and one that is only publishing if the angle passes a threshold.
The modes and threshold levels is set by default, but can be changed with messages from the webapp in a subscribed topic.

MicroPython project structure

config.py
boot.py
LIS2HH12.py
main.py
pycoproc_2.py
umqttsimple.py

config.py Is used to store SSID for wifi, Password, IP adress and portnumber. (this is not published on github)

pycoproc_2.py Library for the PySense

LIS2HH12.py Library for the Accelerator-sensors in the Pysense.

umqttsimple.py Library for the MQTTClient

boot.py Is executed once on device startup. Connecting to wifi and setup for the Pysense.

main.py Here are the functional part of the code. The logic for detecting motion and publish and subsribe messages to the MQTT-message broker.

MQTT-broker built in .Net6

I used the MQTTnet library to get a functional MQTT-broker up and running as a BackgroundWorker process in .Net6.

MQTT - WebManager built in .Net6 Blazor

This application is subscribing and publishing MQTT-messages.
If it gets a message on topic_data (from the PyCom) with an angle.

The webapp shows all recived messages from the PyCom without filtering. All the decisions when to send data is done in the PyCom. Thow the filtering parameters and modes are adjustable from the webapp.

From the webapp it is possible to adjust the mode and threshold value.

The Angle is shown in a list on the WebManager and is updated i real time. Benefits on the fact that Blazor is a webassembly so the code is running in the browser, not on the server. That means that the roundtrips to the server is minmized.

When the webapp recieves an Angle it also publish a MQTT message with the topic topic_command and green if the angel is below the low threshold value and red if its above.

.Net project structure

Nuget Packages (Nuget is a .net package manager)

MQTTnet
Program.cs

MQTTnet is a high performance .NET library for MQTT based communication. https://github.com/dotnet/MQTTnet

All code for the project is here: https://github.com/lourma/IoTSummerCourse2022

Interesting parts of code
Check if the angle has changed on PyCom
if((roll + change < li.roll()) or (roll - change > li.roll()) or (pitch + change < li.pitch()) or (pitch - change > li.pitch())):
​​​       roll = li.roll()
​​​       pitch = li.pitch()
​​​       client.publish(topic_data, str(roll)+":"+str(pitch))
​​​       print(b'Sent:' + str(roll) + ':' + str(pitch))

Where li is the sensor LIS2HH12(py).
This publish a message on topic_data with the roll and pitch angle.

To control threshold and if all data should be sent on PyCom
def sub_cb(topic, msg):
    print((topic, msg))
    if topic == topic_command:
        if("sensor" in msg):
            parsed = ujson.loads(msg)
            print(parsed)
            if(parsed["sensor"] == "ROLL"):
                if(parsed["setting"] == "MIN"):
                    global rollMin
                    rollMin = float(parsed["value"])
                elif(parsed["setting"] == "MAX"):
                    global rollMax
                    rollMax = float(parsed["value"])
                elif(parsed["setting"] == "ALL"):
                    global rollAll
                    rollAll = float(parsed["value"])
                elif(parsed["setting"] == "GetValues"):
                    client.publish(topic_data, b'ROLL_ALL ' + str(rollAll))

First, make shure its a topic_command that is recieved.
The settings is sent in json-format so it is read into the parsed class.
Then the updated setting is updated.

Transmitting the data / connectivity

Data to and from the Pycom is transitted via WiFi and with MQTT as transfer protocol.
The server is a windows machine with a webserver and a MQTT-broker.

There is a posibillity to switch what to trigger when data is sent from the PyCom to the server.
Currently there are 2 modes.

Modes

Threshold mode

Sends a message when a threshold is passed.
For example if -33 is a threshold, it triggers a MQTT message send when the PySense gives an angle below -33 degrees.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Change mode

This mode sends a messages when the angle changes more than a certain number of degrees. For example if the angle changes more than 4 degrees from last message, send a new message.

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

Select mode and thresholds

This is actually the core of this tutorial. The recieving of values is on thing but this makes it possible to dynamically setup from the WebManager when data should be sent.

When clicking on Threshold in the webmanager a message is sent to the PyCom telling it to just publish a message when the threshold is passed and what angles that are the tresholds.

When clicking on Change in the webmanager a message is sent to the PyCom telling it to publish a message when the angle changes more than the Angle setting.

Presenting the data

The Dashboard is built in Blazor that is updated when new data is recieved.

For the visual experiance there is just a change in the CSS-styling of the HTML.
This is the HTML code for the "cockpit esqe instrument:"

    <div class="innerdiv" style="transform: @RollDraw; 
        background: linear-gradient(#9ff, #9ff @PitchDraw, #7f5a3d @PitchDraw, #7f5a3d)">
    </div>
    <div class="linediv">&nbsp;</div>
        <div class="textdiv">
            Roll: @Roll&deg;<br />
            Pitch: @Pitch&deg;
        </div>
    </div>

The change in the UI is conducted by the @RollDraw and @PitchDraw.
In the example above:

  • @RollDraw will be translated into rotate(40deg)
  • @PitchDraw will be translated into 55%
    No data is currently saved to a database. It is just added to a list and presented. But since it is in Microsoft .net world it is easy to save the data to a SQL-server database.

The interesting parts in this tutorial is to control when and how the PyCom should send messages.
This concept is applicible to all type of IOT devices that uses MQTT since it makes it possible to
adjust how much data that should be sent after the installation of the IOT-device on a location.

An improvement should be to always send json-data to make it easier to decode the parameters both in the webapp and on the PyCom.

YouTube video

https://youtu.be/W7N0UHFGD7o

Github

https://github.com/lourma/IoTSummerCourse2022