MQTT und Datenagnostik

MQTT ist datenagnostisch, d.h. es schert sich einen Dreck um die Art der Daten, deshalb kann man auch Grafiken usw. usf. dort (aus)tauschen.

https://stackoverflow.com/questions/37499739/how-can-i-send-a-image-by-using-mosquitto

Senden:

import paho.mqtt.client as mqtt

def on_publish(mosq, userdata, mid):
    mosq.disconnect()

client = mqtt.Client()
client.connect("test.mosquitto.org", 1883, 60)
client.on_publish = on_publish

f=open("b.jpg", "rb") #3.7kiB in same folder
fileContent = f.read()
byteArr = bytearray(fileContent)
client.publish("image",byteArr,0)

client.loop_forever()

Empfangen:

import paho.mqtt.client as mqtt

def on_connect(client, userdata, rc):
    print("Connect" + str(rc))
    client.subscribe("image") 

def on_message(client, userdata, msg):
    print "Topic : ", msg.topic
    f = open("/tmp/output.jpg", "w")  #there is a output.jpg which is different
    f.write(msg.payload)
    f.close()

client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("test.mosquitto.org", 1883, 60)

client.loop_forever()

Damit lässt sich auch ASCII-Art darstellen

Tasmota reset

reset-Modi in Tasmota, siehe: https://tasmota.github.io/docs/Commands/#management
„reset 4“ lässt WiFi-Konfiguration, passt!

Reset1 = reset device settings to firmware defaults and restart (see warning below)
2 = erase flash, reset device settings to firmware defaults and restart
3 = erase System Parameter Area in flash (Wi-Fi calibration and related data) and restart (see warning below)
4 = reset device settings to firmware defaults but retain Wi-Fi credentials and restart
5 = erase all flash and reset parameters to firmware defaults but keep Wi-Fi settings and restart
6 = erase all flash and reset parameters to firmware defaults but keep Wi-Fi and MQTT settings and restart
(Erase of flash can take a few seconds to complete and there is no output during the erase process on the serial or web console)
99 = reset device bootcount to zero
⚠ For reset 3and reset 1, device must be power-cycled in order to load new Wifi System parameters.

OpenVPN: Android => Server für Videostreaming/-überwachung

Passend zur Automate-Lösung noch die Möglichkeit bei Bedarf auf Videostream zuzugreifen.

Ziel: Androidwerkzeuge wie IP Webcam über 4G aufzurufen
Lösung: Zertifikatsbasiertes VPN von Android per 4G auf Server mit öffentlicher IP (2.99€/Monat)

  1. OpenVPN-Server installieren
  2. „OpenVPN für Android“ auf Androidphone installieren
  3. server.conf und client.conf erstellen
    in server.conf das Übliche + Zeile „client-to-client“, dann sehen sich die Clients
  4. Zertifikate für Server und Client mit easy-rsa erstellen (ca.crt, server.crt, server.key, client.crt, client.key, dh.pem)
  5. ca.crt, client.conf und client.key auf Androidphone übertragen und in „OpenVPN für Android“ einpflegen
  6. VPN von Android initiieren
  7. IP Webcam starten und auf VPN-IP zulassen

TelegramBot

Wieder mal ein Versuch das zu strukturieren.
Angelehnt an: https://www.tutonaut.de/anleitung-einfuehrung-in-telegram-bots-nachrichten-und-dateien-aus-dem-terminal-senden/

Wir brauchen:

  1. Chat mit BotFather: /newbot =>Ergebnis: Nutzer– , Bot-Name, Token:
    DeineMudda, grafanabot, 1203576106:FAAUgddCGAecDAClWc***Ia…
    Der Bot-Name grafanabot ist da irgendwie mit dem Token verknüpft, taucht später nicht mehr auf (?).
  2. Einmal Chat beginnen mit Fon auf Nutzername DeineMudda
  3. Chat-ID herausfinden:
    https://api.telegram.org/bot1203576106:FAAUgddCGAecDAClWc***Ia/getUpdates
    Wenn das leer ist, nochmal was reinchatten.
    =>Chat-ID 12345678
  4. Alles da, Message senden mit:
    https://api.telegram.org/bot1203576106:FAAUgddCGAecDAClWc***Ia/sendmessage?12345678&text=Werdasliestwirdblind!

Alert mit Grafana, geht nur mit Diagrammen, nicht mit „gauge“: https://gist.github.com/ilap/cb6d512694c3e4f2427f85e4caec8ad7

