继上篇介绍利用巴法云来实现ota,有朋友表示服务器不稳,故搜索本地实现过程,在网上找到这篇介绍,原本是esp32,现修改为esp8266.
1、本地电脑执行py,将bin放到同级目录
from http.server import BaseHTTPRequestHandler, HTTPServer
import os
class MyHttpRequestHandler(BaseHTTPRequestHandler):
def __init__(self, request, client_address, server, folderPath):
self.folderPath = folderPath
self.UpDateFileName = self.getFileExtensionPath(
self.folderPath, '.bin')
self.UpDateFilePath = self.folderPath + "\\" + \
self.getFileExtensionPath(self.folderPath, '.bin')
super().__init__(request, client_address, server)
@classmethod
def Creator(cls, *args, **kwargs):
def _HandlerCreator(request, client_address, server):
cls(request, client_address, server, *args, **kwargs)
return _HandlerCreator
def do_GET(self):
# 处理逻辑
path = str(self.path)
if path == "/getFile":
self.send_response(200)
self.send_header(
"Content-type", "text/plain")
self.end_headers()
self.wfile.write(bytes(self.UpDateFileName, "utf-8"))
elif path == "/update":
with open(self.UpDateFilePath, 'rb') as resultf:
buf = resultf.read()
length = resultf.tell()
self.send_response(200) # 文件存在返回状态码
# 返回请求格式为"application/octet-stream"
self.send_header("Content-type", "application/octet-stream")
self.send_header("Content-Length", str(length))
self.send_header("Content-Disposition",
"attachment; filename=\"%s\"" % self.UpDateFileName)
self.end_headers()
# 读取文件发送给客户端
self.wfile.write(buf)
def do_POST(self):
pass
def getFileExtensionPath(self, path, name):
for root, dirs, files in os.walk(path): # 遍历该文件夹
for file in files: # 遍历刚获得的文件名files
(filename, extension) = os.path.splitext(file) # 将文件名拆分为文件名与后缀
if (extension == name):
return file
if __name__ == '__main__':
ts = HTTPServer(('0.0.0.0', 8989),
MyHttpRequestHandler.Creator(os.getcwd()))
ts.serve_forever()
2、arduino加入如下代码
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266httpUpdate.h>
#include <Preferences.h>
// #include <HTTPUpdate.h>
#include "ESPAsyncWebServer.h"
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
String getUpDateName; // 获取的升级包名
String upDateName; // 上次的升级包名
bool UpdateVersionIsOk; // 包名判断可以升级的标志位
String getUpdateUrl = "http://192.168.31.69:8989/getFile"; // 获取升级包名的URL
String downLoadUpdateUrl = "http://192.168.31.69:8989/update"; // 下载升级包的URL
// OTA升级开始回调函数
void update_started()
{
Serial.println("CALLBACK: HTTP update process started");
}
// OTA升级完成回调函数
void update_finished()
{
Serial.println("CALLBACK: HTTP update process finished");
Preferences prefs; // NVS读写实例化
prefs.begin("WiFiConfig");
prefs.putString("Version", getUpDateName);
prefs.end();
upDateName = getUpDateName;
UpdateVersionIsOk = false;
Serial.println("升级记录已保存");
}
// 当升级开始时,打印日志
void update_started()
{
Serial.println("CALLBACK: HTTP update process started");
}
// 当升级结束时,打印日志
void update_finished()
{
Serial.println("CALLBACK: HTTP update process finished");
// u8g2.clearBuffer();
// u8g2.drawStr(u8g2.getWidth() / 2, u8g2.getHeight() / 2, "Restart");
// u8g2.sendBuffer();
}
// 当升级中,打印日志
void update_progress(int cur, int total)
{
Serial.printf("CALLBACK: HTTP update process at %d of %d bytes...%d%% \n", cur, total, cur / (total / 100));
//ota_OLED_onProgress(4, 32, 120, 8, cur / (total / 100));
}
// 当升级失败时,打印日志
void update_error(int err)
{
Serial.printf("CALLBACK: HTTP update fatal error code %d\n", err);
}
// OTA升级检查线程
void seachUpdate()
{
while (true)
{
if (WiFi.status() == WL_CONNECTED)
{
WiFiClient client;
HTTPClient http;
http.begin(client, getUpdateUrl);
int httpCode = http.GET();
delay(500);
if (httpCode > 0)
{
if (httpCode == HTTP_CODE_OK)
{
getUpDateName = http.getString();
Serial.println(getUpDateName);
// 判断get的字符串和nvs存储的升级包名不一致
if (getUpDateName != "" && getUpDateName != upDateName)
{
UpdateVersionIsOk = true;
}
else
{
UpdateVersionIsOk = false;
}
}
}
else
{
Serial.println("HTTP GET... failed, error: " + http.errorToString(httpCode));
}
http.end();
WiFiClient UpdateClient;
ESPhttpUpdate.onStart(update_started); // 当升级开始时
ESPhttpUpdate.onEnd(update_finished); // 当升级结束时
ESPhttpUpdate.onProgress(update_progress); // 当升级中
ESPhttpUpdate.onError(update_error); // 当升级失败时
if (UpdateVersionIsOk)
{
ESPhttpUpdate.update(UpDateClient, downLoadUpdateUrl);
}
}
delay(5000);
}
}
void setup()
{
Preferences prefs; // NVS读写实例化
prefs.begin("WiFiConfig");
if (prefs.isKey("Version"))
{
upDateName = prefs.getString("Version");
}
// xTaskCreatePinnedToCore(seachUpdate, "seachUpdate", 10000, NULL, 1, NULL, 0);
}
void loop()
{
delay(10);
}
以上作为记录