Zum Inhalt springen

Wetterstation

Was braucht man ?

  • Eine laufende openHAB installation (2.5 oder neuer)
  • nodeMCU 32 (ESP-32)
  • AS3935
  • Tinkerforge Master Brick
  • Tinkerforge Master Extension WiFi 2.0
  • Tinkerforge Humidity Bricklet 2.0
  • Tinkerforge UV-Light Bricklet 2.0
  • Tinkerforge Barometer Bricklet 2.0
  • Tinkerforge Particular Matter Bricklet
  • Tinkerforge Outdoor Weather Bricklet
  • Tinkerforge Outdoor Wetterstation
  • Tinkerforge Temperature IR Bricklet 2.0
  • Tinkerforge PTC Bricklet 2.0 + PT100
  • Diverse Kabel
  • Stromversorgung

Das Zeugs von Tinkerforge kann man übrigens sehr gut direkt beim Hersteller kaufen (online). Die sitzen in Schloss Holte Stukenbrock und haben einen sehr hervoragenden Support. Als Beispiel einfach mal durchlesen wie das Binding für openHAB entwickelt wurde.

Was kann das alles ?

  • Luftdruck
  • Luftfeuchte
  • Lufttemperatur
  • UV-Index
  • UV-A Strahlung
  • UV-B Strahlung
  • Feinstaub (PM 1,0  /  2,5  / 10,0)
  • Windrichtung
  • Windgeschwindigkeit
  • Böengeschwindigkeit
  • Niederschlag (Regen)
  • Blitze
  • Gefühlte Temperatur (errechnet aus örtlicher: Lufttemperatur, Windgeschwindigkeit und Luftfeuchte)
  • Taupunkt (errechnet aus örtlicher Lufttemperatur und Luftfeuchte)
  • Bodentemperatur (20cm tiefe)
  • Himmelstemperatur
  • Bedeckungsgrad (Wolkendecke)

Es lädt die Werte nicht nur in den Persistence Service von openHAB (Das kann man dann mit Grafana visualisieren), sondern schickt die Daten auch nach windy.com, somit haben die Nachbarn auch was davon. WINDY.COM

Generelles zu openHAB

Generell werde ich nicht darauf eingehen, wie man openHAB installiert, was man dafür braucht und was man damit machen kann. Lediglich auf das Tinkerforge Binding werde ich etwas näher eingehen. Auch die Verwendung von Grafana in Verbindung mit InfluxDB werde ich hier nicht näher beschreiben. Sollte jemand openHAB installiert haben, wird er das ohne weiteres selbst hinbekommen.

Wetterstation - Das Gehäuse und der Standort

Um eine brauchbare, vergleichbare Messreihe zu bekommen ist der richtige Standort wichtig. Es gibt beim Deutschen Wetterdienst eine PDF Datei (Link erspare ich mir, die bauen so oft um) wie sowas auszusehen hat. Vergleichbarkeit der Messwerte ist immer das Hauptthema. Bedeutet:

  • Temperaturmessung in aller Regel in 2m höhe über kurz gemähter Wiese, möglichst ohne Einfluss von Schatten. Spielt auch für die Luftfeuchtigkeit eine Rolle.
  • Wind misst man eigentlich in 10 Höhe, an einem Standort ohne störende Einflüsse. Also Bäume, Häuser.....
  • Die UV-Messung muss so angebracht sein, dass im Prinzip über den Tag keine Schattenwürfe zu erwarten sind. Und natürlich auch nichts "draufspiegelt"
  • Regen ist das gleiche Thema, auch ohne "störende" Umwelteinflüsse....
  • Die IR Messung vom Himmel zeigt idealerweise senkrecht nach oben und hat freie Sicht
  • Die Messung der Bodentemperatur soll - oh wunder - an einem Ort ohne Störende Umwelteinflüsse (Schattenwurf) stattfinden.

