Station météo avec ESP-Now

Bonsoir,

Voici un petit projet que j'ai commencé avec ESPHome dans Home assistant (HA).

Station météo - Do It Yourself / Vos Projets - Home Assistant Communauté Francophone (hacf.fr)

Le projet est devenu impossible à faire avec ESPHome et ça oblige de disposer de HA.

Donc me voici à chercher une solution pour faire communiquer plusieurs ESP ou Arduinos ensemble avec une consultation de données possible avec seulement une connexion internet (car maintenant je dois en faire une pour mon beau-père aussi :slight_smile: ). Je suis tombé sur des tutos ESP-Now et j'ai trouvé LA solution.

Pour l'instant c'est un peu brouillon, je dois trouver un moyen de faire de mesurer la vitesse et la direction du vent et aussi la pluviométrie, en avoir un historique sur au moins 24h, tout envoyer vers MQTT car ça doit me servir dans HA et faire une page html propre avec les scripts dans un fichier à part. Toute aide ou aidée est la bienvenue :slight_smile: .

Voici les différents codes mais d'ici peux je vais publier des repo public.

Emetteur extérieur

/*
Docstring à faire
*/

#include <Arduino.h>
#include <esp_now.h>
#include <esp_wifi.h>
#include <WiFi.h>
#include <Wire.h>
#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>
#include <BH1750.h>
#include <arduino_secrets.h>
#include "MeteoFunctions.h"
#include "WeatherMeters.h"
#include <Ticker.h>

// Set your Board ID (ESP32 Sender #1 = BOARD_ID 1, ESP32 Sender #2 = BOARD_ID 2, etc)
#define BOARD_ID 1

Adafruit_BME280 bme; // I2C
BH1750 lightMeter;
MeteoFunctions calc;

// MAC Address of the receiver
uint8_t broadcastAddress[] = {0xC8, 0xC9, 0xA3, 0xCA, 0xEF, 0xB4};

// Structure example to send data
// Must match the receiver structure
typedef struct struct_message
{
  int id;
  float temp;
  float hum;
  float pres;
  float lum;
  float humidex;
  float dewpoint;
  float HI;
  float cloudh;
  float relpres;
  float absolutehum;
  float winddegrees;
  float windspeed;
  float rain;
  
  int readingId;
} struct_message;

// Create a struct_message called myData
struct_message myData;

unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000;      // Interval at which to publish sensor readings

unsigned int readingId = 0;

// Insert your SSID
constexpr char WIFI_SSID[] = SECRET_WIFI_SSID;

// WeatherMeters
const int windvane_pin = 32;
const int anemometer_pin = 26;
const int raingauge_pin = 27;

volatile bool got_data = false;

Ticker ticker;
WeatherMeters<4> meters(windvane_pin, 8); // filter last 4 directions, refresh data every 8 sec

void ICACHE_RAM_ATTR intAnemometer()
{
  meters.intAnemometer();
}

void ICACHE_RAM_ATTR intRaingauge()
{
  meters.intRaingauge();
}

void secondCount()
{
  meters.timer();
}

void readDone(void)
{
  got_data = true;
}

// WeatherMeters end

esp_now_peer_info_t peerInfo;

int32_t getWiFiChannel(const char *ssid)
{
  if (int32_t n = WiFi.scanNetworks())
  {
    for (uint8_t i = 0; i < n; i++)
    {
      if (!strcmp(ssid, WiFi.SSID(i).c_str()))
      {
        return WiFi.channel(i);
      }
    }
  }
  return 0;
}

// callback when data is sent
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status)
{
  Serial.print("\r\nLast Packet Send Status:\t");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

void setup()
{
  // Init Serial Monitor
  Serial.begin(115200);

  Serial.println(__FILE__);

  Wire.begin();

  bool status;

  // WeatherMeters
    attachInterrupt(digitalPinToInterrupt(anemometer_pin), intAnemometer, FALLING);
    attachInterrupt(digitalPinToInterrupt(raingauge_pin), intRaingauge, FALLING);

    meters.attach(readDone);
    ticker.attach(1.0, secondCount);
    meters.reset();  // in case we got already some interrupts

  // WeatherMeters end

  status = lightMeter.begin(); // 0x23
  if (!status)
  {
    Serial.println("Could not find a valid BH1750 sensor, check wiring!");
    while (1)
      ;
  }

  status = bme.begin(0x76);
  if (!status)
  {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1)
      ;
  }

  // Set device as a Wi-Fi Station and set channel
  WiFi.mode(WIFI_STA);

  int32_t channel = getWiFiChannel(WIFI_SSID);

  WiFi.printDiag(Serial); // Uncomment to verify channel number before
  esp_wifi_set_promiscuous(true);
  esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
  esp_wifi_set_promiscuous(false);
  WiFi.printDiag(Serial); // Uncomment to verify channel change after

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK)
  {
    Serial.println("Error initializing ESP-NOW");
    ESP.restart();
  }

  // Once ESPNow is successfully Init, we will register for Send CB to
  // get the status of Trasnmitted packet
  esp_now_register_send_cb(OnDataSent);

  // Register peer
  //  esp_now_peer_info_t peerInfo;
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.encrypt = false;

  // Add peer
  if (esp_now_add_peer(&peerInfo) != ESP_OK)
  {
    Serial.println("Failed to add peer");
    return;
  }
}

void loop()
{

  float temp;
  float hum;
  float pres;
  float lum;
  float humidex;
  float dewpoint;
  float HI;
  float cloudh;
  float relpres;
  float absolutehum;
  float winddegrees;
  float windspeed;
  float rain;

  const float above_sea = 10;

 /* // WeatherMeters
  if (got_data)
  {
    got_data = false;
    Serial.print("Wind degrees: ");
    Serial.print(meters.getDir(), 1);
    Serial.print(" Wind speed: ");
    Serial.print(meters.getSpeed(), 1);
    Serial.print("km/h, Rain: ");
    Serial.print(meters.getRain(), 4);
    Serial.println("mm");
  }

  delay(1); // or do something else

  // WeatherMeters end */

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval)
  {
    // Save the last time a new reading was published
    previousMillis = currentMillis;
    // Set values to send
    myData.id = BOARD_ID;
    myData.temp = bme.readTemperature(), 1;
    myData.hum = bme.readHumidity(), 0;
    myData.pres = bme.readPressure() / 100.0F, 0;
    myData.lum = lightMeter.readLightLevel(), 0;
    myData.humidex = calc.humidex_c(bme.readTemperature(), bme.readHumidity()), 0;
    myData.dewpoint = calc.dewPoint_c(bme.readTemperature(), bme.readHumidity()), 1;
    myData.HI = calc.heatIndex_c(bme.readTemperature(), bme.readHumidity()), 0;
    myData.cloudh = calc.cloudBase_m(bme.readTemperature(), bme.readHumidity()), 0;
    myData.relpres = calc.relativePressure_c(bme.readPressure() / 100.0F, above_sea, bme.readTemperature()), 0;
    myData.absolutehum = calc.absoluteHumidity_c(bme.readTemperature(), bme.readHumidity()), 0;
    myData.winddegrees = meters.getDir(), 1;
    myData.windspeed = meters.getSpeed(), 1;
    myData.rain = meters.getRain(), 4;
    myData.readingId = readingId++;

    Serial.print("Temperature: ");
    Serial.print(myData.temp);
    Serial.println(" °C");

    Serial.print("Humidity: ");
    Serial.print(myData.hum);
    Serial.println(" %");

    Serial.print("Pressure: ");
    Serial.print(myData.pres);
    Serial.println(" hPa");

    Serial.print("Luminosity: ");
    Serial.print(myData.lum);
    Serial.println(" lux");

    Serial.print("Humidex: ");
    Serial.println(myData.humidex);

    Serial.print("Dew point: ");
    Serial.print(myData.dewpoint);
    Serial.println(" °C");

    Serial.print("Heat index: ");
    Serial.println(myData.HI);

    Serial.print("Cloud height: ");
    Serial.print(myData.cloudh);
    Serial.println(" mètres");

    Serial.print("Relative pressure: ");
    Serial.print(myData.relpres);
    Serial.println(" hPa");

    Serial.print("Absolute humidity: ");
    Serial.print(myData.absolutehum);
    Serial.println(" g/m3");

    Serial.print("Wind degrees: ");
    Serial.print(myData.winddegrees, 1);
    Serial.println(" °");

    Serial.print("Wind speed: ");
    Serial.print(myData.windspeed, 1);
    Serial.println(" km/h");

    Serial.print("Rain: ");
    Serial.print(myData.rain, 4);
    Serial.println("mm");

    // Send message via ESP-NOW
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *)&myData, sizeof(myData));
    if (result == ESP_OK)
    {
      Serial.println("Sent with success");
    }
    else
    {
      Serial.println("Error sending the data");
    }
  }
}

// https://www.123calculus.com/calculer-pression-altitude-page-8-30-300.html
// https://www.omnicalculator.com/physics#s-16
// https://github.com/pilotak/MeteoFunctions/blob/master/examples/MeteoFunctions/MeteoFunctions.ino
// https://github.com/pilotak/WeatherMeters/blob/master/examples/WeatherMeters_external_ADC/WeatherMeters_external_ADC.ino

Recepteur (.cpp)

/*
Docstring à faire
*/

// Import required libraries
#include <Arduino.h>
#include <esp_now.h>
#include "WiFi.h"
#include "ESPAsyncWebServer.h"
#include "SPIFFS.h"
#include <ESPAsyncTCP/ESPAsyncTCP.h>
#include <Arduino_JSON.h>
#include <arduino_secrets.h>

// Replace with your network credentials (STATION)
const char *ssid = SECRET_WIFI_SSID;
const char *password = SECRET_WIFI_PASS;

// Structure example to receive data
// Must match the sender structure
typedef struct struct_message
{
  int id;
  float temp;
  float hum;
  float pres;
  float lum;
  float humidex;
  float dewpoint;
  float HI;
  float cloudh;
  float relpres;
  float absolutehum;
  float winddegrees;
  float windspeed;
  float rain;
  unsigned int readingId;
} struct_message;

struct_message incomingReadings;

JSONVar board;

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

// callback function that will be executed when data is received
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *incomingData, int 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["pressure"] = incomingReadings.pres;
  board["luminosity"] = incomingReadings.lum;
  board["humidex"] = incomingReadings.humidex;
  board["dewpoint"] = incomingReadings.dewpoint;
  board["HI"] = incomingReadings.HI;
  board["cloudh"] = incomingReadings.cloudh;
  board["relpres"] = incomingReadings.relpres;
  board["absolutehum"] = incomingReadings.absolutehum;
  board["winddregrees"] = incomingReadings.winddegrees;
  board["windspeed"] = incomingReadings.windspeed;
  board["rain"] = incomingReadings.rain;

  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.1f \n", incomingReadings.temp);
  Serial.printf("h value: %4.1f \n", incomingReadings.hum);
  Serial.printf("p value: %4.0f \n", incomingReadings.pres);
  Serial.printf("l value: %4.0f \n", incomingReadings.lum);
  Serial.printf("hx value: %4.0f \n", incomingReadings.humidex);
  Serial.printf("dp value: %4.1f \n", incomingReadings.dewpoint);
  Serial.printf("HI value: %4.0f \n", incomingReadings.HI);
  Serial.printf("ch value: %4.0f \n", incomingReadings.cloudh);
  Serial.printf("rp value: %4.0f \n", incomingReadings.relpres);
  Serial.printf("ah value: %4.1f \n", incomingReadings.absolutehum);
  Serial.printf("wd value: %4.1f \n", incomingReadings.winddegrees);
  Serial.printf("ws value: %4.1f \n", incomingReadings.windspeed);
  Serial.printf("r value: %4.4f \n", incomingReadings.rain);
}

void setup()
{
  // Serial port for debugging purposes
  Serial.begin(115200);

  // Initialize SPIFFS
  if (!SPIFFS.begin(true))
  {
    Serial.println("An Error has occurred while mounting SPIFFS");
    return;
  }

  // Set the device as a Station and Soft Access Point simultaneously
  WiFi.mode(WIFI_AP_STA);

  // Set device as a Wi-Fi Station
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(1000);
    Serial.println("Setting as a Wi-Fi Station..");
  }
  Serial.print("Station IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.print("Wi-Fi Channel: ");
  Serial.println(WiFi.channel());

  // Init ESP-NOW
  if (esp_now_init() != ESP_OK)
  {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  // Once ESPNow is successfully Init, we will register for recv CB to
  // get recv packer info
  esp_now_register_recv_cb(OnDataRecv);

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(SPIFFS, "/index.html", String(), false); });

  // Route to load style.css file
  server.on("/style.css", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(SPIFFS, "/style.css", "text/css"); });

  events.onConnect([](AsyncEventSourceClient *client)
                   {
    if(client->lastId()){
      Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
    }
    // send event with message "hello!", id current millis
    // and set reconnect delay to 1 second
    client->send("hello!", NULL, millis(), 10000); });
  server.addHandler(&events);
  server.begin();
}

void loop()
{

  static unsigned long lastEventTime = millis();
  static const unsigned long EVENT_INTERVAL_MS = 5000;
  if ((millis() - lastEventTime) > EVENT_INTERVAL_MS)
  {
    events.send("ping", NULL, millis());
    lastEventTime = millis();
  }
}

Recepteur (index.html)

<!DOCTYPE html>
<html lang="fr">

<head>
  <title>Station m&eacute;t&eacute;o</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css"
    integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <link rel="icon" href="data:,">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
  <style>
    html {
      font-family: Arial;
      display: inline-block;
      text-align: center;
    }

    p {
      font-size: 1.2rem;
    }

    body {
      margin: 0;
    }

    .topnav {
      overflow: hidden;
      background-color: #2f4468;
      color: white;
      font-size: 1.7rem;
    }

    .darkmode {
      overflow: hidden;
      background-color: #2f4468;
      color: white;
      font-size: 1rem;
    }

    .content {
      padding: 20px;
    }

    .card {
      box-shadow: 2px 2px 12px 1px rgba(140, 140, 140, .5);
    }

    .cards {
      max-width: 2000px;
      margin: 0 auto;
      display: grid;
      column-gap: 2rem;
      row-gap: 2rem;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    }

    .reading {
      font-size: 2.8rem;
    }

    .timestamp {
      color: #bebebe; font-size: 1rem;
    }

    .packet {
      color: #bebebe;
    }

    .card.temperature {
      color: #fd7e14;
    }

    .card.humidity {
      color: #1b78e2;
    }

    .card.pressure {
      color: #008000;
    }

    .card.luminosity {
      color: #e6d300;
    }

    .card.dewpoint {
      color: #fd7e14;
    }

    .card.humidex {
      color: #1b78e2;
    }

    .card.HI {
      color: #fd7e14;
    }

    .card.cloudh {
      color: #bebebe;
    }

    .card.relpres {
      color: #008000;
    }

    .card.absohum {
      color: #1b78e2;
    }

    .card.winddegrees {
      color: #6eb4f5;
    }

    .card.windspeed {
      color: #6eb4f5;
    }

    .card.rain {
      color: #bebebe;
    }

    .card.test {
      color: #FFFFFF;
    }

    .dark {
      background-color: #222;
      color: #e6e6e6;
    }

    .mode {
      float: right;
    }

    .change {
      cursor: pointer;
      border: 1px solid rgb(119, 15, 15);
      border-radius: 40%;
      width: 20px;
      text-align: center;
      padding: 5px;
      margin-left: 8px;
    }

    .text-right {
      text-align: right
    }
  </style>
</head>

<body>
  <div class="topnav">
    <h3>Station m&eacute;t&eacute;o</h3>
  </div>
  <div class="darkmode">
    <div class="switch">
      <h5 class="text-right">Dark mode: <span class="inner-switch">OFF</span></h5>
    </div>
  </div>
  <div class="content">
    <div class="cards">
      <div class="card temperature">
        <h4><i class="fas fa-thermometer-half"></i> Temp&eacute;rature ext&eacute;rieure</h4>
        <p><span class="reading"><span id="t"></span> &deg;C</span></p>
      </div>
      <div class="card humidity">
        <h4><i class="fas fa-tint"></i> Humidit&eacute; ext&eacute;rieure</h4>
        <p><span class="reading"><span id="h"></span> &percnt;</span></p>
      </div>
      <div class="card pressure">
        <h4><i class="fas fa-ruler-vertical"></i> Pression atmosph&eacute;rique</h4>
        <p><span class="reading"><span id="p"></span> hPa</span></p>
      </div>
      <div class="card luminosity">
        <h4><i class="fas fa-star-of-life"></i> Luminosit&eacute; ext&eacute;rieure</h4>
        <p><span class="reading"><span id="l"></span> lux</span></p>
      </div>
      <div class="card dewpoint">
        <h4><i class="fas fa-thermometer-half"></i> Point de ros&eacute;e</h4>
        <p><span class="reading"><span id="dp"></span> &deg;C</span></p>
      </div>
      <div class="card humidex">
        <h4><i class="fas fa-thermometer-half"></i> Humidex (Canada)</h4>
        <p><span class="reading"><span id="hx"></span></span></p>
      </div>
      <div class="card HI">
        <h4><i class="fas fa-thermometer-half"></i> Heat Index (USA)</h4>
        <p><span class="reading"><span id="HI"></span></span></p>
      </div>
      <div class="card cloudh">
        <h4><i class="fas fa-cloud"></i> Hauteur couverture nuageuse</h4>
        <p><span class="reading"><span id="ch"></span> m</span></p>
      </div>
      <div class="card relpres">
        <h4><i class="fas fa-ruler-vertical"></i> Pression atmosph&eacute;riqu relative</h4>
        <p><span class="reading"><span id="rp"></span> hPa</span></p>
      </div>
      <div class="card absohum">
        <h4><i class="fas fa-tint"></i> Humidit&eacute;e absolue</h4>
        <p><span class="reading"><span id="ah"></span> g/m<sup>3</sup></span></p>
      </div>
      <div class="card winddegrees">
        <h4><i class="fas fa-compass"></i> Direction vents degr&eacute;s</h4>
        <p><span class="reading"><span id="wd"></span> &deg;</span></p>
      </div>
      <div class="card windspeed">
        <h4><i class="fas fa-wind"></i> Vitesse vents</h4>
        <p><span class="reading"><span id="ws"></span> km/h</span></p>
      </div>
      <div class="card rain">
        <h4><i class="fas fa-cloud-rain"></i> Pluviom&eacute;trie</h4>
        <p><span class="reading"><span id="r"></span> mm</span></p>
      </div>
    </div>
  </div>
  <script>
    $(document).ready(function () {
      if (localStorage.getItem("mode") == "dark") {
        $("body").addClass("dark");
        $(".inner-switch").text("ON");
      } else if (localStorage.getItem("mode") == "light") {
        $("body").removeClass("dark");
        $(".inner-switch").text("OFF");
      }
      var mq = window.matchMedia('(prefers-color-scheme: dark)');
      if (localStorage.getItem("mode") == "light") {
        $("body").removeClass("dark");
        $(".inner-switch").text("OFF");
      } else if (mq.matches) {
        $("body").addClass("dark");
        $(".inner-switch").text("ON");
      }
    });
    $(".inner-switch").on("click", function () {
      if ($("body").hasClass("dark")) {
        $("body").removeClass("dark");
        $(".inner-switch").text("OFF");
        localStorage.setItem("mode", "light");
      } else {
        $("body").addClass("dark");
        $(".inner-switch").text("ON");
        localStorage.setItem("mode", "dark");
      }
    });
    function getDateTime() {
      var currentdate = new Date();
      var datetime = currentdate.getDate() + "/"
        + (currentdate.getMonth() + 1) + "/"
        + currentdate.getFullYear() + " at "
        + currentdate.getHours() + ":"
        + currentdate.getMinutes() + ":"
        + currentdate.getSeconds();
      return datetime;
      }
    if (!!window.EventSource) {
      var source = new EventSource('/events');
      source.addEventListener('open', function (e) {
        console.log("Events Connected");
      }, false);
      source.addEventListener('error', function (e) {
        if (e.target.readyState != EventSource.OPEN) {
          console.log("Events Disconnected");
        }
      }, false);
      source.addEventListener('message', function (e) {
        console.log("message", e.data);
      }, false);
      source.addEventListener('new_readings', function (e) {
        console.log("new_readings", e.data);
        var obj = JSON.parse(e.data);
        document.getElementById("t").innerHTML = obj.temperature.toFixed(1);
        document.getElementById("h").innerHTML = obj.humidity.toFixed(1);
        document.getElementById("p").innerHTML = obj.pressure.toFixed(0);
        document.getElementById("l").innerHTML = obj.luminosity.toFixed(0);
        document.getElementById("hx").innerHTML = obj.humidex.toFixed(0);
        document.getElementById("dp").innerHTML = obj.dewpoint.toFixed(1);
        document.getElementById("HI").innerHTML = obj.HI.toFixed(0);
        document.getElementById("ch").innerHTML = obj.cloudh.toFixed(0);
        document.getElementById("rp").innerHTML = obj.relpres.toFixed(0);
        document.getElementById("ah").innerHTML = obj.absolutehum.toFixed(1);
        document.getElementById("wd").innerHTML = obj.winddegrees.toFixed(1);
        document.getElementById("ws").innerHTML = obj.windspeed.toFixed(1);
        document.getElementById("r").innerHTML = obj.rain.toFixed(4);
        document.getElementById("time").innerHTML = getDateTime();
      }, false);
    }
  </script>
