Add T-Beam WiFi button toggle
This commit is contained in:
1 parent
933697f65c
commit
7afa6b11a8
15 files changed
+263
-45
No files matched your search
@@ -181,6 +181,12 @@ service on ports 5001 and 5002. See the
|
||||
[full Companion guide](./companion_radio_full.md) for its build, terminal mode,
|
||||
and complete update-source workflow.
|
||||
|
||||
The LilyGo T-Beam 1W Full Companion maps a triple click of the physical button
|
||||
labeled `17` to a persistent WiFi on/off toggle. Turning WiFi off closes the
|
||||
WebConfig, Companion TCP, mOTA, and MQTT network services while USB, BLE, the
|
||||
display, GPS, and LoRa remain available. The same triple click turns WiFi back
|
||||
on even after reboot.
|
||||
|
||||
The companion loads runtime credentials saved in NVS. A non-placeholder
|
||||
compile-time `WIFI_SSID`/`WIFI_PWD` can be used as a first-boot fallback, but
|
||||
saved credentials take priority. With no credentials, its WebConfig portal
|
||||
|
||||
@@ -80,6 +80,13 @@ clock and keeps GPS awake. Full Companion transports remain available in both
|
||||
states; WiFi modem sleep stays enabled when BLE is present because coexistence
|
||||
requires it. The selected state is retained after reboot.
|
||||
|
||||
On the LilyGo T-Beam 1W Full Companion, triple-click the physical button
|
||||
labeled `17` to turn the ESP32 WiFi radio and all WiFi services off or on. The
|
||||
screen confirms `WiFi: OFF` or `WiFi: ON`, and the selected state is retained
|
||||
after reboot. When WiFi is off, TCP ports 5000-5002, WebConfig, and MQTT are
|
||||
stopped; USB, BLE, the display, GPS, and LoRa continue to operate. Triple-click
|
||||
button 17 again to restore WiFi, including the saved station or setup-AP mode.
|
||||
|
||||
Artifacts are written to `out/` by default.
|
||||
|
||||
On 4 MB ESP32 boards, the full target uses a single 3 MB application
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
|
||||
// The requested state is persisted immediately. Network services transition
|
||||
// from the main loop so a button callback never tears down an active server.
|
||||
bool toggleCompanionWiFi();
|
||||
bool isCompanionWiFiEnabled();
|
||||
|
||||
#endif
|
||||
@@ -336,6 +336,10 @@ void DataStore::loadPrefsInt(const char *filename, CompanionNodePrefs& _prefs, d
|
||||
if (file.available() >= (int)sizeof(_prefs.powersaving_enabled)) {
|
||||
file.read((uint8_t *)&_prefs.powersaving_enabled,
|
||||
sizeof(_prefs.powersaving_enabled)); // 137
|
||||
if (file.available() >= (int)sizeof(_prefs.wifi_enabled)) {
|
||||
file.read((uint8_t *)&_prefs.wifi_enabled,
|
||||
sizeof(_prefs.wifi_enabled)); // 138
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,6 +405,8 @@ bool DataStore::savePrefs(const CompanionNodePrefs& _prefs, double node_lat, dou
|
||||
sizeof(_prefs.rx_ps_preamble)) == sizeof(_prefs.rx_ps_preamble); // 136
|
||||
success = success && file.write((uint8_t *)&_prefs.powersaving_enabled,
|
||||
sizeof(_prefs.powersaving_enabled)) == sizeof(_prefs.powersaving_enabled); // 137
|
||||
success = success && file.write((uint8_t *)&_prefs.wifi_enabled,
|
||||
sizeof(_prefs.wifi_enabled)) == sizeof(_prefs.wifi_enabled); // 138
|
||||
|
||||
#if defined(NRF52_PLATFORM)
|
||||
success = file.commit(success);
|
||||
|
||||
@@ -1356,6 +1356,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
||||
_prefs.rx_ps_rx_us = RX_POWERSAVING_DEFAULT_RX_US;
|
||||
_prefs.rx_ps_sleep_us = RX_POWERSAVING_DEFAULT_SLEEP_US;
|
||||
_prefs.powersaving_enabled = 0;
|
||||
_prefs.wifi_enabled = 1;
|
||||
recalcRxPowerSavingFromLevel(_prefs.rx_ps_level, _prefs.sf, _prefs.bw,
|
||||
_prefs.rx_ps_preamble, &_prefs.rx_ps_rx_us,
|
||||
&_prefs.rx_ps_sleep_us);
|
||||
@@ -1439,6 +1440,7 @@ void MyMesh::begin(bool has_display) {
|
||||
_prefs.radio_fem_txgain = constrain(_prefs.radio_fem_txgain, 0, 1);
|
||||
_prefs.rx_powersaving_enabled = constrain(_prefs.rx_powersaving_enabled, 0, 1);
|
||||
_prefs.powersaving_enabled = constrain(_prefs.powersaving_enabled, 0, 1);
|
||||
_prefs.wifi_enabled = constrain(_prefs.wifi_enabled, 0, 1);
|
||||
_prefs.rx_ps_level = constrain(_prefs.rx_ps_level, 0, 10);
|
||||
if (_prefs.rx_ps_preamble != 16 && _prefs.rx_ps_preamble != 32) {
|
||||
_prefs.rx_ps_preamble = 0;
|
||||
@@ -1813,6 +1815,11 @@ void MyMesh::serviceMQTT(const char* wifi_ssid, const char* wifi_password) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MyMesh::stopMQTT() {
|
||||
if (_mqtt_started && _mqtt_bridge) _mqtt_bridge->end();
|
||||
_mqtt_started = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_WEBCONFIG
|
||||
@@ -1938,6 +1945,10 @@ void MyMesh::serviceWebConfig() {
|
||||
if (_webconfig) _webconfig->tick(millis());
|
||||
}
|
||||
|
||||
bool MyMesh::isWebConfigActiveOrStopping() const {
|
||||
return _webconfig && (_webconfig->isRunning() || _webconfig->isStopping());
|
||||
}
|
||||
|
||||
bool MyMesh::isWebConfigSetupActive() const {
|
||||
return _webconfig && _webconfig->mode() == WebConfigServer::MODE_SETUP
|
||||
&& !_webconfig->isStopping();
|
||||
|
||||
@@ -121,6 +121,7 @@ public:
|
||||
|
||||
#if defined(WITH_MQTT_BRIDGE) && defined(ESP32_PLATFORM) && defined(WIFI_SSID)
|
||||
void serviceMQTT(const char* wifi_ssid, const char* wifi_password);
|
||||
void stopMQTT();
|
||||
bool isMQTTConfigured() const { return _mqtt_configured; }
|
||||
#endif
|
||||
|
||||
@@ -128,6 +129,7 @@ public:
|
||||
bool startWebConfig(bool force_ap, char* reply);
|
||||
void stopWebConfig();
|
||||
void serviceWebConfig();
|
||||
bool isWebConfigActiveOrStopping() const;
|
||||
bool isWebConfigSetupActive() const;
|
||||
bool isWebConfigWiFiRecoveryActive() const;
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ struct CompanionNodePrefs { // persisted to file
|
||||
uint8_t rx_ps_level; // 0=manual timings, 1..10=level-derived
|
||||
uint8_t rx_ps_preamble; // 0=auto from SF, otherwise 16 or 32
|
||||
uint8_t powersaving_enabled; // device CPU/GPS idle power saving
|
||||
uint8_t wifi_enabled; // Companion WiFi radio and services
|
||||
|
||||
// Keep the upstream repeat API while retaining the existing binary prefs
|
||||
// layout used by this branch.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Arduino.h> // needed for PlatformIO
|
||||
#include <Mesh.h>
|
||||
#include "MyMesh.h"
|
||||
#include "CompanionWiFi.h"
|
||||
|
||||
#ifdef ESP32_PLATFORM
|
||||
#include "esp_bt.h"
|
||||
@@ -431,6 +432,27 @@ void halt() {
|
||||
bool wifi_setup_recovery_mode = false;
|
||||
static char configured_wifi_ssid[32];
|
||||
static char configured_wifi_password[64];
|
||||
static bool companion_wifi_has_credentials = false;
|
||||
static bool companion_wifi_requested = true;
|
||||
static bool companion_wifi_active = false;
|
||||
static bool companion_wifi_disable_in_progress = false;
|
||||
static bool companion_wifi_services_stopped = false;
|
||||
|
||||
bool isCompanionWiFiEnabled() {
|
||||
return companion_wifi_requested;
|
||||
}
|
||||
|
||||
bool toggleCompanionWiFi() {
|
||||
companion_wifi_requested = !companion_wifi_requested;
|
||||
the_mesh.getNodePrefs()->wifi_enabled = companion_wifi_requested ? 1 : 0;
|
||||
the_mesh.savePrefs();
|
||||
if (!companion_wifi_requested && companion_wifi_active) {
|
||||
companion_wifi_disable_in_progress = true;
|
||||
}
|
||||
WIFI_DEBUG_PRINTLN("GPIO 17 triple click requested WiFi %s",
|
||||
companion_wifi_requested ? "on" : "off");
|
||||
return companion_wifi_requested;
|
||||
}
|
||||
|
||||
#if defined(WITH_WEBCONFIG) && defined(DISPLAY_CLASS)
|
||||
static DisplayDriver* companion_setup_display = nullptr;
|
||||
@@ -492,6 +514,7 @@ void halt() {
|
||||
configured_wifi_ssid[sizeof(configured_wifi_ssid) - 1] = '\0';
|
||||
strncpy(configured_wifi_password, password ? password : "", sizeof(configured_wifi_password) - 1);
|
||||
configured_wifi_password[sizeof(configured_wifi_password) - 1] = '\0';
|
||||
companion_wifi_has_credentials = true;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -502,6 +525,7 @@ void halt() {
|
||||
`normalradio` here so a host can run an end-to-end mOTA source without occupying the binary port. */
|
||||
#if defined(ESP32) && defined(WIFI_SSID) && defined(ENABLE_OTA)
|
||||
#include <helpers/ota/OtaCli.h> // mesh::ota::handle_ota_command(line, reply, board)
|
||||
#include <helpers/esp32/WiFiOtaSeeder.h>
|
||||
#ifndef OTA_CONSOLE_TCP_PORT
|
||||
#define OTA_CONSOLE_TCP_PORT 5002
|
||||
#endif
|
||||
@@ -510,6 +534,18 @@ void halt() {
|
||||
static char ota_console_line[128];
|
||||
static uint8_t ota_console_len = 0;
|
||||
|
||||
static void ota_console_start() {
|
||||
ota_console_server.begin();
|
||||
WIFI_DEBUG_PRINTLN("OTA console listening on :%d (nc <ip> %d, type `ota ...`)",
|
||||
OTA_CONSOLE_TCP_PORT, OTA_CONSOLE_TCP_PORT);
|
||||
}
|
||||
|
||||
static void ota_console_stop() {
|
||||
if (ota_console_client) ota_console_client.stop();
|
||||
ota_console_server.end();
|
||||
ota_console_len = 0;
|
||||
}
|
||||
|
||||
static void ota_console_loop() {
|
||||
if (!ota_console_client || !ota_console_client.connected()) {
|
||||
WiFiClient c = ota_console_server.available();
|
||||
@@ -543,6 +579,107 @@ void halt() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
static void resetCompanionWiFiRecoveryState() {
|
||||
wifi_reconnect_tracker = WiFiReconnectPolicy::Tracker();
|
||||
wifi_setup_attempted = false;
|
||||
last_wifi_setup_attempt = 0;
|
||||
wifi_setup_recovery_mode = false;
|
||||
}
|
||||
|
||||
static void startCompanionWiFi() {
|
||||
if (companion_wifi_active) return;
|
||||
|
||||
board.setInhibitSleep(true);
|
||||
WiFi.setAutoReconnect(true);
|
||||
resetCompanionWiFiRecoveryState();
|
||||
|
||||
if (companion_wifi_has_credentials) {
|
||||
WiFi.mode(WIFI_STA);
|
||||
wifi_reconnect_tracker.noteDisconnected(millis());
|
||||
WiFi.begin(configured_wifi_ssid, configured_wifi_password);
|
||||
}
|
||||
#ifndef WITH_WEBCONFIG
|
||||
else if (!wifiSetupPortal().begin(COMPANION_WIFI_SETUP_AP,
|
||||
saveCompanionWiFi, nullptr)) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi setup: could not start setup portal");
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_WEBCONFIG
|
||||
if (WebConfigServer::loadEnabled(true)) {
|
||||
char web_reply[160];
|
||||
the_mesh.startWebConfig(!companion_wifi_has_credentials, web_reply);
|
||||
WIFI_DEBUG_PRINTLN("%s", web_reply);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLE_PIN_CODE)
|
||||
WiFi.setSleep(true);
|
||||
#else
|
||||
WiFi.setSleep(false);
|
||||
#endif
|
||||
wifi_interface.begin(TCP_PORT);
|
||||
wifi_interface.enable();
|
||||
#ifdef ENABLE_OTA
|
||||
ota_console_start();
|
||||
#endif
|
||||
companion_wifi_active = true;
|
||||
companion_wifi_services_stopped = false;
|
||||
WIFI_DEBUG_PRINTLN("WiFi enabled by GPIO 17 control");
|
||||
}
|
||||
|
||||
static void stopCompanionWiFiServices() {
|
||||
if (companion_wifi_services_stopped) return;
|
||||
wifi_interface.end();
|
||||
#ifdef ENABLE_OTA
|
||||
ota_console_stop();
|
||||
mesh::ota::WiFiOtaSeeder::stop();
|
||||
#endif
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
the_mesh.stopMQTT();
|
||||
#endif
|
||||
companion_wifi_services_stopped = true;
|
||||
}
|
||||
|
||||
static bool finishStoppingCompanionWiFi() {
|
||||
stopCompanionWiFiServices();
|
||||
#ifdef WITH_WEBCONFIG
|
||||
if (the_mesh.isWebConfigActiveOrStopping()) {
|
||||
the_mesh.stopWebConfig();
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
if (wifiSetupPortal().isActive()) {
|
||||
wifiSetupPortal().stop();
|
||||
return false;
|
||||
}
|
||||
if (wifiSetupPortal().isStopping()) return false;
|
||||
#endif
|
||||
|
||||
WiFi.setAutoReconnect(false);
|
||||
WiFi.disconnect(true, false);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
board.setInhibitSleep(false);
|
||||
resetCompanionWiFiRecoveryState();
|
||||
companion_wifi_active = false;
|
||||
WIFI_DEBUG_PRINTLN("WiFi radio disabled by GPIO 17 control");
|
||||
return true;
|
||||
}
|
||||
|
||||
static void serviceCompanionWiFiState() {
|
||||
if (!companion_wifi_requested && companion_wifi_active) {
|
||||
companion_wifi_disable_in_progress = true;
|
||||
}
|
||||
if (companion_wifi_disable_in_progress) {
|
||||
if (!finishStoppingCompanionWiFi()) return;
|
||||
companion_wifi_disable_in_progress = false;
|
||||
}
|
||||
if (companion_wifi_requested && !companion_wifi_active) {
|
||||
startCompanionWiFi();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
board.begin();
|
||||
@@ -644,64 +781,39 @@ void setup() {
|
||||
|
||||
// add wifi interface
|
||||
#ifdef WIFI_SSID
|
||||
board.setInhibitSleep(true); // prevent sleep when WiFi is active
|
||||
WiFi.setAutoReconnect(true);
|
||||
|
||||
WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){
|
||||
if (event == ARDUINO_EVENT_WIFI_STA_DISCONNECTED) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi disconnected; automatic recovery is active");
|
||||
if (companion_wifi_requested) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi disconnected; automatic recovery is active");
|
||||
}
|
||||
} else if (event == ARDUINO_EVENT_WIFI_STA_GOT_IP) {
|
||||
WIFI_DEBUG_PRINTLN("connected! IP %s (companion app on :%d)",
|
||||
WiFi.localIP().toString().c_str(), TCP_PORT);
|
||||
}
|
||||
});
|
||||
|
||||
bool have_wifi = WiFiSetupPortal::loadStoredCredentials(
|
||||
companion_wifi_has_credentials = WiFiSetupPortal::loadStoredCredentials(
|
||||
configured_wifi_ssid, sizeof(configured_wifi_ssid),
|
||||
configured_wifi_password, sizeof(configured_wifi_password));
|
||||
if (!have_wifi && !WiFiSetupPortal::isPlaceholderSSID(WIFI_SSID)) {
|
||||
if (!companion_wifi_has_credentials
|
||||
&& !WiFiSetupPortal::isPlaceholderSSID(WIFI_SSID)) {
|
||||
strncpy(configured_wifi_ssid, WIFI_SSID, sizeof(configured_wifi_ssid) - 1);
|
||||
configured_wifi_ssid[sizeof(configured_wifi_ssid) - 1] = '\0';
|
||||
strncpy(configured_wifi_password, WIFI_PWD, sizeof(configured_wifi_password) - 1);
|
||||
configured_wifi_password[sizeof(configured_wifi_password) - 1] = '\0';
|
||||
have_wifi = true;
|
||||
companion_wifi_has_credentials = true;
|
||||
}
|
||||
|
||||
if (have_wifi) {
|
||||
WiFi.mode(WIFI_STA);
|
||||
wifi_reconnect_tracker.noteDisconnected(millis());
|
||||
WiFi.begin(configured_wifi_ssid, configured_wifi_password);
|
||||
}
|
||||
#ifndef WITH_WEBCONFIG
|
||||
else if (!wifiSetupPortal().begin(COMPANION_WIFI_SETUP_AP, saveCompanionWiFi, nullptr)) {
|
||||
WIFI_DEBUG_PRINTLN("WiFi setup: could not start setup portal");
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_WEBCONFIG
|
||||
// WiFi companions expose the shared WebUI by default. With no stored
|
||||
// credentials it opens the captive setup AP; otherwise it waits for the
|
||||
// station connection and serves the same page on the LAN.
|
||||
if (WebConfigServer::loadEnabled(true)) {
|
||||
char web_reply[160];
|
||||
the_mesh.startWebConfig(!have_wifi, web_reply);
|
||||
WIFI_DEBUG_PRINTLN("%s", web_reply);
|
||||
}
|
||||
#endif
|
||||
// ESP-IDF requires WiFi modem sleep when Bluetooth is active. Full ESP32
|
||||
// companions provide both transports, so use the lowest sleep policy there;
|
||||
// WiFi-only companions keep modem sleep disabled to avoid pauses in SX1262
|
||||
// SPI/DIO service.
|
||||
#if defined(BLE_PIN_CODE)
|
||||
WiFi.setSleep(true);
|
||||
#else
|
||||
WiFi.setSleep(false);
|
||||
#endif
|
||||
wifi_interface.begin(TCP_PORT);
|
||||
interface_manager.addInterface(InterfaceType::WiFi, &wifi_interface);
|
||||
#ifdef ENABLE_OTA
|
||||
ota_console_server.begin(); // dedicated OTA text-console port (`nc <ip> 5002` -> `ota ...`)
|
||||
WIFI_DEBUG_PRINTLN("OTA console listening on :%d (nc <ip> %d, type `ota ...`)", OTA_CONSOLE_TCP_PORT, OTA_CONSOLE_TCP_PORT);
|
||||
#endif
|
||||
companion_wifi_requested = the_mesh.getNodePrefs()->wifi_enabled != 0;
|
||||
if (companion_wifi_requested) {
|
||||
startCompanionWiFi();
|
||||
} else {
|
||||
WiFi.setAutoReconnect(false);
|
||||
WiFi.mode(WIFI_OFF);
|
||||
board.setInhibitSleep(false);
|
||||
WIFI_DEBUG_PRINTLN("WiFi remains off from the saved GPIO 17 setting");
|
||||
}
|
||||
#endif
|
||||
|
||||
// add usb interface
|
||||
@@ -729,6 +841,9 @@ void setup() {
|
||||
#endif
|
||||
|
||||
the_mesh.startInterface(interface_manager);
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
if (!companion_wifi_requested) wifi_interface.disable();
|
||||
#endif
|
||||
sensors.begin();
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
@@ -766,11 +881,12 @@ void loop() {
|
||||
sensors.loop();
|
||||
#ifdef DISPLAY_CLASS
|
||||
#if defined(ESP32) && defined(WIFI_SSID) && defined(WITH_WEBCONFIG)
|
||||
if (the_mesh.isWebConfigSetupActive()
|
||||
if (isCompanionWiFiEnabled() && (the_mesh.isWebConfigSetupActive()
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
|| !the_mesh.isMQTTConfigured()
|
||||
#endif
|
||||
) {
|
||||
)) {
|
||||
ui_task.serviceWiFiToggleButton();
|
||||
renderCompanionSetupDisplay();
|
||||
} else {
|
||||
ui_task.loop();
|
||||
@@ -807,6 +923,8 @@ void loop() {
|
||||
#ifdef WITH_WEBCONFIG
|
||||
the_mesh.serviceWebConfig();
|
||||
#endif
|
||||
serviceCompanionWiFiState();
|
||||
if (companion_wifi_requested && companion_wifi_active) {
|
||||
#ifdef ENABLE_OTA
|
||||
ota_console_loop(); // service the OTA text console (port 5002)
|
||||
#endif
|
||||
@@ -903,5 +1021,6 @@ void loop() {
|
||||
#ifdef WITH_MQTT_BRIDGE
|
||||
the_mesh.serviceMQTT(configured_wifi_ssid, configured_wifi_password);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "UITask.h"
|
||||
#include <helpers/TxtDataHelpers.h>
|
||||
#include "../MyMesh.h"
|
||||
#include "../CompanionWiFi.h"
|
||||
#include "target.h"
|
||||
#ifdef WIFI_SSID
|
||||
#include <WiFi.h>
|
||||
@@ -234,8 +235,12 @@ public:
|
||||
display.drawTextCentered(display.width() / 2, 22, tmp);
|
||||
|
||||
#ifdef WIFI_SSID
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
if (isCompanionWiFiEnabled()) {
|
||||
IPAddress ip = WiFi.localIP();
|
||||
snprintf(tmp, sizeof(tmp), "IP: %d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||
} else {
|
||||
strcpy(tmp, "WiFi: OFF");
|
||||
}
|
||||
display.setTextSize(1);
|
||||
display.drawTextCentered(display.width() / 2, 54, tmp);
|
||||
#endif
|
||||
@@ -622,6 +627,14 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, CompanionNode
|
||||
setCurrScreen(splash);
|
||||
}
|
||||
|
||||
void UITask::serviceWiFiToggleButton() {
|
||||
#if defined(TBEAM_1W) && defined(WIFI_SSID) && defined(PIN_USER_BTN)
|
||||
if (user_btn.check() == BUTTON_EVENT_TRIPLE_CLICK) {
|
||||
handleTripleClick(KEY_SELECT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void UITask::showAlert(const char* text, int duration_millis) {
|
||||
strcpy(_alert, text);
|
||||
_alert_expiry = millis() + duration_millis;
|
||||
@@ -1000,7 +1013,13 @@ char UITask::handleDoubleClick(char c) {
|
||||
char UITask::handleTripleClick(char c) {
|
||||
MESH_DEBUG_PRINTLN("UITask: triple click triggered");
|
||||
checkDisplayOn(c);
|
||||
#if defined(TBEAM_1W) && defined(WIFI_SSID)
|
||||
const bool enabled = toggleCompanionWiFi();
|
||||
showAlert(enabled ? "WiFi: ON" : "WiFi: OFF", 1200);
|
||||
_next_refresh = 0;
|
||||
#else
|
||||
toggleBuzzer();
|
||||
#endif
|
||||
c = 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
curr = NULL;
|
||||
}
|
||||
void begin(DisplayDriver* display, SensorManager* sensors, CompanionNodePrefs* node_prefs);
|
||||
void serviceWiFiToggleButton();
|
||||
|
||||
void gotoHomeScreen() { setCurrScreen(home); }
|
||||
void showAlert(const char* text, int duration_millis);
|
||||
|
||||
@@ -321,6 +321,15 @@ bool WiFiSetupPortal::begin(const char* ap_name, SaveCallback save_callback, voi
|
||||
return true;
|
||||
}
|
||||
|
||||
void WiFiSetupPortal::stop() {
|
||||
_active = false;
|
||||
}
|
||||
|
||||
bool WiFiSetupPortal::isStopping() const {
|
||||
const PortalImpl* impl = static_cast<const PortalImpl*>(_impl);
|
||||
return impl && impl->task != nullptr;
|
||||
}
|
||||
|
||||
void WiFiSetupPortal::configureRecovery(const char* ssid, const char* password,
|
||||
uint32_t interval_ms,
|
||||
uint32_t initial_delay_ms) {
|
||||
|
||||
@@ -14,6 +14,7 @@ public:
|
||||
// Starts an open setup AP and captive HTTP form. The AP remains available
|
||||
// after a failed association and shuts down shortly after a successful one.
|
||||
bool begin(const char* ap_name, SaveCallback save_callback, void* context);
|
||||
void stop();
|
||||
// Retry interval is the steady-state cadence. initial_delay_ms defaults to
|
||||
// that interval, but callers that opened the portal partway through an
|
||||
// outage can preserve the original reconnect schedule with a shorter delay.
|
||||
@@ -21,6 +22,7 @@ public:
|
||||
uint32_t interval_ms, uint32_t initial_delay_ms = 0);
|
||||
|
||||
bool isActive() const { return _active; }
|
||||
bool isStopping() const;
|
||||
IPAddress apIP() const { return IPAddress(192, 168, 4, 1); }
|
||||
|
||||
// Companion WiFi builds keep their runtime credentials in NVS.
|
||||
|
||||
@@ -7,6 +7,15 @@ void SerialWifiInterface::begin(int port) {
|
||||
server.begin(port);
|
||||
}
|
||||
|
||||
void SerialWifiInterface::end() {
|
||||
disable();
|
||||
if (client) client.stop();
|
||||
server.end();
|
||||
deviceConnected = false;
|
||||
resetReceivedFrameHeader();
|
||||
clearBuffers();
|
||||
}
|
||||
|
||||
// ---------- public methods
|
||||
void SerialWifiInterface::enable() {
|
||||
if (_isEnabled) return;
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
}
|
||||
|
||||
void begin(int port);
|
||||
void end();
|
||||
|
||||
// BaseSerialInterface methods
|
||||
void enable() override;
|
||||
|
||||
@@ -65,6 +65,21 @@ TEST(CompanionNodePrefs, DevicePowerSavingIsIndependentFromRxps) {
|
||||
EXPECT_EQ(1, prefs.powersaving_enabled);
|
||||
}
|
||||
|
||||
TEST(CompanionNodePrefs, WiFiStateIsIndependentFromPowerSaving) {
|
||||
CompanionNodePrefs prefs = {};
|
||||
prefs.wifi_enabled = 1;
|
||||
prefs.powersaving_enabled = 0;
|
||||
|
||||
EXPECT_EQ(1, prefs.wifi_enabled);
|
||||
EXPECT_EQ(0, prefs.powersaving_enabled);
|
||||
|
||||
prefs.wifi_enabled = 0;
|
||||
prefs.powersaving_enabled = 1;
|
||||
|
||||
EXPECT_EQ(0, prefs.wifi_enabled);
|
||||
EXPECT_EQ(1, prefs.powersaving_enabled);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Re-enable test once we can SET fem_ values in companion
|
||||
TEST(CompanionNodePrefs, RxGainSettingsRoundTripIndependently) {
|
||||
|
||||
Reference in new issue
Block a user