Requête GET JS, je coince, help

Bonsoir
Je continue de galérer avec ma page web et la requête. Ce soir j'ai enfin réussi à récupérer une variable (timer01)
J'aurai de nombreuses variables à récupérer et le code sera aussi lourd que redondant. pour l'instant je n'arrive pas à récupérer la deuxième valeur...
Est-ce que quelqu'un peut me donner un coup de pouce?

/*
 * inspiré de Mish Mash Labs
 "Webserver with PWM Control of Brightness of LED"
*/
#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

// codes wifi
const char* ssid = "Livebox-XXX";
const char* password = "XXX";


String timer01 = "0";
String timer02 = "0";


const char* INPUT_PARAMETER = "value";

// port 80
AsyncWebServer webServer(80);

// HTML ci-dessous
const char htmlCode[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <!  define meta data >
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <! define the style CSS of your page >
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h1 {font-size: 2.9rem;}
    h2 {font-size: 2.1rem;}
    p {font-size: 1.9rem;}
    body {max-width: 400px; margin:0px auto; padding-bottom: 30px;}
    .slider { -webkit-appearance: none; margin: 14px; width: 70px; height: 15px; 
    border-radius: 5px; background: #CEE3F6; }

  </style>
</head>

<body>
  <! Edit the pages your heading 1 >
  <h1>TITRE</h1>
    <h2>blablabla</h2>

  <p><input type="time" onchange="updateTimer01(this)" id="inTimer01"     step="60" class="slider"></p>
  <p><input type="time" onchange="updateTimer02(this)" id="inTimer02"     step="60" class="slider"></p>
  
<script>
function updateTimer01(element) {
      var timer01 = document.getElementById("inTimer01").value;
      var httpRequest = new XMLHttpRequest();
      httpRequest.open("GET", "/slider?value="+timer01, true);
      httpRequest.send();}


</script>
</body>
</html>
)rawliteral";

// Replaces the placeholder with the button in your web page
String updateButton(const String& var){ return String();}//je ne comprends pas trop cette ligne

void setup(){
  // Moniteur
  Serial.begin(115200);
  

  // Se connecter au wifi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // imprime l'ip
  Serial.println(WiFi.localIP());

  // Detail the route for root / web page
  webServer.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", htmlCode, updateButton);
  });

  // Send a GET request to <ESP_IP>/slider?value=<inputMessage>
  webServer.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    // GET timer01 à <ESP_IP>/slider?value=<inputMessage>
    if (request->hasParam(INPUT_PARAMETER)) {
      inputMessage = request->getParam(INPUT_PARAMETER)->value();
      Serial.println(INPUT_PARAMETER);
      timer01 = inputMessage; // du coup comment faire pour récupérer timer02??
    }
    else {
      inputMessage = "No message sent";
    }
    Serial.println("");
    request->send(200, "text/plain", "OK");
  });
  
  // Start server (remembering its on port 80)
  webServer.begin();
}
  
void loop() {
  Serial.println(timer01); //fonctionne
  Serial.println(timer02); //ne fonctionne pas encore
  Serial.println("");
  delay(1000);
  
}

Je suis désolé, j'ai regardé vite fait ton code et peut être que j'ai été trop vite.
Ton code javascript ne donne pas de second paramètre.

que donne l'affichage de timer01, "value=0123456" ?

Pourquoi tu n'a pas ce code:
...
var timer02 = document.getElementById("inTimer02").value;
..
httpRequest.open("GET", "/slider?value1="+timer01+"&value2="+timer02, true);

ou une deuxième fonction updateTimer02

Merci terwal.
J'ai fait ceci:

  <p><input type="time" onchange="updateTimer01(this)" id="inTimer01"     step="60" class="slider"></p>
  <p><input type="time" onchange="updateTimer01(this)" id="inTimer02"     step="60" class="slider"></p>
  
<script>
function updateTimer01(element) {
      var timer01 = document.getElementById("inTimer01").value;
      var timer02 = document.getElementById("inTimer02").value;
      var httpRequest = new XMLHttpRequest();
      alert(timer01);alert(timer02);
      httpRequest.open("GET", "/slider?value="+timer01+"&value="+timer02, true);
      httpRequest.send();}

alert(timer01); et alert(timer02) me renvoient bien les valeur respectives.
Par contre, dans ma partie en C, je n'ai que timer01 qui s'imprime.
Je n'ai jamais autant galéré sur un bout de code si petit. Et en galère je m'y connais :sweat_smile:

essayez un truc comme cela:

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#include <AsyncTCP.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>

const char*   ssid = "XXX";
const char*   password = "XXX";


const char homepage[] PROGMEM = R"---(
<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <title>Pour Kammo</title>
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h1 {font-size: 2.9rem;}
    h2 {font-size: 2.1rem;}
    p {font-size: 1.9rem;}
    body {max-width: 400px; margin:0px auto; padding-bottom: 30px;}
    .slider { -webkit-appearance: none; margin: 14px; width: 70px; height: 15px; 
    border-radius: 5px; background: #CEE3F6; }
  </style>
  
  <script>
   function updateTimer() {
      var t1 = document.getElementById("T1").value;
      var t2 = document.getElementById("T2").value;
      var httpRequest = new XMLHttpRequest();
      httpRequest.open("GET", "/slider?s1=" + t1 + "&s2=" + t2, true);
      httpRequest.send(null);
   }
  </script>
</head>

<body>
  <h1>TITRE</h1>
  <h2>blablabla</h2>
  <p><input type="time" onchange="updateTimer()" id="T1" value="09:00" step="60" class="slider"></p>
  <p><input type="time" onchange="updateTimer()" id="T2" value="17:00" step="60" class="slider"></p>
</body>
</html>
)---";

