MySQL-Daten zur Steuerung von NodeMCU verwenden.

Hi Zusammen,

erstmal ein schönes neues Jahr (kann man ja heute noch sagen).
Nachdem ich mich seit etwa zwei Wochen fast ausschließlich nur noch damit beschäftigt habe und noch keine funktionierende Lösung gefunden habe, dürft ihr mich retten.

Mein Problem: Ich habe NodeMCU´s in Betrieb, die zB. die Außenhelligkeit messen und die Daten dann in eine MySQL-Datenbank auf einem RasPi schreiben. Nach einigen Versuchen hat das gut funktioniert, ich habe alle fünf Minuten einen aktuellen Wert.
Mit dem Auslesen allerdings stehe ich (als nicht-Informatiker) derzeit aber irgendwie an einer Wand.
Ich bräuchte einen Code/Sketch (ob über PHP oder nicht ist mir egal, es soll nur funktionieren), mit dessen Hilfe ich den letzten Wert aus der Tabelle abfragen kann um mit diesem dann im Arduino/NodeMCU eine Methode auszulösen (oder eben nicht).
Bsp: Außenhelligkeit hat Schwellenwert unterschritten → Rolladen herunterfahren.
Ideal wäre ein Beispielcode, der an viele verschiedene Situationen angepasst werden kann (wie zB der Upload-Code, bei dem nur Variablen geändert bzw ergänzt werden müssen).

Anbei mal meine Codeschnipsel, die für das Eintragen verantwortlich sind (ja, im Upload-Code ist bereits eine Abfrage inbegriffen, ich verstehe allerdings nicht wirklich, ob und wie ich diese nutzen kann.)

  1. Im ESP8266 ist folgendes Stück vorhanden:
#include <ESP8266WiFi.h>

//_richte Netzwerkverbindung ein
const char* ssid      = "WLan-Name";               //_Name des WLan
const char* password  = "WLan-Passwort";      	   //_WLan-Passwort
const char* host      = "xxx.xxx.xxx.xxx";         //_IP der Datenbank (Synology DS-212) (Server-IP)
const int   port      = 80;                        //_Server Port 80



void datenSenden() {
  //_verwenden der WiFiClient-Klasse, um TCP-Verbindungen zu erstellen
  WiFiClient client;
  
  if (!client.connect(host, port)) {
    Serial.println("Connection failed");
    return;
  }
  

  String url = "http://IPADRESSERASPI/DATEINAME.php";    //_Übergabe via PHP-Script auf RasPi
  url += "?D1="+(String)hell;			//Variable01
  url += "&D2="+(String)temperatur;	//Variable02
  url += "&name=Aussenstation01";		//Signatur, von wo aus eingetragen

  Serial.print("Requesting URL: "); Serial.println(url);
  

  //_Anfrage an den Server
  
  client.print(String("GET ") + url + "HTTP/1.1\r\n" +
            "Host: " + host + "\r\n" +
            "Connection: close\r\n\r\n");
  unsigned long timeout = millis();
  while(client.available() == 0) {
    if (millis() - timeout > 5000) {
      Serial.println(">>> Client Timeout !");
      client.stop();
  //    return;
    }
  }

  //Read all the lines of the reply from server and print them to Serial
  while(client.available()) {
    String line = client.readStringUntil('\r');
    Serial.println(line);
  }
}

dazugehöriges PHP-Skript:

<?php
        //Abfrage der Variablen
		
	  $helligkeit     = $_GET["D1"];
	  $temperatur  = $_GET["D2"];
	  $autor	    = $_GET["D3"];
        $user = 'DB-User';
        $pass = 'DB-Passwort';
        $db = new PDO( 'mysql:host=localhost;dbname=DB-Name', $user, $pass );
        //Fehlermeldungen aktivieren
        $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
        //Eintrag in Tabelle machen
        $sql = "INSERT INTO dbtabelle (helligkeit,temperatur,autor) VALUES ( ':eins' ,':zwei',':drei');";
        $alt = array(":eins",":zwei",":drei");
        $neu = array($helligkeit,$temperatur,$autor);
        $sql = str_replace($alt, $neu, $sql);
        $db-> exec($sql);
        // Abfrage durchführen
        $sql = "SELECT * FROM test";
        $result = $db->query( $sql );
        // Tabelle zeilenweise ausgeben
        echo "<font size=\"5\">Ausgabe der Datensätze:</font> 

