esp_garden git · master
Distributed ESP sensor and actuator system (garden)
C++ 70.7% Markdown 18% C 10.7%git clone https://git.christianimmanuel.de/embedded/esp_garden.gitwget https://git.christianimmanuel.de/embedded/esp_garden/archive/esp_garden.tar.gzCleanup New Server header file
server/Server.cpp | 316 ++++++++++++++++++++++++++++++++++++++++++++++++++ server/Server.h | 57 +++++++++ server/server.ino | 340 +++--------------------------------------------------- 3 files changed, 389 insertions(+), 324 deletions(-) diff --git a/server/Server.cpp b/server/Server.cpp new file mode 100644 index 0000000..fcdf6f3 --- /dev/null +++ b/server/Server.cpp @@ -0,0 +1,316 @@ +#include "Server.h" +#include "secrets.h" +#include "WiFiManager.h" + +#include <esp_now.h> + + +uint8_t received_from_mac_addr[6]; + + +// ---------------------------------------------------------------------------- +// Helper +// ---------------------------------------------------------------------------- + +void print_SensorConfigServer(const SensorConfigServer_s& cfg) { + DBG_PRINTLN("----------------------------"); + DBG_PRINTF("Got cfg for moisture_1:\n"); + DBG_PRINTF("Pin: %d\n", cfg.pin); + DBG_PRINTF("Use Time: %d\n", cfg.use_time); + DBG_PRINTF("Delay: %d\n", cfg.delay_ms); + DBG_PRINTF("Notification MAC: %s\n", cfg.pump_mac); + DBG_PRINTF("Notification Name: %s\n", cfg.notification_name); + DBG_PRINTF("Min Moisture: %d\n", cfg.min_moisture); + DBG_PRINTF("Active: %d\n", cfg.is_active); + DBG_PRINTF("Pumping Delay: %d\n", cfg.pumping_delay_sec); + DBG_PRINTF("Pumping Duration: %d\n", cfg.pumping_duration); + + for (uint8_t i = 0; i < cfg.time_count; i++) { + uint16_t minutes = cfg.times[i]; + uint8_t hh = minutes / 60; + uint8_t mm = minutes % 60; + DBG_PRINTF("Time[%d]: %02u:%02u (%u min)\n", i, hh, mm, minutes); + } + DBG_PRINTLN("----------------------------"); +} + +// ---------------------------------------------------------------------------- +// Server handling (g_buffer) + // ---------------------------------------------------------------------------- + +void add_ReadingCallback(const char* table, const char* value, const int64_t time) { + if (g_buffer_count >= BUFFER_SIZE) { + for (int i = 1; i < g_buffer_count; i++) g_buffer[i-1] = g_buffer[i]; + g_buffer_count--; + } + strncpy(g_buffer[g_buffer_count].table, table, TABLE_SIZE-1); + g_buffer[g_buffer_count].table[TABLE_SIZE-1] = '\0'; + strncpy(g_buffer[g_buffer_count].value, value, VALUE_SIZE-1); + g_buffer[g_buffer_count].time = time; + g_buffer_count++; +} + +void init_Server() { + WIFI_OnAddReading = add_ReadingCallback; +} + +// ---------------------------------------------------------------------------- +// WiFi handling +// ---------------------------------------------------------------------------- + +void init_WiFi() { + WiFi.mode(WIFI_MODE_APSTA); + WiFi.begin(ssid, password); + + DBG_PRINTF("Connecting to %s .", ssid); + while (WiFi.status() != WL_CONNECTED) { DBG_PRINT("."); delay(200); } + DBG_PRINTLN(" ok"); + + IPAddress ip = WiFi.localIP(); + + DBG_PRINTF("SSID: %s\n", ssid); + DBG_PRINTF("Channel: %u\n", WiFi.channel()); + DBG_PRINTF("IP: %u.%u.%u.%u\n", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, ip >> 24); +} + +// ---------------------------------------------------------------------------- +// ESP-NOW helpers (add peer + send callback) +// ---------------------------------------------------------------------------- + +void on_DataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) { + if (!info) return; + + DBG_PRINT("Delivery to "); + for (int i = 0; i < 6; i++) { + DBG_PRINTF("%02X", info->des_addr[i]); + if (i < 5) DBG_PRINT(":"); + } + DBG_PRINT(" -> "); + DBG_PRINTLN(status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL"); +} + +void add_Peer(const uint8_t* addr) { + if (esp_now_is_peer_exist(addr)) return; + + esp_now_peer_info_t peer{}; + memcpy(peer.peer_addr, addr, 6); + peer.ifidx = WIFI_IF_STA; // server is in APSTA mode but acts as STA on same SSID + peer.channel = (uint8_t)WiFi.channel(); // ensure same channel + peer.encrypt = false; + + esp_err_t res = esp_now_add_peer(&peer); + if (res != ESP_OK) { + DBG_PRINT("Failed to add peer: "); + for (int i=0; i<6; i++) { + DBG_PRINTF("%02X", addr[i]); + if (i<5) DBG_PRINT(":"); + } + DBG_PRINTF(" -> error code %d\n", res); + } else { + DBG_PRINT("Added peer: "); + for (int i=0; i<6; i++) { + DBG_PRINTF("%02X", addr[i]); + if (i<5) DBG_PRINT(":"); + } + DBG_PRINTLN(""); + } +} + +// ---------------------------------------------------------------------------- +// ESP-NOW receive callback +// ---------------------------------------------------------------------------- + +void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) { + if (!info || !data || len <= 0) return; + memcpy(received_from_mac_addr, info->src_addr, 6); + add_Peer(received_from_mac_addr); + + char msg[128]; + int copylen = len < (int)sizeof(msg)-1 ? len : (int)sizeof(msg)-1; + memcpy(msg, data, copylen); + msg[copylen] = '\0'; + + DBG_PRINTF("Received from %02X:%02X:%02X:%02X:%02X:%02X: %s\n", + received_from_mac_addr[0], received_from_mac_addr[1], received_from_mac_addr[2], + received_from_mac_addr[3], received_from_mac_addr[4], received_from_mac_addr[5], msg); + + if (strcmp(msg, "time?") == 0) { + char time_msg[32]; + snprintf(time_msg, sizeof(time_msg), "time:%lld", now()); + esp_now_send(received_from_mac_addr, (uint8_t*)time_msg, strlen(time_msg)); + return; + } + + // Queue config request instead of calling HTTP directly + if (strncmp(msg, "next_read:", 10) == 0) { + + const char* value_str = msg + 10; + next_connection_unix = atoll(value_str); + go_to_sleep = true; + DBG_PRINTF("Received next_read: %lld\n", next_connection_unix); + return; + + } else if (strncmp(msg, "get_config:", 11) == 0 && !pending_config.active) { + + pending_config.active = true; + memcpy(pending_config.mac, received_from_mac_addr, 6); + strncpy(pending_config.sensor_name, msg + 11, sizeof(pending_config.sensor_name) - 1); + pending_config.sensor_name[sizeof(pending_config.sensor_name) - 1] = '\0'; + DBG_PRINTF("Queued config request for %s\n", pending_config.sensor_name); + return; + } + + // --- Normal table:value:time handling --- + DBG_PRINTLN("Message:"); + DBG_PRINTF(" %s\n", msg); + g_received_ok_from_server = false; + + char *first = strchr(msg, ':'); + char *second = first ? strchr(first + 1, ':') : NULL; + + if (first && second) { + *first = '\0'; + *second = '\0'; + + const char *sensor_name = msg; + const char *value_str = first + 1; + const int64_t time = atoll(second + 1); + + add_ReadingCallback(sensor_name, value_str, time); + } else { + DBG_PRINTLN("Invalid message format (expected <name>:<value>:<time>)"); + } + + /* + * Replying to Sensor happens in main loop + */ +} + + +// ---------------------------------------------------------------------------- +// Init ESP-NOW +// ---------------------------------------------------------------------------- + +void init_EspNow() { + if (esp_now_init() != ESP_OK) { + DBG_PRINTLN("ESP-NOW failed to initialize"); + while (true); + } + + esp_now_register_recv_cb(on_DataRecv); + esp_now_register_send_cb(on_DataSent); +} + +// ---------------------------------------------------------------------------- +// Config handling +// ---------------------------------------------------------------------------- + +void get_PendingConfigFromServer() { + pending_config.active = false; + SensorConfigServer_s cfg_response; + + if (WIFI_GetSensorConfigServer(pending_config.sensor_name, cfg_response)) { + char response[250]; + int len_out = snprintf(response, sizeof(response), + "cfg:%s,%d,%d,%d,%s,%d,%d,%s,%d,%d", + cfg_response.sensor_name, + cfg_response.is_active, + cfg_response.pin, + cfg_response.min_moisture, + cfg_response.notification_name, + cfg_response.pumping_delay_sec, + cfg_response.pumping_duration, + cfg_response.pump_mac, + cfg_response.delay_ms, + cfg_response.use_time); + + if (cfg_response.time_count > 0) { + strncat(response, ",times=", sizeof(response)-strlen(response)-1); + for (uint8_t i = 0; i < cfg_response.time_count; i++) { + char buf[8]; + snprintf(buf, sizeof(buf), "%u", cfg_response.times[i]); + strncat(response, buf, sizeof(response)-strlen(response)-1); + if (i < cfg_response.time_count - 1) + strncat(response, "|", sizeof(response)-strlen(response)-1); + } + } + + esp_now_send(pending_config.mac, (uint8_t*)response, strlen(response)); + DBG_PRINTF("Sent config for %s\n", cfg_response.sensor_name); + DBG_PRINTF("Sending: %s\n", response); + } else { + const char* err = "cfg_error:fetch_failed"; + esp_now_send(pending_config.mac, (uint8_t*)err, strlen(err)); + DBG_PRINTLN("Config fetch failed"); + } +} + +void send_ConfigToEsp() { + DBG_PRINTLN("Preparing time + configs message"); + char msg[256]; + size_t offset = 0; + + time_t now_t; + time(&now_t); + offset += snprintf(msg + offset, sizeof(msg) - offset, "time:%lu", (unsigned long)now_t); + + // add configs if available + if (g_pending_sensor_configs_count > 0) { + DBG_PRINTLN("Appending pending configs..."); + for (size_t i = 0; i < g_pending_sensor_configs_count; i++) { + DBG_PRINTF(" adding config: %s\n", g_pending_sensor_configs[i]); + offset += snprintf(msg + offset, sizeof(msg) - offset, ",cfg:%s", g_pending_sensor_configs[i]); + if (offset >= sizeof(msg)) break; + } + g_pending_sensor_configs_count = 0; + } + + DBG_PRINTLN("Sending combined message:"); + DBG_PRINTLN(msg); + + esp_err_t result = esp_now_send(received_from_mac_addr, (uint8_t*)msg, strlen(msg)); + if (result == ESP_OK) + DBG_PRINTLN("Send queued successfully."); + else + DBG_PRINTF("Send failed: %d\n", result); + + g_received_ok_from_server = false; +} + + +// ---------------------------------------------------------------------------- +// Sleep +// ---------------------------------------------------------------------------- + +void sleep_UntilNextReceive() { + go_to_sleep = false; + uint32_t min_delay_ms = (next_connection_unix - now())*1000; + + int64_t unix_now = now(); + if (next_connection_unix < unix_now) return; + + DBG_PRINTF("Nex: %lld\nNow: %lld\n", next_connection_unix, unix_now); + + next_connection_unix = 0; + + // Prevent sleeping if next send is within g_min_sleep_time + if (min_delay_ms < g_min_sleep_time) { + DBG_PRINTF("Delaying for %u ms (no deep sleep)\n", min_delay_ms); + DBG_PRINTF("######################\n\n"); + delay(min_delay_ms); + } else { + uint32_t prep_time_ms = g_setup_duration + g_wakeup_earlier_server; + uint32_t sleep_time_ms = (min_delay_ms > prep_time_ms) + ? (min_delay_ms - prep_time_ms) + : 0; + + + DBG_PRINTF("Sleeping for %u ms (setup margin: %u ms)\n", + sleep_time_ms, prep_time_ms); + DBG_PRINTF("######################\n\n"); + + esp_sleep_enable_timer_wakeup((uint64_t)sleep_time_ms * 1000ULL); + esp_deep_sleep_start(); + } + +} diff --git a/server/Server.h b/server/Server.h new file mode 100644 index 0000000..a17c1be --- /dev/null +++ b/server/Server.h @@ -0,0 +1,57 @@ +#ifndef SERVER_H +#define SERVER_H + +#include "globals.h" + +#include <Arduino.h> + + +extern int64_t next_connection_unix; +extern bool go_to_sleep; + +struct PendingConfigRequest_s { + bool active = false; + uint8_t mac[6]; + char sensor_name[32]; +}; + +extern PendingConfigRequest_s pending_config; + +// ---------------------------------------------------------------------------- +// Helper +// ---------------------------------------------------------------------------- + +void print_SensorConfigServer(const SensorConfigServer_s& cfg); + +// ---------------------------------------------------------------------------- +// Server handling (g_buffer) +// ---------------------------------------------------------------------------- + +void init_Server(); + +// ---------------------------------------------------------------------------- +// WiFi handling +// ---------------------------------------------------------------------------- + +void init_WiFi(); + +// ---------------------------------------------------------------------------- +// Init ESP-NOW +// ---------------------------------------------------------------------------- + +void init_EspNow(); + +// ---------------------------------------------------------------------------- +// Config handling +// ---------------------------------------------------------------------------- + +void get_PendingConfigFromServer(); +void send_ConfigToEsp(); + +// ---------------------------------------------------------------------------- +// Sleep +// ---------------------------------------------------------------------------- + +void sleep_UntilNextReceive(); + +#endif diff --git a/server/server.ino b/server/server.ino index e7206d0..a342986 100644 --- a/server/server.ino +++ b/server/server.ino @@ -1,196 +1,11 @@ -#include "secrets.h" +#include "Server.h" #include "WiFiManager.h" -#include "globals.h" -#include <Arduino.h> -#include <WiFi.h> -#include <esp_now.h> - - -uint8_t received_from_mac_addr[6]; - -int64_t next_connection_unix; -bool go_to_sleep; - -struct PendingConfigRequest_s { - bool active = false; - uint8_t mac[6]; - char sensor_name[32]; -}; +int64_t next_connection_unix = 0; +bool go_to_sleep = false; PendingConfigRequest_s pending_config; -SensorConfigServer_s cfg_response; - -// ---------------------------------------------------------------------------- -// Server handling (g_buffer) - // ---------------------------------------------------------------------------- - -void add_ReadingCallback(const char* table, const char* value, const int64_t time) { - if (g_buffer_count >= BUFFER_SIZE) { - for (int i = 1; i < g_buffer_count; i++) g_buffer[i-1] = g_buffer[i]; - g_buffer_count--; - } - strncpy(g_buffer[g_buffer_count].table, table, TABLE_SIZE-1); - g_buffer[g_buffer_count].table[TABLE_SIZE-1] = '\0'; - strncpy(g_buffer[g_buffer_count].value, value, VALUE_SIZE-1); - g_buffer[g_buffer_count].time = time; - g_buffer_count++; -} - -void init_Server() { - WIFI_OnAddReading = add_ReadingCallback; -} - -// ---------------------------------------------------------------------------- -// WiFi handling -// ---------------------------------------------------------------------------- - -void init_WiFi() { - WiFi.mode(WIFI_MODE_APSTA); - WiFi.begin(ssid, password); - - DBG_PRINTF("Connecting to %s .", ssid); - while (WiFi.status() != WL_CONNECTED) { DBG_PRINT("."); delay(200); } - DBG_PRINTLN(" ok"); - - IPAddress ip = WiFi.localIP(); - - DBG_PRINTF("SSID: %s\n", ssid); - DBG_PRINTF("Channel: %u\n", WiFi.channel()); - DBG_PRINTF("IP: %u.%u.%u.%u\n", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, ip >> 24); -} - -// ---------------------------------------------------------------------------- -// ESP-NOW helpers (add peer + send callback) -// ---------------------------------------------------------------------------- - -void on_DataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) { - if (!info) return; - - DBG_PRINT("Delivery to "); - for (int i = 0; i < 6; i++) { - DBG_PRINTF("%02X", info->des_addr[i]); - if (i < 5) DBG_PRINT(":"); - } - DBG_PRINT(" -> "); - DBG_PRINTLN(status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL"); -} - -void add_Peer(const uint8_t* addr) { - if (esp_now_is_peer_exist(addr)) return; - - esp_now_peer_info_t peer{}; - memcpy(peer.peer_addr, addr, 6); - peer.ifidx = WIFI_IF_STA; // server is in APSTA mode but acts as STA on same SSID - peer.channel = (uint8_t)WiFi.channel(); // ensure same channel - peer.encrypt = false; - - esp_err_t res = esp_now_add_peer(&peer); - if (res != ESP_OK) { - DBG_PRINT("Failed to add peer: "); - for (int i=0; i<6; i++) { - DBG_PRINTF("%02X", addr[i]); - if (i<5) DBG_PRINT(":"); - } - DBG_PRINTF(" -> error code %d\n", res); - } else { - DBG_PRINT("Added peer: "); - for (int i=0; i<6; i++) { - DBG_PRINTF("%02X", addr[i]); - if (i<5) DBG_PRINT(":"); - } - DBG_PRINTLN(""); - } -} - -// ---------------------------------------------------------------------------- -// ESP-NOW receive callback -// ---------------------------------------------------------------------------- - -void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) { - if (!info || !data || len <= 0) return; - memcpy(received_from_mac_addr, info->src_addr, 6); - add_Peer(received_from_mac_addr); - - char msg[128]; - int copylen = len < (int)sizeof(msg)-1 ? len : (int)sizeof(msg)-1; - memcpy(msg, data, copylen); - msg[copylen] = '\0'; - - DBG_PRINTF("Received from %02X:%02X:%02X:%02X:%02X:%02X: %s\n", - received_from_mac_addr[0], received_from_mac_addr[1], received_from_mac_addr[2], - received_from_mac_addr[3], received_from_mac_addr[4], received_from_mac_addr[5], msg); - - if (strcmp(msg, "time?") == 0) { - char time_msg[32]; - snprintf(time_msg, sizeof(time_msg), "time:%lld", now()); - esp_now_send(received_from_mac_addr, (uint8_t*)time_msg, strlen(time_msg)); - return; - } - - // Queue config request instead of calling HTTP directly - if (strncmp(msg, "next_read:", 10) == 0) { - - const char* value_str = msg + 10; - next_connection_unix = atoll(value_str); - go_to_sleep = true; - DBG_PRINTF("Received next_read: %lld\n", next_connection_unix); - return; - - } else if (strncmp(msg, "get_config:", 11) == 0 && !pending_config.active) { - - pending_config.active = true; - memcpy(pending_config.mac, received_from_mac_addr, 6); - strncpy(pending_config.sensor_name, msg + 11, sizeof(pending_config.sensor_name) - 1); - pending_config.sensor_name[sizeof(pending_config.sensor_name) - 1] = '\0'; - DBG_PRINTF("Queued config request for %s\n", pending_config.sensor_name); - return; - } - - // --- Normal table:value:time handling --- - DBG_PRINTLN("Message:"); - DBG_PRINTF(" %s\n", msg); - g_received_ok_from_server = false; - - char *first = strchr(msg, ':'); - char *second = first ? strchr(first + 1, ':') : NULL; - if (first && second) { - *first = '\0'; - *second = '\0'; - - const char *sensor_name = msg; - const char *value_str = first + 1; - const int64_t time = atoll(second + 1); - - add_ReadingCallback(sensor_name, value_str, time); - } else { - DBG_PRINTLN("Invalid message format (expected <name>:<value>:<time>)"); - } - - /* - * Replying to Sensor happens in main loop - */ -} - - -// ---------------------------------------------------------------------------- -// Init ESP-NOW -// ---------------------------------------------------------------------------- - -void init_EspNow() { - if (esp_now_init() != ESP_OK) { - DBG_PRINTLN("ESP-NOW failed to initialize"); - while (true); - } - - esp_now_register_recv_cb(on_DataRecv); - esp_now_register_send_cb(on_DataSent); -} - -// ---------------------------------------------------------------------------- -// Initialization -// ---------------------------------------------------------------------------- void setup() { uint32_t setup_start = millis(); @@ -202,31 +17,12 @@ void setup() { init_Server(); init_EspNow(); - SensorConfigServer_s cfg; - /* -if (WIFI_GetSensorConfigServer("moisture_1", cfg)) { - DBG_PRINTF("Got cfg for moisture_1:\n"); - DBG_PRINTF("Pin: %d\n", cfg.pin); - DBG_PRINTF("Use Time: %d\n", cfg.use_time); - DBG_PRINTF("Delay: %d\n", cfg.delay_ms); - DBG_PRINTF("Notification MAC: %s\n", cfg.pump_mac); - DBG_PRINTF("Notification Name: %s\n", cfg.notification_name); - DBG_PRINTF("Min Moisture: %d\n", cfg.min_moisture); - DBG_PRINTF("Active: %d\n", cfg.is_active); - DBG_PRINTF("Pumping Delay: %d\n", cfg.pumping_delay_sec); - DBG_PRINTF("Pumping Duration: %d\n", cfg.pumping_duration); - - for (uint8_t i = 0; i < cfg.time_count; i++) { - uint16_t minutes = cfg.times[i]; - uint8_t hh = minutes / 60; - uint8_t mm = minutes % 60; - DBG_PRINTF("Time[%d]: %02u:%02u (%u min)\n", i, hh, mm, minutes); - } -} else { - DBG_PRINTLN("Failed to get cfg!"); -} -*/ +SensorConfigServer_s cfg; +if (WIFI_GetSensorConfigServer("moisture_1", cfg)) + print_SensorConfigServer(cfg); +else DBG_PRINTLN("Failed to get cfg!"); + */ go_to_sleep = false; next_connection_unix = 0; @@ -234,122 +30,18 @@ if (WIFI_GetSensorConfigServer("moisture_1", cfg)) { DBG_PRINTF("Setup duration: %u ms\n", g_setup_duration); } -// ---------------------------------------------------------------------------- -// Main control loop -// ---------------------------------------------------------------------------- void loop() { - if (pending_config.active) { - pending_config.active = false; - if (WIFI_GetSensorConfigServer(pending_config.sensor_name, cfg_response)) { - char response[250]; - int len_out = snprintf(response, sizeof(response), - "cfg:%s,%d,%d,%d,%s,%d,%d,%s,%d,%d", - cfg_response.sensor_name, - cfg_response.is_active, - cfg_response.pin, - cfg_response.min_moisture, - cfg_response.notification_name, - cfg_response.pumping_delay_sec, - cfg_response.pumping_duration, - cfg_response.pump_mac, - cfg_response.delay_ms, - cfg_response.use_time); - - if (cfg_response.time_count > 0) { - strncat(response, ",times=", sizeof(response)-strlen(response)-1); - for (uint8_t i = 0; i < cfg_response.time_count; i++) { - char buf[8]; - snprintf(buf, sizeof(buf), "%u", cfg_response.times[i]); - strncat(response, buf, sizeof(response)-strlen(response)-1); - if (i < cfg_response.time_count - 1) - strncat(response, "|", sizeof(response)-strlen(response)-1); - } - } - - esp_now_send(pending_config.mac, (uint8_t*)response, strlen(response)); - DBG_PRINTF("Sent config for %s\n", cfg_response.sensor_name); - DBG_PRINTF("Sending: %s\n", response); - } else { - const char* err = "cfg_error:fetch_failed"; - esp_now_send(pending_config.mac, (uint8_t*)err, strlen(err)); - DBG_PRINTLN("Config fetch failed"); - } - } - - if (g_buffer_count > 0) { - DBG_PRINTLN("Posting g_buffer..."); - bool ok = WIFI_PostBufferSync(); - if (!ok) DBG_PRINTLN("Post failed, will retry next loop"); - } - - - - - if (g_received_ok_from_server) { - DBG_PRINTLN("Preparing time + configs message"); - - char msg[256]; - size_t offset = 0; - - time_t now_t; - time(&now_t); - offset += snprintf(msg + offset, sizeof(msg) - offset, "time:%lu", (unsigned long)now_t); - - // add configs if available - if (g_pending_sensor_configs_count > 0) { - DBG_PRINTLN("Appending pending configs..."); - for (size_t i = 0; i < g_pending_sensor_configs_count; i++) { - DBG_PRINTF(" adding config: %s\n", g_pending_sensor_configs[i]); - offset += snprintf(msg + offset, sizeof(msg) - offset, ",cfg:%s", g_pending_sensor_configs[i]); - if (offset >= sizeof(msg)) break; - } - g_pending_sensor_configs_count = 0; - } - - DBG_PRINTLN("Sending combined message:"); - DBG_PRINTLN(msg); - - esp_err_t result = esp_now_send(received_from_mac_addr, (uint8_t*)msg, strlen(msg)); - if (result == ESP_OK) - DBG_PRINTLN("Send queued successfully."); - else - DBG_PRINTF("Send failed: %d\n", result); - - g_received_ok_from_server = false; - } - - if (go_to_sleep) { - go_to_sleep = false; - uint32_t min_delay_ms = (next_connection_unix - now())*1000; - - int64_t unix_now = now(); - if (next_connection_unix < unix_now) return; - - DBG_PRINTF("Nex: %lld\nNow: %lld\n", next_connection_unix, unix_now); - - next_connection_unix = 0; - - // Prevent sleeping if next send is within g_min_sleep_time - if (min_delay_ms < g_min_sleep_time) { - DBG_PRINTF("Delaying for %u ms (no deep sleep)\n", min_delay_ms); - DBG_PRINTF("######################\n\n"); - delay(min_delay_ms); - } else { - uint32_t prep_time_ms = g_setup_duration + g_wakeup_earlier_server; - uint32_t sleep_time_ms = (min_delay_ms > prep_time_ms) - ? (min_delay_ms - prep_time_ms) - : 0; - + if (pending_config.active) + get_PendingConfigFromServer(); - DBG_PRINTF("Sleeping for %u ms (setup margin: %u ms)\n", - sleep_time_ms, prep_time_ms); - DBG_PRINTF("######################\n\n"); + if (g_buffer_count > 0) + WIFI_PostBufferSync(); - esp_sleep_enable_timer_wakeup((uint64_t)sleep_time_ms * 1000ULL); - esp_deep_sleep_start(); - } + if (g_received_ok_from_server) + send_ConfigToEsp(); - } + if (go_to_sleep) + sleep_UntilNextReceive(); }