Merge pull request #6 from technyon/ota

Ota
This commit is contained in:
Jan-Ole Schümann
2022-06-15 20:45:44 +02:00
committed by GitHub
10 changed files with 130 additions and 9 deletions

View File

@@ -38,10 +38,11 @@ jobs:
cmake -D CMAKE_TOOLCHAIN_FILE=../arduino-toolchain/Arduino-toolchain.cmake ..
echo "# Espressif ESP32 Partition Table" > partitions.csv
echo "# Name, Type, SubType, Offset, Size, Flags" >> partitions.csv
echo "nvs,data,nvs,0x9000,20K," >> partitions.csv
echo "otadata,data,ota,0xe000,8K," >> partitions.csv
echo "app0,app,ota_0,0x10000,3M," >> partitions.csv
echo "spiffs,data,spiffs,0x310000,960K," >> partitions.csv
echo "nvs, data, nvs, 0x9000, 0x5000," >> partitions.csv
echo "otadata, data, ota, 0xe000, 0x2000," >> partitions.csv
echo "app0, app, ota_0, 0x10000, 0x1E0000," >> partitions.csv
echo "app1, app, ota_1, 0x1F0000,0x1E0000," >> partitions.csv
echo "spiffs, data, spiffs, 0x3D0000,0x30000," >> partitions.csv
make
- name: Upload artifacts
run: |

View File

@@ -37,6 +37,7 @@ file(GLOB SRCFILES
NukiWrapper.cpp
NukiOpenerWrapper.cpp
MqttTopics.h
Ota.cpp
WebCfgServer.cpp
PresenceDetection.cpp
PreferencesKeys.h

29
Ota.cpp Normal file
View File

@@ -0,0 +1,29 @@
#include <Arduino.h>
#include "Ota.h"
#define FULL_PACKET 1436 // HTTP_UPLOAD_BUFLEN in WebServer,h
void Ota::updateFirmware(uint8_t* buf, size_t size)
{
if (!_updateFlag)
{ //If it's the first packet of OTA since bootup, begin OTA
Serial.println("BeginOTA");
esp_ota_begin(esp_ota_get_next_update_partition(NULL), OTA_SIZE_UNKNOWN, &otaHandler);
_updateFlag = true;
}
esp_ota_write(otaHandler, buf, size);
if (size != FULL_PACKET)
{
esp_ota_end(otaHandler);
Serial.println("EndOTA");
if (ESP_OK == esp_ota_set_boot_partition(esp_ota_get_next_update_partition(NULL)))
{
delay(2000);
esp_restart();
}
else
{
Serial.println("Upload Error");
}
}
}

15
Ota.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
#include <stdint.h>
#include <cstddef>
#include "esp_ota_ops.h"
class Ota
{
public:
void updateFirmware(uint8_t* buf, size_t size);
private:
bool _updateFlag = false;
esp_ota_handle_t otaHandler = 0;
};

View File

@@ -1,3 +1,3 @@
#pragma once
#define nuki_hub_version "3.1"
#define nuki_hub_version "4.0"

View File

@@ -112,6 +112,27 @@ void WebCfgServer::initialize()
waitAndProcess(false, 1000);
}
});
_server.on("/ota", [&]() {
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
return _server.requestAuthentication();
}
String response = "";
buildOtaHtml(response);
_server.send(200, "text/html", response);
});
_server.on("/uploadota", HTTP_POST, [&]() {
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
return _server.requestAuthentication();
}
_server.send(200, "text/html", "");
}, [&]() {
if (_hasCredentials && !_server.authenticate(_credUser, _credPassword)) {
return _server.requestAuthentication();
}
handleOtaUpload();
});
_server.begin();
}
@@ -366,6 +387,11 @@ void WebCfgServer::buildHtml(String& response)
response.concat("<button type=\"submit\">Edit</button>");
response.concat("</form>");
response.concat("<BR><BR><h3>Firmware update</h3>");
response.concat("<form method=\"get\" action=\"/ota\">");
response.concat("<button type=\"submit\">Open</button>");
response.concat("</form>");
if(_allowRestartToPortal)
{
response.concat("<br><br><h3>WiFi</h3>");
@@ -438,14 +464,32 @@ void WebCfgServer::buildCredHtml(String &response)
}
response.concat("</BODY>\n");
response.concat("</HTML>\n");
}
void WebCfgServer::buildOtaHtml(String &response)
{
buildHtmlHeader(response);
response.concat("<form id=\"upform\" enctype=\"multipart/form-data\" action=\"/uploadota\" method=\"POST\"><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"100000\" />Choose a file to upload: <input name=\"uploadedfile\" type=\"file\" accept=\".bin\" /><br/>");
response.concat("<br><input id=\"submitbtn\" type=\"submit\" value=\"Upload File\" /></form>");
response.concat("<div id=\"msgdiv\" style=\"visibility:hidden\">Initiating Over-the-air update. This will take about a minute, please be patient.<br>You will be forwarwed automatically when the update is complete.</div>");
response.concat("<script type=\"text/javascript\">");
response.concat("window.addEventListener('load', function () {");
response.concat(" var button = document.getElementById(\"submitbtn\");");
response.concat(" button.addEventListener('click',hideshow,false);");
response.concat(" function hideshow() {");
response.concat(" document.getElementById('upform').style.visibility = 'hidden';");
response.concat(" document.getElementById('msgdiv').style.visibility = 'visible';");
response.concat(" setTimeout(\"location.href = '/';\",60000);");
response.concat(" }");
response.concat("});");
response.concat("</script>");
response.concat("</BODY>\n</HTML>\n");
}
void WebCfgServer::buildMqttConfigHtml(String &response)
{
response.concat("<FORM ACTION=method=get >");
response.concat("<h3>MQTT COnfiguration</h3>");
response.concat("<h3>MQTT Configuration</h3>");
response.concat("<table>");
printInputField(response, "HOSTNAME", "Host name", _preferences->getString(preference_hostname).c_str(), 100);
printInputField(response, "MQTTSERVER", "MQTT Broker", _preferences->getString(preference_mqtt_broker).c_str(), 100);
@@ -661,3 +705,28 @@ void WebCfgServer::waitAndProcess(const bool blocking, const uint32_t duration)
}
}
void WebCfgServer::handleOtaUpload()
{
if (_server.uri() != "/uploadota") {
return;
}
esp_task_wdt_init(30, false);
HTTPUpload& upload = _server.upload();
if (upload.status == UPLOAD_FILE_START) {
String filename = upload.filename;
if (!filename.startsWith("/")) {
filename = "/" + filename;
}
Serial.print("handleFileUpload Name: "); Serial.println(filename);
} else if (upload.status == UPLOAD_FILE_WRITE) {
_transferredSize = _transferredSize + upload.currentSize;
Serial.println(_transferredSize);
_ota.updateFirmware(upload.buf, upload.currentSize);
} else if (upload.status == UPLOAD_FILE_END) {
Serial.println();
Serial.print("handleFileUpload Size: "); Serial.println(upload.totalSize);
}
}