AsyncWebServer server(80);

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.printf("WiFi Failed!\n");
    return;
  }

  Serial.print("ouvrez l'URL http://"); Serial.println(WiFi.localIP());

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/html", homepage);
  });

  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest * request) {
    if (request->hasParam("s1")) {
      Serial.print("Slider 1: "); Serial.println(request->getParam("s1")->value());
    }
    if (request->hasParam("s2")) {
      Serial.print("Slider 2: "); Serial.println(request->getParam("s2")->value());
    }
    request->send(200, "text/plain", "OK");
  });

  // error
  server.onNotFound(notFound);

  server.begin();
}

void loop() {}

ici les 2 champs appellent la même fonction javascript updateTimer() et j'ai fait une fonction qui envoie les 2 paramètres à chaque fois sous forme d'un GET "slider?s1=21:01&s2=17:00"

      httpRequest.open("GET", "/slider?s1=" + t1 + "&s2=" + t2, true);

vous pourriez avoir 2 fonctions et dans ce cas appeler /s1?v=21:01 alors que l'autre appellerait /s2?v=17:00 par exemple ce qui fait que votre programme arduino ne serait notifié que d'un seul changement au lieu de toujours recevoir les 2 valeurs

(je trouve que c'est mieux de recevoir les 2 valeurs d'un coup comme ça si une requête précédente s'est perdue pour une raison ou une autre, on est synchro avec ce que l'utilisateur voit à l'écran)

Effectivement je n'avais pas vu que INPUT_PARAMETER avait comme valeur la chaine "value"
Donc que la fonction getParam, prend en paramètre le nom du paramètre que tu veux récupérer.

Pfouah! Il était temps de vous demander ^^ C'est exactement ça!
Merci beaucoup!!! :star_struck:
Rahhh le soulagement :face_exhaling:

Merci à tous les deux, c'est vraiment très sympa, je n'ose pas dire depuis combien de temps je suis là-dessus ^^

bonne continuation. prenez le temps d'étudier le code en détail

Re.
J'ai avancé, pas mal, même. Par contre, je rencontre un problème. J'ai une trentaine de variables à récupérer.

  server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/html", homepage);
  });

  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest * request) {
    if (request->hasParam("s1")) {
      variable1=(request->getParam("s1")->value());
    }
    if (request->hasParam("s2")) {
      variable2=(request->getParam("s2")->value());
    }
    request->send(200, "text/plain", "OK");
  });

Le plus simple c'est de recopier cette méthode 30 fois mais c'est moche et ça prend de la place. Je n'y arrive pas. Est-il possible de créer une boucle pour faire cela où int i permettrait de faire

    if (request->hasParam("s(i)")) {
      variable(i)=(request->getParam("s(i)")->value());

Je ne sais pas si je me fais comprendre... je ne dois pas être loin mais je tourne en ronds...

Peut-être en remplaçant dans ces lignes le "s(i)" par la composante numéro i d'un tableau de char*

Tu peux faire un for sur le nombre de variables, et faire un Switch pour savoir dans quel variable mettre la valeur.
Mais ça reste encore moche :worried:

Un tableau de valeur est quand même mieux je trouve

Pas besoin d’un switch. Si la requête est bien formée, on itere sur l’ensemble des paramètres (s’il peut t en avoir plusieurs d’un coup) et on extrait le N° du slider du texte (un atoi() ou strtol() en sautant le première caractère qui est le ‘s’) et cette valeur c’est l’index dans un tableau ou stocker la valeur

Alors je suis peut-être parti d'une erreur d'interprétation. Cette nuit je me suis fait une remarque. Jusqu'ici je tenais compte des apostrophes du nom de la variable "s1" "s2" mais je peux peut-être les virer et travailler avec s1 s2 s3...
C'est idiot mai je me suis acharné à les laisser Oo
En fait si, les gullemets font bien partie du nom de la variable

Un switch case serait aussi long finalement que de faire du cas par cas avec des if même si c'est un peu plus élégant et certes plus lisible...
Il s'avère que j'essaie de gagner quelques lignes parce que mon programme est énorme et que je suis tout juste côté place ^^

Mon souci c'est que le nom de la variable comporte des guillemet dont je ne peux pas m'affranchir.

    char buf[4];
    sprintf(buf, "s%d", i);
    if (request->hasParam(buf)) {
      variable[i]=(request->getParam(buf)->value());
    }

Non, les guillemets ne font pas partie du nom de la variable. "s1" est une chaîne de caractères constante.
Je constate que tu as laissé tomber ta formation en C et que tu continues avec la méthode voodoo programming :woozy_face:

Le prototype de hasParam est :
bool hasParam(const String& name, bool post=false, bool file=false) const;
Tu lui passes donc un argument qui est une String. Soit tu le mets en dur genre
if(request->hasParam("download"))
soit tu utilises une variable ou un élément de tableau
String mesParams[3] = {"s1", "s2", "s3"};
et dans une boucle :
if (request->hasParam(mesParams[i]))

Non, je continue la formation.
Maintenant ne te sens pas obligé de venir me harceler sur mes posts. Occupe-toi de ta porte de poulailler...

Je t'assures que ma solution à base de sprintf() n'est pas du harcèlement.

je te crois là dessus, j'ai essayé dans tous les sens avec ce sprint() mais je n'y suis pas arrivé. je pense simplement qu'il serait plus judicieux de m'indiquer un code comme tu l'as gracieusement fait accompagné d'un lien qui ciblerait un cours qui m'aiderait à avancer. Là on serait sur du constructif...