";
        foreach( $result as $row ){
            echo "Eintrag Nr: " . $row[ 'id' ] . "
" . "Helligkeit: " . $row[ 'helligkeit' ] ."
". "Temperatur: " . $row[ 'temperatur' ] ."
" ."Autor: ". $row['autor']."
"."

";
        }
      ?>
      <?php

Danke bereits im Vorfeld für eure Mühe, vielleicht kann es mir ja einer verständlich machen oder mir eine Lösung geben.

Gruß Chris

Warum benennst Du Deine SQL-Platzhalter :eins usw. warum nicht so, wie die Werte heißen (:helligkeit)?

Wie willst Du den letzten Wert finden, wenn Du dazu keine Info mitlieferst?

Du hast die Wahl zwischen einem Autoincrement-Feld und einem TIMESTAMP.

Mal am Beispiel TIMESTAMP Feldname tmst, den als PK einrichten

"INSERT INTO dbtabelle (tmst, helligkeit,temperatur,autor) VALUES ( now(), ':eins' ,':zwei',':drei');"

Für die Abfrage:

"SELECT * FROM dbtabelle WHERE tmst = (SELECT MAX(tmst) FROM dbtabelle);"

Gruß Tommy

Ich bräuchte einen Code/Sketch (ob über PHP oder nicht ist mir egal, es soll nur funktionieren), mit dessen Hilfe ich den letzten Wert aus der Tabelle abfragen kann um mit diesem dann im Arduino/NodeMCU eine Methode auszulösen (oder eben nicht).

Ist mir unklar.

Möchtest du "den letzten Wert aus der Tabelle"

a) als Antwort auf die Einmeldung der Außenhelligkeit des NodeMCU antworten?
b) periodisch vom NodeMCU am Rasperry abfragen lassen (wiederum der NodeMCU als Client, aber separater "Task")?
c) periodisch vom Rasperry zum NodeMCU pushen (NodeMCU als Server)?

Ich kann diese deutschen Codeschnipsel bald nicht mehr sehen (brech, kotz). Wir programmieren english !!!.