Alert mit Node-RED:https://github.com/rdmtc/RedMatic/wiki/Nachrichten-an-Telegram-versenden

MAC-Adresse auslesen ESP8266 bzw. ESP32

Wenn man die MAC-Adresse male eben für den DHCP-Server braucht ist esptool.py das Mittel wer Wahl. ESP an den USB-Port und gib ihm:

esptool.py read_mac

esptool.py v2.8
Found 1 serial ports
Serial port /dev/ttyUSB0
Connecting….
Detecting chip type… ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: 2c:f4:32:3c:82:d1
Uploading stub…
Running stub…
Stub running…
MAC: 2c:f4:32:3c:71:d1
Hard resetting via RTS pin…

Ausreisser (outlier) löschen

Manche Messschaltungen produzieren gelegentlich Ausreisser,  die elektronisch schwierig in den Griff zu bekommen sind.

Dreckige Lösungsansätze

  1. Gleich mit Node-RED auf den möglichen Bereich filtern, dann landet der Schrott nicht in der DB.
  2. Am anderen Ende (Grafana) auf einen bestimmten Bereich filtern.
  3. Nachträglich aus der InfluxDB löschen, hier der Code.
    Ablauf: Ausreisser identifizieren und in delete_timestamps.txt schreiben, danach diese löschen.
    Schicker wäre ein

    delete from z1_aktuell where value > 1000

    Geht nicht, da nur Zeitstempel gelöscht werden können, also mit CURL:

curl -G 'http://localhost:8086/query?db=smartmeter' \
  --data-urlencode "q=SELECT * FROM metrics WHERE value>10000" |\
  jq -r "(.results[0].series[0].values[][0])" > delete_timestamps.txt

for i in $(cat delete_timestamps.txt); do
  echo $i;
  curl -G 'http://localhost:8086/query?db=smartmeter' \
    --data-urlencode "q=DELETE FROM metrics WHERE time='$i'"; 
done

Smartmeter mit Tasmota

Entwurf, noch nicht fertig

Ablauf

  1. Sourcecode runterladen und entpacken:
    https://github.com/arendst/Tasmota/archive/v8.2.0.zip
  2. Mit Visual Studio Code öffnen, folgende Dateien umbenennen:
    im Wurzelverzeichnis:
    platformio_override_sample.ini => platformio_override.ini
    im tasmota-Verzeichnis:
    user_config_override_sample.h => user_config_override.h
  3. platformio_override.ini
  4. user_config_override.h unter Linux:
    upload_port = COM5 => upload_port /dev/ttyUSB0

    SML aktivieren
    Script einschalten, Rules abschalten (falls vorher aktiviert)
    #define USE_SML_M
    #ifndef​ USE_SCRIPT
    #define​ USE_SCRIPT​ //# adds about 17k flash size, variable ram size
    #endif
    #ifdef​ USE_RULES
    #undef​ USE_RULES
    #endif
  5. Kompilieren und hochladen
  6. Infrarottransistor anschliessen, konfigurieren
  7. In console: sensor53 d1 eingeben und mit Infrarotfernbedienung da mal drauffeuern, irgendein Hexscheiss flirrt da vorbei
  8. Für zwei (!) ISKRAs an einem (!) ESP8266, siehe hier:  https://forum.creationx.de/forum/index.php?thread/1095-d0-z%C3%A4hler-sml-auslesen-mit-tasmota/&postID=31261#post31261
    Leseköpfe hängen an 12 und 13 (GPIO 12 und 13)
    sensor53 d1 => 12
    sensor53 d2 => 13 oder so

Tasmota und Schalten

Tasmota als MQTT-Client kann Ausgänge des ESPs schalten

  1. Einstellungen, Gerät konfigurieren, GPIOs auf Relais stellen, auch mehrere
  2. In der „Console“ die MQTT-Topics herausfinden
  3. Per MQTT die Topics mit on/off füttern:
    mosquitto_pub -h 10.16.1.246 -t cmnd/tasmota_shit/POWER2 -m OFF

Tasmotizer Teil 101

Für Windows gibt’s auf github eine .exe, tut auf Anhieb.

Probleme beim Installieren unter Debian Buster, jede Menge verschiedene Fehlermeldungen.

So geht’s dann doch: Pythonkram installieren, pip upgraden, tasmotizer installieren

