Nextion Display - Teil 4 - Integration in FHEM und Node-Red

Mit ** gekennzeichnete Links auf dieser Seite sind Affiliatelinks.

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
  • Ein Wemos D1 Mini
  • Eine Micro-SD-Karte
  • Einen laufenden MQTT-Server
  • Ein Windows PC oder eine virtuelle Maschine mit Windows

Video

Arduino-Kurs

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;
}


Newsletter

Trage Dich jetzt in den Newsletter ein und genieße dadurch viele exklusive Vorteile:

  • 5€-Gutschein für den Online-Shop
  • Zugang zu exklusiven Inhalten
  • Angebote für Produkte
  • Immer auf dem Laufenden

* Durch Angabe meiner E-Mail-Adresse erkläre ich mich damit einverstanden, dass mir regelmäßig Informationen und Produktempfehlungen aus dem Fachgebiet Smart Home zugesendet werden. Mit dem Eintrag akzeptieren Sie unsere Datenschutzbestimmungen. Meine Einwilligung kann ich jederzeit widerrufen.

Auf YouTube und hier im Blog gibt es bereits unzählige kostenlose Videos, Informationen und Tutorials. Wenn Dir das noch nicht reicht, ist ein Training genau das richtige für Dich! Die folgenden Trainings haben den Vorteil, dass immer von Anfang an gestartet wird und Du ohne Vorwissen teilnehmen kannst.