Nodemcu and http update
Posted: Tue Aug 21, 2018 8:57 am
Hi all, I'm new here; so if I posted this in the wrong forum, I'm sorry.
I'm trying to setup my ModeMCU to get it's updates from a web server. I set up a PHP file to make sure it doesn't keep downloading the update file. My web site is being hosted by Ipower.com It's not local so I'm have a hard time getting verbose error logs. I do know that I can access the php file by the NodeMCU. I'm currently getting this error: HTTP_UPDATE_FAILD Error (-103): Forbidden (403. It makes me think that I'm not using the right MAC address. When I flash the NodeMCU with the NodeMCU flasher I get 2 MAC address's, AP and STA.
When I use a script to get the MAC address I get a different MAC address. I've tried all 3 mac address's in my script and still get an error.
Here is my sketch. Edited for security..,:
Here is my PHP file:
Any help will be appreciated.
Thank you
I'm trying to setup my ModeMCU to get it's updates from a web server. I set up a PHP file to make sure it doesn't keep downloading the update file. My web site is being hosted by Ipower.com It's not local so I'm have a hard time getting verbose error logs. I do know that I can access the php file by the NodeMCU. I'm currently getting this error: HTTP_UPDATE_FAILD Error (-103): Forbidden (403. It makes me think that I'm not using the right MAC address. When I flash the NodeMCU with the NodeMCU flasher I get 2 MAC address's, AP and STA.
When I use a script to get the MAC address I get a different MAC address. I've tried all 3 mac address's in my script and still get an error.
Here is my sketch. Edited for security..,:
Code: Select all
#define BLYNK_PRINT Serial
#include <Arduino.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266httpUpdate.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
// #include <Wire.h>
#define N_DIMMERS 3
#define led_pin D0
#define USE_SERIAL Serial
#define led_blink D1
ESP8266WiFiMulti WiFiMulti;
int dimmer_pin[] = {14, 5, 15};
// Voltage Sensor Data
float vout = 0.0;
float vin = 0.0;
float R1 = 29980.0; //
float R2 = 7520.0; //
int value = 0;
char auth[] = "adaefce52c2a4ac09f98800fbe76a87b";
char ssid[] = "**";
char pass[] = "**";
char host[] = "ESP-OTA";
// Select your pin with physical button
const int btnPin = D5;
const int Stop = D6;
const int Prime = D6;
WidgetLED led3(V3);
WidgetLED led4(V4);
BlynkTimer timer;
BLYNK_CONNECTED() {
Blynk.syncAll();
}
void LedWidget() {
if (digitalRead(btnPin) == HIGH) { // Sets LED widget ON or OFF depending on state of btnpin
led3.on();
} else {
led3.off ();
}
if (digitalRead(Stop) == HIGH) { // Sets LED widget ON or OFF depending on state of btnpin
led4.on();
} else {
led4.off ();
}
}
void ButtonWidget() {
if (digitalRead(btnPin) == HIGH) { // Sets LED widget ON or OFF depending on state of btnpin
Blynk.virtualWrite(V20, HIGH);
} else {
Blynk.virtualWrite(V20, LOW);
}
if (digitalRead(Stop) == HIGH) { // Sets LED widget ON or OFF depending on state of btnpin
Blynk.virtualWrite(V21, HIGH);
} else {
Blynk.virtualWrite(V21, LOW);
}
if (digitalRead(Prime) == HIGH) { // Sets LED widget ON or OFF depending on state of btnpin
Blynk.virtualWrite(V22, HIGH);
} else {
Blynk.virtualWrite(V22, LOW);
}
}
void myTimerEvent(){
value = analogRead(A0);
vout = (value * 3.253 / 1024); // see text
vin = vout / (R2 / (R1 + R2));
Blynk.virtualWrite(V1, vin);
}
void myBlinkEvent(){
digitalWrite(led_blink, HIGH);
delay(1000);
digitalWrite(led_blink, LOW);
delay(1000);
}
void myUpdateEvent(){
// wait for WiFi connection
if ((WiFiMulti.run() == WL_CONNECTED))
{
t_httpUpdate_return ret = ESPhttpUpdate.update("**", 80, "/bin/nodemcu.php");
//t_httpUpdate_return ret = ESPhttpUpdate.update("https://server/file.bin", "", "fingerprint");
switch (ret) {
case HTTP_UPDATE_FAILED:
USE_SERIAL.printf("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
break;
case HTTP_UPDATE_NO_UPDATES:
USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES");
break;
case HTTP_UPDATE_OK:
USE_SERIAL.println("HTTP_UPDATE_OK");
break;
}
}
}
void setup()
{
Serial.begin(115200);
// USE_SERIAL.setDebugOutput(true);
Blynk.begin(auth, ssid, pass);
pinMode(led_pin, OUTPUT);
digitalWrite(led_pin, LOW);
pinMode(btnPin, OUTPUT);
pinMode(Stop, OUTPUT);
pinMode(led_blink, OUTPUT);
digitalWrite(btnPin, LOW);
digitalWrite(Stop, LOW);
timer.setInterval(100L, LedWidget);
timer.setInterval(100L, ButtonWidget);
timer.setInterval(1000L, myTimerEvent);
timer.setInterval(2000L, myBlinkEvent);
timer.setInterval(60000L, myUpdateEvent);
Serial.println("Booting");
for (uint8_t t = 4; t > 0; t--) {
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
USE_SERIAL.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
Blynk.begin(auth, ssid, pass);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Blynk.begin(auth, ssid, pass);
Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 80);
Serial.println("Retrying connection...");
}
/* switch off led */
digitalWrite(led_pin, HIGH);
/* configure dimmers, and OTA server events */
analogWriteRange(1000);
analogWrite(led_pin, 990);
for (int i = 0; i < N_DIMMERS; i++) {
pinMode(dimmer_pin[i], OUTPUT);
analogWrite(dimmer_pin[i], 50);
}
ArduinoOTA.setHostname(host);
ArduinoOTA.onStart([]() { // switch off all the PWMs during upgrade
for (int i = 0; i < N_DIMMERS; i++) {
analogWrite(dimmer_pin[i], 0);
}
analogWrite(led_pin, 0);
});
ArduinoOTA.onEnd([]() { // do a fancy thing with our board led at end
for (int i = 0; i < 30; i++) {
analogWrite(led_pin, (i * 100) % 1001);
delay(50);
}
});
ArduinoOTA.onError([](ota_error_t error) {
(void)error;
ESP.restart();
});
/* setup the OTA server */
ArduinoOTA.begin();
Serial.println("Ready");
}
BLYNK_WRITE(V20) {
digitalWrite(btnPin, param.asInt()); // Sets btnPin HIGH or LOW depending on state of Button Widget.
int value = param.asInt();
if (value == 1) {
Serial.println("Start x on");
digitalWrite(btnPin, HIGH);
timer.setTimeout(10000L, []() { // 10 seconds
digitalWrite(btnPin, LOW);
}); // END Timer Function
Blynk.virtualWrite(V20, LOW);
//stop running
}
}
BLYNK_WRITE(V21) {
digitalWrite(Stop, param.asInt()); // Sets btnPin HIGH or LOW depending on state of Button Widget.
int kill = param.asInt();
if (kill == 1) {
Serial.println("Shutdown x on");
digitalWrite(Stop, HIGH);
timer.setTimeout(1000L, []() { // 1 seconds
digitalWrite(Stop, LOW);
}); // END Timer Function
Blynk.virtualWrite(V20, LOW);
//stop running
}
}
BLYNK_WRITE(V22) {
digitalWrite(btnPin, param.asInt()); // Sets btnPin HIGH or LOW depending on state of Button Widget.
int prime = param.asInt();
if (prime == 1) {
Serial.println("Prime x on");
digitalWrite(Stop, HIGH);
timer.setTimeout(15000L, []() { // 15 seconds
digitalWrite(Stop, LOW);
}); // END Timer Function
Blynk.virtualWrite(V22, LOW);
//stop running
}
}
BLYNK_WRITE(V23) {
digitalWrite(btnPin, param.asInt()); // Sets btnPin HIGH or LOW depending on state of Button Widget.
}
BLYNK_WRITE(V24) {
digitalWrite(btnPin, param.asInt()); // Sets btnPin HIGH or LOW depending on state of Button Widget.
}
void loop()
{
Blynk.run();
ArduinoOTA.handle();
timer.run();
}
Here is my PHP file:
Code: Select all
<?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(
"38:2B:78:03:84:A3" => "update.bin" # <-- I have added the ESP MAC address and file name
);
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);
?>
Any help will be appreciated.
Thank you