Wenn du php auf dem Raspi verwendest:
Schicke eine Anfrage per GET oder POST an eine php Datei auf dem Raspi (wo dann die SQL Abfrage ausgeführt wird und warte auf die Antwort des Webservers:

bool get_data(String data) {
  String msg = "GET /[dirctory]/get_data.php?foo=" + data * "\r\n";
    // Use WiFiClient class to create TCP connections
    WiFiClient client;
    if (!client.connect([myHOST], [myPORT])) {
      return false;
    }
    // This will send the request to the server
    client.println(msg + " HTTP/1.1");
    client.println("Host: " + [myHOST]);
    client.println("Connection: close\r\n");
    delay(500);

    String response = "";

    // Read all the lines of the reply from server and print them to Serial
    while (client.available()) {
      response = client.readStringUntil('\r');
      Serial.print(response);

      //Hier kannst die den response auswerten.

     if (response.indexof("bar") > -1) {
   
       doSomething(bar);

     }
  }
  client.flush();
  client.stop();

  return true;
}

freddy64:
Ich kann diese deutschen Codeschnipsel bald nicht mehr sehen (brech, kotz). Wir programmieren english !!!.

Wenn Du jetzt noch sagen könntest, auf welchen Teil welchen Codeschnipsels Du Dich beziehst...

Gruß

Gregor

int türstellung = 1,0;
oder was man auch immer hier liest

Das ist doch Schrott²

Ich habe vor Jahren für eine Firma die Fehlerursache für eine nichtfunktionierende Java-Anwendung finden müssen. Der Softwareschreiber hat darauf bestanden, dass unsere Hardware Schrott ist und ich war der Meinung, dass seine Software Schrott ist.
Dann habe ich das ganze Programm durch einen Decompiler gejagt (bei java Apps geht das). Da wurde der ganze Quellcode wieder sichtbar

Durch mehrfache gleichzeitige exclusive Schreibzugriffe auf eine Datenbank und funktionen wie: löscheDas(), hat es mehrmals täglich Boom gemacht und 20 Mitarbeiter hatten plötzlich eine zusätzliche Raucherpause, bis der Webserver wieder neu gestartet war.

Und wegen der Globalisierung sitzt plötzlich ein Russe oder Inder an der Software und soll die weiter entwickeln. Alle Variablen und Kommentare sind aber nur auf Spanisch oder Norwegisch.
Wer soll dann damit arbeiten?

Deshalb bin ich für einen Code mit englischen Variablen, englischen Funktionen und englischen Kommentaren.

freddy64:
int türstellung = 1,0;
oder was man auch immer hier liest

Ja nu ... es gibt auch Leute, die Dateien so benennen. Womöglich mit Umlauten und Leerzeichen ... brrr.

Hast ja irgendwie recht, irgendwie aber auch nichso. Aus der Sicht eines spezialisierten und erfahrenen Computerzeug-Insiders ist das blöd. Aber es geht halt - vor allen Dingen für Leute, die eben nichso Insider sind. An Händys hast Du Dich auch gewöhnt.

freddy64:
Deshalb bin ich für einen Code mit englischen Variablen, englischen Funktionen und englischen Kommentaren.

... die im Idealfall ausschließlich aus Zeichen bis max. ASCII 127 bestehen.

Ich weiß, was Du meinst.

Gruß

Gregor

freddy64:
Ich kann diese deutschen Codeschnipsel bald nicht mehr sehen (brech, kotz). Wir programmieren english !!!.

So geht es mir, wenn ich Deine unqualifizierten Beiträge lese.

Gruß Tommy

Edit: Der Einzige, der hier

int türstellung = 1,0;

verwendet, bist doch Du.

Hi

Ich kann die Sicht von freddy64 durchaus nachvollziehen, bin selber aber eher der Meinung, wenn man sich schon im deutschen Forum bewegt, wird's wohl an der Sprache hapern (meld (*1)), man hat 'den Kürzeren' gezogen und kann Deutsch (Gruß an Uwe :wink: (*2)) oder ist einfach nur ein guter Mensch, Der auch dem dummen Deutschen(*3) etwas Code flicken will.

Bei den Threads hier wird wohl zum Großteil Erstes zutreffen.
Und genau Dann reagiere ich allergisch auf (d)englische Kommentare, weil Das halt wohl cool ist - ich aber nicht in der Lage bin, mit Leuten zu kommunizieren, Die die Kommentare 'von Haus aus' lesen können.

So unterscheiden sich die Geister :slight_smile:

MfG

*1 - Mit Händen und Füßen bekomme ich mich auch mit einem Englänger unterhalten, zumindest hatten wir viel Spaß (und es war Bier/Rotwein im Spiel)
*2 - Eventuell war dieser Forenzweig ja auch der ausdrückliche Wunsch von Uwe, ich will Ihm hier NIX unterstellen (und ja, das Nix wäre als Nichts deutscher)
*3 - sprachlich gesehen - man kann Intelligent sein, wie man will - wenn's mit der Sprache nicht klappt, ist's halt trotzdem blöd.

*2 - Eventuell war dieser Forenzweig ja auch der ausdrückliche Wunsch von Uwe, ich will Ihm hier NIX unterstellen (und ja, das Nix wäre als Nichts deutscher)

Nein, der war schon da als ich angefangen habe im Forum zu schreiben.

Ich sehe kein Problem sein Arduino-Programm mit für sich verständlichen Variablen, Funktionsnamen und Komentaren zu verwenden. Wenn man um Hilfe bittet, dann sollten die Namen den um Hilfe Gebetenen verständlich sein.

Anders sieht es aus wenn man ein Programm bzW Bibliothek veröffentlichen möchte. Da sehe ich Englich schon überaus vorteilhaft.

In einem komerziellen Programm sehe ich Englisch auch vorteilhaft und gebe freddy64 recht.

Hier im Forum sind einfach viele User die für sich selbst programmieren und da ist Deutsch im Sketch kein Problem.

Grüße Uwe

PS:Heut viel's mir schwer die Leute mit denen ich in der Arbeit geredet habe, immer mit der richtigen Sprache anzusprechen. Hab 3-4 mal die falsche benutzt. Eine Spanierin die englisch sprach ist auch (für mich) nicht so leicht verständlich).

Diese ganze deutsch-englisch Diskussion ist sinnarm. Insbesondere, wenn der TO eh nicht mehr mitliest und sich nicht zu Wort meldet.

Kann zu.

Warum benennst Du Deine SQL-Platzhalter :eins usw. warum nicht so, wie die Werte heißen (:helligkeit)?
Hab das so aus einem "Tutorial" herauskopiert, um überhaupt erstmal das ganze funktionsfähig zu bekommen und dann das ganze für meine Bedürfnisse umzubauen. Frei nach dem Motto: "Ever touch a running system" :wink:

Wie willst Du den letzten Wert finden, wenn Du dazu keine Info mitlieferst?
Hab ne automatische "ID" mit drin, die aber über die MySQL-Datenbank selbst erstellt und fortgeführt wird. Aber dank deinem Abfrage-Tipp hab ich das auch mit der Variable hinbekommen. Jedenfalls zeigt es mir den korrekten Eintrag auf dem PC an, wenn ich die PHP-Datei im Browser aufrufe. Muss halt noch rausfinden, wie ich diese Daten zur Weiterverwendung auf dem Mikrocontroller nutzen kann.

b) periodisch vom NodeMCU am Rasperry abfragen lassen (wiederum der NodeMCU als Client, aber separater "Task")?
Genau so. Ich hatte vor, in regelmäßigen Abständen diese Werte (in dem Fall die Helligkeit im Außenbereich) abzufragen und bei Unterschreiten eines Schwellenwertes zB. einen Rolladen automatisch herunterfahren zu lassen.

