如何解决如何在 ESP32 中为 OTA 发布 bin 文件,而无需在 Web 服务器中托管的浏览器中手动打开页面
我试图在外部托管在 ESP32 上的网络服务器上触发 OTA 更新,并且无需打开网络服务器的浏览器地址。
我已经看到一些示例,如果 ESP 作为客户端连接,则可以实现 OTA 更新操作,但我正在寻找可以将 ESP 仅作为网络服务器保留的解决方案。 由于,假设此操作是通过网络触发的,因此,如果有任何方法 curl、python/JavaScript http 方法、节点红色等,我将很乐意接受。
这是在 ESP32 中运行的代码的服务器部分:
YYYY
- 现在,如果我打开,这将允许我选择并选择一个 bin 文件 如果单击“更新”按钮,则本地IP并处理OTA。
- 但是在使用任一 python 时,相同的“行为”将无法触发它 curl 命令的脚本。从 chrome 开发者工具的网络部分复制 curl 命令。
Python 脚本在这里。
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
#include <WiFiManager.h>
WebServer server(80);
const char* serverIndex =
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"
"<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>"
"<input type='file' name='update'>"
"<input type='submit' value='Update'>"
"</form>"
"<div id='prg'>progress: 0%</div>"
"<script>"
"$('form').submit(function(e){"
"e.preventDefault();"
"var form = $('#upload_form')[0];"
"var data = new FormData(form);"
" $.ajax({"
"url: '/update',"
"type: 'POST',"
"data: data,"
"contentType: false,"
"processData:false,"
"xhr: function() {"
"var xhr = new window.XMLHttpRequest();"
"xhr.upload.addEventListener('progress',function(evt) {"
"if (evt.lengthComputable) {"
"var per = evt.loaded / evt.total;"
"$('#prg').html('progress: ' + Math.round(per*100) + '%');"
"}"
"},false);"
"window.location.href ='/login';"
"return xhr;"
"},"
"success:function(d,s) {"
"console.log('successok !')"
"},"
"error: function (a,b,c) {"
"}"
"});"
"});"
"</script>";
void setup()
{
//redundant parts have been removed intentionally
WiFi.begin(ssid,pass);
int ct =0;
while (!MDNS.begin(host)) { //http://esp32.local //http://shariq-room.local
Serial.println("Error setting up MDNS responder!");
delay(1000);
ct= ct+1000;
if (ct>5000) {
Serial.println("MDNS cannot be set");
break;
}
}
MDNS.addService("http","tcp",80);
server.on("/serverIndex",HTTP_GET,[]() {
server.sendHeader("Connection","close");
server.send(200,"text/html",serverIndex);
});
server.on("/update",HTTP_POST,[]() {
server.sendHeader("Connection","close");
server.send(200,"text/plain",(Update.hasError()) ? "FAIL" : "OK");
ESP.restart();
},[]() {
Serial.println("OTA started ");
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
Serial.printf("Update: %s\n",upload.filename.c_str());
if (!Update.begin(UPDATE_SIZE_UNKNowN)) { //start with max available size
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_WRITE) {
/* flashing firmware to ESP*/
if (Update.write(upload.buf,upload.currentSize) != upload.currentSize) {
Update.printError(Serial);
}
} else if (upload.status == UPLOAD_FILE_END) {
if (Update.end(true)) { //true to set the size to the current progress
Serial.printf("Update Success: %u\nRebooting...\n",upload.totalSize);
} else {
Update.printError(Serial);
}
}
});
server.begin();
}
void loop()
{
server.handleClient();
delay(400);
}
但是我会在任何一个 post 方法上出错,比如 引发连接错误(错误,请求=请求) requests.exceptions.ConnectionError: ('Connection aborted.',Remotedisconnected('Remote end closed connection without response'))
在 curl
中尝试时相同##python
import requests
data = open("home_automate_inc_ota_v.0.2a.ino.esp32.bin",'rb').read()
files = {'file': open("home_automate_inc_ota_v.0.2a.ino.esp32.bin",'rb')}
#headers = { "Content-Type":"application/binary",}
headers= { 'Accept': 'text/plain'}
print("started")
upload = requests.post("http://192.168.0.7/update",data=data,headers=headers)
#tried below method too
# final_resp = requests.post("http://192.168.0.7/update",files=files,headers=headers)
print("done");
希望我已经很好地解释了这个问题。如果您需要更多说明,请告诉我。
问候, 沙里克
解决方法
正如 Romkey 建议的那样,我所要做的就是从我的请求中删除标头。 我发现我的 python 代码成功了,但是 curl 命令失败了。 这是脚本。
#!Python
import requests
files = {'file': open(r"<full path of the bin file including dir>home_automate_inc_ota_v.0.2a.ino.esp32.bin",'rb')}
final_resp = requests.post("http://192.168.0.50/update",files=files)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。