Kann man also in einem normalen Garten nur sehr schwer bis gar nicht umsetzen. Die Sensoren für Temperatur, Luftfeuchte und Luftdruck kann man in ein Gehäuse bauen und auf 2m Höhe über Rasen anbringen. Wer eine Fassade hat, hat eventuell die Möglichkeit, den Windmesser so anzubringen das er über das Dach "guckt" und so möglichst 360° "rundsicht" hat. Den Regenmesser bekommt man evtl. auch noch so montiert, dass er nicht im "Regenschatten" einer Hausfassade steht. ACHTUNG! Die meisten Regenmesser haben eine Waage eingebaut, die die Regenmenge misst. Heißt: Das Ding muss so stabil wie möglich angebracht werden, sonst kommt es zu fehlmessungen. Bedeutet natürlich, Regenmesser und Windmesser an einem Mast wären schön, aber ohne große Umbaumaßnahmen (sehr stabiles Rohr) nicht machbar.

Als erstes Gehäuse habe ich eine Holzkiste gebaut. Sehr einfach, sehr preiswert. Das ganze wurde weiß lackiert, und mit einem Dach aus Plexiglas (Weiss) versehen. Das hat soweit gut funktioniert, hat aber leider den ersten Winter nicht gut überstanden. Die ein oder andere Leimstelle ist locker und der Lack müsste aufgefrischt werden. Das Plexiglas sah auch schon mal besser aus..... Darum: Wir bauen was anständiges. Die Gehäuse zum Strahlungsschutz sind normalweise rund, also war die eckige Kiste eh schon nicht die beste Lösung. Ich habe lange überlegt, wie man einfach ein Rundes Gehäuse bauen kann. Zur Auswahl standen:

  • Plexiglasgehäuse (Ringe bestellen, im Backofen tiefziehen)
  • Neue Holzkiste
  • GFK-Gehäuse bauen
  • Fertige Gehäuseteile zusammenschrauben

Gut, Plexiglas im Backofen tiefziehen geht, ist aber nachher sehr empfindlich gegenüber Bruch. Holzkiste hatte ich schon mal, GFK ist mir zu teuer und zu viel sauerei. Also bleibt die Frage, wie kommt man an fertige Gehäuseteile. Viele andere haben einfach Deckel für HT-Rohr genommen, ich habe weiße Polycarbonat-Teller bestellt. In die Teller kommen Löcher, damit sich das ganze möglichst wenig aufheizt und dann wird alles mit 3 Gewindestangen verschraubt und die Elektrontik (MasterBricks usw.) kommt in eine Kiste unter die Sensoren.

Wenn man das später alles am laufen hat und sich damit ein paar Tage/Wochen beschäftigt, passieren viele lustige Sachen. Man guckt sich auf dem "smart TV" live an, wie der Wind draußen immer neue Höchstwerte erreicht, oder wundert sich warum der Feinstaubwert auf einmal dreimal höher als an Sylvester ist: Die Nachbarn haben gegrillt.

openHAB Wetterstation auf Basis Tinkerforge

Genrell mal vorweg: Man muss nicht alles auf einmal kaufen.
Nötig für den Anfang sind:

  • Master Brick 2.1 (oder neuer)
  • WiFi Master Extension 2.0 (oder neuer)
  • mindestens ein Sensor Bricklet, vielleicht das Humidity Bricklet 2.0 (Luftfeuchte und Lufttemperatur)
  • Ein Verbindungskabel (Tinkerforge) und natürlich ein USB-Netzteil

Das steckt man alles sehr einfach zusammen, damit ist "das gebastel" fertig. Also sehr einfach und schnell und ohne Löten. Als nächstes installiert man den Brick Viewer und den Brick Deamon für Windows (oder was ihr da so habt). Jetzt nimmt man ein USB-Kabel zu Hilfe und verbindet den MasterBrick mit einem Computer. Die Konfiguration erfolgt mit dem Brick Viewer: Bei Host trägt man dann einfach Localhost ein und kann dann auf den Stapel zugreifen. Später kann man dort die IP Adresse eintragen und dann per WiFi auf den kompletten Stapel zugreifen. Jetzt kann man sich zum Beispiel das Humiditiy Bricklet anschauen und siehst schon mal, dass Werte erfasst werden. Für die WiFi Extension trägt man hier die SSID, Passwort etc. für die WiFi Verbindung ein. Wenn das eingetragen ist, kann man die Verbindung zwischen Stapel und Computer trennen und der Stapel läuft ab dann über WiFi - Stromversorgung vorrausgesetzt.