apt install python3-pip python3-serial python3-pyqt5 --reinstall
pip3 install --upgrade pip
pip install tasmotizer

Guter Einstieg  Tasmota

Und das hier, fast noch besser:

ESP32 Wemos 128×64 OLED

Sketch ist fuer 128×32, also zu „flach“

 

Code

#include "WiFi.h"
#include "Wire.h"
#include "SSD1306.h"

SSD1306 display (0x3c, 5, 4);

void setup()
{
    Serial.begin(115200);
    
    // Set WiFi to station mode and disconnect from an AP if it was previously connected
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
    Serial.println("Setup done");

    display.init();
    display.flipScreenVertically ();
    display.clear();
    display.setTextAlignment (TEXT_ALIGN_LEFT);
    display.setFont(ArialMT_Plain_10);
}

void loop()
{
    Serial.println("scan start");
    display.setColor(BLACK);
    display.fillRect(0,0,127,10);
    display.setColor(WHITE);
    display.drawString(0, 0, "Scanning...     ");
    display.display();
    
    // WiFi.scanNetworks will return the number of networks found
    int n = WiFi.scanNetworks();
    display.clear();
    display.drawString(0, 0, "Scan results:");
    display.display();    
    Serial.println("scan done");
    if (n == 0) {
        Serial.println("no networks found");
        display.drawString(0,10,"No networks found");
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        for (int i = 0; i < n; ++i) {
            // Print SSID and RSSI for each network found
            Serial.print(i + 1);
            Serial.print(": ");
            Serial.print(WiFi.SSID(i));
            display.drawString( 0 , i*8+10  , String(WiFi.SSID(i)));
            Serial.print(" (");
            Serial.print(WiFi.RSSI(i));
            display.drawString( 100 , i*8+10  ,String(WiFi.RSSI(i)));
            Serial.print(")");
            Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*");
            delay(10);
        }
    }
    Serial.println("");
    display.display();
    // Wait a bit before scanning again
    delay(5000);
}

 

Grafana, InfluxDB, Node-Red

Dieser Artikel gilt speziell für den Raspberry Pi, sollte aber weitgehend auch auf normalen Rechnern tun.

Stichwort Sicherheit: Alle beteiligten Komponenten lassen sich durch Passwörter, Zertifikate und Verschlüsselung sicher betreiben, aus pädagogischen Gründen wird darauf weitgehend verzichtet.

Kurswechsel, Ziel ist Grafana für die Visualisierung der Kurven und dafür gibt es in der neuesten Version lediglich ein rudimentäres Modul für MySQL, aber für InfluxDB ein Gutes.

Der Versuch MySQL in die schöne neue IoT-Welt rüberzuretten ist aus meiner Sicht erstmal gescheitert, das hat mehrere Gründe.

InfluxDB ist speziell für „time series“ entwickelt, genau diese lädt die riesige Sensorenwolke wie blöd auf den MQTT-Brokern ab.

ESP8266 (mit DHT11/22-Sensor) => MQTT => Node-Red => InfluxDB => Grafana

