httpUpdate OTA - Probleme

Begonnen von Pf@nne, 10 März 2016, 05:59:47

Vorheriges Thema - Nächstes Thema

Pf@nne

Moin,

hat schon mal jemand das httpUpdate getestet, bzw. läuft das bei jemandem?
Das sollte ja eigentlich, Webserver vorausgesetzt, die einfachste der 3 OTA- Möglichkeiten sein.

Bei mir findet er zwar den *.bin, bleibt aber irgendwie hängen.

[httpUpdate] Header read fin.<\n>
[httpUpdate] Server header:<\n>
[httpUpdate] - code: 200<\n>
[httpUpdate] - len: 234224<\n>
[httpUpdate] ESP8266 info:<\n>
[httpUpdate] - free Space: 2854912<\n>
[httpUpdate] - current Sketch Size: 287460<\n>
[httpUpdate] runUpdate flash...<\n>
ets Jan 8 2013,rst cause:4, boot mode:(1,6)<\r>
wdt reset<\r><\n>
FHEM auf: DS415+ (Master), Raspberry Pi 2

scuba

Servus!

Ja ich hab das bei mir am Laufen! Ich hab mich an die Anleitung des "advanced Updaters" https://github.com/esp8266/Arduino/blob/master/doc/ota_updates/readme.md#http-server gehalten.

Ablauf des Update Prozesses:
- Der kompilierte Sketch liegt am Webserver mit dem Namen <Firmware_Version>.bin
- Der ESP schaut zyklisch am Webserver vorbei, und sendet eine Anfrage mit seiner aktuellen Firmware Version an den Webserver.
- Der Webserver überprüft ob es sich um einen gültige Update Anfrage eines ESP handelt, und schaut nach ob es für die MAC Adresse des ESP ein neues Update gibt.
  Falls ja wird mit Status 200 das File übergeben, falls nein bricht er mit Status 304 ab.

ACHTUNG!!!! Im Tutorial wird davon ausgegangen, dass die Firmware den Dateinamen "<Firmware_Version>bin" (also ohne ".") hat. Hat mich einige Stunden gekostet ;-)


Zu deinem Problem: gpio0 hast du eh nicht auf GRND oder?



Pf@nne

ZitatZu deinem Problem: gpio0 hast du eh nicht auf GRND oder?

Am GPIO0 ist der Flash-Taster dran, der ist ja aber offen.

Ich hab gerade mal meinen WEB-Server getestet, der kann ja sogar PHP, cool..... 8)

Kannst du deinen Sketch und das PHP Script mal drann hängen?

Gruß
Pf@nne
FHEM auf: DS415+ (Master), Raspberry Pi 2

scuba

Klar , die entsprechen aber eh weitestgehend denen aus dem Tutorial:

Serverseitig:
arduino.php
<?PHP


header('Content-type: text/plain; charset=utf8', true);



function check_header($name, $value = false) {
    if(!isset($_SERVER[$name])) {
        return false;
    }
    if($value && $_SERVER[$name] != $value) {
        return false;
    }
    return true;
}

function sendFile($path) {
    header($_SERVER["SERVER_PROTOCOL"].' 200 OK', true, 200);
    header('Content-Type: application/octet-stream', true);
    header('Content-Disposition: attachment; filename='.basename($path));
    header('Content-Length: '.filesize($path), true);
    header('x-MD5: '.md5_file($path), true);
    readfile($path);
}

if(!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater!\n";
    exit();
}

if(
    !check_header('HTTP_X_ESP8266_STA_MAC') ||
    !check_header('HTTP_X_ESP8266_AP_MAC') ||
    !check_header('HTTP_X_ESP8266_FREE_SPACE') ||
    !check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
    !check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
    !check_header('HTTP_X_ESP8266_SDK_VERSION') ||
    !check_header('HTTP_X_ESP8266_VERSION')
) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater! (header)\n";
    exit();
}

$db = array(
    "18:FE:AA:AA:AA:B1" => "heizraum_messwerte_0.5.3",
    "18:FE:AA:AA:AA:B2" => "kueche_dht22_0.1.1",
    "18:FE:AA:AA:AA:B3" => "bad_dht22_0.1.1",
    "18:FE:AA:AA:AA:BB" => "TEMP-1.0.0"
);

