#pragma once #include #include #include "Config.h" #include "ScreenState.h" #include "DisplayManager.h" #include "NetManager.h" class DoorbellLogic { public: explicit DoorbellLogic(DisplayManager* display); /// Call from setup(). Pass board-specific WiFi creds. void begin(const char* version, const char* boardName, const WiFiCred* creds, int credCount); /// Call from loop() — polls topics, runs timers, transitions state. void update(); /// Transition out of BOOTED → SILENT. Call at end of setup(). void finishBoot(); /// Serial debug console. void onSerialCommand(const String& cmd); const ScreenState& getScreenState() const { return _state; } /// Externally trigger silence (e.g. hold-to-silence gesture). void silenceAlert(); private: void pollTopics(); void pollTopic(const String& url, const char* label); void onAlert(const String& title, const String& body); void onSilence(); void onAdmin(const String& command); void flushStatus(const String& message); void heartbeat(); void transition(DeviceState s); String topicUrl(const char* base); DisplayManager* _display; NetManager _net; ScreenState _state; const char* _version = ""; const char* _board = ""; bool _debug = false; uint32_t _lastPollMs = 0; uint32_t _lastHeartbeatMs = 0; uint32_t _bootGraceEnd = 0; String _alertUrl; String _silenceUrl; String _adminUrl; String _statusUrl; };