Jetzt wird es kompliziert. Wir müssen in openHAB das Tinkerforge Binding installieren. Im Moment, Stand April 2020, gibt es nur ein Beta Binding. Das funktioniert aber bisher einwandfrei. Runterladen kann man das im Forum von TINKERFORGE.

HINWEIS: Auf der ERSTEN Seite beschreibt Erik immer, was genau zu tun ist. Sollte sich also mal etwas ändern, findet ihr dort auf jeden Fall die aktuelle Vorgehensweise zur Installation.

Dann taucht nach kurzer Zeit das TF Binding auch in openHAB auf. In der Inbox kann man dann die Produkte von TF "einpflegen". Dazu drückt man auf das + und wählt das Tinkerforge Binding aus:

Anfangen muss man mit dem Brick Daemon, also der Verbindung von openHAB zu einem Stapel. Wenn man zwei oder mehr Stapel hat, benötigt man auch mehrere Brick Daemons. Dann kann man Anfangen die einzelnen Bricklets und Kanäle (Chanel) zu verbinden, also nicht wirlich schwer. Sollte OH die nach Anlegen des Brick Deamons nicht direkt selbst finden, muss auch hier wieder in der Inbox das + bemüht werden. Dann könnt ihr nach Lust und Laune - am einfachsten über Paper UI - Things und Items anlegen und damit lustige sachen machen.

Ich habe in meiner Sitemap dazu einen Punkt Wetter, hier kann ich mir zum einen die Live Daten anschauen und dann auch noch über einen Unterpunkt die Vorhersage und die Statistischen Daten anschauen.

Für die Berechnung des Taupunktes einfach mal bei http://www.wetterochs.de/wetter/feuchte.html vorbeischauen.

Wenn man das in eine openHAB Rule umschreibt sieht das so aus:

val org.eclipse.xtext.xbase.lib.Functions$Function2<Double, Double, Double> getDewPoint = [

    

    Double Temperature, 

    Double Humidity 

    

    |

    var Double a

    var Double b

    var Double SDD

    var Double DD

    var Double v

    var Double t = Temperature

    var Double h = Humidity

    

    if (t >= 0.0){ // T >= 0 °C

        a = 7.5

        b = 237.3

    } else { // T < 0 °C über Wasser

        a = 7.6

        b = 240.7

    }

    SDD=(6.1078 * Math::pow(10.0, ((a*t)/(b+t))))

    DD = (h/100.0*SDD)

    v = Math::log10((DD/6.107))

    return ((b*v)/(a-v))

]

rule "Taupunkt draußen"

when

    Item TF_Barometer_1_Temperatur received update

then

    if ((TF_Barometer_1_Temperatur.state != NULL) && (TF_Luftfeuchtigkeit_1_Luftfeuchtigkeit.state != NULL))

    {

        var t = (TF_Barometer_1_Temperatur.state as QuantityType<Number>).doubleValue

        var h = (TF_Luftfeuchtigkeit_1_Luftfeuchtigkeit.state as QuantityType<Number>).doubleValue

        

        TFTaupunktOutside.postUpdate(getDewPoint.apply(t, h))

    

                

    }

end

Dann gehts weiter mit Regeln, wir berechnen die gefühlte Temperatur:

rule "Gefühlte Temperatur berechnen"

when

    Item TF_Barometer_1_Temperatur changed

then 

    if (TF_Barometer_1_Temperatur.state > 15)

    {

    var tempCurrent = (TF_Barometer_1_Temperatur.state as Number).floatValue

    var temphumidity = (TF_Luftfeuchtigkeit_1_Luftfeuchtigkeit.state as Number).floatValue

    var hitzeindex = -8.784695 + 1.61139411*tempCurrent + 2.338549*temphumidity - 0.14611605*tempCurrent*temphumidity - 0.012308094*(tempCurrent*tempCurrent) - 0.016424828*(temphumidity*temphumidity) + 0.002211732 *(tempCurrent*tempCurrent)*temphumidity + 0.00072546*tempCurrent*(temphumidity*temphumidity) - 0.000003582*(tempCurrent*tempCurrent)*(temphumidity*temphumidity)

    TFTempFeel.postUpdate(hitzeindex as Number)

    }

    

    else

    {

    var speedCurrent = Math.pow((((Wetterstation_Windgeschwindigkeit.state as Number).floatValue) * 1.0), 0.16)  //bei m/s aus 1.0 3.6 machen oder 1.0 bei km/h

    var tempCurrent = (TF_Barometer_1_Temperatur.state as Number).floatValue

    var tempfeel = (13.12 + 0.6215 * tempCurrent - 11.37 * speedCurrent + 0.3965 * tempCurrent * speedCurrent ).floatValue

    TFTempFeel.postUpdate(tempfeel as Number)

   }

