ESP 8266 ESP-NOW Webserver

OP #7112743
Lesenswert?

Hallo,

ich arbeite zurzeit an einer kleinen Wetterstation mit dem ESP 8266 D1 
mini.

Ich habe momentan einen Sender (es werden dann aber mehr) und einen 
Empfänger.

Das Master/Slave-Prinzip funktioniert gut und die Messwerte der 
Temperatursensoren werden zum Schluss auf einem Webserver angezeigt, so 
weit so gut.

Mir ist nur aufgefallen, dass das, was als Letztes empfangen wurde, 
nicht gespeichert wird. Besser gesagt, dass mein Webserver mir keine 
Werte anzeigen kann, wenn ich die Seite neu aktualisieren tue oder wenn 
sie zum ersten Mal aufgerufen wird, da theoretisch der µController immer 
arbeitet, habe ich mir gedacht, dass die Werte da sein sollten.

Mein Sender liefert mir die Werte alle 2 Minuten und dann geht er 
schlafen.
Über den USB-Port kann ich sehen, dass alles empfangen wird und 
funktioniert.

Ich habe die Webseite nicht immer offen, aber ich möchte, wenn ich sie 
aufrufe, dass die letzten Messwerten, die empfangen wurden, mir 
angezeigt werden.

Da habe ich noch keine Lösung.

Ich werde mich sehr freuen, wenn jemand da mir weiter helfen könnte.
Angehängte Dateien:
Gast #7112754
Lesenswert?

Dann musst du dir halt ein strukturiertes Array auf dem Sammler anlegen, 
wo er die Daten ablegt. Die Webseite kann die Daten aus dem Array lesen, 
anstatt auf Signale von den Sensoren zu warten.

Ob und wie ESP-Now das kann, weiß ich allerdings nicht. Ich würde so 
etwas selbst programmieren, weil mir das eh Spaß macht.
Gast #7112782
Lesenswert?

Oha, da hat der Mario die Problembeschreibung ganz anders interpretiert, 
als ich. Vielleicht sollte man das klären, bevor wie weiter diskutieren, 
denn einer von uns beiden liegt mit Sicherheit völlig daneben.

Daniel, starte den Browser mal neu, lade dann die Webseite, und lade sie 
dann sofort erneut (durch Klick auf den Reload Button). Werden dann die 
letzten Messwerte aller Sensoren angezeigt, oder nicht?
#7112892
Lesenswert?

die Daten werden ja im Prinzip im Client gesammelt, und wenn der sich 
neu verbindet fängt der bei 0 an.
Also muss das Sammeln in den Server verlagert werden wie auch schon 
StefanUS schrieb. Die Sensoren haben ja eine einzigartige ID, die MAC. 
Die kann man als Key in einem key/value store nehmen (was das JSONVar 
schon macht). Also wenn neue MAC ankommt, dann neues Element mit MAC und 
Daten anlegen. Wenn die MAC schon vorhanden ist, dann Daten 
überschreiben.
In der Webseite dann beim Start aus den vorhandenen Datensätzen die 
Cards erzeugen.
Jetzt ist das Konzept nicht gut wie ich finde, wenn es einen weiteren 
Sensor gibt muss die Message für alle Sensoren erweitert werden. Als 
Message reicht ja id (eigntlich überflüssig durch die MAC), Temp, Hum, 
Voltage.
Beitrag #7113002 wurde von einem Moderator gelöscht.
OP #7113070
Lesenswert?

Aber wenn das ganze im Abschnitt passiert:

JSONVar board;

AsyncWebServer server(80);
AsyncEventSource events("/events");

// callback function that will be executed when data is received
void OnDataRecv(uint8_t * mac_addr, uint8_t *incomingData, uint8_t len) 
{
  // Copies the sender mac address to a string
  char macStr[18];

  Serial.print("Packet received from: ");
  snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], 
mac_addr[4], mac_addr[5]);
  Serial.println(macStr);
  memcpy(&incomingReadings, incomingData, sizeof(incomingReadings));

  board["id"] = incomingReadings.id;
  board["temperature"] = incomingReadings.temp;
  board["humidity"] = incomingReadings.hum;
  board["temp1"] = incomingReadings.temp1;
  board["temp2"] = incomingReadings.temp2;
  board["temp3"] = incomingReadings.temp3;
  board["temp4"] = incomingReadings.temp4;
  board["voltage"] = incomingReadings.volt;
  board["readingId"] = String(incomingReadings.readingId);

  String jsonString = JSON.stringify(board);

  events.send(jsonString.c_str(), "new_readings", millis());

  Serial.printf("Board ID %u: %u bytes\n", incomingReadings.id, len);
  Serial.printf("t value: %4.2f \n", incomingReadings.temp);
  Serial.printf("h value: %4.2f \n", incomingReadings.hum);
  Serial.printf("temp1 value: %4.2f \n", incomingReadings.temp1);
  Serial.printf("temp2 value: %4.2f \n", incomingReadings.temp2);
  Serial.printf("temp3 value: %4.2f \n", incomingReadings.temp3);
  Serial.printf("temp4 value: %4.2f \n", incomingReadings.temp4);
  Serial.printf("v value: %4.2f \n", incomingReadings.volt);
  Serial.printf("readingID value: %d \n", incomingReadings.readingId);
  Serial.println();
}


Könnte man da eine char-Variable schreiben und diese statt jsonString 
in das Event "events.send" schicken?
Gast #7113085
Lesenswert?

Daniel K. schrieb:
> Könnte man da eine char-Variable schreiben und diese statt jsonString
> in das Event "events.send" schicken?

Ja, aber das wäre noch keine Lösung.

Außerdem musst du nämlich nach dem laden der Webseite einen Aufruf von 
events.send() auslösen. Oder der Browser muss sich die Daten selbst über 
eine andere URL/Funktion (die noch nicht existiert) holen.
#7113117
Lesenswert?

um die Daten für einen Sensor zu speichern/übertragen kann man die 
JSONVar auch als Array von Strukturen gebrauchen:
1
    String id(iid);
2

3
    board[id]["id"] = iid;
4
    board[id]["temperature"] = temperatureX;
5
    board[id]["humidity"] = 66.2f;
6
    board[id]["voltage"] = 3.05f;
7
    board[id]["readingId"] = 11;
8

9
    String jsonString = JSON.stringify(board[id]); // send current dataset
10
    String jsonString = JSON.stringify(board);     // send all datasets
11

12
    events.send(jsonString.c_str(), "new_readings", millis());

beim Init der Seite würde man dann einmal 'board' Senden, beim update 
eines Sensors dann 'board[id]'.
Im html muss man dann in einer Schleife einfach alle elemente 
durchlaufen die ankommen, das wären am Anfang alle und sonst nur das was 
aktualisiert wird.
Dann kann man die Cards auch dynmisch erzeugen und neue Sensoren ohne 
Codeänderung auf Serverseite hinzufügen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren