
Nextion Display - Teil 4 - Integration in FHEM und Node-RED
Jetzt haben wir schon viele kleine Bausteine in den letzten Videos gesehen. Was jetzt noch fehlt? Alles miteinander verknüpfen natürlich. In diesem Video bauen wir gemeinsam eine MQTT_Bridge in FHEM, senden Die Daten an das Display und stellen alles gleichzeitig noch auf dem Node-RED-Dashboard dar (optional). Natürlich möchte ich dann auch noch entsprechende Button-Events in MQTT haben, sodass ich dann auf den Touch reagieren kann, eine MQTT-Nachricht bekomme und damit dann tun und lassen kann was ich möchte. Zum Beispiel das Licht an und aus schalten.
Was wird benötigt?
- Eine Nextion-Display (in meinem Fall das NX3224T024)
- Ein Wemos D1 Mini
- Eine Micro-SD-Karte
- Einen laufenden MQTT-Server
- Ein Windows PC oder eine virtuelle Maschine mit Windows
Video
Download
Hier gibt es die PSD, die Bilder und auch die HMI-Datei.
Befehle
define OUT_Abfall_MQTT MQTT_BRIDGE OUT_Abfall
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <PubSubClient.h>
#include <Nextion.h>
#define WIFI_DISCONNECTED false
#define WIFI_CONNECTED true
#define PAGE_HOME 1
#define PAGE_JUNK 2
const char* mqtt_server = "192.168.178.11";
const char* ssid = "PlitschPlatsch";
const char* password = "PASSWORD";
WiFiClient net;
PubSubClient client(net);
// Page Home
NexPage pHome = NexPage(0, 0, "page0"); // Page Home
NexGauge zLeft = NexGauge(0, 4, "zLeft"); // Gauge left
NexGauge zRight = NexGauge(0, 3, "zRight"); // Gauge right
NexGauge zTop = NexGauge(0, 1, "zTop"); // Gauge top
NexText tTop = NexText(0, 5, "tTop"); // Text top
NexPicture pWiFi = NexPicture(0, 2, "pWiFi"); // Picture WiFi
NexButton bOnoff = NexButton(0, 6, "bOnoff"); // Button On Off
NexButton bJunkPage = NexButton(0, 7, "bJunkPage"); // Button Junk Page
// Page Junk
NexPage pJunk = NexPage(1, 0, "page1"); // Page Junk
NexButton bBackHome = NexButton(1, 5, "bBackHome"); // Button On Off
NexText tJunkGrey = NexText(1, 1, "tJunkGrey"); // Text Junk Grey
NexText tJunkYellow = NexText(1, 2, "tJunkYellow"); // Text Junk Yellow
NexText tJunkBlue = NexText(1, 3, "tJunkBlue"); // Text Junk Blue
NexText tJunkGreen = NexText(1, 4, "tJunkGreen"); // Text Junk Green
// Touch Event Objects
NexTouch *nexListenList[] = {
&bOnoff,
&bJunkPage,
&bBackHome,
NULL // String terminated
};
bool valueChanged = false;
bool pageChanged = false;
bool wifiChanged = false;
bool wifiState = WIFI_DISCONNECTED;
uint32_t currentPage = PAGE_HOME;
uint32_t gaugeLeft = 0;
uint32_t gaugeRight = 0;
uint32_t gaugeTop = 0;
uint32_t junkGrey = 0;
uint32_t junkYellow = 0;
uint32_t junkBlue = 0;
uint32_t junkGreen = 0;
void setup() {
pinMode(BUILTIN_LED, OUTPUT);
digitalWrite(BUILTIN_LED, HIGH); // Turn OFF internal LED
Serial.begin(9600);
nexInit();
bOnoff.attachPush(bOnoffPushCallback);
bOnoff.attachPop(bOnoffPopCallback);
bJunkPage.attachPush(bJunkPagePushCallback);
bJunkPage.attachPop(bJunkPagePopCallback);
bBackHome.attachPush(bBackHomePushCallback);
bBackHome.attachPop(bBackHomePopCallback);
connect();
valueChanged = true;
}
void loop() {
if (!client.connected()) {
if (wifiState == WIFI_CONNECTED) {
wifiChanged = true;
}
wifiState = WIFI_DISCONNECTED;
reconnect();
} else {
if (wifiState == WIFI_DISCONNECTED) {
wifiChanged = true;
}
wifiState = WIFI_CONNECTED;
}
nexLoop(nexListenList); // Check touch events
client.loop();
refreshDisplay();
delay(10);
}
void refreshDisplay()
{
if (valueChanged || pageChanged || wifiChanged) {
digitalWrite(BUILTIN_LED, LOW); // Turn ON internal LED
if (currentPage == PAGE_HOME) {
zLeft.setValue(calculateGaugeValue(gaugeLeft));
zRight.setValue(calculateGaugeValue(gaugeRight));
zTop.setValue(calculateTopGaugeValue(gaugeTop));
tTop.setText(String(gaugeTop, DEC).c_str());
if (wifiState == WIFI_CONNECTED) {
pWiFi.setPic(2);
} else if (wifiState == WIFI_DISCONNECTED) {
pWiFi.setPic(1);
}
}
if (currentPage == PAGE_JUNK) {
tJunkGrey.setText(String(junkGrey, DEC).c_str());
tJunkYellow.setText(String(junkYellow, DEC).c_str());
tJunkBlue.setText(String(junkBlue, DEC).c_str());
tJunkGreen.setText(String(junkGreen, DEC).c_str());
}
valueChanged = false;
pageChanged = false;
wifiChanged = false;
digitalWrite(BUILTIN_LED, HIGH); // Turn OFF internal LED
}
}
void connect() {
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
// WiFi
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
}
// MQTT
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
uint32_t calculateGaugeValue(uint32_t val) {
if (val < 45) {
return val + 315;
} else if (val > 270) {
return 225;
} else {
return val - 45;
}
}
uint32_t calculateTopGaugeValue(uint32_t val) {
val += 30;
if (val > 150) {
return 150;
} else {
return val;
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String sTopic = String(topic);
// Workaround to get int from payload
payload[length] = '\0';
uint32_t value = String((char*)payload).toInt();
if (sTopic == "/SmartHome/Buero/Display/left") {
gaugeLeft = value;
} else if (sTopic == "/SmartHome/Buero/Display/right") {
gaugeRight = value;
} else if (sTopic == "/SmartHome/Buero/Display/top") {
gaugeTop = value;
} else if (sTopic == "/SmartHome/Buero/Display/junk/grey") {
junkGrey = value;
} else if (sTopic == "/SmartHome/Buero/Display/junk/yellow") {
junkYellow = value;
} else if (sTopic == "/SmartHome/Buero/Display/junk/blue") {
junkBlue = value;
} else if (sTopic == "/SmartHome/Buero/Display/junk/green") {
junkGreen = value;
}
valueChanged = true;
}
void reconnect() {
while (!client.connected()) {
String clientId = "WemosNextion-";
clientId += String(random(0xffff), HEX);
if (client.connect(clientId.c_str())) {
client.subscribe("/SmartHome/Buero/Display/left");
client.subscribe("/SmartHome/Buero/Display/right");
client.subscribe("/SmartHome/Buero/Display/top");
client.subscribe("/SmartHome/Buero/Display/junk/grey");
client.subscribe("/SmartHome/Buero/Display/junk/yellow");
client.subscribe("/SmartHome/Buero/Display/junk/blue");
client.subscribe("/SmartHome/Buero/Display/junk/green");
} else {
delay(5000);
}
}
}
void bOnoffPushCallback(void *ptr) {
digitalWrite(BUILTIN_LED, LOW); // Turn ON internal LED
}
void bOnoffPopCallback(void *ptr) {
client.publish("/SmartHome/Buero/Display/buttonPressed", "onOff");
digitalWrite(BUILTIN_LED, HIGH); // Turn OFF internal LED
}
void bJunkPagePushCallback(void *ptr) {
}
void bJunkPagePopCallback(void *ptr) {
client.publish("/SmartHome/Buero/Display/buttonPressed", "junkPage");
pJunk.show();
pageChanged = true;
currentPage = PAGE_JUNK;
}
void bBackHomePushCallback(void *ptr) {
}
void bBackHomePopCallback(void *ptr) {
client.publish("/SmartHome/Buero/Display/buttonPressed", "backHome");
pHome.show();
pageChanged = true;
currentPage = PAGE_HOME;
}
Links
Transparenz-Hinweis (Level 1)
An diesem Beitrag ist kein Hersteller beteiligt! Sämtliche Produkte habe ich selbst gekauft und trage die kompletten Kosten für diesen Beitrag alleine! Die Inhalte wurden somit von niemandem gesehen oder abgestimmt. Es handelt sich zu 100% um meine persönliche Meinung und Erfahrung!