</body>

</html>

Si tu envois tout via MQTT sur un serveur de stockage, tu as du coup ton historique.
MQTT étant uniquement un protocole d'échange, a tu déjà choisi le service qui recevra tes données.
Tu parle aussi de faire communiquer tes ESP, ce que tu veux/besoin n'est pas très claire, pourquoi faire dialoguer les ESP?
Pourquoi veux tu avoir une page HTML?

Peux tu détailler ce que tu veux faire, indépendamment d'un ESP ou de ce que tu as déjà fait?

MQTT va seulement me servir pour créer des automatismes et historique dans HA mais je dois faire une 2eme station sans MQTT pour mon beau père.

La communication des ESP sert à avoir un point de mesure extérieur et un intérieur. Sur cette partie, ça fonctionne plutôt bien.

La page html du web server sert à consulter les mesures.

Voici un diagramme du projet

Bonsoir @gregauriz

il est intéressant de découvrir un même ESP32 qui tout à la fois :
-communique avec d'autres ESP32 avec le protocole 'maison' ESP-NOW
-est acteur sur le réseau WiFi avec son petit serveur HTML + publie via MQTT

la cohabitation dans un ESP32 (nommé ici récepteur) d'ESP-NOW et de WiFi (en station+ point d'accès ) ne semble pas poser problème , bonne nouvelle !

Si tes ESP n'utilisent donc pas MQTT la solution la plus traditionnel est de faire une socket serveur(avec un listen) et une socket client. Le client ce connecte au serveur et envois ses informations, le serveur pouvant alors répondre, si besoin.
Mais si tu utilise un serveur WEB pour afficher les données, tu peux l'utiliser pour que ton ESP client envois ses informations via une speudo API.

Le MQTT, c'est pas pour tout de suite.

J'ai un ESP qui est en web server.

Pour l'instant je suis bloqué sur les lignes des anémomètre, girouette et pluviomètre. Je n'arrive pas à compter et à analyser les infos. Je suis également coincé avec esp_now, je n'arrive pas à séparer les donnés des 2 esp.

Si quelqu'un peut m'aider je suis preneur. :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.