end
Das entspricht aber nicht wirklich der Wahrheit, ist aber das, was man an Berechnungen frei zugänglich bekommen kann. Diese Art der Berechnung zur gefühlten Temperatur war lange Zeit gängige Praxis, wurde aber inzwischen von moderneren Formen bzw. Methoden ersetzt.. Aber im großen und ganzen bekommt man damit schon mal ein gutes gefühl, wie es draußen so sein könnte. Im Prinzip ist das auch nicht schwer, über 15°C nimmt die Formel die Luftfeuchtigkeit zum berechnen der gefühlten Temperatur, darunter die Windgeschwindigkeit. Macht aber schon deutlich, dass viele aspekte in dieser alten Formel nicht wirklich verarbeitet sind, wie zum Beispiel die Sonneneinstrahlung.

Upload der Daten - Windy.com

Was soll das Theater überhaupt ?

Die Daten die man so sammelt sind ja eventuell auch für die Nachbarn interessant. Unserer freut sich zum Beispiel immer über die aktuellen, örtlichen Windgeschwindigkeiten. Aber da ich und vermutlich alle anderen nicht jedem Zugang zum eigenen Netz geben wollen, ist ein teilen der Daten schwierig. Daten ins Netz zu schicken, ist aufwendig, egal ob man Dienste wie Thinkspeak oder die eigene Website nutzt.

Warum also Windy ?

Bei Windy kann man seine Daten einfach hochladen und direkt mit mehreren Wettervorhersagen bzw. Rechenmodellen vergleichen. Außerdem muss man in openHAB nichts installieren und kommt mit sehr sehr wenig Text aus.

Zunächst einmal muss man einen Key (Schlüssel) für die API (application programming interface - Programmierschnittstelle) haben, den bekommt man hier:
https://stations.windy.com/

Dort registriert man seine Station und ist dann auch schon so gut wie fertig.

Jetzt kommt der zweite Teil, wir legen eine Regel in openHAB an. Abgelegt wird die Datei im Rules Ordner mit der Dateiendung .rule.

 

var String WINDY_URL="https://stations.windy.com/pws/update/WINDY.COM-API-KEY"

rule "Sende Wetterdaten alle 5 Minuten an Windy"

when

       Time cron "0 0/5 * * * ?"  

 then    

      var gust = (((Boengeschwindigkeit.state as Number).floatValue)/3.6)

      var wind = (((Windgeschwindigkeit.state as Number).floatValue)/3.6)

      sendHttpGetRequest(WINDY_URL + "&temp=" + ((LUFTTEMPERATUR.state as Number).floatValue) + "&rh=" + ((LUFTFEUCHTIGKEIT.state as Number).floatValue) + "&dewpoint=" + ((TAUPUNKT.state as Number).floatValue) + "&mbar=" + (LUFTDRUCK.state as Number) +  "&winddir=" + (WINDRICHTUNG.state) + "&gust=" + gust + "&wind=" + wind )

