AutoConnectUpdate-rc1

pull/123/head
Hieromon Ikasamo 6 years ago
parent a9b2ae0f98
commit f0dde87064
  1. 96
      src/AutoConnectUpdate.cpp
  2. 23
      src/AutoConnectUpdate.h
  3. 18
      src/AutoConnectUpdatePage.h

@ -89,14 +89,20 @@ namespace AutoConnectUtil {
AC_HAS_FUNC(onProgress); AC_HAS_FUNC(onProgress);
template<typename T> template<typename T>
typename std::enable_if<AutoConnectUtil::has_func_onProgress<T>::value, AutoConnectUpdateAct::AC_UPDATEDIALOG_t>::type onProgress(T& updater, std::function<void(size_t, size_t)> fn) { typename std::enable_if<AutoConnectUtil::has_func_onProgress<T>::value, AutoConnectUpdateAct::AC_UPDATEDIALOG_t>::type onProgress(T& updater, UpdateVariedClass::THandlerFunction_Progress fn) {
#if defined(ARDUINO_ARCH_ESP32) || (defined(ARDUINO_ARCH_ESP8266) && (WEBSOCKETS_NETWORK_TYPE == NETWORK_ESP8266_ASYNC))
updater.onProgress(fn); updater.onProgress(fn);
AC_DBG("Updater keeps callback\n"); AC_DBG("Updater keeps callback\n");
return AutoConnectUpdateAct::UPDATEDIALOG_METER; return AutoConnectUpdateAct::UPDATEDIALOG_METER;
#else
(void)(updater);
(void)(fn);
return AutoConnectUpdateAct::UPDATEDIALOG_LOADER;
#endif
} }
template<typename T> template<typename T>
typename std::enable_if<!AutoConnectUtil::has_func_onProgress<T>::value, AutoConnectUpdateAct::AC_UPDATEDIALOG_t>::type onProgress(T& updater, std::function<void(size_t, size_t)> fn) { typename std::enable_if<!AutoConnectUtil::has_func_onProgress<T>::value, AutoConnectUpdateAct::AC_UPDATEDIALOG_t>::type onProgress(T& updater, UpdateVariedClass::THandlerFunction_Progress fn) {
(void)(updater); (void)(updater);
(void)(fn); (void)(fn);
return AutoConnectUpdateAct::UPDATEDIALOG_LOADER; return AutoConnectUpdateAct::UPDATEDIALOG_LOADER;
@ -111,7 +117,6 @@ AutoConnectUpdateAct::~AutoConnectUpdateAct() {
_catalog.reset(nullptr); _catalog.reset(nullptr);
_progress.reset(nullptr); _progress.reset(nullptr);
_result.reset(nullptr); _result.reset(nullptr);
_WiFiClient.reset(nullptr);
_ws.reset(nullptr); _ws.reset(nullptr);
} }
@ -136,7 +141,7 @@ void AutoConnectUpdateAct::attach(AutoConnect& portal) {
updatePage = new AutoConnectAux(String(FPSTR(_auxResult.uri)), String(FPSTR(_auxResult.title)), _auxResult.menu); updatePage = new AutoConnectAux(String(FPSTR(_auxResult.uri)), String(FPSTR(_auxResult.title)), _auxResult.menu);
_buildAux(updatePage, &_auxResult, lengthOf(_elmResult)); _buildAux(updatePage, &_auxResult, lengthOf(_elmResult));
_result.reset(updatePage); _result.reset(updatePage);
_result->chunk = PB_ByteStream;
_catalog->on(std::bind(&AutoConnectUpdateAct::_onCatalog, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); _catalog->on(std::bind(&AutoConnectUpdateAct::_onCatalog, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD);
_progress->on(std::bind(&AutoConnectUpdateAct::_onUpdate, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); _progress->on(std::bind(&AutoConnectUpdateAct::_onUpdate, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD);
_result->on(std::bind(&AutoConnectUpdateAct::_onResult, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD); _result->on(std::bind(&AutoConnectUpdateAct::_onResult, this, std::placeholders::_1, std::placeholders::_2), AC_EXIT_AHEAD);
@ -159,7 +164,6 @@ void AutoConnectUpdateAct::attach(AutoConnect& portal) {
// of the UpdateClass. // of the UpdateClass.
AutoConnectElement* loader = _progress->getElement(String(F("loader"))); AutoConnectElement* loader = _progress->getElement(String(F("loader")));
AutoConnectElement* enable_loader = _progress->getElement(String(F("enable_loader"))); AutoConnectElement* enable_loader = _progress->getElement(String(F("enable_loader")));
AutoConnectElement* enable_loader_post = _progress->getElement(String(F("enable_loader_post")));
AutoConnectElement* progress_meter = _progress->getElement(String(F("progress_meter"))); AutoConnectElement* progress_meter = _progress->getElement(String(F("progress_meter")));
AutoConnectElement* inprogress_meter = _progress->getElement(String(F("inprogress_meter"))); AutoConnectElement* inprogress_meter = _progress->getElement(String(F("inprogress_meter")));
AutoConnectElement* progress_loader = _progress->getElement(String(F("progress_loader"))); AutoConnectElement* progress_loader = _progress->getElement(String(F("progress_loader")));
@ -172,7 +176,6 @@ void AutoConnectUpdateAct::attach(AutoConnect& portal) {
case UPDATEDIALOG_METER: case UPDATEDIALOG_METER:
loader->enable = false; loader->enable = false;
enable_loader->enable =false; enable_loader->enable =false;
enable_loader_post->enable =false;
progress_loader->enable =false; progress_loader->enable =false;
inprogress_loader->enable = false; inprogress_loader->enable = false;
break; break;
@ -183,11 +186,10 @@ void AutoConnectUpdateAct::attach(AutoConnect& portal) {
* Detach the update item from the current AutoConnect menu. * Detach the update item from the current AutoConnect menu.
* AutoConnectUpdateAct still active. * AutoConnectUpdateAct still active.
*/ */
void AutoConnectUpdateAct::disable(void) { void AutoConnectUpdateAct::disable(const bool activate) {
_enable = activate;
if (_catalog) { if (_catalog) {
_catalog->menu(false); _catalog->menu(false);
if (_WiFiClient)
_WiFiClient.reset(nullptr);
AC_DBG("AutoConnectUpdate disabled\n"); AC_DBG("AutoConnectUpdate disabled\n");
} }
} }
@ -197,23 +199,19 @@ void AutoConnectUpdateAct::disable(void) {
* function into the menu. * function into the menu.
*/ */
void AutoConnectUpdateAct::enable(void) { void AutoConnectUpdateAct::enable(void) {
if (_catalog) { _enable = true;
_catalog->menu(true);
_status = UPDATE_IDLE; _status = UPDATE_IDLE;
_period = 0; if (_catalog) {
_catalog->menu(WiFi.status() == WL_CONNECTED);
AC_DBG("AutoConnectUpdate enabled\n"); AC_DBG("AutoConnectUpdate enabled\n");
} }
} }
void AutoConnectUpdateAct::handleUpdate(void) { void AutoConnectUpdateAct::handleUpdate(void) {
// Purge WiFiClient instances that have exceeded their retention // Activate the update menu conditional with WiFi connected.
// period to avoid running out of memory. if (!isEnable() && _enable) {
if (_WiFiClient) { if (WiFi.status() == WL_CONNECTED)
if (millis() - _period > AUTOCONNECT_UPDATE_DURATION) enable();
if (_status != UPDATE_START) {
_WiFiClient.reset(nullptr);
AC_DBG("Purged WifiClient due to duration expired.\n");
}
} }
if (isEnable()) { if (isEnable()) {
@ -222,6 +220,7 @@ void AutoConnectUpdateAct::handleUpdate(void) {
// execute it accordingly. It is only this process point that // execute it accordingly. It is only this process point that
// requests update processing. // requests update processing.
if (_status == UPDATE_START) { if (_status == UPDATE_START) {
AC_DBG("Waiting for WS connection\n");
unsigned long tm = millis(); unsigned long tm = millis();
while (!_wsConnected) { while (!_wsConnected) {
if (millis() - tm > AUTOCONNECT_TIMEOUT) { if (millis() - tm > AUTOCONNECT_TIMEOUT) {
@ -229,6 +228,7 @@ void AutoConnectUpdateAct::handleUpdate(void) {
break; break;
} }
_ws->loop(); // Crawl the connection request. _ws->loop(); // Crawl the connection request.
yield();
} }
// Launch the update // Launch the update
if (_wsConnected) if (_wsConnected)
@ -244,7 +244,7 @@ void AutoConnectUpdateAct::handleUpdate(void) {
// If WiFi is not connected, disables the update menu. // If WiFi is not connected, disables the update menu.
// However, the AutoConnectUpdateAct class stills active. // However, the AutoConnectUpdateAct class stills active.
else else
disable(); disable(_enable);
} }
} }
@ -258,11 +258,12 @@ AC_UPDATESTATUS_t AutoConnectUpdateAct::update(void) {
String uriBin = uri + '/' + _binName; String uriBin = uri + '/' + _binName;
if (_binName.length()) { if (_binName.length()) {
AC_DBG("%s:%d/%s update in progress...", host.c_str(), port, uriBin.c_str()); AC_DBG("%s:%d/%s update in progress...", host.c_str(), port, uriBin.c_str());
if (!_WiFiClient) { #if defined(ARDUINO_ARCH_ESP8266)
_WiFiClient.reset(new WiFiClient); t_httpUpdate_return ret = HTTPUpdateClass::update(host, port, uriBin);
_period = millis(); #elif defined(ARDUINO_ARCH_ESP32)
} WiFiClient wifiClient;
t_httpUpdate_return ret = HTTPUpdateClass::update(*_WiFiClient, host, port, uriBin); t_httpUpdate_return ret = HTTPUpdateClass::update(wifiClient, host, port, uriBin);
#endif
switch (ret) { switch (ret) {
case HTTP_UPDATE_FAILED: case HTTP_UPDATE_FAILED:
_status = UPDATE_FAIL; _status = UPDATE_FAIL;
@ -278,7 +279,6 @@ AC_UPDATESTATUS_t AutoConnectUpdateAct::update(void) {
AC_DBG_DUMB(" completed\n"); AC_DBG_DUMB(" completed\n");
break; break;
} }
_WiFiClient.reset(nullptr);
// Request the client to close the WebSocket. // Request the client to close the WebSocket.
_ws->sendTXT(_wsClient, "#e"); _ws->sendTXT(_wsClient, "#e");
} }
@ -349,19 +349,14 @@ String AutoConnectUpdateAct::_onCatalog(AutoConnectAux& catalog, PageArgument& a
AC_UNUSED(args); AC_UNUSED(args);
HTTPClient httpClient; HTTPClient httpClient;
// Reallocate WiFiClient if it is not existence. // Reallocate available firmwares list.
if (!_WiFiClient) { _binName = String("");
_WiFiClient.reset(new WiFiClient);
_period = millis();
}
AutoConnectText& caption = catalog.getElement<AutoConnectText>(String(F("caption"))); AutoConnectText& caption = catalog.getElement<AutoConnectText>(String(F("caption")));
AutoConnectRadio& firmwares = catalog.getElement<AutoConnectRadio>(String(F("firmwares"))); AutoConnectRadio& firmwares = catalog.getElement<AutoConnectRadio>(String(F("firmwares")));
AutoConnectSubmit& submit = catalog.getElement<AutoConnectSubmit>(String(F("update"))); AutoConnectSubmit& submit = catalog.getElement<AutoConnectSubmit>(String(F("update")));
firmwares.empty(); firmwares.empty();
firmwares.tags.clear(); firmwares.tags.clear();
submit.enable = false; submit.enable = false;
_binName = String("");
String qs = String(F(AUTOCONNECT_UPDATE_CATALOG)) + '?' + String(F("op=list&path=")) + uri; String qs = String(F(AUTOCONNECT_UPDATE_CATALOG)) + '?' + String(F("op=list&path=")) + uri;
AC_DBG("Query %s:%d%s\n", host.c_str(), port, qs.c_str()); AC_DBG("Query %s:%d%s\n", host.c_str(), port, qs.c_str());
@ -369,7 +364,7 @@ String AutoConnectUpdateAct::_onCatalog(AutoConnectAux& catalog, PageArgument& a
// Throw a query to the update server and parse the response JSON // Throw a query to the update server and parse the response JSON
// document. After that, display the bin type file name contained in // document. After that, display the bin type file name contained in
// its JSON document as available updaters to the page. // its JSON document as available updaters to the page.
if (httpClient.begin(*_WiFiClient.get(), host, port, qs, false)) { if (httpClient.begin(host, port, qs)) {
int responseCode = httpClient.GET(); int responseCode = httpClient.GET();
if (responseCode == HTTP_CODE_OK) { if (responseCode == HTTP_CODE_OK) {
@ -378,7 +373,7 @@ String AutoConnectUpdateAct::_onCatalog(AutoConnectAux& catalog, PageArgument& a
char beginOfList[] = "["; char beginOfList[] = "[";
char endOfEntry[] = ","; char endOfEntry[] = ",";
char endOfList[] = "]"; char endOfList[] = "]";
Stream& responseBody = httpClient.getStream(); WiFiClient& responseBody = httpClient.getStream();
// Read partially and repeatedly the responded http stream that is // Read partially and repeatedly the responded http stream that is
// including the JSON array to reduce the buffer size for parsing // including the JSON array to reduce the buffer size for parsing
@ -491,9 +486,15 @@ String AutoConnectUpdateAct::_onResult(AutoConnectAux& result, PageArgument& arg
bool restart = false; bool restart = false;
if (_ws) { if (_ws) {
_ws->close();
while (_wsConnected)
_ws->loop(); _ws->loop();
while (_wsConnected) {
IPAddress ipAny;
if (_ws->remoteIP(_wsClient) == ipAny)
_wsConnected = false;
else
_ws->close();
yield();
}
_ws.reset(nullptr); _ws.reset(nullptr);
} }
@ -519,9 +520,18 @@ String AutoConnectUpdateAct::_onResult(AutoConnectAux& result, PageArgument& arg
result.getElement<AutoConnectElement>(String(F("restart"))).enable = restart; result.getElement<AutoConnectElement>(String(F("restart"))).enable = restart;
if (restart) if (restart)
_status = UPDATE_RESET; _status = UPDATE_RESET;
return String(""); return String("");
} }
/**
* An update callback function in HTTPUpdate::update.
* This callback handler acts as an HTTPUpdate::update callback and
* sends the updated amount over the web socket to advance the progress
* of the progress meter displayed in the browser.
* @param amount Already transferred size.
* @param size Total size of the binary to update.
*/
void AutoConnectUpdateAct::_inProgress(size_t amount, size_t size) { void AutoConnectUpdateAct::_inProgress(size_t amount, size_t size) {
if (_ws) { if (_ws) {
_amount = amount; _amount = amount;
@ -531,6 +541,16 @@ void AutoConnectUpdateAct::_inProgress(size_t amount, size_t size) {
} }
} }
/**
* An event handler of WebSocket which should be opened to monitor
* update progress. AutoConnectUpdate will send #s to start the update
* progress notification to the client when the WebSocket client
* connected. This has the meaning of ACK.
* @param client WS client number of WebSocketsServer
* @param event Event id
* @param payload Payload content
* @param length payload length
*/
void AutoConnectUpdateAct::_wsEvent(uint8_t client, WStype_t event, uint8_t* payload, size_t length) { void AutoConnectUpdateAct::_wsEvent(uint8_t client, WStype_t event, uint8_t* payload, size_t length) {
AC_DBG("WS client:%d event(%d)\n", client, event); AC_DBG("WS client:%d event(%d)\n", client, event);
if (event == WStype_CONNECTED) { if (event == WStype_CONNECTED) {

@ -88,7 +88,7 @@ class AutoConnectUpdateVoid {
virtual ~AutoConnectUpdateVoid() {} virtual ~AutoConnectUpdateVoid() {}
virtual void attach(AutoConnect& portal) { AC_UNUSED(portal); } virtual void attach(AutoConnect& portal) { AC_UNUSED(portal); }
virtual void enable(void) {} virtual void enable(void) {}
virtual void disable(void) {} virtual void disable(const bool activate = false) { AC_UNUSED(activate); }
virtual void handleUpdate(void) {} virtual void handleUpdate(void) {}
virtual bool isEnable(void) { return false; } virtual bool isEnable(void) { return false; }
virtual AC_UPDATESTATUS_t status(void) { return UPDATE_IDLE; } virtual AC_UPDATESTATUS_t status(void) { return UPDATE_IDLE; }
@ -100,12 +100,12 @@ class AutoConnectUpdateVoid {
class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClass { class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClass {
public: public:
explicit AutoConnectUpdateAct(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) explicit AutoConnectUpdateAct(const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT)
: HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _status(UPDATE_IDLE), _binName(String()), _period(0) { : HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _wsClient(0), _wsConnected(false), _amount(0), _binSize(0), _enable(false), _dialog(UPDATEDIALOG_LOADER), _status(UPDATE_IDLE), _binName(String()) {
UPDATE_SETLED(LOW); /**< LED blinking during the update that is the default. */ UPDATE_SETLED(LOW); /**< LED blinking during the update that is the default. */
rebootOnUpdate(false); /**< Default reboot mode */ rebootOnUpdate(false); /**< Default reboot mode */
} }
AutoConnectUpdateAct(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT) AutoConnectUpdateAct(AutoConnect& portal, const String& host = String(""), const uint16_t port = AUTOCONNECT_UPDATE_PORT, const String& uri = String("."), const int timeout = AUTOCONNECT_UPDATE_TIMEOUT)
: HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _status(UPDATE_IDLE), _binName(String()), _period(0) { : HTTPUpdateClass(timeout), host(host), port(port), uri(uri), _wsClient(0), _wsConnected(false), _amount(0), _binSize(0), _enable(false), _dialog(UPDATEDIALOG_LOADER), _status(UPDATE_IDLE), _binName(String()) {
UPDATE_SETLED(LOW); UPDATE_SETLED(LOW);
rebootOnUpdate(false); rebootOnUpdate(false);
attach(portal); attach(portal);
@ -113,7 +113,7 @@ class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClas
~AutoConnectUpdateAct(); ~AutoConnectUpdateAct();
void attach(AutoConnect& portal) override; /**< Attach the update class to AutoConnect */ void attach(AutoConnect& portal) override; /**< Attach the update class to AutoConnect */
void enable(void) override; /**< Enable the AutoConnectUpdateAct */ void enable(void) override; /**< Enable the AutoConnectUpdateAct */
void disable(void) override; /**< Disable the AutoConnectUpdateAct */ void disable(const bool activte = false) override; /**< Disable the AutoConnectUpdateAct */
void handleUpdate(void) override; /**< Behaves the update process */ void handleUpdate(void) override; /**< Behaves the update process */
bool isEnable(void) override { return _catalog ? _catalog->isMenu() : false; } /**< Returns current updater effectiveness */ bool isEnable(void) override { return _catalog ? _catalog->isMenu() : false; } /**< Returns current updater effectiveness */
AC_UPDATESTATUS_t status(void) override { return _status; } /**< reports the current update behavior status */ AC_UPDATESTATUS_t status(void) override { return _status; } /**< reports the current update behavior status */
@ -123,10 +123,10 @@ class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClas
uint16_t port; /**< Port number of the update server */ uint16_t port; /**< Port number of the update server */
String uri; /**< The path on the update server that contains the sketch binary to be updated */ String uri; /**< The path on the update server that contains the sketch binary to be updated */
// // Indicate the type of progress dialog
typedef enum { typedef enum {
UPDATEDIALOG_LOADER, UPDATEDIALOG_LOADER, /**< Cyclic loader icon */
UPDATEDIALOG_METER UPDATEDIALOG_METER /**< Progress meter */
} AC_UPDATEDIALOG_t; } AC_UPDATEDIALOG_t;
protected: protected:
@ -141,7 +141,7 @@ class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClas
// Attributes to treat included update pages as AutoConnectAux. // Attributes to treat included update pages as AutoConnectAux.
typedef struct { typedef struct {
const char* uri; /**< URI for the page */ const char* uri; /**< URI for the page */
const char* title; /**< Menut title of update page */ const char* title; /**< Menu title of update page */
const bool menu; /**< Whether to display in menu */ const bool menu; /**< Whether to display in menu */
const ACElementProp_t* element; const ACElementProp_t* element;
} ACPage_t; } ACPage_t;
@ -153,7 +153,7 @@ class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClas
String _onUpdate(AutoConnectAux& update, PageArgument& args); String _onUpdate(AutoConnectAux& update, PageArgument& args);
String _onResult(AutoConnectAux& result, PageArgument& args); String _onResult(AutoConnectAux& result, PageArgument& args);
void _wsEvent(uint8_t client, WStype_t event, uint8_t* payload, size_t length); void _wsEvent(uint8_t client, WStype_t event, uint8_t* payload, size_t length);
void _inProgress(size_t amount, size_t size); void _inProgress(size_t amount, size_t size); /**< UpdateClass::THandlerFunction_Progress */
std::unique_ptr<AutoConnectAux> _catalog; /**< A catalog page for internally generated update binaries */ std::unique_ptr<AutoConnectAux> _catalog; /**< A catalog page for internally generated update binaries */
std::unique_ptr<AutoConnectAux> _progress; /**< An update in-progress page */ std::unique_ptr<AutoConnectAux> _progress; /**< An update in-progress page */
@ -162,15 +162,14 @@ class AutoConnectUpdateAct : public AutoConnectUpdateVoid, public HTTPUpdateClas
std::unique_ptr<WebSocketsServer> _ws; /**< Reports the update progress measure */ std::unique_ptr<WebSocketsServer> _ws; /**< Reports the update progress measure */
uint8_t _wsClient; /**< WebSocket client id */ uint8_t _wsClient; /**< WebSocket client id */
bool _wsConnected; /**< WebSocket connection status */ bool _wsConnected; /**< WebSocket connection status */
size_t _amount; /**< Received amound bytes */ size_t _amount; /**< Received amount bytes */
size_t _binSize; /**< Updater binary size */ size_t _binSize; /**< Updater binary size */
private: private:
bool _enable; /**< Validation status of the Update class */
AC_UPDATEDIALOG_t _dialog; /**< The type of updating dialog displayed on the client */ AC_UPDATEDIALOG_t _dialog; /**< The type of updating dialog displayed on the client */
AC_UPDATESTATUS_t _status; /**< Status of update processing during the cycle of receiving a request */ AC_UPDATESTATUS_t _status; /**< Status of update processing during the cycle of receiving a request */
String _binName; /**< .bin name to update */ String _binName; /**< .bin name to update */
unsigned long _period; /**< Duration of WiFiClient holding for the connection with the update server */
std::unique_ptr<WiFiClient> _WiFiClient; /**< Provide to HTTPUpdate class */
static const ACPage_t _auxCatalog PROGMEM; static const ACPage_t _auxCatalog PROGMEM;
static const ACElementProp_t _elmCatalog[] PROGMEM; static const ACElementProp_t _elmCatalog[] PROGMEM;

@ -14,7 +14,7 @@
// Define the AUTOCONNECT_URI_UPDATE page to select the sketch binary // Define the AUTOCONNECT_URI_UPDATE page to select the sketch binary
// for update and order update execution. // for update and order update execution.
const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmCatalog[] PROGMEM = { const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmCatalog[] PROGMEM = {
{ AC_Element, "binSty", "<style type\"text/css\">.bins{display:grid;font-size:14px;grid-gap:10px 0;grid-template-columns:1em repeat(4,max-content);overflow-x:auto}.bins input[type=radio]{-moz-appearance:radio;-webkit-appearance:radio;margin:0;vertical-align:middle}.noorder .bins label,span{margin:0 .5em 0 .5em;padding:0;text-align:left}</style>", nullptr }, { AC_Element, "binSty", "<style type=\"text/css\">.bins{display:grid;font-size:14px;grid-gap:10px 0;grid-template-columns:1em repeat(4,max-content);overflow-x:auto}.bins input[type=radio]{-moz-appearance:radio;-webkit-appearance:radio;margin:0;vertical-align:middle}.noorder .bins label,span{margin:0 .5em 0 .5em;padding:0;text-align:left}</style>", nullptr },
{ AC_Text, "caption", nullptr, nullptr }, { AC_Text, "caption", nullptr, nullptr },
{ AC_Element, "c1", "<div class=\"bins\">", nullptr }, { AC_Element, "c1", "<div class=\"bins\">", nullptr },
{ AC_Radio, "firmwares", nullptr, nullptr }, { AC_Radio, "firmwares", nullptr, nullptr },
@ -38,16 +38,14 @@ const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmProgress[]
{ AC_Element, "progress_loader", "<div id=\"ld\" />", nullptr }, { AC_Element, "progress_loader", "<div id=\"ld\" />", nullptr },
{ AC_Element, "c4", "</span></div></div>", nullptr }, { AC_Element, "c4", "</span></div></div>", nullptr },
{ AC_Text, "status", nullptr, nullptr }, { AC_Text, "status", nullptr, nullptr },
{ AC_Element, "c5", "<script type=\"text/javascript\">function rd(){location.href=\"" AUTOCONNECT_URI_UPDATE_RESULT "\"}var ws;window.onload=function(){(ws=new WebSocket(\"", nullptr }, { AC_Element, "c5", "<script type=\"text/javascript\">var ws,conn=!1;function rd(){location.href=\"" AUTOCONNECT_URI_UPDATE_RESULT "\"}function bar(){(ws=new WebSocket(\"", nullptr },
{ AC_Element, "wsurl", nullptr, nullptr }, { AC_Element, "wsurl", nullptr, nullptr },
{ AC_Element, "c6", "\")).onopen=function(){ws.onmessage=function(e){var o=e.data.split(\",\");\"#s\"==o[0]?", nullptr }, { AC_Element, "c6", "\")).onopen=function(){ws.onmessage=function(e){var t=e.data.split(\",\");\"#s\"==t[0]?(", nullptr },
{ AC_Element, "enable_loader", "(document.getElementById(\"ld\").className=\"loader\",", nullptr }, { AC_Element, "enable_loader", "document.getElementById(\"ld\").className=\"loader\",", nullptr },
{ AC_Element, "c7", "window.setTimeout(rd()," AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_DURATION) ")", nullptr }, { AC_Element, "c7", "window.setTimeout(rd()," AUTOCONNECT_STRING_DEPLOY(AUTOCONNECT_UPDATE_DURATION) "),conn=!0):\"#e\"==t[0]?(ws.close(),conn=!1):\"#p\"==t[0]&&incr(t[1])}},ws.onclose=function(e){conn?setTimeout(function(){bar()},2e3):rd()},ws.onerror=function(e){console.log(\"WS err(\"+e.code+\")\"+e.reason),1==ws.readyState&&(document.getElementById(\"status\").textContent=\"WebSocket \"+e.type)}}", nullptr },
{ AC_Element, "enable_loader_post", ")", nullptr }, { AC_Element, "inprogress_meter", "function incr(e){var t=e.split(\":\"),n=document.getElementById(\"progress\").getElementsByTagName(\"meter\");n[0].setAttribute(\"value\",t[0]),n[0].setAttribute(\"max\",t[1])}", nullptr },
{ AC_Element, "c8", ":\"#e\"==o[0]?ws.close():\"#p\"==o[0]&&incr(o[1])}},ws.onclose=function(e){rd()},ws.onerror=function(e){console.log(\"WS err(\"+e.code+\")\"+e.reason),1==ws.readyState&&(document.getElementById(\"status\").textContent=\"WebSocket \"+e.type)}};", nullptr },
{ AC_Element, "inprogress_meter", "function incr(e){var t=e.split(\":\"),r=document.getElementById(\"progress\").getElementsByTagName(\"meter\");r[0].setAttribute(\"value\",t[0]),r[0].setAttribute(\"max\",t[1])}", nullptr },
{ AC_Element, "inprogress_loader", "function incr(pv){}", nullptr }, { AC_Element, "inprogress_loader", "function incr(pv){}", nullptr },
{ AC_Element, "c9", "</script>", nullptr } { AC_Element, "c8", "window.onload=bar;</script>", nullptr }
}; };
const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxProgress PROGMEM = { const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxProgress PROGMEM = {
AUTOCONNECT_URI_UPDATE_ACT, "Update", false, AutoConnectUpdateAct::_elmProgress AUTOCONNECT_URI_UPDATE_ACT, "Update", false, AutoConnectUpdateAct::_elmProgress
@ -56,7 +54,7 @@ const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxProgress PROGMEM
// Definition of the AUTOCONNECT_URI_UPDATE_RESULT page to notify update results // Definition of the AUTOCONNECT_URI_UPDATE_RESULT page to notify update results
const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmResult[] PROGMEM = { const AutoConnectUpdateAct::ACElementProp_t AutoConnectUpdateAct::_elmResult[] PROGMEM = {
{ AC_Text, "status", nullptr, nullptr }, { AC_Text, "status", nullptr, nullptr },
{ AC_Element, "restart", "<script type=\"text/javascript\">setTimeout(\"location.href='" AUTOCONNECT_HOMEURI "'\",1000*10);</script>", nullptr } { AC_Element, "restart", "<script type=\"text/javascript\">setTimeout(\"location.href='" AUTOCONNECT_HOMEURI "'\",1e4);</script>", nullptr }
}; };
const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxResult PROGMEM = { const AutoConnectUpdateAct::ACPage_t AutoConnectUpdateAct::_auxResult PROGMEM = {
AUTOCONNECT_URI_UPDATE_RESULT, "Update", false, AutoConnectUpdateAct::_elmResult AUTOCONNECT_URI_UPDATE_RESULT, "Update", false, AutoConnectUpdateAct::_elmResult

Loading…
Cancel
Save