Interface and Application Programming
This week's assignment was:
Processing - Wikipedia is a Java based language and IDE for interactive graphics and visual arts. You use GUI libraries like ControlP5 to improve the sketches (canvas drawings).
Home Assistant - Wikipedia is an open source, Python based platform with a customizable dashboard and automation engine.
Electron embeds Node.js + Chromium so you can build cross platform desktop GUIs with HTML, CSS, and JavaScript.
Python GUI Library offers various GUI frameworks, such asTkinter, PyQt/PySide, Kivy, wxPython, PySimpleGUI, BeeWare, ..etc.
You can check out further widget tools here!
We opt for MQTT as Protocoll. So we just needed to publish something to a topic with the UI and the programm on the recieving end(Pi Pico 2 W) stays the same
We went with Mika's Board and changed the Code he did in Week 11. You can also find there how to setup MQTT in combination with HomeAssistant, which is used later in this Documentation.
#include <Arduino.h> #include <WiFi.h> #include <PubSubClient.h> // WiFi-Credentials const char *ssid = "ssid"; const char *password = "password!"; // MQTT Broker IP address const char *mqtt_identifier = "TestClient"; const char *mqtt_server = "192.168.188.52"; const char *mqtt_user = "mosquitouser2"; const char *mqtt_pass = "mosquitouser2"; WiFiClient ppClient; PubSubClient client(ppClient); char msg[50]; char topic[50]; int value = 0; void setup(void) { Serial.begin(115200); pinMode(22, OUTPUT); setup_wifi(); client.setServer(mqtt_server, 1883); client.setCallback(callback); } void setup_wifi() { delay(2000); // We start by connecting to a WiFi network Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); delay(500); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } void callback(char *topic, byte *message, unsigned int length) { Serial.print("Message arrived on topic: "); Serial.print(topic); Serial.print(". Message: "); String messageTemp; for (int i = 0; i < length; i++) { Serial.print((char)message[i]); messageTemp += (char)message[i]; } Serial.println(); Serial.print("Changing output to " + messageTemp); if (messageTemp == "ON") { digitalWrite(22, HIGH); } else if (messageTemp == "OFF") { digitalWrite(22, LOW); } } void reconnect() { // Loop until we're reconnected while (!client.connected()) { Serial.print("Attempting MQTT connection..."); // Attempt to connect if (client.connect(mqtt_identifier, mqtt_user, mqtt_pass)) { Serial.println("connected"); // Subscribe client.subscribe("home/switch1"); } else { Serial.print("failed, rc="); Serial.print(client.state()); Serial.println(" try again in 5 seconds"); // Wait 5 seconds before retrying delay(5000); } } } void loop() { if (!client.connected()) { reconnect(); } client.loop(); }
So what the code does, it connects to the WiFi and our MQTT Broker and listens to the Topic of the switch. If there is a "state change", the Pi Pico recognized it, because we subscribed to the channel and it turns ON or OFF the LED, which was connnected to Ground and GP0 on Mika's Board, acording to the Commands.
To see how you import libraries through the library-manager take a look at Mika's documentation. There is also a small explanation on what ControlP5 is.
The MQTT library, allows us to connect to a MQTT Broker, and publish and subscribing to topics.
What does the Code? The code first connects to our MQTT Broker in a second/parallel thread to help reduce time with drawing the GUI and Connecting to MQTT. After that with the help of the ControlP5 library, the Switch was created. If the switch is flipped, the state is switched and send to the Topic "home/switch1". The states are ON and OFF. The draw() function is calld in a specific period, which then updates the last sent state of the LED in the UI
import controlP5.*; import mqtt.*; ControlP5 cp5; MQTTClient client; boolean switchState = false; // state of the switch void setup() { size(400, 200); cp5 = new ControlP5(this); new Thread(() -> { client = new MQTTClient(this); try { client.connect("mqtt://mosquitouser:mosquitouser@192.168.188.52:1883", "ProcessingTest"); println("Connected to MQTT."); } catch (Exception e) { println("MQTT connection failed: " + e.getMessage()); } }).start(); // Create a toggle switch cp5.addToggle("lightSwitch") .setPosition(150, 80) .setSize(100, 40) .setValue(false) .setMode(ControlP5.SWITCH); } void lightSwitch(boolean theValue) { switchState = theValue; String message = theValue ? "ON" : "OFF"; println("Switch turned " + message); client.publish("home/switch1", message); } void draw() { background(180); fill(0); textAlign(CENTER); textSize(30); text("Light Switch", width/2, 30); fill(0); textSize(25); text("LED:", 30, 180); // Show light status if (switchState) { fill(0, 200, 0); // Green for ON text("ON", 80, 180); } else { fill(200, 0, 0); // Red for OFF text("OFF", 80, 180); } } void messageReceived(String topic, byte[] payload) { // Do nothing – avoids the "Callback not found" warning }
all changes are based on the previous Setup by Mika, because its the HA server in our LAB.
In Mika's Setup the Switch was missing, so we added the switch part. the full MQTT part in the configuration.yaml looks like this:
mqtt: sensor: - name: "MG_FA25_Temperature" state_topic: "mika/FA25/temperature" unique_id: "mgfa25_temperature" unit_of_measurement: "°C" - name: "MG_FA25_Humidity" state_topic: "mika/FA25/humidity" unique_id: "mgfa25_humidity" unit_of_measurement: "%" switch: - name: "FA25_GUITest" state_topic: "home/switch2" command_topic: "home/switch1" payload_on: "ON" payload_off: "OFF" state_on: "ON" state_off: "OFF" unique_id: "fa25_GUItest"
By reloading the YAML through the Developer Tools, it already added the Switch to the Dashboard by itself
In the Vido you see, how the Switch action publishes a message on the MQTT Topic, without the board, because one Video before you saw the board reacting to the Statechange in MQTT.