end 
Und das wars auch schon. Öfter als 5min kann man eh nicht hochladen, die Items sind alle in Fett markiert und wer noch z.B. Regenmenge o.ö. hochladen möchte, findet hier die entsprechende Anleitung dazu:
Also sehr sehr sehr einfach. Windy zeigt die ersten Daten nicht direkt an, es kann also mal ein paar Stunden dauern, bis Windy.com die Daten anzeigt, aber sobald die einmal auftauchen, wird dann entsprechend bei Dateneingang (max. alle 5 min) aktualisiert.
Mir gefällt besonders gut, dass man die Vorhersagen ändern kann mit denen man seine eigenen Daten vergleichen kann. Ich persönlich nutze meistens den ECMWF (European Centre for Medium-Range Weather Forecasts). Wenn man mit der Maus über die Datenanzeige fährt popt ein Feld auf, in dem ihre eure Werte und die Werte vom Wetterdienst vergleichen könnt. Aber mal als Hinweis, es muss nicht unbedingt das stimmen was der Wetterdienst da anzeigt, die haben nämlich nicht in jedem Ort eine Wetterstation 😉

AS3935 mit ESP-32 per MQTT an openHAB

Ihr braucht natürlich den AS3935 und einen ESP-32, ich nehme wieder meine nodeMCU ESP32 da ich davon noch einen habe. Vom Franklich AS3935 gibt es Diverse schon vorgefertigte Boards, ich habe mich für das DFRobot Lightning Sensor V1.0 entschieden. Da ist schon direkt (fast) alles dran und mann muss so gut wie nichts löten. Zum programmieren des AS3935 benötigt man noch Ardudiono IDE (oder ein Programm seiner wahl). Und natürlich einen funktionsfähigen MQTT Broker (bei mir Mosquito auf einem Raspberry Pi 4).

Zu nächst löten wir auf dem Lighting Detector Board ein zusätzliches Kabel an (bei mir WEISS), dass kommt an den IRQ PIN. Am ESP-32 kommt das weisse Kabel an GPIO 4. Das blaue Kabel kommt an GPIO 22 und das grüne Kabel an GPIO 21 (Das ist die I²C Schnittstelle). Das schwarze Kabel an GND und das Rote Kabel an 3V3, beides ist die Spannungsversorgung.

In der Arudino IDE fehlt noch die Bibliothek PubSubClient.h (für MQTT) und die SparkFun_AS3935.h (für den Blitzsensor).

Im Sketch muss man eigentlich nur noch für die WiFi-Verbindung SSID und Passwort eingeben. Dann noch für die MQTT Verbindung, den Server, Benutzername, Passwort, sketch auf den ESP übertragen und das war es.

Der Sketch überprüft ob eine WiFi verbindung besteht, stellt diese bei bedarf wieder her, gleiches gilt für die MQTT verbindung. Darüber hinaus schickt der Sketch alle 5minuten eine Alivemeldung an den MQTT-Broker. Sollte es Blitzen, schickt der ESP eine Meldung an den Broker, dass es geblitzt hat und natürlich auch, wie weit der Blitz weg war. Letzteres passiert in "Schritten" und nicht beliebig. Angeblich kann der Sensor Blitze in bis zu 40km Entfernung erkennen.....

UPDATE April 2020

Das ganze funktioniert jetzt in beide Richtungen. Der ESP kann nun auch Empfangen. Was tut er damit ? Er gibt auf 2 NEOPIXEL-Sticks (8er) unterschiedliche Farbsignale aus. Ich habe einen Stick als optische Temperaturanzeige der Wetterstation und einen als Statusanzeige für den Blitzsensor vorgsehen. Im Sketch könnt ihr relativ einfach sehen, an welchen Pins die beiden angelötet wurden, ihr könnt aber frei wählen und dann einfach den Sketch ändern.

Was passiert nun ?

Beim einschalten gehen erst mal alle LED´s auf Orange und signalisieren somit, dass das Programm angefangen hat. Nach dem Verbinden ins WiFi Netz und anmelden am MQTT Broker wird die Statusanzeige des Blitzsensor Blau/Grün (je 4 LED´s). Beides geht recht fix. Mein OH2 schickt nun alle 5min eine MQTT Nachricht an den Chanel ESP/input. Inhalt der Nachricht eine Zahl von 1-9. Und je nach dem welche Zahl der ESP nun empfängt, wird die Temperaturanzeige geändert. Beispiel: Zwischen 18-25°C leuchten sie Grün, ab 51 Rot, und unter -10 Dunkelblau.

Sofern das Gerät eine Störung (Rot) und Rauschen (Lila) empfängt, ändert sich entsprechend die Statusanzeige. Bei jedem Durchlauf der Rücksetzung werden die Statusanzeigen automatisch gelöscht.