if(isset($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']])) {
    if($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION']) {
        sendFile("./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']].".bin");
    } else {
        header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
    }
    exit();
}

header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);


Wie bereits vorher erwähnt enden meine Firmwaredateien auf *.bin. Daher die Pfadangabe mit ..._STA_MAC']].".bin". im originalen ist es nur ..."bin". Im Array "db" wird die MAC des jeweiligen ESP sowie die aktuelle Firmware Version (nicht der Dateiname der FW) definiert.

Listing des Firmware Ordners
-rw-r--r-- 1 www-data www-data 268000 Mär 10 21:21 bad_dht22_0.1.1.bin
-rw-r--r-- 1 www-data www-data 268016 Mär 10 21:22 kueche_dht22_0.1.1.bin
-rw-r--r-- 1 www-data www-data 268048 Mär 10 21:23 buegelzimmer_dht22_0.1.1.bin
-rw-r--r-- 1 www-data www-data 268048 Mär 10 21:24 schlafzimmer_dht22_0.1.1.bin
-rw-r--r-- 1 www-data www-data 268048 Mär 10 21:26 speisekammer_dht22_0.1.1.bin
-rw-r--r-- 1 www-data www-data 270960 Mär 10 21:28 heizraum_messwerte_0.5.3.bin


Clientseitig:


#include <ESP8266httpUpdate.h>

#define room "heizraum"
#define firmware_version room"_messwerte_0.X.Y"
#define update_server "10.0.0.X"
#define update_uri "/esp/update/arduino.php"

void do_update(){
  Serial.println("do update");
  t_httpUpdate_return ret = ESPhttpUpdate.update(update_server, 80, update_uri, firmware_version);
  switch(ret) {
    case HTTP_UPDATE_FAILED:
        Serial.println("[update] Update failed.");
        break;
    case HTTP_UPDATE_NO_UPDATES:
        Serial.println("[update] Update no Update.");
        break;
    case HTTP_UPDATE_OK:
        Serial.println("[update] Update ok."); // may not called we reboot the ESP
        break;
  }
}


Das Define "firmware-version" muss natürlich bei jeder Änderung alteriert werden. Ansonsten würd der ESP im Kreis updaten ;-)

Pf@nne

Danke für den Code,

ich habe auf meinem Server das arduino.php im root, die MAC habe ich an meinen ESP angepasst
<?PHP


header('Content-type: text/plain; charset=utf8', true);



function check_header($name, $value = false) {
    if(!isset($_SERVER[$name])) {
        return false;
    }
    if($value && $_SERVER[$name] != $value) {
        return false;
    }
    return true;
}

function sendFile($path) {
    header($_SERVER["SERVER_PROTOCOL"].' 200 OK', true, 200);
    header('Content-Type: application/octet-stream', true);
    header('Content-Disposition: attachment; filename='.basename($path));
    header('Content-Length: '.filesize($path), true);
    header('x-MD5: '.md5_file($path), true);
    readfile($path);
}

if(!check_header('HTTP_USER_AGENT', 'ESP8266-http-Update')) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater!\n";
    exit();
}

if(
    !check_header('HTTP_X_ESP8266_STA_MAC') ||
    !check_header('HTTP_X_ESP8266_AP_MAC') ||
    !check_header('HTTP_X_ESP8266_FREE_SPACE') ||
    !check_header('HTTP_X_ESP8266_SKETCH_SIZE') ||
    !check_header('HTTP_X_ESP8266_CHIP_SIZE') ||
    !check_header('HTTP_X_ESP8266_SDK_VERSION') ||
    !check_header('HTTP_X_ESP8266_VERSION')
) {
    header($_SERVER["SERVER_PROTOCOL"].' 403 Forbidden', true, 403);
    echo "only for ESP8266 updater! (header)\n";
    exit();
}

$db = array(
    //"18:FE:AA:AA:AA:B1" => "heizraum_messwerte_0.5.3",
    "18:FE:AA:AA:AA:B2" => "kueche_dht22_0.1.1",
    "18:FE:AA:AA:AA:B3" => "bad_dht22_0.1.1",
    "18:FE:AA:AA:AA:BB" => "TEMP-1.0.0",
"1E:27:6:7F:CF:5C" => "heizraum_messwerte_0.0.1"
);