Ich kann diese deutschen Codeschnipsel bald nicht mehr sehen (brech, kotz). Wir programmieren english !!!.
Satzzeichen sind keine Rudeltiere (Sorry, das musste sein) :wink: - Ja, auch ich verstehe deine Meinung und bin da auch vollkommen bei dir. Allerdings geht es mir auch darum, dass meine Kinder auch mit in die Materie einsteigen können und nicht erstmal mit einem Wörterbuch die Variablen übersetzen müssen. Der Arduino ist ja schließlich auch zum einfachen Einstieg in die elektronische Welt gedacht.

Ich werde das mit GET und POST mal etwas mehr vertiefen - das scheint mir der Weg zur Lösung zu sein.

Diese ganze deutsch-englisch Diskussion ist sinnarm. Insbesondere, wenn der TO eh nicht mehr mitliest und sich nicht zu Wort meldet.
In ersterem muss ich dir zustimmen. Das trägt nicht zu Lösungen bei und hilft auch anderen nicht, wenn sie nur Off-Topic lesen müssen.
Zu zweitem: Ich muss dir widersprechen. Ich lese mit (sobald ich Zeit habe). Nur bin ich eben nicht täglich online, weil ich so ganz nebenbei auch noch einen Job habe. Dieser verlangt leider von mir, dass ich am Tag über 10 Stunden vollkommen konzentriert bin, weil mir mehrere Tausend Menschen ihr Leben anvertrauen. Da bin ich dann doch lieber mal nicht noch 1-2 Stunden online um nach Antworten zu schauen. Außerdem habe ich auch noch eine Familie, die ab und an mal etwas Zeit von mir erwartet (und das ist auch gut so).
Der Umbau der Haustechnik ist nun mal eben eher nebensächlich. (Entschuldigung, aber das musste ich jetzt mal anmerken).

BTT: DANKE an alle, die mir bisher Lösungen angeboten haben und mich (und vll andere Mitleser) unterstützen. Sobald ich dazu komme weiterzuprobieren, werde ich selbstverständlich eine Rückmeldung geben.

Ciaro:
b) periodisch vom NodeMCU am Rasperry abfragen lassen (wiederum der NodeMCU als Client, aber separater "Task")?
Genau so. Ich hatte vor, in regelmäßigen Abständen diese Werte (in dem Fall die Helligkeit im Außenbereich) abzufragen und bei Unterschreiten eines Schwellenwertes zB. einen Rolladen automatisch herunterfahren zu lassen.

Ist das der gleiche MCU, der sowohl die Daten nach MySQL schreibt, als auch die Helligkeit holen will?
Dann weiß er diese doch bereits, warum soll er sie dann noch abfragen, wenn er sie gerade erst an MySQL gesendet hat?

Auch sonst musst Du nichts mit Tasks machen. So schnell ändert sich die Helligkeit nicht. Wenn Du da im Abstand 1-5 Minuten was tust genügt das völlig. Damit kannst Du problemlos das Schreiben nach MySQL und wenn nötig auch das Lesen nacheinander machen.
Das Lesen würde ich auch über eine PHP-Anfrage laufen lassen, die Dir "text/plain" zurückliefert, z.B. hell=345+Zeilenvorschub (\n).
Das kannst Du einfach parsen und hast durch das zusätzliche Kennwort noch einen deutlicheren Bezug, als wenn nur 345 zurück kommt.

Gruß Tommy

