t5s3 wifi companion

This commit is contained in:
pelgraine
2026-03-12 17:34:22 +11:00
parent 182231deeb
commit 74b24f1222
5 changed files with 105 additions and 2 deletions
+4
View File
@@ -537,7 +537,11 @@ MyMesh the_mesh(radio_driver, fast_rng, rtc_clock, tables, store
if (row == 0 && col == 2) { ui_task.gotoSettingsScreen(); return 0; }
if (row == 1 && col == 0) { ui_task.gotoTextReader(); return 0; }
if (row == 1 && col == 1) { ui_task.gotoNotesScreen(); return 0; }
#ifdef MECK_WEB_READER
if (row == 1 && col == 2) { ui_task.gotoWebReader(); return 0; }
#else
if (row == 1 && col == 2) { ui_task.gotoDiscoveryScreen(); return 0; }
#endif
}
// Tap outside tiles — left half backward, right half forward
return (vx < 64) ? (char)KEY_PREV : (char)KEY_NEXT;
@@ -173,6 +173,9 @@ private:
char _wifiPassBuf[64];
int _wifiPassLen;
unsigned long _wifiFormLastChar; // For brief password reveal
#if defined(LilyGo_T5S3_EPaper_Pro)
bool _wifiNeedsVKB; // T5S3: signal UITask to open VKB for password
#endif
#endif
// ---------------------------------------------------------------------------
@@ -447,6 +450,9 @@ public:
_wifiPassLen = 0;
memset(_wifiPassBuf, 0, sizeof(_wifiPassBuf));
_wifiFormLastChar = 0;
#if defined(LilyGo_T5S3_EPaper_Pro)
_wifiNeedsVKB = false;
#endif
#endif
rebuildRows();
}
@@ -519,6 +525,60 @@ public:
digitalWrite(SDCARD_CS, HIGH);
}
}
#if defined(LilyGo_T5S3_EPaper_Pro)
// T5S3 VKB integration — UITask polls this to open the virtual keyboard
// when settings enters WiFi password phase (no physical keyboard available).
bool needsWifiVKB() const { return _wifiNeedsVKB; }
void clearWifiNeedsVKB() { _wifiNeedsVKB = false; }
// Called by UITask::onVKBSubmit with the password text from VKB.
// Fills the password buffer and triggers the WiFi connect sequence.
void submitWifiPassword(const char* pass) {
_wifiNeedsVKB = false;
int len = strlen(pass);
if (len > 63) len = 63;
memcpy(_wifiPassBuf, pass, len);
_wifiPassBuf[len] = '\0';
_wifiPassLen = len;
// Trigger the same connect sequence as pressing Enter in password phase
_wifiPhase = WIFI_PHASE_CONNECTING;
// Save credentials to SD (so web reader can reuse them)
if (SD.exists("/web") || SD.mkdir("/web")) {
File f = SD.open("/web/wifi.cfg", FILE_WRITE);
if (f) {
f.println(_wifiSSIDs[_wifiSSIDSelected]);
f.println(_wifiPassBuf);
f.close();
}
digitalWrite(SDCARD_CS, HIGH);
}
WiFi.disconnect(false);
WiFi.begin(_wifiSSIDs[_wifiSSIDSelected].c_str(), _wifiPassBuf);
// Brief blocking wait — fine for e-ink
unsigned long timeout = millis() + 8000;
while (WiFi.status() != WL_CONNECTED && millis() < timeout) {
delay(100);
}
if (WiFi.status() == WL_CONNECTED) {
Serial.printf("Settings VKB: WiFi connected to %s, IP: %s\n",
_wifiSSIDs[_wifiSSIDSelected].c_str(),
WiFi.localIP().toString().c_str());
_editMode = EDIT_NONE;
_wifiPhase = WIFI_PHASE_IDLE;
if (_onboarding) _onboarding = false;
} else {
Serial.println("Settings VKB: WiFi connection failed");
_wifiPhase = WIFI_PHASE_SELECT; // Back to SSID list to retry
}
}
#endif
#endif
// ---------------------------------------------------------------------------
@@ -955,7 +1015,11 @@ public:
bool sel = (wi == _wifiSSIDSelected);
if (sel) {
display.setColor(DisplayDriver::LIGHT);
#if defined(LilyGo_T5S3_EPaper_Pro)
display.fillRect(bx + 2, wy, bw - 4, 8);
#else
display.fillRect(bx + 2, wy + 5, bw - 4, 8);
#endif
display.setColor(DisplayDriver::DARK);
} else {
display.setColor(DisplayDriver::LIGHT);
@@ -1136,6 +1200,9 @@ public:
_wifiPassLen = 0;
memset(_wifiPassBuf, 0, sizeof(_wifiPassBuf));
_wifiFormLastChar = 0;
#if defined(LilyGo_T5S3_EPaper_Pro)
_wifiNeedsVKB = true; // Signal UITask to open virtual keyboard
#endif
return true;
}
if (c == 'q' || c == 'Q') {
@@ -377,7 +377,11 @@ public:
struct Tile { const uint8_t* icon; const char* label; };
const Tile tiles[2][3] = {
{ {icon_envelope, "Messages"}, {icon_people, "Contacts"}, {icon_gear, "Settings"} },
#ifdef MECK_WEB_READER
{ {icon_book, "Reader"}, {icon_notepad, "Notes"}, {icon_search, "Browser"} }
#else
{ {icon_book, "Reader"}, {icon_notepad, "Notes"}, {icon_search, "Discover"} }
#endif
};
const int tileW = 40;
@@ -1527,6 +1531,18 @@ if (curr) curr->poll();
}
} else {
int delay_millis = curr->render(*_display);
// Check if settings screen needs VKB for WiFi password entry
#ifdef MECK_WIFI_COMPANION
if (isOnSettingsScreen() && !_vkbActive) {
SettingsScreen* ss = (SettingsScreen*)settings_screen;
if (ss->needsWifiVKB()) {
ss->clearWifiNeedsVKB();
showVirtualKeyboard(VKB_WIFI_PASSWORD, "WiFi Password", "", 63);
}
}
#endif
if (millis() < _alert_expiry) {
_display->setTextSize(1);
int y = _display->height() / 3;
@@ -1785,6 +1801,19 @@ void UITask::onVKBSubmit() {
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
break;
}
#ifdef MECK_WIFI_COMPANION
case VKB_WIFI_PASSWORD: {
SettingsScreen* ss = (SettingsScreen*)settings_screen;
ss->submitWifiPassword(text);
if (WiFi.status() == WL_CONNECTED) {
showAlert("WiFi connected!", 2000);
} else {
showAlert("WiFi failed", 2000);
}
if (_screenBeforeVKB) setCurrScreen(_screenBeforeVKB);
break;
}
#endif
}
_screenBeforeVKB = nullptr;
_next_refresh = 0;
@@ -28,7 +28,8 @@ enum VKBPurpose {
VKB_ADMIN_PASSWORD, // Repeater admin login
VKB_ADMIN_CLI, // Repeater admin CLI command
VKB_NOTES, // Insert text into notes
VKB_SETTINGS_NAME // Edit node name
VKB_SETTINGS_NAME, // Edit node name
VKB_WIFI_PASSWORD // WiFi password entry (settings screen)
};
class VirtualKeyboard {
@@ -124,8 +124,9 @@ lib_deps =
https://github.com/lewisxhe/SensorLib/archive/refs/tags/v0.3.4.zip
; ---------------------------------------------------------------------------
; T5S3 WiFi companion — touch UI, WiFi phone bridging
; T5S3 WiFi companion — touch UI, WiFi phone bridging, web browser
; Connect via MeshCore web app or meshcore.js over local network (TCP:5000)
; MECK_WEB_READER: shares WiFi companion connection — no extra setup needed
; Flash: pio run -e meck_t5s3_wifi -t upload
; ---------------------------------------------------------------------------
[env:meck_t5s3_wifi]
@@ -136,6 +137,7 @@ build_flags =
-D MAX_CONTACTS=1500
-D MAX_GROUP_CHANNELS=20
-D MECK_WIFI_COMPANION=1
-D MECK_WEB_READER=1
-D TCP_PORT=5000
-D OFFLINE_QUEUE_SIZE=256
-D DISPLAY_CLASS=FastEPDDisplay