Apologies in advance for any mistakes as I'm very new to Node-Red. I'm trying to set up a simple HTTP server to update my ESP8266 node.
How it works is: the ESP8266 will send an HTTP request to a specific URL, and await a response of a binary folder. The binary file is stored in a folder locally on my Windows PC where the Node-Red is running. How can I setup a Node-Red flow that will do this?
This is my current setup but it doesn't work. When I request the URL through a web browser, it just downloads a folder with no file type.
These are the documentations for the ESP8266 side. The documentation recommends to setup a PHP server with the following code. However, this code is a little more complex which helps check the version before updating with the right binary file which I plan to implement later on in Node-Red.
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:AA" => "DOOR-7-g14f53a19",
"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);
Any help will be much appreciated. Thank you.
First things first. Let´s try to understand why your flow does not work and try to have it fixed.
There is a flow in Node-RED library that performs exactly what you want to achieve. If you have not tried yet please do it asap. Link: https://cookbook.nodered.org/http/serve-a-local-file
Second point to consider: When we want to serve local content we need to set up an http static path in Node-RED configuration file called: settings.js
You have to open this file, find the line that start with httpStatic:
, modify it to your fit your setup and leave it uncommented. Here is how my setup looks like (don´t simply copy and paste, you need to configure your directory here).
// following property can be used to identify a directory of static content
// that should be served at http://localhost:1880/.
//httpStatic: '/home/nol/node-red-static/',
httpStatic: "C://Users/OCM/.node-red/static",
Be careful when selecting the file to edit. According to the words of the experts:
"Most often, when your changes to the settings file are not taking effect, it means you have edited the wrong file. There is one delivered with the installed code, which is then copied into your user directory (typically ~/.node-red). Rickus"
Finally, don´t forget to copy your binary file to this static directory.
After checking all those points it is likely that the outcome of your flow will be the binary file and this can be checked by adding a debug node (configured to display complete msg object) right after the file in node. If you see a buffer in your msg.payload it means that your flow is serving the binary file.
EDIT: Searching Node-RED library I see that there is already an example flow that is compliant with ESP8266httpUpdate HTTP requests.
Link: https://flows.nodered.org/flow/888b4cd95250197eb429b2f40d188185