View File

@@ -5,6 +5,7 @@
#include "NukiWrapper.h"
#include "Network.h"
#include "NukiOpenerWrapper.h"
#include "Ota.h"
enum class TokenType
{
@@ -32,6 +33,7 @@ private:
bool processArgs(String& message);
void buildHtml(String& response);
void buildCredHtml(String& response);
void buildOtaHtml(String& response);
void buildMqttConfigHtml(String& response);
void buildConfirmHtml(String& response, const String &message, uint32_t redirectDelay = 5);
void buildConfigureWifiHtml(String& response);
@@ -47,17 +49,21 @@ private:
String generateConfirmCode();
void waitAndProcess(const bool blocking, const uint32_t duration);
void handleOtaUpload();
WebServer _server;
NukiWrapper* _nuki;
NukiOpenerWrapper* _nukiOpener;
Network* _network;
Preferences* _preferences;
Ota _ota;
bool _hasCredentials = false;
char _credUser[20] = {0};
char _credPassword[20] = {0};
bool _allowRestartToPortal = false;
uint32_t _transferredSize = 0;
bool _otaStart = true;
String _confirmCode = "----";

View File

@@ -89,7 +89,7 @@ void setupTasks()
{
// configMAX_PRIORITIES is 25
xTaskCreate(networkTask, "ntw", 8192, NULL, 3, NULL);
xTaskCreatePinnedToCore(networkTask, "ntw", 8192, NULL, 3, NULL, 1);
xTaskCreate(nukiTask, "nuki", 4096, NULL, 2, NULL);
xTaskCreate(presenceDetectionTask, "prdet", 768, NULL, 5, NULL);
xTaskCreate(checkMillisTask, "mlchk", 512, NULL, 1, NULL);

Binary file not shown.

Binary file not shown.