if(isset($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']])) {
    if($db[$_SERVER['HTTP_X_ESP8266_STA_MAC']] != $_SERVER['HTTP_X_ESP8266_VERSION']) {
        sendFile("./bin/".$db[$_SERVER['HTTP_X_ESP8266_STA_MAC']].".bin");
    } else {
        header($_SERVER["SERVER_PROTOCOL"].' 304 Not Modified', true, 304);
    }
    exit();
}

header($_SERVER["SERVER_PROTOCOL"].' 500 no version for ESP MAC', true, 500);


Sketch:

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#include <ESP8266HTTPClient.h>
#include <ESP8266httpUpdate.h>

#define room "heizraum"
#define firmware_version room"_messwerte_0.0.1"
#define update_server "192.168.1.3"
#define update_uri "/arduino.php"


void setup() {
  Serial.begin(115200);
  Serial.println("");
  Serial.println("");

  WiFi.begin("xx", "xx");

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("connected");

  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  Serial.print(mac[5],HEX);
  Serial.print(":");
  Serial.print(mac[4],HEX);
  Serial.print(":");
  Serial.print(mac[3],HEX);
  Serial.print(":");
  Serial.print(mac[2],HEX);
  Serial.print(":");
  Serial.print(mac[1],HEX);
  Serial.print(":");
  Serial.println(mac[0],HEX);

  Serial.println("");
  Serial.println("start flashing......");

  t_httpUpdate_return ret = ESPhttpUpdate.update(update_server, 80, update_uri, firmware_version);
  switch(ret) {
    case HTTP_UPDATE_FAILED:
        Serial.println("[update] Update failed.");
        break;
    case HTTP_UPDATE_NO_UPDATES:
        Serial.println("[update] Update no Update.");
        break;
    case HTTP_UPDATE_OK:
        Serial.println("[update] Update ok."); // may not called we reboot the ESP
        break;
  }
}

void loop() {
}


Den compilierten .bin habe ich unter /bin auf dem Server liegen.
Den .bin  habe ich "heizraum_messwerte_0.0.2.bin" genannt.

jetzt sollte die laufende Version 0.0.1 doch eigentlich auf die Version 0.0.2 geflasht werden?


........<\r><\n>
connected<\r><\n>
MAC: 1E:27:6:7F:CF:5C<\r><\n>
<\r><\n>
start flashing......<\r><\n>
[httpUpdate] Header read fin.<\n>
[httpUpdate] Server header:<\n>
[httpUpdate]  - code: 500<\n>
[httpUpdate]  - len: -1<\n>
[httpUpdate] ESP8266 info:<\n>
[httpUpdate]  - free Space: 2854912<\n>
[httpUpdate]  - current Sketch Size: 288524<\n>
[httpUpdate]  - current version: heizraum_messwerte_0.0.1<\n>
[httpUpdate] HTTP Code is (500)<\n>
[update] Update failed.<\r><\n>
pm open,type:2 0<\r><\n>


Warum gibt das jetzt einen Code 500?
Der zu flashende ist doch eine Version neuer?

Mache ich da noch einen Gedankenfehler?

FHEM auf: DS415+ (Master), Raspberry Pi 2

sbiermann

Aus dem Bauch heraus geschossen, dein PHP Skript hat einen Fehler. Daher kommt vom Webserver der Statuscode 500 zurück.

eppi

#6
Hallo zusammen
Ich versuche ebenfalls mit OTA meinen ESP zu flashen, aber irgendwie will er einfach nicht.

Mein ESP-Sketch ruft nach dem Wifi Connect folgenden Code auf:
    t_httpUpdate_return ret = ESPhttpUpdate.update("192.168.111.12", 80, "/updatesketch/bin/ESPFHEM-Kueche_V1_0.cpp.bin");
  switch(ret) {
    case HTTP_UPDATE_FAILED:
        Serial.println("[update] Update failed.");
        break;
    case HTTP_UPDATE_NO_UPDATES:
        Serial.println("[update] Update no Update.");
        break;
    case HTTP_UPDATE_OK:
        Serial.println("[update] Update ok."); // may not called we reboot the ESP
        break;
  }
"
Das File "ESPFHEM-Kueche_V1_0.cpp.bin" habe ich gemäss Arduino-IDE Log von "C:\Users\admin\AppData\Local\Temp\build4256764384887221989.tmp/ESPFHEM-Kueche_V1_0.cpp.bin" im Apache unter "/updatesketch/bin/" abgelegt.
Das Apache Accesslog sagt mir auch, dass die Anfrage des ESP "OK" war:
192.168.111.65 - - [13/Mar/2016:09:21:12 +0100] "GET /updatesketch/bin/ESPFHEM-Kueche_V1_0.cpp.bin HTTP/1.1" 200 29200 "-" "ESP8266-http-Update"

Mein Serial Monior sagt jedoch immer:
[update] Update failed.

Kann mir jemand einen Hint geben, wo ich suchen könnte um den Fehler zu finden?
Danke vielmals!

Update: Fehler gefunden - Sketch (bin-File) war zu gross!

Pf@nne

Ahhhh.....

mit einem Anderen ESP klappt zumindest:

t_httpUpdate_return ret = ESPhttpUpdate.update(update_server, 80, "/bin/FW.bin");

Obwohl ich den ESP zwischenzeitlich platt gebügelt hatte......
Ein klein wenig zickig sind die Dinger manchmal schon.......

Jetzt werde ich das UpdateScript mal versuchen.....
FHEM auf: DS415+ (Master), Raspberry Pi 2

scuba

@ Pf@nne:

im "db" Array sagst du dem PHP Script welche MAC Adresse welches Image bekommen soll. Die Aktuelle Firmware auf deinem ESP hat die Version #define firmware_version room"_messwerte_0.0.1".

Du hast im PHP File nun  folgendes definiert ""1E:27:6:7F:CF:5C" => "heizraum_messwerte_0.0.1"". Sprich dein Script glaubt das die Datei "heizraum_messwerte_0.0.1.bin" die aktuelle Firmware für dein ESP ist. Im Normalfall sollte der Webserver nun Status 304 zurückliefern und dein ESP sollt mit der Meldung "No Update" quittieren.
Ich vermute mal, dass im "/bin" Verzeichnis die Datei "heizraum_messwerte_0.0.1.bin" nicht zur Verfügung steht (da du ja eigentlich "heizraum_messwerte_0.0.2.bin" als aktuelle Datei drin hast) und sich das Script deshalb mit Status 500 (Server Error) verabschiedet.