/* * KLUBHAUS ALERT v5.1 — E32R35T Edition * * Target: LCDWiki E32R35T (ESP32-WROOM-32E + 3.5" ST7796S + XPT2046) * * Hold-and-release interaction model: * - Hold finger → progress bar fills * - Bar full → jitter/flash ("RELEASE!") * - Lift finger → action fires (finger already off screen) */ #include #include "Config.h" #include "DisplayManager.h" #include "DoorbellLogic.h" #include #ifndef LOAD_GLCD #error "LOAD_GLCD is NOT defined — fonts missing!" #endif #ifndef ST7796_DRIVER #error "ST7796_DRIVER is NOT defined — wrong setup!" #endif #define HOLD_TO_SILENCE_MS 1000 DoorbellLogic logic; DisplayManager display; void setup() { Serial.begin(115200); unsigned long t = millis(); while (!Serial && millis() - t < 3000) delay(10); delay(500); Serial.println("\n========================================"); Serial.println(" KLUBHAUS ALERT v5.1 — E32R35T"); #if DEBUG_MODE Serial.println(" *** DEBUG MODE — _test topics ***"); #endif Serial.println("========================================"); display.begin(); logic.begin(); display.render(logic.getScreenState()); delay(1500); logic.beginWiFi(); display.render(logic.getScreenState()); logic.connectWiFiBlocking(); display.render(logic.getScreenState()); delay(1500); logic.finishBoot(); display.setBacklight(false); Serial.println("[BOOT] Ready — monitoring ntfy.sh\n"); } void loop() { logic.update(); const ScreenState& state = logic.getScreenState(); // ---- Touch handling varies by screen ---- if (state.screen == ScreenID::ALERT) { // Hold-and-release to silence HoldState hold = display.updateHold(HOLD_TO_SILENCE_MS); if (hold.completed) { // Finger lifted after full charge → silence now // Small delay so user sees the clean transition delay(80); logic.onTouch(TouchEvent{true, hold.x, hold.y}); } // charged/filling states are rendered by drawSilenceProgress() // cancelled = finger lifted early, no action needed } else if (state.screen == ScreenID::DASHBOARD) { TouchEvent evt = display.readTouch(); if (evt.pressed) { int tile = display.dashboardTouch(evt.x, evt.y); if (tile >= 0) { Serial.printf("[DASH] Tile %d tapped\n", tile); // Tile-specific actions go here } else { logic.onTouch(evt); } delay(300); // debounce } } else if (state.screen == ScreenID::OFF) { // Any touch wakes TouchEvent evt = display.readTouch(); if (evt.pressed) { logic.onTouch(evt); delay(300); } } else { // Boot/WiFi screens: simple touch passthrough TouchEvent evt = display.readTouch(); if (evt.pressed) { logic.onTouch(evt); delay(300); } } // ---- Render ---- display.setBacklight(state.screen != ScreenID::OFF); display.render(logic.getScreenState()); // ---- Serial commands ---- if (Serial.available()) { String cmd = Serial.readStringUntil('\n'); cmd.trim(); if (cmd.length() > 0) logic.onSerialCommand(cmd); } }