ESP32 HTTP Post php echo nem múködik... kezdő kérdés.
2021-04-11T22:55:39+02:00
2021-04-13T18:18:40+02:00
2022-08-19T02:12:16+02:00
Skandar Graun
Sziasztok!

Többéves mikrokontrolleres programozási múlttal kénytelen voltam belevágni a PHP programozásba is. 
A jelenlegi rendszer egy ESP32-es wifi-s mikrokontroller és egy PI között épül fel. Az ESP-ről megy át adat a PI-re, HTTP_POST utasításokkal, ahol azt PHP filével fogadom és elteszem SQL adatbázisba.
Természetesen én is mintafeladatokból kezdtem dolgozni, aztán egy ponton megállt a tudomány. 
Az adatbázis rekord elkészül, de valahol zavar van az erőben, mert a program ráfut a hibakiíratásra.
Ezt az ESP által kapott válaszban látom, amit kiíratok egy soros terminálra.
Tapasztalatom szerint (az a csekély... ) ha a PHP parancsvégrehajtásban hiba van, akkor egyszerűen a hiba utáni rész nem hajtódik végre. 

Itt jött a következő csavar, mert ugye a HTTP_POST-ra adott válaszban van benne az összes echo kimenete. Ezt felhasználva megpróbáltam kitalálni, mi is a hiba és echo-val, majd az ESP-vel kiírattam a válaszokat. Csakhogy azok nem jelentek meg. Próbaként kiírattam különböző definiált változókat, számoltat is, azok mentek. Csak azok a változók nem, amik a POST-ból jöttek... 

Íme a program által átküldött válasz:
"Connected successfully<br>+x+<br/>13<br/><br/>Error: <br>"

A kód:

<?php /* Rui Santos Complete project details at https://RandomNerdTutorials.com/esp32-esp8266-mysql-database-php/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. $servername = "localhost"; $username = "xxxx"; $password = "xxxx"; $dbname = "xxxx"; */ $servername = "localhost"; // REPLACE with your Database name $dbname = "xxxx"; // REPLACE with Database user $username = "xxxx"; // REPLACE with Database user password $password = "xxxx"; // Keep this API Key value to be compatible with the ESP32 code provided in the project page. // If you change this value, the ESP32 sketch needs to match $api_key_value = "abcdefghij"; $szam = 13; $api_key= $sensor = $location = $value1 = $value2 = $value3 = ""; // Create connection $conn = new mysqli($servername, $username, $password); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } else { echo "Connected successfully<br>"; } mysqli_select_db($conn, $dbname) or die("Nem sikerült kiválasztani az adatbázist!"); if ($_SERVER["REQUEST_METHOD"] == "POST") { $api_key = test_input($_POST["api_key"]); $api_key_save = $api_key; echo $api_key,"+x+<br/>"; if($api_key == $api_key_value) { $sensor = test_input($_POST["sensor"]); $location = test_input($_POST["location"]); $value1 = test_input($_POST["value1"]); $value2 = test_input($_POST["value2"]); $value3 = test_input($_POST["value3"]); echo "$value1"; $sql = "INSERT INTO SensorData (sensor, location, value1, value2, value3) VALUES ('" . $sensor . "', '" . $location . "', '" . $value1 . "', '" . $value2 . "', '" . $value3 . "')"; if ($conn->query($sql) == TRUE) { echo "New record created successfully"; echo $szam,"<br/>"; $szam = $szam+1; } else { echo "Error: " . $sql . "<br>" . $conn->error; } $conn->close(); } else { $szam = $szam+1; echo $szam,"<br/>"; echo $value1,"<br/>"; echo "Error: " . $sql . "<br>" . $conn->error; // echo "Wrong API Key provided."; } } else { echo "No data posted with HTTP POST"; echo $szam,"<br/>"; $szam = $szam+1; } function test_input($data) { $data = trim($data); $data = stripslashes($data); $data = htmlspecialchars($data); return $data; } ?>

