diff --git a/CHANGELOG.md b/CHANGELOG.md index 803669c..9d69285 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file. - Added Arduino Log Colors - Possibility to add a loop callback to ESP32-Sveltekit to leverage its loop threat. Meant to include custom services so no separate task is needed for them. - Change wake-up pin in SleepService during runtime. It is also possible to use the internal pull-up or pull-down resistors now. +- Get current connection status from ESP32-SvelteKit. Useful for status LED or displays. ### Changed diff --git a/docs/statefulservice.md b/docs/statefulservice.md index 1e6a374..2482fad 100644 --- a/docs/statefulservice.md +++ b/docs/statefulservice.md @@ -550,9 +550,28 @@ esp32sveltekit.getBatteryService()->updateSOC(float stateOfCharge); // update st esp32sveltekit.getBatteryService()->setCharging(boolean isCharging); // notify the client that the device is charging ``` +### ESP32-SvelteKit Connection Status + +Especially for a cases like a colored status LED it can be useful to have a quick indication of the connection status. By calling: + +```cpp +ConnectionStatus status = esp32sveltekit.getConnectionStatus(); +``` + +the current connection status can be accessed. The following stats are available: + +| Status | Description | +| ------------- | ------------------------------------------------------------------------------- | +| OFFLINE | Device is completely offline | +| AP | Access Point is available, but no client is connected | +| AP_CONNECTED | Access Point is used and at least 1 client is connected | +| STA | Device connected to a WiFi Station | +| STA_CONNECTED | Device connected to a WiFi Station and at least 1 client is connected | +| STA_MQTT | Device connected to a WiFi Station and the device is connected to a MQTT server | + ### Custom Features -You may use the compile time feature service also to enable or disable custom features at runtime and thus control the frontend. A custom feature can only be added during initializing the ESP32 and ESP32-SvelteKit. A feature can't be updated on runtime once it is set. +You may use the compile time feature service also to enable or disable custom features at runtime and thus control the frontend. A custom feature can only be added during initializing the ESP32 and ESP32-SvelteKit. The frontend queries the features only when first loading the page. Thus the frontend must be refreshed for the changes to become effective. ```cpp esp32sveltekit.getFeatureService()->addFeature("custom_feature", true); // or false to disable it diff --git a/factory_settings.ini b/factory_settings.ini index af67974..7189d61 100644 --- a/factory_settings.ini +++ b/factory_settings.ini @@ -48,7 +48,7 @@ build_flags = -D FACTORY_JWT_SECRET=\"#{random}-#{random}\" ; supports placeholders ; Deep Sleep Configuration - -D WAKEUP_PIN_NUMBER=38 ; pin number to wake up the ESP + -D WAKEUP_PIN_NUMBER=0 ; pin number to wake up the ESP -D WAKEUP_SIGNAL=0 ; 1 for wakeup on HIGH, 0 for wakeup on LOW diff --git a/features.ini b/features.ini index 782d9b8..049068a 100644 --- a/features.ini +++ b/features.ini @@ -5,6 +5,6 @@ build_flags = -D FT_NTP=1 -D FT_UPLOAD_FIRMWARE=1 -D FT_DOWNLOAD_FIRMWARE=1 ; requires FT_NTP=1 - -D FT_SLEEP=0 + -D FT_SLEEP=1 -D FT_BATTERY=0 -D FT_ANALYTICS=1 diff --git a/lib/framework/APStatus.cpp b/lib/framework/APStatus.cpp index cb8b70a..45c4e1f 100644 --- a/lib/framework/APStatus.cpp +++ b/lib/framework/APStatus.cpp @@ -43,3 +43,8 @@ esp_err_t APStatus::apStatus(PsychicRequest *request) return response.send(); } + +bool APStatus::isActive() +{ + return _apSettingsService->getAPNetworkStatus() == APNetworkStatus::ACTIVE ? true : false; +} diff --git a/lib/framework/APStatus.h b/lib/framework/APStatus.h index 25b62f7..83c36c9 100644 --- a/lib/framework/APStatus.h +++ b/lib/framework/APStatus.h @@ -32,6 +32,8 @@ class APStatus void begin(); + bool isActive(); + private: PsychicHttpServer *_server; SecurityManager *_securityManager; diff --git a/lib/framework/ESP32SvelteKit.cpp b/lib/framework/ESP32SvelteKit.cpp index 055d162..0c826e0 100644 --- a/lib/framework/ESP32SvelteKit.cpp +++ b/lib/framework/ESP32SvelteKit.cpp @@ -191,6 +191,11 @@ void ESP32SvelteKit::begin() void ESP32SvelteKit::_loop() { + bool wifi = false; + bool ap = false; + bool event = false; + bool mqtt = false; + while (1) { _wifiSettingsService.loop(); // 30 seconds @@ -198,6 +203,32 @@ void ESP32SvelteKit::_loop() #if FT_ENABLED(FT_MQTT) _mqttSettingsService.loop(); // 5 seconds #endif + // Query the connectivity status + wifi = _wifiStatus.isConnected(); + ap = _apStatus.isActive(); + event = _socket.getConnectedClients() > 0; +#if FT_ENABLED(FT_MQTT) + mqtt = _mqttStatus.isConnected(); +#endif + + // Update the system status + if (wifi && mqtt) + { + _connectionStatus = ConnectionStatus::STA_MQTT; + } + else if (wifi) + { + _connectionStatus = event ? ConnectionStatus::STA_CONNECTED : ConnectionStatus::STA; + } + else if (ap) + { + _connectionStatus = event ? ConnectionStatus::AP_CONNECTED : ConnectionStatus::AP; + } + else + { + _connectionStatus = ConnectionStatus::OFFLINE; + } + // iterate over all loop functions for (auto &function : _loopFunctions) { diff --git a/lib/framework/ESP32SvelteKit.h b/lib/framework/ESP32SvelteKit.h index 7d8d6d8..e3d8fae 100644 --- a/lib/framework/ESP32SvelteKit.h +++ b/lib/framework/ESP32SvelteKit.h @@ -68,6 +68,17 @@ // define callback function to include into the main loop typedef std::function loopCallback; +// enum for connection status +enum class ConnectionStatus +{ + OFFLINE, + AP, + AP_CONNECTED, + STA, + STA_CONNECTED, + STA_MQTT +}; + class ESP32SvelteKit { public: @@ -75,6 +86,11 @@ class ESP32SvelteKit void begin(); + ConnectionStatus getConnectionStatus() + { + return _connectionStatus; + } + FS *getFS() { return &ESPFS; @@ -224,6 +240,9 @@ class ESP32SvelteKit void _loop(); std::vector _loopFunctions; + + // Connectivity status + ConnectionStatus _connectionStatus = ConnectionStatus::OFFLINE; }; #endif diff --git a/lib/framework/EventSocket.cpp b/lib/framework/EventSocket.cpp index 286e972..0c92d30 100644 --- a/lib/framework/EventSocket.cpp +++ b/lib/framework/EventSocket.cpp @@ -25,7 +25,7 @@ void EventSocket::registerEvent(String event) { if (!isEventValid(event)) { - ESP_LOGV("EventSocket", "Registering event: %s", event.c_str()); + ESP_LOGD("EventSocket", "Registering event: %s", event.c_str()); events.push_back(event); } else @@ -224,3 +224,8 @@ bool EventSocket::isEventValid(String event) { return std::find(events.begin(), events.end(), event) != events.end(); } + +unsigned int EventSocket::getConnectedClients() +{ + return (unsigned int)_socket.getClientList().size(); +} diff --git a/lib/framework/EventSocket.h b/lib/framework/EventSocket.h index d10f66d..5ac1364 100644 --- a/lib/framework/EventSocket.h +++ b/lib/framework/EventSocket.h @@ -43,6 +43,8 @@ class EventSocket void emitEvent(String event, JsonObject &jsonObject, const char *originId = "", bool onlyToSameOrigin = false); // if onlyToSameOrigin == true, the message will be sent to the originId only, otherwise it will be broadcasted to all clients except the originId + unsigned int getConnectedClients(); + private: PsychicHttpServer *_server; PsychicWebSocketHandler _socket; diff --git a/lib/framework/MqttStatus.cpp b/lib/framework/MqttStatus.cpp index 85235d6..aee7f0b 100644 --- a/lib/framework/MqttStatus.cpp +++ b/lib/framework/MqttStatus.cpp @@ -44,3 +44,8 @@ esp_err_t MqttStatus::mqttStatus(PsychicRequest *request) return response.send(); } + +bool MqttStatus::isConnected() +{ + return _mqttSettingsService->isConnected(); +} diff --git a/lib/framework/MqttStatus.h b/lib/framework/MqttStatus.h index 364b100..bde096b 100644 --- a/lib/framework/MqttStatus.h +++ b/lib/framework/MqttStatus.h @@ -31,6 +31,8 @@ class MqttStatus void begin(); + bool isConnected(); + private: PsychicHttpServer *_server; SecurityManager *_securityManager; diff --git a/lib/framework/SleepService.cpp b/lib/framework/SleepService.cpp index 769675c..48426a1 100644 --- a/lib/framework/SleepService.cpp +++ b/lib/framework/SleepService.cpp @@ -86,11 +86,13 @@ void SleepService::sleepNow() { case pinTermination::PULL_UP: esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + rtc_gpio_init((gpio_num_t)_wakeUpPin); rtc_gpio_pullup_dis((gpio_num_t)_wakeUpPin); rtc_gpio_pulldown_en((gpio_num_t)_wakeUpPin); break; case pinTermination::PULL_DOWN: esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + rtc_gpio_init((gpio_num_t)_wakeUpPin); rtc_gpio_pullup_en((gpio_num_t)_wakeUpPin); rtc_gpio_pulldown_dis((gpio_num_t)_wakeUpPin); break; @@ -103,13 +105,11 @@ void SleepService::sleepNow() Serial.println("Good by!"); #endif - xTaskCreate( - [](void *pvParams) - { - delay(200); - esp_deep_sleep_start(); - }, - "Sleep task", 4096, nullptr, 10, nullptr); + // Just to be sure + delay(100); + + // Hibernate + esp_deep_sleep_start(); } void SleepService::setWakeUpPin(int pin, bool level, pinTermination termination) diff --git a/lib/framework/WiFiStatus.cpp b/lib/framework/WiFiStatus.cpp index 4134862..12c01bc 100644 --- a/lib/framework/WiFiStatus.cpp +++ b/lib/framework/WiFiStatus.cpp @@ -91,3 +91,8 @@ esp_err_t WiFiStatus::wifiStatus(PsychicRequest *request) return response.send(); } + +bool WiFiStatus::isConnected() +{ + return WiFi.status() == WL_CONNECTED; +} diff --git a/lib/framework/WiFiStatus.h b/lib/framework/WiFiStatus.h index e7c03ba..3e27e7d 100644 --- a/lib/framework/WiFiStatus.h +++ b/lib/framework/WiFiStatus.h @@ -31,6 +31,8 @@ class WiFiStatus void begin(); + bool isConnected(); + private: PsychicHttpServer *_server; SecurityManager *_securityManager; diff --git a/platformio.ini b/platformio.ini index f6c25bc..b8778b6 100644 --- a/platformio.ini +++ b/platformio.ini @@ -109,3 +109,12 @@ build_flags = ${env.build_flags} -D LED_BUILTIN=2 -D KEY_BUILTIN=0 + +[env:adafruit_feather_esp32s3_nopsram] +board = adafruit_feather_esp32s3_nopsram +board_build.partitions = default_8MB.csv +board_upload.before_reset = usb_reset +build_flags = + ${env.build_flags} + -DARDUINO_USB_CDC_ON_BOOT=1 + -DARDUINO_USB_MODE=1 \ No newline at end of file