ESP8266 und MQTT (falls den Broker hier jemand sucht, der „Mosquitto“ läuft auf einem Banana-Pi nebenan  (apt install mosquitto), bleiben Node-Red, InfluxDB und Grafana

„Neue“ Anwendungen im IoT-Bereich entwickeln sich sehr schnell weiter, hierbei kommt Debian mit seinem recht konservativen Ansatz im Repository an seine Grenzen, wir nutzen „Fremdpakete“.

Probleme bei Stretch für den Rasperry Pi

  • Node-Red: veraltet und es fehlt der wichtige „Manage palette“-Button um Nodes nachzuinstallieren, zumindest hab ich sie nicht gefunden
  • Grafana aus dem Stretch-Repository ist ebenfalls episch veraltet und es tut auch nicht, beim Anmelden auf http://10.0.0.244:3000 passiert…Nichts!
  • der ganze Node.js-Kram als Unterbau für Node-Red ist auch veraltet
  • InfluxDB trauen wir mal: apt install influxdb influxdb-client Zu Unrecht vertraut, tut auch nicht richtig.
    Installation von InfluxDB siehe hier, „jessie“ durch „stretch“ ersetzen:
    https://gist.github.com/boseji/bb71910d43283a1b84ab200bcce43c26

 

Node-Red: Alles lesen: https://nodered.org/docs/hardware/raspberrypi

oder einfach folgenden Befehlt auf der Kommandozeile als root eingeben

bash <(curl -sL https://raw.githubusercontent.com/node-red/raspbian-deb-package/master/resources/update-nodejs-and-nodered)

Danach für automatischen Start:

systemctl enable nodered.service

 

Grafana für den Pi holen wir uns von hier:

https://bintray.com/fg2it/deb/grafana-on-raspberry/_latestVersion

Installation: dpkg -i grafana_xyz.deb

danach: apt -f install falls Abhängigkeiten aufgelöst werden müssen.

Für Start und Autostart:

/bin/systemctl daemon-reload
/bin/systemctl enable grafana-server

Danach laufen einige Dienste auf dem Server, festzustellen über externen Portscan oder besser über ein „netstat -tulpn“ auf dem Server.
(nmap scannt übrigens per default Port 1880 von Node-Red nicht)

root@deinemudda:~# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name 
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 417/sshd 
tcp 0 0 0.0.0.0:1880 0.0.0.0:* LISTEN 365/node-red 
tcp 0 0 0.0.0.0:1883 0.0.0.0:* LISTEN 390/mosquitto 
tcp6 0 0 :::8083 :::* LISTEN 413/influxd 
tcp6 0 0 :::8086 :::* LISTEN 413/influxd 
tcp6 0 0 :::22 :::* LISTEN 417/sshd 
tcp6 0 0 :::8088 :::* LISTEN 413/influxd 
tcp6 0 0 :::1883 :::* LISTEN 390/mosquitto

InfluxDB kann per Kommandozeile influx verwaltet werden, hier gibt’s hier Infos:
https://docs.influxdata.com/influxdb/v1.2/introduction/getting_started/

root@deinemudda:~# influx
Connected to http://localhost:8086 version 1.3.5
InfluxDB shell version: 1.3.5
> create database temperatur
> create database luftfeuchte

 

Influx-Magie:
show shards => Zeigt den Scherbenhaufen

use database bullshit => Laden von bullshit
select * from haufen  => Zeigt die Inhalte der Messung „haufen“ in der Datenbank „bullshit“
show measurements => zeigt Messungen in der gewählten Datenbank
show stats => Messstatistiken anzeigen

 

Node-Red abonniert die Topics vom MQTT-Broker und pumpt diese in InfluxDB, notwendiger Code => Null Zeilen, alles fertig.

tempfeuchte.png

Grafana

Grafana soll die InfluxDB-Daten visualsieren, das Dashboard von Node-Red kann das auch direkt per MQTT, aber nach einem Reboot ist alles weg und das „geht gar nicht“.

http://10.0.0.241:3000  (Benuzter: admin Passwort: admin)  => add datasource => …
danach: neues Dashboard => Graph => auf Graph-/Dashboardtitel klicken um das editieren zu können (rot und kursiv, da ich das 2h nicht gefunden habe)

http://docs.grafana.org/features/datasources/influxdb/

datasource.png

Zu allem Elend kommt immer eine „mean“-Fehlermeldung beim Generieren des Plots mit Grafana.

Grund nach mehrstündigem Ver-/Suchen: MQTT bzw. InfluxDB legt die Daten als String in die Datenbank, Mittelwert ist daraus nicht zu bilden. quick&dirty-Lösung, in Node-Red ein json-Node wandelt das um.

stringinteger.png

In Grafana sieht das dann so aus:

tempfeuchtegrafana2.png

 

Interessante Links zum Thema
http://air.imag.fr/index.php/Developing_IoT_Mashups_with_Docker,_MQTT,_Node-RED,_InfluxDB,_Grafana
https://primalcortex.wordpress.com/2017/02/23/setting-up-a-grafana-dashboard-using-node-red-and-influxdb-part-1-installing/

Grafana-Tuning:
http://www.neteye-blog.com/2017/02/how-to-tune-your-grafana-dashboards/

RFID-Reader RC522 am ESP8266

Ohne wifi, nur über serielle Verbindung UID auslesen:

http://funduino.de/nr-18-rfid-kit
Hier folgende Werte ändern:

#define SS_PIN 10 D8// SDA an Pin 10 (bei MEGA anders)

#define RST_PIN 9 D3// RST an Pin 9 (bei MEGA anders)

 

Gute Zusammenfassung zum Thema RFID: http://www.msxfaq.de/sonst/bastelbude/rfid.htm