mirror of
https://github.com/paperdash/device-epd.git
synced 2024-11-10 07:10:32 +00:00
#13 basic working version of OTA
This commit is contained in:
parent
94a53071a7
commit
93ed45f572
@ -22,10 +22,12 @@
|
||||
Weather
|
||||
<v-icon>$wb_sunny</v-icon>
|
||||
</v-tab>
|
||||
<!--
|
||||
<v-tab>
|
||||
Cloud
|
||||
<v-icon>$cloud</v-icon>
|
||||
</v-tab>
|
||||
-->
|
||||
</v-tabs>
|
||||
|
||||
<v-card v-if="settings" class="mx-auto" width="400">
|
||||
@ -45,6 +47,65 @@
|
||||
label="i8n:Theme"
|
||||
placeholder
|
||||
></v-select>
|
||||
|
||||
<v-dialog v-model="dialogSystemUpdate" max-width="400">
|
||||
<template v-slot:activator="{ on }">
|
||||
<v-btn class="my-5" block small outlined color="warning" v-on="on">System update</v-btn>
|
||||
</template>
|
||||
<v-card :loading="system.updateProgress > 0">
|
||||
<template v-slot:progress>
|
||||
<v-progress-linear
|
||||
v-model="system.updateProgress"
|
||||
:indeterminate="system.updateProgress === 100"
|
||||
height="10"
|
||||
></v-progress-linear>
|
||||
</template>
|
||||
<v-card-title class="headline">System update</v-card-title>
|
||||
<v-card-text>
|
||||
<!--
|
||||
<v-alert border="left" type="warning" outlined>
|
||||
Sed in libero ut nibh placerat accumsan. Phasellus leo dolor, tempus non, auctor et
|
||||
</v-alert>
|
||||
-->
|
||||
|
||||
<v-file-input
|
||||
v-model="system.firmware"
|
||||
show-size
|
||||
accept="application/octet-stream"
|
||||
label="Firmware"
|
||||
></v-file-input>
|
||||
</v-card-text>
|
||||
<v-card-actions>
|
||||
<v-btn text href="https://github.com/paperdash" target="_blank">Get firmware</v-btn>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn
|
||||
outlined
|
||||
color="warning"
|
||||
ref="firmware"
|
||||
@click="onSystemUpdate()"
|
||||
>Update system</v-btn>
|
||||
|
||||
<!--
|
||||
<v-btn color="green darken-1" text @click="dialogSystemUpdate = false">Disagree</v-btn>
|
||||
<v-btn color="green darken-1" text @click="dialogSystemUpdate = false">Agree</v-btn>
|
||||
-->
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
|
||||
<v-dialog :value="system.updateResult !== null" persistent max-width="400">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
update result...
|
||||
{{ system.updateResult }}
|
||||
</v-card-title>
|
||||
|
||||
<v-card-actions>
|
||||
<v-spacer></v-spacer>
|
||||
<v-btn text @click="onUpdateDone()">OK</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</v-dialog>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
@ -108,6 +169,7 @@
|
||||
></v-select>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
<!--
|
||||
<v-tab-item>
|
||||
<v-card-text>
|
||||
<v-select
|
||||
@ -130,6 +192,7 @@
|
||||
></v-text-field>
|
||||
</v-card-text>
|
||||
</v-tab-item>
|
||||
-->
|
||||
</v-tabs-items>
|
||||
|
||||
<v-card-actions>
|
||||
@ -149,6 +212,7 @@
|
||||
<script>
|
||||
import apiDevice from "../api/device";
|
||||
import weatherFindLocation from "./../components/WeatherFindLocation";
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
name: "Settings",
|
||||
@ -186,7 +250,14 @@ export default {
|
||||
weatherUnit: [
|
||||
{ text: "Imperial", value: "" },
|
||||
{ text: "Metrisch", value: "metric" }
|
||||
]
|
||||
],
|
||||
|
||||
dialogSystemUpdate: false,
|
||||
system: {
|
||||
firmware: null,
|
||||
updateProgress: 0,
|
||||
updateResult: null
|
||||
}
|
||||
}),
|
||||
created() {
|
||||
this.$vuetify.icons.values.tv = {
|
||||
@ -225,10 +296,28 @@ export default {
|
||||
/* webpackChunkName: "icons" */ "!vue-svg-loader!@material-icons/svg/svg/wb_sunny/baseline.svg"
|
||||
)
|
||||
};
|
||||
this.$vuetify.icons.values.update = {
|
||||
this.$vuetify.icons.values.system_update = {
|
||||
component: () =>
|
||||
import(
|
||||
/* webpackChunkName: "icons" */ "!vue-svg-loader!@material-icons/svg/svg/update/baseline.svg"
|
||||
/* webpackChunkName: "icons" */ "!vue-svg-loader!@material-icons/svg/svg/system_update_alt/baseline.svg"
|
||||
)
|
||||
};
|
||||
this.$vuetify.icons.values.file = {
|
||||
component: () =>
|
||||
import(
|
||||
/* webpackChunkName: "icons" */ "!vue-svg-loader!@material-icons/svg/svg/attach_file/baseline.svg"
|
||||
)
|
||||
};
|
||||
this.$vuetify.icons.values.warning = {
|
||||
component: () =>
|
||||
import(
|
||||
/* webpackChunkName: "icons" */ "!vue-svg-loader!@material-icons/svg/svg/warning/baseline.svg"
|
||||
)
|
||||
};
|
||||
this.$vuetify.icons.values.clear = {
|
||||
component: () =>
|
||||
import(
|
||||
/* webpackChunkName: "icons" */ "!vue-svg-loader!@material-icons/svg/svg/clear/baseline.svg"
|
||||
)
|
||||
};
|
||||
|
||||
@ -249,6 +338,49 @@ export default {
|
||||
|
||||
this.$router.push("/");
|
||||
});
|
||||
},
|
||||
|
||||
onSystemUpdate() {
|
||||
let self = this;
|
||||
self.system.updateProgress = 0;
|
||||
|
||||
const config = {
|
||||
onUploadProgress: function(progressEvent) {
|
||||
let percentCompleted = Math.round(
|
||||
(progressEvent.loaded * 100) / progressEvent.total
|
||||
);
|
||||
|
||||
self.system.updateProgress = percentCompleted;
|
||||
}
|
||||
};
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append("update", this.system.firmware);
|
||||
|
||||
axios
|
||||
.post("/update", formData, config)
|
||||
.then(response => {
|
||||
console.log(response.data);
|
||||
|
||||
self.system.updateProgress = null;
|
||||
self.system.updateResult = response.data.success;
|
||||
})
|
||||
.catch(response => {
|
||||
console.log(response);
|
||||
|
||||
self.system.updateProgress = null;
|
||||
self.system.updateResult = false;
|
||||
});
|
||||
},
|
||||
|
||||
onUpdateDone() {
|
||||
if (this.system.updateResult === true) {
|
||||
window.location = "/";
|
||||
} else {
|
||||
this.system.firmware = null;
|
||||
this.system.updateProgress = 0;
|
||||
this.system.updateResult = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
67
src/app.cpp
67
src/app.cpp
@ -1,4 +1,5 @@
|
||||
#include <SPIFFS.h>
|
||||
#include <Update.h>
|
||||
#include "app.h"
|
||||
#include "ESPAsyncWebServer.h"
|
||||
#include "ArduinoJson.h"
|
||||
@ -21,8 +22,14 @@ void setupWifiConnect();
|
||||
void setupCurrentImage();
|
||||
void setupApiFace();
|
||||
void setupApiUpdate();
|
||||
void setupOTA();
|
||||
|
||||
//flag to use from web update to update display
|
||||
bool updateDisplayRequired = false;
|
||||
|
||||
//flag to use from web update to reboot the ESP
|
||||
bool shouldReboot = false;
|
||||
|
||||
// bmp
|
||||
void write16(AsyncResponseStream &f, uint16_t v);
|
||||
void write32(AsyncResponseStream &f, uint32_t v);
|
||||
@ -51,6 +58,7 @@ void setupApp()
|
||||
setupCurrentImage();
|
||||
setupApiFace();
|
||||
setupApiUpdate();
|
||||
setupOTA();
|
||||
|
||||
server.onNotFound([](AsyncWebServerRequest *request) {
|
||||
request->send(404);
|
||||
@ -102,6 +110,13 @@ void setupApp()
|
||||
|
||||
void loopApp()
|
||||
{
|
||||
if (shouldReboot)
|
||||
{
|
||||
Serial.println("Rebooting...");
|
||||
delay(100);
|
||||
ESP.restart();
|
||||
}
|
||||
|
||||
if (updateDisplayRequired)
|
||||
{
|
||||
Serial.println("loop app update display");
|
||||
@ -396,6 +411,58 @@ void setupApiUpdate()
|
||||
});
|
||||
}
|
||||
|
||||
void setupOTA()
|
||||
{
|
||||
// Simple Firmware Update Form
|
||||
/*
|
||||
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request) {
|
||||
// TODO in die pwa auslagern
|
||||
request->send(200, "text/html", "<form method='POST' action='/update' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>");
|
||||
});
|
||||
*/
|
||||
|
||||
server.on(
|
||||
"/update", HTTP_POST, [](AsyncWebServerRequest *request) {
|
||||
shouldReboot = !Update.hasError();
|
||||
AsyncWebServerResponse *response = request->beginResponse(200, "application/ld+json; charset=utf-8", shouldReboot ? "{\"success\": true}" : "{\"success\": false}");
|
||||
|
||||
response->addHeader("Connection", "close");
|
||||
request->send(response);
|
||||
},
|
||||
[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
|
||||
if (!index)
|
||||
{
|
||||
Serial.printf("Update Start: %s\n", filename.c_str());
|
||||
// bool canBegin = Update.begin(contentLength, U_FLASH);
|
||||
// bool canBegin = Update.begin(contentLength, U_SPIFFS);
|
||||
if (!Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000))
|
||||
{
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Update.hasError())
|
||||
{
|
||||
if (Update.write(data, len) != len)
|
||||
{
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
|
||||
if (final)
|
||||
{
|
||||
if (Update.end(true))
|
||||
{
|
||||
Serial.printf("Update Success: %uB\n", index + len);
|
||||
}
|
||||
else
|
||||
{
|
||||
Update.printError(Serial);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void write16(AsyncResponseStream &f, uint16_t v)
|
||||
{
|
||||
f.write(uint8_t(v));
|
||||
|
Loading…
Reference in New Issue
Block a user