Wenn es Blitz, fangen beide Streifen an, langsam zu blinken. Auch das geht aus sobald die Statusanzeige gelöscht wird.

 

 

 

 

Der Code

Hinweise zum Sketch

Also, um es vorweg mal klar zu sagen: Eigentlich habe ich von dem Thema keine Ahnung und habe auch nur sehr aufwendig probiert und im Netz gesucht. Die Reconnect (WiFi & MQTT) progammierung geht in so ziemlich allem auf einen Post und dem User  urs_eppenberger zurück.Hier der Link zum POST.

#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <SparkFun_AS3935.h>
#include <Adafruit_NeoPixel.h>

String WiFi_SSID = "SSID";
String WiFi_PW = "WIFI PASSWORT";
const char* mqttServer = "SERVER IP";
const int mqttPort = 1883;
const char* mqttUser = "MQTT BENUTZER";
const char* mqttPassword = "MQTT PASSWORT";

unsigned long waitCount = 0;
uint8_t conn_stat = 0;
unsigned long lastStatus = 0;
unsigned long lastTask = 0;

const char* Status = "{\"Message\":\"ich laufe\"}";

long lastMsg = 0;
char msg[50];
int value = 0;

int flash =0;
int value_1;
long time_1 = 0;
int strip_helligkeitswert = 0;
int periode = 1000;

#define PIN_Strip_a 27 //Strip A - BLITZSENSOR
#define PIN_Strip_b 26 //Strip B - WETTERSTATION
#define NUMPIXEL_a 8
#define NUMPIXEL_b 8
#define AS3935_ADDR 0x03
#define INDOOR 0x12
#define OUTDOOR 0xE
// Interrupt pin for lightning detection
const int lightningInt = 4;
#define LIGHTNING_INT 0x08
#define DISTURBER_INT 0x04
#define NOISE_INT 0x01

int noiseFloor = 2;
int intVal = 0;

Adafruit_NeoPixel strip_a = Adafruit_NeoPixel(NUMPIXEL_a, PIN_Strip_a, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip_b = Adafruit_NeoPixel(NUMPIXEL_b, PIN_Strip_b, NEO_GRB + NEO_KHZ800);
WiFiClientSecure TCP;
WiFiClient espClient;
PubSubClient client(espClient);
SparkFun_AS3935 lightning(AS3935_ADDR);

uint32_t blue = strip_a.Color(0, 0, 255);
uint32_t orange = strip_a.Color(238, 154, 0);
uint32_t green = strip_a.Color(0, 255, 0);
uint32_t red = strip_a.Color(255, 0, 0);
uint32_t yellow = strip_a.Color(255, 255, 0);
uint32_t purple = strip_a.Color(160, 32, 240);
uint32_t aqua = strip_a.Color(135, 206, 250);
uint32_t navy = strip_a.Color(0, 0, 205);
uint32_t gray = strip_a.Color(143, 143, 143);
uint32_t off = strip_a.Color(0, 0, 0);

void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA);
pinMode(lightningInt, INPUT);
strip_a.begin();
strip_b.begin();
delay(50);
strip_a.fill(orange, 0, 8);
strip_b.fill(orange, 0, 8);
strip_a.setBrightness(5);
strip_b.setBrightness(5);
delay(100);
strip_a.show();
strip_b.show();
delay(500);
client.setCallback(callback);
Wire.begin();
lightning.begin();
lightning.setIndoorOutdoor(OUTDOOR);
}

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();