Nein, es ist nicht der selbe. Dann wär es ja einfach. Draußen ist der Helligkeitssensor (Wetterstation), innen in den Räumen sind eigene rauminterne Steuerungen, die einfach nur die auf dem Pi zusammengefassten Daten nutzen sollen.
Das mit dem Parsen hatte ich in einem anderen Beitrag mal gelesen. Da ging es darum, die Temperatur aus einer Seite via Google zu erhalten.
( http://glaskugelsehen.wordpress.com/2016/02/05/tutorial-website-parsen-mit-dem-esp8266-teil-2/ )

Deswegen empfehle ich Dir ja auch "text/plain", weil da das "parsen" einfacher wird.

Eigentlich ist parsen ja dafür schon stark übertrieben.

Gruß Tommy

Sende die Daten doch direkt an den SQL-Server!
Mache ich auch so:

//for esp8266
//#include <ESP8266WiFi.h>

//for ESP32
#include <WiFi.h>

#include <MySQL_Connection.h>
#include <MySQL_Cursor.h>


WiFiClient client;
MySQL_Connection conn((WiFiClient *)&client);


void save_data() {
  Serial.println(F("Connecting to SQL server..."));

  if (conn.connect(<IP of SQL Server>, <Port of SQL Server>, <SQL User>, <SQLPass>)) {

    Serial.println(F("Connection established"));

    // Initiate the query class instance
    MySQL_Cursor *cursor = new MySQL_Cursor(&conn);
    if (cursor) {
      // Execute the query
      cursor->execute(String("INSERT INTO <tableName> (field1, field2) VALUES (value1, value2);
    }
    // Deleting the cursor also frees up used memory
    delete cursor;
    conn.close();      
  }
  else {
    Serial.println(F("Connection failed"));
  }
}

Daten vom SQL-Server lesen, geht auch.
Du musst halt die MySQL_Connector library in die Arduino - IDE installieren und die examples anschauen.

Nun fühle ich mich ein Wenig wie jemand, dem ein Arzt eine Handvoll verschiedene Pillen, Tabletten etc. vorlegt und sagt: “sortier mal bitte nach Wirkung” - ich verstehe gerade gar nichts mehr.

Ich habe weder eine Ahnung, wo/wie ich das mit dem “text/plain” einbringen soll, noch komme ich vom ESP aus an meine PHP-Datei dran.
Im Browser funktioniert “http://IP-Adresse/Dateiname.php” wunderbar - und ja, ich hab es derzeit auf ein Minimum (sprich: nur auf den Wert) reduziert. Aber sobald ich versuche, irgendwie mit dem Microcontroller drauf zuzugreifen bekomme ich nur

404 Not Found

Not Found

The requested URL was not found on this server.


Apache/2.4.38 (Raspbian) Server at 192.168.2.117 Port 80

Ich will doch nur einen Wert aus der Datenbank haben, den ich mit dem MC verwenden kann. Das kann doch eigentlich gar nicht so schwer sein :confused:

Daten vom SQL-Server lesen, geht auch.
Du musst halt die MySQL_Connector library in die Arduino - IDE installieren und die examples anschauen.
Ja, die hab ich installiert (inzwischen sogar zwei Versionen, bei denen (für mich) im Sketch ganz viele böhmische Dörfer stehen (SimCity, juhuu!) ).
Hab ja schon einige Tutorials etc durch, die aber aus mir unverständlichen Gründen immer in Fehlermeldungen oder bestenfalls in “404” enden.

Der Beispiel-Code von freddy sieht so simpel aus - doch irgendwie ist der ja auch nur zum Eintragen. Das hab ich ja irgendwie hinbekommen - aber das Auslesen klappt nicht.
Langsam frage ich mich, ob ich zu unfähig bin, etwas zu verstehen oder warum in den ganzen Beispielen immer nur in die Datenbank geschrieben wird. Was macht man mit den ganzen Datensätzen, wenn man sie nirgends verwendet?

Im Idealfall soll eben der entsprechende Controller seinerseits Daten in die DB eintragen können, andererseits aber auch (andere Werte) auslesen und verwenden.

In den Beispielen zum MySQL-Connector ist doch ein SELECT-Beispiel dabei.
Lass Dich nicht stören, dass das mit Ethernet gemacht wurde, das geht genau so mit WLAN.

Die meisten Beispiele schreiben nur in die DB, weil sie die Auswertung (Grafiken usw. mit anderen Systemen machen).

Du musst Dich erst mal entscheiden, ob Du den direkten Weg oder den über PHP gehen willst.

Dann kann man weiter sehen.

Gruß Tommy