Lehet, hogy tök egyszerű lesz a válasz, de nekem semmi nem jön be az én tudásom alapján.
Mutasd a teljes hozzászólást!
Küldtem egy privát üzenetet.
Mutasd a teljes hozzászólást!

  • Jaigen, a kérdés, hogy miért nem műxik az echo, a másik pedig, hogy a témafelvetés közben kísérleteztem, csak már mentések voltak. 

    A válaszban ezért a 13 az 14... még mielőtt más felveti, hogy ott valami nem stimmel.
    Mutasd a teljes hozzászólást!
  • Gyors észrevétel:

    echo $api_key,"+x+<br/>";
    Vessző helyett pont akart lenni gondolom. Több helyen is van.
    Mutasd a teljes hozzászólást!
  • És talán hatékonyabb lenne, ha a hibákat nem a response-ból, hanem mondjuk a php error logból mazsoláznád ki.
    Írhatsz saját error_handler is, amiben aztán szintén naplózhatsz szerver oldalon. Másik példa: w3schools
    Mutasd a teljes hozzászólást!
  • Átírtam, nem változik. 
    De a "echo $szam,"<br/>";" sorban is vessző van, az pedig működik. 

    Jelenleg még az ESP-hez értek jobban, ezért használom a responsét hibakiíratásra.
    Mutasd a teljes hozzászólást!
  • Az kiderült, hogy konkrétan melyik sorig jut el a program?
    Mutasd a teljes hozzászólást!
  • Létrehozza az új adatbázis rekordot, majd érdekes mód ráfut az alatta levő, pont ezzel szemben megjelenő hibaüzenetre. 
    Az "if (api_key ==" feltétel true ága hozná létre a rekordot, az el is készül, majd az üzenet a false ág részéből jön.
    De az api_key kibontása utáni echo-ból is csak az idézőjelek közötti rész jelenik meg.
    Mutasd a teljes hozzászólást!
  • Megkérdezem még egyszer: konkrétan melyik sorig jut el a program?
    A (szerver oldali) hibanaplót megnézted végül?
    Mutasd a teljes hozzászólást!
  • if ($conn->query($sql) == TRUE)
    helyett

    if ($conn->query($sql) === TRUE)
    Mutasd a teljes hozzászólást!
  • Na, meglett a log file.

    [Sun Apr 11 23:21:21.252615 2021] [php7:notice] [pid 668] [client 192.168.1.133:51206] PHP Notice:  Undefined index: api_key in /var/www/html/post-esp-data.php on line 59
    [Sun Apr 11 23:21:21.253004 2021] [php7:notice] [pid 668] [client 192.168.1.133:51206] PHP Notice:  Undefined variable: sql in /var/www/html/post-esp-data.php on line 95

    Mondjuk ezt sem értem... de az legyen egy másik lépés. 

    Viszont, ha már sorszámoknál tartunk:
    Az 59-ik sorban levő echo sem megy. Bár igaz, hogy a hibaüzenet szerint a változó üres. Viszont akkor a 60-ik sorban levő feltétel hogy teljesül? Merthogy az adatbázis bejegyzés létrejön. Valamint két sorral felette van definiálva az $api_key... akkor hogyhogy nem létezik?
    Mutasd a teljes hozzászólást!
  • Köszönöm. 
    Eredetileg úgy volt, csak én hittem, C-hez szokottan és itt is látva, hogy véletlen belekerült. 
    De érdekes mód semmit nem változtat a hibajelenségen.
    Mutasd a teljes hozzászólást!
  • Gondolom valamit már átírtál a php fájlban, mert a sorszámok nem stimmelnek.
    Beidézhetnéd azt, ami párban van a logban olvasható információkkal!
    Mutasd a teljes hozzászólást!
  • Nagyon az a tippem, hogy a szenzornak a kódjánál keresendő a hiba nem pedig a php kódba.
    Mert ha $api_key == $api_key_value akkor az már nem futhat false ágra max akkor ha a szenzor küld még egy olyan kérést ahol az $api_key más és azt vizsgálod.
    Mutasd a teljes hozzászólást!
  • Biztos, hogy nem.
    Ugyanis a HTTP_POST nem tér vissza a mikrokontrollerhez (ESP), míg le nem tudja a kódját. Az api_key statikus, nem változik üzenetenként. A rekordban van egy üzenetszámláló, amit a mikrokontroller léptet és én utána látom a rekord egyik mezőjében, az lineáris, nincs kihagyás.
    Nem tudom, hogy működik pontosan a http request lekezelése, de az ESP addig ácsorog a főrutinjában, amíg a PHP file le nem rendezte a teljes "if ($_SERVER["REQUEST_METHOD"] == "POST")" ágat. Ekkor kapom meg responsében az összes echo eredményét, csak hiányosan (lásd az alapkérdést)
    Ebben az ágban hozza létre az adatbázis rekordot is, majd annak létrehozása után ráfut arra a hibaüzenetre, ami a rekord létrehozásának az else ága... na, itt adtam fel és fordultam hozzátok.
    Mutasd a teljes hozzászólást!
  • Küldtem egy privát üzenetet.
    Mutasd a teljes hozzászólást!
  • Meglett a megoldás.

    Valóban az ESP kódjában volt a trükk.

    HTTPClient http; // Your Domain name with URL path or IP address with path http.begin(serverName); http.addHeader("Content-Type", "application/x-www-form-urlencoded"); String httpRequestData = "api_key=" + apiKeyValue + "&sensor=" + sensorName + "&location=" + sensorLocation + "&value1=" + String(tesztki_cnt++) + "&value2=" + String(ido_cnt) + "&value3=" + String(ki_cnt) + ""; if (http.POST(httpRequestData)) { int httpResponseCode = http.POST(httpRequestData); String payload = http.getString(); Serial.println(payload); http.end(); }
    Itt az "if (http.POST(httpRequestData))" alatt már végrehajtódott a http post. 
    Majd egy sorral lejjebb újra. A két request meg egymásra futott és meghülyítette a php fordítót. 
    Az adatbázison meg azért nem volt nyoma, mert közben nem változtak az értékek. 
    Az itt eddig nem részletezett őrült hosszú válaszidőt is jó eséllyel ez okozta, ugyanis azóta már majdnem elfogadható 3-400 msec-es válaszidő van a PI sql szerverétől (MariaDB)
    És megint egy érv az átgondolatlanul átvett mintaprogramok ellen... de hát valahol el kell kezdeni tanulni. 
    A megoldásért külön köszönet Shadow21-nek.
    Mutasd a teljes hozzászólást!
abcd