if ((String(topic) == "ESP321/input")&&(flash == 0 )) {
Serial.print("Changing output to ");
if(messageTemp == "1"){
Serial.println("1 - navy");
strip_b.fill(navy, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "2"){
Serial.println("2 - blue");
strip_b.fill(blue, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "3"){
Serial.println("3- aqua");
strip_b.fill(aqua, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "4"){
Serial.println("4 - gray");
strip_b.fill(gray, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "5"){
Serial.println("5 - green");
strip_b.fill(green, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "6"){
Serial.println("6 - yellow");
strip_b.fill(yellow, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "7"){
Serial.println("7 - orange");
strip_b.fill(orange, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "8"){
Serial.println("8 - red");
strip_b.fill(red, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}
else if(messageTemp == "9"){
Serial.println("9 - purple");
strip_b.fill(purple, 0, 8);
strip_b.setBrightness(255);
strip_b.show();
}

}
}

void loop() {
// start of non-blocking connection setup section
if ((WiFi.status() != WL_CONNECTED) && (conn_stat != 1)) { conn_stat = 0; }
if ((WiFi.status() == WL_CONNECTED) && !client.connected() && (conn_stat != 3)) { conn_stat = 2; }
if ((WiFi.status() == WL_CONNECTED) && client.connected() && (conn_stat != 5)) { conn_stat = 4;}
switch (conn_stat) {
case 0: // MQTT and WiFi down: start WiFi
Serial.println("MQTT and WiFi down: start WiFi");
WiFi.begin(WiFi_SSID.c_str(), WiFi_PW.c_str());
conn_stat = 1;
break;
case 1: // WiFi starting, do nothing here
Serial.println("WiFi starting, wait : "+ String(waitCount));
waitCount++;
break;
case 2: // WiFi up, MQTT down: start MQTT
Serial.println("WiFi up, MQTT down: start MQTT");
client.setServer(mqttServer, mqttPort);
client.connect("ESP32Client", mqttUser, mqttPassword );
conn_stat = 3;
waitCount = 0;
break;
case 3: // WiFi up, MQTT starting, do nothing here
Serial.println("WiFi up, MQTT starting, wait since: "+ String(waitCount));
waitCount++;
break;
case 4: // WiFi up, MQTT up: finish MQTT configuration
Serial.println("WiFi up, MQTT up: finish MQTT configuration");
client.publish("ESP321/Status", "MQTT Verbunden");
client.subscribe("ESP321/input");
flash = 0;
strip_a.fill(green, 0, 4);
strip_a.show();
strip_a.fill(blue, 4, 4);
strip_a.setBrightness(50);
strip_a.show();
conn_stat = 5;
break;
}
// end of non-blocking connection setup section

// start section with tasks where WiFi/MQTT is required
if (conn_stat == 5) {
if (millis() - lastStatus > 300000) {
Serial.println(Status);
client.publish("ESP321/Status", "MQTT Alive");
client.publish("ESP321/Disturber", "-");
client.publish("ESP321/Noise", "-");
client.publish("ESP321/Blitzerkennung", "-");
client.publish("ESP321/Blitzentfernung", "-");
strip_a.fill(off, 0, 8);
strip_a.setBrightness(30);
strip_a.show();
lastStatus = millis();
flash = 0;

}

if((digitalRead(lightningInt) == HIGH) &&(flash == 0 )){
intVal = lightning.readInterruptReg();
if(intVal == NOISE_INT){
client.publish("ESP321/Noise", "Rauschen empfangen");
Serial.println("Rauschen!");
strip_a.fill(purple, 0, 8);
strip_a.setBrightness(100);
strip_a.show();
lastStatus = millis();
}
else if((intVal == DISTURBER_INT)&&(flash == 0 )){
client.publish("ESP321/Disturber", "Störung empfangen");
Serial.println("Störung!");
strip_a.fill(red, 0, 8);
strip_a.setBrightness(100);
strip_a.show();
lastStatus = millis();
}
else if(intVal == LIGHTNING_INT){
client.publish("ESP321/Blitzerkennung", "Blitz erkannt");
Serial.println("Blitz erkannt");
byte distance = lightning.distanceToStorm();
char s [20];
sprintf (s, "%d", lightning.distanceToStorm());
client.publish("ESP321/Blitzentfernung", (const char*) s);
strip_a.fill(blue, 0, 8);
strip_b.fill(blue, 0, 8);
flash =1;
lastStatus = millis();
}
}

if (flash == 1){
time_1 = millis();
value_1 = 128+127*sin(2*PI/periode*time_1);
strip_helligkeitswert = value_1;
strip_a.setBrightness(strip_helligkeitswert);
strip_b.setBrightness(strip_helligkeitswert);
strip_a.show();
strip_b.show();
}
}
client.loop();
}