fix: suspend web panel for OTA
Этот коммит содержится в:
@@ -68,7 +68,7 @@ Legacy dotted aliases are also accepted:
|
|||||||
### Web Panel Controls
|
### Web Panel Controls
|
||||||
|
|
||||||
- `get web`
|
- `get web`
|
||||||
- `get web.status`: shows whether the local HTTPS panel is available.
|
- `get web.status`: shows whether the local HTTPS panel is available. After `start ota`, this reports `web:suspended ota` until the repeater reboots.
|
||||||
- `get web.stats.status`: shows whether the dedicated stats page and history subsystem are enabled, whether recent history is active, whether PSRAM-backed history is available, and whether the SD-backed archive is mounted. When enabled, the history capture now covers supported environment telemetry too, not just the original battery/radio series.
|
- `get web.stats.status`: shows whether the dedicated stats page and history subsystem are enabled, whether recent history is active, whether PSRAM-backed history is available, and whether the SD-backed archive is mounted. When enabled, the history capture now covers supported environment telemetry too, not just the original battery/radio series.
|
||||||
- `set web on|off`
|
- `set web on|off`
|
||||||
- `set.web on|off`: enables or disables the local HTTPS panel.
|
- `set.web on|off`: enables or disables the local HTTPS panel.
|
||||||
@@ -123,6 +123,7 @@ Notes:
|
|||||||
- the panel still uses the repeater admin password for access
|
- the panel still uses the repeater admin password for access
|
||||||
- commands run with the same care as if you typed them into the repeater CLI directly
|
- commands run with the same care as if you typed them into the repeater CLI directly
|
||||||
- this is intended for local admin use on a trusted network
|
- this is intended for local admin use on a trusted network
|
||||||
|
- `start ota` suspends the local repeater web panel until reboot so the OTA HTTP listener can take over port `80`
|
||||||
|
|
||||||
## Companion WiFi Rescue Commands
|
## Companion WiFi Rescue Commands
|
||||||
|
|
||||||
|
|||||||
@@ -277,7 +277,8 @@ On mobile:
|
|||||||
|
|
||||||
1. Press `Start OTA`.
|
1. Press `Start OTA`.
|
||||||
2. Confirm the action.
|
2. Confirm the action.
|
||||||
3. Continue with your normal OTA workflow.
|
3. The local repeater web panel is suspended until reboot so OTA can take over HTTP on port `80`.
|
||||||
|
4. Continue with your normal OTA workflow.
|
||||||
|
|
||||||
### Use Historical Stats
|
### Use Historical Stats
|
||||||
|
|
||||||
|
|||||||
@@ -1973,6 +1973,12 @@ void MyMesh::clearStats() {
|
|||||||
((SimpleMeshTables *)getTables())->resetStats();
|
((SimpleMeshTables *)getTables())->resetStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyMesh::prepareForOTAStart() {
|
||||||
|
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||||
|
web.suspendForOTA();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply) {
|
void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply) {
|
||||||
if (region_load_active) {
|
if (region_load_active) {
|
||||||
if (StrHelper::isBlank(command)) { // empty/blank line, signal to terminate 'load' operation
|
if (StrHelper::isBlank(command)) { // empty/blank line, signal to terminate 'load' operation
|
||||||
|
|||||||
@@ -255,6 +255,7 @@ public:
|
|||||||
void formatRadioStatsReply(char *reply, size_t reply_size) override;
|
void formatRadioStatsReply(char *reply, size_t reply_size) override;
|
||||||
void formatPacketStatsReply(char *reply, size_t reply_size) override;
|
void formatPacketStatsReply(char *reply, size_t reply_size) override;
|
||||||
void formatMemoryReply(char *reply, size_t reply_size) override;
|
void formatMemoryReply(char *reply, size_t reply_size) override;
|
||||||
|
void prepareForOTAStart() override;
|
||||||
void startRegionsLoad() override;
|
void startRegionsLoad() override;
|
||||||
bool saveRegions() override;
|
bool saveRegions() override;
|
||||||
void onDefaultRegionChanged(const RegionEntry* r) override;
|
void onDefaultRegionChanged(const RegionEntry* r) override;
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
|||||||
strcpy(reply, "ERR: clock cannot go backwards");
|
strcpy(reply, "ERR: clock cannot go backwards");
|
||||||
}
|
}
|
||||||
} else if (memcmp(command, "start ota", 9) == 0) {
|
} else if (memcmp(command, "start ota", 9) == 0) {
|
||||||
|
_callbacks->prepareForOTAStart();
|
||||||
if (!_board->startOTAUpdate(_prefs->node_name, reply)) {
|
if (!_board->startOTAUpdate(_prefs->node_name, reply)) {
|
||||||
strcpy(reply, "Error");
|
strcpy(reply, "Error");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,6 +92,9 @@ public:
|
|||||||
virtual void saveIdentity(const mesh::LocalIdentity& new_id) = 0;
|
virtual void saveIdentity(const mesh::LocalIdentity& new_id) = 0;
|
||||||
virtual void clearStats() = 0;
|
virtual void clearStats() = 0;
|
||||||
virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0;
|
virtual void applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) = 0;
|
||||||
|
virtual void prepareForOTAStart() {
|
||||||
|
// no op by default
|
||||||
|
}
|
||||||
|
|
||||||
virtual void startRegionsLoad() {
|
virtual void startRegionsLoad() {
|
||||||
// no op by default
|
// no op by default
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
WebService::WebService() : _fs(nullptr), _prefs{}, _runner(nullptr), _network(nullptr) {
|
WebService::WebService() : _fs(nullptr), _prefs{}, _runner(nullptr), _network(nullptr), _suspended_for_ota(false) {
|
||||||
WebPrefsStore::setDefaults(_prefs);
|
WebPrefsStore::setDefaults(_prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19,6 +19,13 @@ void WebService::end() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebService::suspendForOTA() {
|
||||||
|
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||||
|
_suspended_for_ota = true;
|
||||||
|
_panel.stop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void WebService::loop() {
|
void WebService::loop() {
|
||||||
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||||
ensureWebServer();
|
ensureWebServer();
|
||||||
@@ -39,9 +46,12 @@ bool WebService::savePrefs() {
|
|||||||
|
|
||||||
bool WebService::setWebEnabled(bool enabled) {
|
bool WebService::setWebEnabled(bool enabled) {
|
||||||
_prefs.web_enabled = enabled ? 1 : 0;
|
_prefs.web_enabled = enabled ? 1 : 0;
|
||||||
|
if (!enabled) {
|
||||||
|
_suspended_for_ota = false;
|
||||||
|
}
|
||||||
bool ok = savePrefs();
|
bool ok = savePrefs();
|
||||||
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||||
if (_prefs.web_enabled != 0) {
|
if (_prefs.web_enabled != 0 && !_suspended_for_ota) {
|
||||||
ensureWebServer();
|
ensureWebServer();
|
||||||
} else {
|
} else {
|
||||||
_panel.stop();
|
_panel.stop();
|
||||||
@@ -62,6 +72,11 @@ void WebService::formatWebStatusReply(char* reply, size_t reply_size) const {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_suspended_for_ota) {
|
||||||
|
snprintf(reply, reply_size, "> web:suspended ota");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!_panel.isRunning() || _network == nullptr || !_network->isWifiConnected()) {
|
if (!_panel.isRunning() || _network == nullptr || !_network->isWifiConnected()) {
|
||||||
snprintf(reply, reply_size, "> web:down");
|
snprintf(reply, reply_size, "> web:down");
|
||||||
return;
|
return;
|
||||||
@@ -76,7 +91,7 @@ void WebService::formatWebStatusReply(char* reply, size_t reply_size) const {
|
|||||||
|
|
||||||
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
#if defined(ESP_PLATFORM) && WITH_WEB_PANEL
|
||||||
void WebService::ensureWebServer() {
|
void WebService::ensureWebServer() {
|
||||||
if (_runner == nullptr || _prefs.web_enabled == 0 || _network == nullptr || !_network->isWifiConnected()) {
|
if (_suspended_for_ota || _runner == nullptr || _prefs.web_enabled == 0 || _network == nullptr || !_network->isWifiConnected()) {
|
||||||
_panel.stop();
|
_panel.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
void begin(FILESYSTEM* fs);
|
void begin(FILESYSTEM* fs);
|
||||||
void end();
|
void end();
|
||||||
void loop();
|
void loop();
|
||||||
|
void suspendForOTA();
|
||||||
|
|
||||||
void setCommandRunner(WebPanelCommandRunner* runner);
|
void setCommandRunner(WebPanelCommandRunner* runner);
|
||||||
void setNetworkStateProvider(NetworkStateProvider* network) { _network = network; }
|
void setNetworkStateProvider(NetworkStateProvider* network) { _network = network; }
|
||||||
@@ -38,4 +39,5 @@ private:
|
|||||||
WebPanelCommandRunner* _runner;
|
WebPanelCommandRunner* _runner;
|
||||||
NetworkStateProvider* _network;
|
NetworkStateProvider* _network;
|
||||||
WebPanelServer _panel;
|
WebPanelServer _panel;
|
||||||
|
bool _suspended_for_ota;
|
||||||
};
|
};
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user