|
[ |
|
{ |
|
"id": "c8dc8a91.74103", |
|
"type": "tab", |
|
"label": "ESP8266" |
|
}, |
|
{ |
|
"id": "ff59207a.78407", |
|
"type": "http in", |
|
"z": "c8dc8a91.74103", |
|
"name": "OTA Request", |
|
"url": "/esp8266-ota/update/:version", |
|
"method": "get", |
|
"upload": false, |
|
"swaggerDoc": "", |
|
"x": 84.5, |
|
"y": 115, |
|
"wires": [ |
|
[ |
|
"d3b826bb.dc20c8", |
|
"eaeeef87.2b0bf" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "eeb8fd90.56a408", |
|
"type": "http response", |
|
"z": "c8dc8a91.74103", |
|
"name": "OTA Response", |
|
"x": 3348.5597534179688, |
|
"y": 594.107177734375, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "34f9b5d5.3b5d2a", |
|
"type": "file in", |
|
"z": "c8dc8a91.74103", |
|
"name": "Load Firmware", |
|
"filename": "", |
|
"format": "", |
|
"sendError": false, |
|
"x": 2586.499786376953, |
|
"y": 379.9285888671875, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408", |
|
"84851e19.4a5868" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "83413646.c2dd4", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "No Update", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "statusCode", |
|
"pt": "msg", |
|
"to": "304", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 2955.607421875, |
|
"y": 238.5714111328125, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "9eb7afe3.46c438", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Forbidden", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "statusCode", |
|
"pt": "msg", |
|
"to": "403", |
|
"tot": "str" |
|
}, |
|
{ |
|
"t": "set", |
|
"p": "payload", |
|
"pt": "msg", |
|
"to": "Forbidden", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 2933.499755859375, |
|
"y": 115.89285278320312, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "d3b826bb.dc20c8", |
|
"type": "switch", |
|
"z": "c8dc8a91.74103", |
|
"name": "Check user agent", |
|
"property": "req.headers.user-agent", |
|
"propertyType": "msg", |
|
"rules": [ |
|
{ |
|
"t": "neq", |
|
"v": "ESP8266-http-Update", |
|
"vt": "str" |
|
}, |
|
{ |
|
"t": "else" |
|
} |
|
], |
|
"checkall": "false", |
|
"outputs": 2, |
|
"x": 303.71435546875, |
|
"y": 114.99999237060547, |
|
"wires": [ |
|
[ |
|
"9eb7afe3.46c438" |
|
], |
|
[ |
|
"76e0c603.3b90e" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "76e0c603.3b90e", |
|
"type": "switch", |
|
"z": "c8dc8a91.74103", |
|
"name": "Update type", |
|
"property": "req.headers.x-esp8266-mode", |
|
"propertyType": "msg", |
|
"rules": [ |
|
{ |
|
"t": "eq", |
|
"v": "spiffs", |
|
"vt": "str" |
|
}, |
|
{ |
|
"t": "eq", |
|
"v": "sketch", |
|
"vt": "str" |
|
} |
|
], |
|
"checkall": "false", |
|
"outputs": 2, |
|
"x": 484.0179748535156, |
|
"y": 208.57144165039062, |
|
"wires": [ |
|
[ |
|
"83413646.c2dd4" |
|
], |
|
[ |
|
"5a91d95d.b3f47" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "11ff4157.023e3f", |
|
"type": "comment", |
|
"z": "c8dc8a91.74103", |
|
"name": "Sketch", |
|
"info": "", |
|
"x": 650.7857055664062, |
|
"y": 293.142822265625, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "67da418c.27d3c", |
|
"type": "comment", |
|
"z": "c8dc8a91.74103", |
|
"name": "Spiffs", |
|
"info": "", |
|
"x": 599.5, |
|
"y": 157, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "12caf8cf.3a330f", |
|
"type": "http in", |
|
"z": "c8dc8a91.74103", |
|
"name": "OTA Manager", |
|
"url": "/esp8266-ota", |
|
"method": "get", |
|
"swaggerDoc": "", |
|
"x": 88.05558013916016, |
|
"y": 648.2856712341309, |
|
"wires": [ |
|
[ |
|
"5ae37750.4cb7a" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "499fe21f.f66814", |
|
"type": "httpInMultipart", |
|
"z": "c8dc8a91.74103", |
|
"name": "OTA Upload", |
|
"url": "/esp8266-ota", |
|
"method": "post", |
|
"fields": "[{ \"name\": \"firmware\"}]", |
|
"swaggerDoc": "", |
|
"x": 79.7857437133789, |
|
"y": 812.4286108016968, |
|
"wires": [ |
|
[ |
|
"8951ec5b.14d068" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "8951ec5b.14d068", |
|
"type": "fs-ops-move", |
|
"z": "c8dc8a91.74103", |
|
"name": "Store firmware", |
|
"sourcePath": "req.files.firmware[0].destination", |
|
"sourcePathType": "msg", |
|
"sourceFilename": "req.files.firmware[0].filename", |
|
"sourceFilenameType": "msg", |
|
"destPath": "firmware.directory", |
|
"destPathType": "flow", |
|
"destFilename": "req.files.firmware[0].originalname", |
|
"destFilenameType": "msg", |
|
"link": false, |
|
"x": 365.89284896850586, |
|
"y": 818.3332557678223, |
|
"wires": [ |
|
[ |
|
"8cd5701d.92156", |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "b95b8c19.19c4e8", |
|
"type": "md5", |
|
"z": "c8dc8a91.74103", |
|
"name": "", |
|
"fieldToHash": "payload", |
|
"hashField": "payload", |
|
"hashFieldType": "msg", |
|
"x": 1031.6668090820312, |
|
"y": 846.6666259765625, |
|
"wires": [ |
|
[ |
|
"b3a0c31.a959d4" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "a4a110d9.d17838", |
|
"type": "file", |
|
"z": "c8dc8a91.74103", |
|
"name": "Save md5 Checksum", |
|
"filename": "", |
|
"appendNewline": false, |
|
"createDir": false, |
|
"overwriteFile": "true", |
|
"x": 1539.9998168945312, |
|
"y": 845.8333740234375, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "ded265c5.515f68", |
|
"type": "file in", |
|
"z": "c8dc8a91.74103", |
|
"name": "Read firmware", |
|
"filename": "", |
|
"format": "", |
|
"x": 842.0833740234375, |
|
"y": 846.6666870117188, |
|
"wires": [ |
|
[ |
|
"b95b8c19.19c4e8" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "8cd5701d.92156", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Extract filename", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "filename", |
|
"pt": "msg", |
|
"to": "firmware.directory", |
|
"tot": "flow" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": "req.files.firmware[0].originalname", |
|
"tot": "msg" |
|
}, |
|
{ |
|
"t": "delete", |
|
"p": "req", |
|
"pt": "msg" |
|
}, |
|
{ |
|
"t": "delete", |
|
"p": "res", |
|
"pt": "msg" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 619.375, |
|
"y": 847.9166870117188, |
|
"wires": [ |
|
[ |
|
"ded265c5.515f68" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "b3a0c31.a959d4", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "", |
|
"rules": [ |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "bin$", |
|
"fromt": "re", |
|
"to": "md5", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 1225.625, |
|
"y": 846.25, |
|
"wires": [ |
|
[ |
|
"a4a110d9.d17838" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "bf8f43a5.95f42", |
|
"type": "file in", |
|
"z": "c8dc8a91.74103", |
|
"name": "Load Hash", |
|
"filename": "", |
|
"format": "utf8", |
|
"sendError": false, |
|
"x": 1743.910629272461, |
|
"y": 321.82147216796875, |
|
"wires": [ |
|
[ |
|
"ee5832d4.7db41" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "ee5832d4.7db41", |
|
"type": "switch", |
|
"z": "c8dc8a91.74103", |
|
"name": "Compare MD5 hash", |
|
"property": "payload", |
|
"propertyType": "msg", |
|
"rules": [ |
|
{ |
|
"t": "eq", |
|
"v": "req.headers.x-esp8266-sketch-md5", |
|
"vt": "msg" |
|
}, |
|
{ |
|
"t": "else" |
|
} |
|
], |
|
"checkall": "false", |
|
"outputs": 2, |
|
"x": 1954.91064453125, |
|
"y": 322.1786193847656, |
|
"wires": [ |
|
[ |
|
"83413646.c2dd4" |
|
], |
|
[ |
|
"c19457f8.014dc8" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "c19457f8.014dc8", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Save MD5 Hash", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "headers.x-MD5", |
|
"pt": "msg", |
|
"to": "payload", |
|
"tot": "msg" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "md5", |
|
"fromt": "str", |
|
"to": "bin", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 2279.2857360839844, |
|
"y": 377.0714416503906, |
|
"wires": [ |
|
[ |
|
"34f9b5d5.3b5d2a" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "70f9cdfb.519584", |
|
"type": "fs-ops-access", |
|
"z": "c8dc8a91.74103", |
|
"name": "Check for MD5 file exists", |
|
"path": "", |
|
"pathType": "str", |
|
"filename": "filename", |
|
"filenameType": "msg", |
|
"read": true, |
|
"write": false, |
|
"throwerror": false, |
|
"x": 1028.857177734375, |
|
"y": 329.1428527832031, |
|
"wires": [ |
|
[ |
|
"bf8f43a5.95f42" |
|
], |
|
[ |
|
"196e6dc4.7e4242" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "5a91d95d.b3f47", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Get MAC hash filename", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "filename", |
|
"pt": "msg", |
|
"to": "firmware.directory", |
|
"tot": "flow" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": "req.headers.x-esp8266-sta-mac", |
|
"tot": "msg" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": ".md5", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 723.1428451538086, |
|
"y": 334.99999809265137, |
|
"wires": [ |
|
[ |
|
"70f9cdfb.519584" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "4f93ee35.d787f", |
|
"type": "comment", |
|
"z": "c8dc8a91.74103", |
|
"name": "Firmware Upgrade", |
|
"info": "The system determines which firmware to send based\non the MAC address, version, and MD5 headers in the\nrequest from the ESP8266.\n\nFirstly, it checks if a firmware hash file with \nthe MAC address as the name exists, or else if a \nfirmware file with the version as the name exists.\nIf neither exist then no update is available.\n\nIt then reads the corresponding MD5 hash from the\nhash file and compares to the MD5 hash in the\nrequest. If they match then the firmware is up\nto date and no update is required.\n\nOtherwise, it sends the contents of the firmware\nbin file and the MD5 hash value.", |
|
"x": 103.5, |
|
"y": 46, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "77e3a5f0.24ed14", |
|
"type": "fs-ops-access", |
|
"z": "c8dc8a91.74103", |
|
"name": "Check for MD5 file exists", |
|
"path": "", |
|
"pathType": "str", |
|
"filename": "filename", |
|
"filenameType": "msg", |
|
"read": true, |
|
"write": false, |
|
"throwerror": false, |
|
"x": 1496.7857055664062, |
|
"y": 439.7142028808594, |
|
"wires": [ |
|
[ |
|
"bf8f43a5.95f42" |
|
], |
|
[ |
|
"83413646.c2dd4" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "1f741000.bf355", |
|
"type": "comment", |
|
"z": "c8dc8a91.74103", |
|
"name": "Firmware Management", |
|
"info": "", |
|
"x": 110.5, |
|
"y": 542, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "9a3fb2c8.fdeae", |
|
"type": "config", |
|
"z": "c8dc8a91.74103", |
|
"name": "Firmware Config", |
|
"properties": [ |
|
{ |
|
"p": "firmware.directory", |
|
"pt": "flow", |
|
"to": "/home/sysadmin/firmware/", |
|
"tot": "str" |
|
} |
|
], |
|
"active": true, |
|
"x": 123.0714111328125, |
|
"y": 360.1428527832031, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "67a99e0a.a70ae8", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Get Version hash filename", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "filename", |
|
"pt": "msg", |
|
"to": "firmware.directory", |
|
"tot": "flow" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": "req.headers.x-esp8266-version", |
|
"tot": "msg" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "filename", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": ".md5", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 1203.2857666015625, |
|
"y": 439.6427917480469, |
|
"wires": [ |
|
[ |
|
"77e3a5f0.24ed14" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "5ae37750.4cb7a", |
|
"type": "fs-ops-dir", |
|
"z": "c8dc8a91.74103", |
|
"name": "Firmware listing", |
|
"path": "firmware.directory", |
|
"pathType": "flow", |
|
"filter": "*.bin", |
|
"filterType": "str", |
|
"dir": "payload.files", |
|
"dirType": "msg", |
|
"x": 493.0355987548828, |
|
"y": 647.8015928268433, |
|
"wires": [ |
|
[ |
|
"f6002008.43daa8" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "dd6fee12.904a58", |
|
"type": "template", |
|
"z": "c8dc8a91.74103", |
|
"name": "Firmware Manager", |
|
"field": "payload", |
|
"fieldType": "msg", |
|
"format": "html", |
|
"syntax": "mustache", |
|
"template": "<html>\n <head>\n <title>ESP8266 OTA Firmware Manager</title>\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <link rel=\"stylesheet\" href=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css\">\n <script src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js\"></script>\n <script src=\"http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script>\n <style>\n .file-btn-grp {\n display: none;\n }\n body {\n background-color: #f6f6f6;\n }\n .text_holder {\n display: block;\n max-width: 100%;\n word-wrap: break-word;\n line-height: 30px;\n }\n #main {\n margin-top: 50px;\n background-color: #ffffff;\n border-radius: 5px;\n width: 70%;\n min-width: 500px;\n border: 1px solid #545454;\n }\n .alert {\n margin-top: 10px;\n margin-bottom: 5px;\n }\n .link {\n font-style: italic;\n }\n .listentry {\n display: none;\n list-style-type: none;\n }\n </style>\n\n </head>\n <body>\n <div class=\"container\" id=\"main\">\n <h1><small>ESP8266 OTA Firmware Manager</small></h1>\n <h2><small>Upload New Firmware</small></h2>\n\n <form role =\"form\" id=\"main_input_box\" action=\"esp8266-ota\" method=\"POST\" enctype=\"multipart/form-data\" class=\"form-inline\">\n <input type=\"file\" accept=\".bin\" class=\"hidden\" id=\"fileUpload\" name=\"firmware\" placeholder=\"firmware.bin\">\n <div class=\"form-group\">\n <div class=\"input-group\">\n <span class=\"input-group-btn\">\n <button id=\"browse\" type=\"button\" class=\"btn btn-primary\">Browse...</button>\n </span>\n <input id=\"filename\" size=100 readonly=\"\" class=\"form-control\" placeholder=\"Firmware.bin\">\n <span class=\"input-group-btn\">\n <input type=\"submit\" value=\"Upload\" class=\"btn btn-primary add_button\">\n </span>\n </div>\n </div>\n </form>\n\n <h2><small>Current Firmware</small></h2>\n <ul class=\"list-group\" id=\"list_of_items\">\n </ul>\n </div>\n\n <div id=\"linkModal\" class=\"modal fade\" role=\"dialog\">\n <div class=\"modal-dialog\">\n \n <!-- Modal content-->\n <div class=\"modal-content\">\n <div class=\"modal-header\">\n <button type=\"button\" class=\"close\" data-dismiss=\"modal\">×</button>\n <h4 class=\"modal-title\">Create Symbolic Link</h4>\n </div>\n <div class=\"modal-body\">\n <form class=\"form-horizontal\" id=\"linkForm\" role=\"form\" action=\"#\" method=\"POST\">\n <div class=\"form-group\">\n <label class=\"control-label col-sm-2\" for=\"linkName\">Link:</label> \n <div class=\"col-sm-10\">\n <input id=\"linkName\" name=\"linkName\" class=\"form-control\"/>\n </div>\n </div>\n <div class=\"form-group\">\n <label class=\"control-label col-sm-2\" for=\"linkFile\">To:</label> \n <div class=\"col-sm-10\">\n <input class=\"form-control\" id=\"linkFile\" name=\"linkFile\"/>\n </div>\n </div>\n </form>\n </div>\n <div class=\"modal-footer\">\n <button type=\"submit\" class=\"btn btn-success link-create\">Create</button>\n <button type=\"button\" class=\"btn btn-warning\" data-dismiss=\"modal\">Cancel</button>\n </div>\n </div>\n </div>\n </div>\n \n <script>\n\n var deleteButton = \"<button id='delete' class='btn btn-warning'>Delete</button>\";\n var linkButton = \"<button id='link' class='btn btn-success'>Link</button>\";\n var oneButton = \"<div class='file-btn-grp btn-group pull-right'>\" + deleteButton + \"</div>\";\n var twoButtons = \"<div class='file-btn-grp btn-group pull-right'>\" + deleteButton + linkButton + \"</div>\";\n \n function addListEntry(list, filename, linkname) {\n \n var entry;\n \n if (linkname === undefined) {\n entry = $(\"<li class='listentry list-group-item'><div class='text_holder'><span>\" \n + filename + \"</span>\" + twoButtons + \"</div></li>\");\n } else {\n entry = $(\"<li class='listentry list-group-item'><div class='text_holder'><span class='link'>\" \n + filename + \"</span> <span class='glyphicon glyphicon-arrow-right'></span> \" \n + linkname + oneButton + \"</div></li>\");\n }\n \n entry.mouseover(function(){\n $(this).find(\".btn-group\").fadeIn(\"fast\");\n });\n entry.mouseleave(function(){\n $(this).find(\".btn-group\").fadeOut(\"slow\");\n });\n \n entry.on(\"click\", \"button#delete\", function(){\n var listItem = this.parentElement.parentElement.parentElement;\n var file = this.parentElement.parentElement.childNodes[0].childNodes[0].data;\n $.ajax({\n type: 'DELETE',\n data: {\"filename\": file},\n success: function(result) {\n $(listItem).fadeOut(\"slow\", function(){\n listItem.remove();\n });\n },\n error: function(result) {\n $(listItem).append(\"<div class='alert alert-danger'>\"\n + \"<a href='#' class='close' data-dismiss='alert'\"\n + \"aria-label='close'>×</a>\"\n + result.responseText + \"</div>\");\n }\n });\n });\n \n entry.on(\"click\", \"button#link\", function(){\n var file = this.parentElement.parentElement.childNodes[0].childNodes[0].data;\n $(\"#linkName\").val(\"\");\n $(\"#linkFile\").prop(\"disabled\", true).val(file);\n $(\"#linkName\").parent().removeClass(\"has-error\");\n $(\"#linkModal\").modal();\n $('#linkModal').on('shown.bs.modal', function () {\n $('#linkName').focus();\n });\n });\n \n if (list.children().length == 0) {\n list.append(entry);\n entry.fadeIn(\"slow\");\n return;\n }\n\n if (filename < $(\"li:first span:first\", list).text()) {\n $(\"li:first\", list).before(entry);\n entry.fadeIn(\"slow\");\n return;\n }\n if (filename > $(\"li:last span:first\", list).text()) {\n $(\"li:last\", list).after(entry);\n entry.fadeIn(\"slow\");\n return;\n }\n \n var count = 0;\n var $li = $(\"li\", list);\n do {\n var index = parseInt($li.length / 2);\n var $compare = $li.eq(index);\n var compare = $(\"span:first\",$compare).text();\n if (filename === compare) {\n break;\n }\n else if (filename > compare) {\n $li = $li.slice(index, $li.length);\n } else {\n $li = $li.slice(0, index);\n }\n } while ($li.length > 1);\n\n if (filename === compare) {\n $compare.slideUp(\"fast\").slideDown(\"slow\");\n return;\n } else if (filename < compare) { \n entry.insertBefore($compare); \n } else { \n entry.insertAfter($compare); \n }\n entry.slideDown(\"slow\");\n }\n \n \n var files = String(\"{{payload.files}}\").split(',');\n var links = String(\"{{payload.links}}\").split(',');\n \n var list_of_items = $(\"#list_of_items\");\n \n files.forEach(function(file,index) {\n if (links[index] == \"\") {\n addListEntry(this, file.slice(0,-4));\n } else {\n addListEntry(this, file.slice(0,-4), links[index].slice(0,-4));\n }\n },list_of_items);\n \n \n $(\"#linkModal\").on(\"click\", \"button.link-create\", function(event){\n event.preventDefault();\n if ($(\"#linkName\").val() == \"\") {\n $('#linkName').focus();\n $('#linkName').parent().addClass(\"has-error\");\n return false;\n }\n $(\"#linkFile\").prop(\"disabled\",false); \n $.ajax({\n type: 'PUT',\n data: $(\"#linkForm\").serialize(),\n success: function(result) {\n $(\"#linkModal\").modal('hide');\n addListEntry(list_of_items, $('#linkName').val(), $('#linkFile').val());\n },\n error: function(result) {\n $(\"#linkFile\").prop(\"disabled\", true);\n $('#linkName').focus();\n $('#linkName').parent().addClass(\"has-error\");\n $(linkForm).append(\"<div id='linkError' class='alert alert-danger'>\"\n + \"<a href='#' class='close' data-dismiss='alert'\"\n + \"aria-label='close'>×</a>\"\n + result.responseText + \"</div>\");\n }\n });\n });\n \n $(\"#browse\").on('click', function () {\n fileUpload.click();\n });\n \n $(\"#fileUpload\").on('change', function () {\n $(\"#filename\").val($(\"#fileUpload\").val().split('/').pop().split('\\\\').pop());\n });\n \n var frm = $(\"#main_input_box\");\n \n frm.submit( function( e ) {\n e.preventDefault();\n if ($('#fileUpload').val() == \"\") return null;\n $.ajax( {\n url: frm.attr('action'),\n type: frm.attr('method'),\n data: new FormData( this ),\n processData: false,\n contentType: false,\n success: function(result) {\n addListEntry(list_of_items, $('#fileUpload').val().slice(0,-4).split('\\\\').pop());\n $('#fileUpload').val('');\n $(':text').val('');\n },\n error: function(result) {\n $(\"#main_input_box\").append(\"<div class='alert alert-danger'>\"\n + \"<a href='#' class='close' data-dismiss='alert'\"\n + \"aria-label='close'>×</a>\"\n + result.responseText + \"</div>\");\n }\n\n });\n });\n </script>\n </body>\n</html>", |
|
"output": "str", |
|
"x": 1381.3333740234375, |
|
"y": 645.8135375976562, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "daac23b5.56202", |
|
"type": "http in", |
|
"z": "c8dc8a91.74103", |
|
"name": "OTA Delete", |
|
"url": "/esp8266-ota", |
|
"method": "delete", |
|
"swaggerDoc": "", |
|
"x": 83.125, |
|
"y": 933.75, |
|
"wires": [ |
|
[ |
|
"b598cd93.0da24" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "eea8a4b7.82d8e", |
|
"type": "fs-ops-delete", |
|
"z": "c8dc8a91.74103", |
|
"name": "Delete firmware", |
|
"path": "firmware.directory", |
|
"pathType": "flow", |
|
"filename": "payload.filename", |
|
"filenameType": "msg", |
|
"x": 1628.6250457763672, |
|
"y": 936.5832777023315, |
|
"wires": [ |
|
[ |
|
"e7711371.64d218" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "ecef5877.cde138", |
|
"type": "catch", |
|
"z": "c8dc8a91.74103", |
|
"name": "File Error", |
|
"scope": [ |
|
"eea8a4b7.82d8e", |
|
"2c0afcd2.18843c", |
|
"b6713897.2c6f58", |
|
"95667d64.83a058", |
|
"8951ec5b.14d068" |
|
], |
|
"x": 1870.6665573120117, |
|
"y": 805.3333158493042, |
|
"wires": [ |
|
[ |
|
"b0e409f8.1fb4e8" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "b0e409f8.1fb4e8", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Error", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "statusCode", |
|
"pt": "msg", |
|
"to": "500", |
|
"tot": "str" |
|
}, |
|
{ |
|
"t": "set", |
|
"p": "payload", |
|
"pt": "msg", |
|
"to": "error.message", |
|
"tot": "msg" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 2159, |
|
"y": 791, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "e7711371.64d218", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Change to MD5 filename", |
|
"rules": [ |
|
{ |
|
"t": "change", |
|
"p": "payload.filename", |
|
"pt": "msg", |
|
"from": "bin", |
|
"fromt": "str", |
|
"to": "md5", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 1879.1666564941406, |
|
"y": 936.6666269302368, |
|
"wires": [ |
|
[ |
|
"2c0afcd2.18843c" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "2c0afcd2.18843c", |
|
"type": "fs-ops-delete", |
|
"z": "c8dc8a91.74103", |
|
"name": "Delete MD5 Hash", |
|
"path": "firmware.directory", |
|
"pathType": "flow", |
|
"filename": "payload.filename", |
|
"filenameType": "msg", |
|
"x": 2170.833206176758, |
|
"y": 936.6665878295898, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "b6713897.2c6f58", |
|
"type": "fs-ops-move", |
|
"z": "c8dc8a91.74103", |
|
"name": "Link firmware", |
|
"sourcePath": "", |
|
"sourcePathType": "str", |
|
"sourceFilename": "payload.linkFile", |
|
"sourceFilenameType": "msg", |
|
"destPath": "firmware.directory", |
|
"destPathType": "flow", |
|
"destFilename": "payload.linkName", |
|
"destFilenameType": "msg", |
|
"link": true, |
|
"x": 1644.5, |
|
"y": 1044, |
|
"wires": [ |
|
[ |
|
"f075e122.d9acf" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "f80cd2dd.cf0098", |
|
"type": "http in", |
|
"z": "c8dc8a91.74103", |
|
"name": "OTA Link", |
|
"url": "/esp8266-ota", |
|
"method": "put", |
|
"swaggerDoc": "", |
|
"x": 84, |
|
"y": 1041.5, |
|
"wires": [ |
|
[ |
|
"119e425c.4ead7e" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "119e425c.4ead7e", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Extract filename", |
|
"rules": [ |
|
{ |
|
"t": "change", |
|
"p": "payload.linkName", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": ".bin", |
|
"tot": "str" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "payload.linkFile", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": ".bin", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 1385, |
|
"y": 1044, |
|
"wires": [ |
|
[ |
|
"b6713897.2c6f58" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "f075e122.d9acf", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Change to MD5 Filename", |
|
"rules": [ |
|
{ |
|
"t": "change", |
|
"p": "payload.linkName", |
|
"pt": "msg", |
|
"from": "bin$", |
|
"fromt": "re", |
|
"to": "md5", |
|
"tot": "str" |
|
}, |
|
{ |
|
"t": "change", |
|
"p": "payload.linkFile", |
|
"pt": "msg", |
|
"from": "bin$", |
|
"fromt": "re", |
|
"to": "md5", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 1908, |
|
"y": 1045, |
|
"wires": [ |
|
[ |
|
"95667d64.83a058" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "95667d64.83a058", |
|
"type": "fs-ops-move", |
|
"z": "c8dc8a91.74103", |
|
"name": "Link MD5", |
|
"sourcePath": "", |
|
"sourcePathType": "str", |
|
"sourceFilename": "payload.linkFile", |
|
"sourceFilenameType": "msg", |
|
"destPath": "firmware.directory", |
|
"destPathType": "flow", |
|
"destFilename": "payload.linkName", |
|
"destFilenameType": "msg", |
|
"link": true, |
|
"x": 2152.5, |
|
"y": 1044, |
|
"wires": [ |
|
[ |
|
"eeb8fd90.56a408" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "b598cd93.0da24", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Extract filename", |
|
"rules": [ |
|
{ |
|
"t": "change", |
|
"p": "payload.filename", |
|
"pt": "msg", |
|
"from": "$", |
|
"fromt": "re", |
|
"to": ".bin", |
|
"tot": "str" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 1382.5, |
|
"y": 937.5, |
|
"wires": [ |
|
[ |
|
"eea8a4b7.82d8e" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "f6002008.43daa8", |
|
"type": "fs-ops-link", |
|
"z": "c8dc8a91.74103", |
|
"name": "Get Links", |
|
"path": "firmware.directory", |
|
"pathType": "flow", |
|
"filename": "payload.files", |
|
"filenameType": "msg", |
|
"link": "payload.links", |
|
"linkType": "msg", |
|
"x": 776.4999923706055, |
|
"y": 648.3333110809326, |
|
"wires": [ |
|
[ |
|
"dd6fee12.904a58" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "84851e19.4a5868", |
|
"type": "debug", |
|
"z": "c8dc8a91.74103", |
|
"name": "Update sent", |
|
"active": true, |
|
"console": "false", |
|
"complete": "req.headers.x-esp8266-sta-mac", |
|
"x": 2931.5000610351562, |
|
"y": 386.00006103515625, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "eaeeef87.2b0bf", |
|
"type": "debug", |
|
"z": "c8dc8a91.74103", |
|
"name": "Update req", |
|
"active": false, |
|
"console": "false", |
|
"complete": "req.headers", |
|
"x": 255.7144012451172, |
|
"y": 215.71426391601562, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "196e6dc4.7e4242", |
|
"type": "switch", |
|
"z": "c8dc8a91.74103", |
|
"name": "", |
|
"property": "req.headers.x-esp8266-version", |
|
"propertyType": "msg", |
|
"rules": [ |
|
{ |
|
"t": "nnull" |
|
}, |
|
{ |
|
"t": "else" |
|
} |
|
], |
|
"checkall": "true", |
|
"outputs": 2, |
|
"x": 696.9642333984375, |
|
"y": 446.7856750488281, |
|
"wires": [ |
|
[ |
|
"67a99e0a.a70ae8" |
|
], |
|
[ |
|
"79c3bba9.58bbbc" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "79c3bba9.58bbbc", |
|
"type": "change", |
|
"z": "c8dc8a91.74103", |
|
"name": "Version in Request", |
|
"rules": [ |
|
{ |
|
"t": "set", |
|
"p": "req.headers.x-esp8266-version", |
|
"pt": "msg", |
|
"to": "req.params.version", |
|
"tot": "msg" |
|
} |
|
], |
|
"action": "", |
|
"property": "", |
|
"from": "", |
|
"to": "", |
|
"reg": false, |
|
"x": 916.4285278320312, |
|
"y": 512.8571166992188, |
|
"wires": [ |
|
[ |
|
"67a99e0a.a70ae8" |
|
] |
|
] |
|
}, |
|
{ |
|
"id": "e718a78e.b5e", |
|
"type": "debug", |
|
"z": "c8dc8a91.74103", |
|
"name": "", |
|
"active": true, |
|
"console": "false", |
|
"complete": "req.params", |
|
"x": 2126.428741455078, |
|
"y": 574.2858276367188, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "7af52504.46f59c", |
|
"type": "debug", |
|
"z": "c8dc8a91.74103", |
|
"name": "Firmware file error", |
|
"active": true, |
|
"console": "false", |
|
"complete": "error", |
|
"x": 2890.7142944335938, |
|
"y": 327.1428527832031, |
|
"wires": [] |
|
}, |
|
{ |
|
"id": "56274a30.925974", |
|
"type": "catch", |
|
"z": "c8dc8a91.74103", |
|
"name": "File error", |
|
"scope": [ |
|
"34f9b5d5.3b5d2a", |
|
"bf8f43a5.95f42" |
|
], |
|
"x": 2627.8572387695312, |
|
"y": 328.5714111328125, |
|
"wires": [ |
|
[ |
|
"83413646.c2dd4", |
|
"7af52504.46f59c" |
|
] |
|
] |
|
} |
|
] |
This is amazing work. Thanks so much for sharing this! Just had a quick question I hope you can help with. I've got it all up and running, but when I upload a new firmware .bin file to the web server, my esp reports through the serial monitor that the update fails.
Checking for firmware updates from server http://---.---.-.---:1880/esp8266-ota/update
HTTP update failed: Error (-102): File Not Found (404)
Am I correct to compile the binary out of the arduino ide and upload that file? Or should I be doing something else? I see reference to SPIFFS in the update type node on your node-red flow so was just curious.
Thanks!