Nimbin[12]?Embedded / esp_garden / commits / b9ed469

esp_garden git · master

Distributed ESP sensor and actuator system (garden)

esp32 esp-idf iot sensors c++ sql · first commit 2025-10-15 · last commit 2026-01-20 (8 months ago) · synced 3 days ago · upstream: git.ide3.de/hsnr/mic/esp_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.gz

Update DeepSleep also for server now

Christian Immanuel · 2025-10-25 07:57 · b9ed469bd7e6432c16bd2fd5ea3a3bf017e21a59

 client_sensor/ClientSensor.cpp  | 20 +++++++++++----
 client_sensor/ClientSensor.h    |  1 +
 client_sensor/client_sensor.ino |  1 +
 globals.cpp                     |  5 ++--
 globals.h                       | 16 +++++++++---
 post_server/WiFiManager.cpp     |  4 +--
 server/server.ino               | 55 +++++++++++++++++++++++++++++++++++++++--
 7 files changed, 87 insertions(+), 15 deletions(-)

diff --git a/client_sensor/ClientSensor.cpp b/client_sensor/ClientSensor.cpp
index 2f3e33e..57e6569 100644
--- a/client_sensor/ClientSensor.cpp
+++ b/client_sensor/ClientSensor.cpp
@@ -448,15 +448,15 @@ void sleep_UntilNextSend(int64_t next_read) {
                           : (uint32_t)(delta_sec * 1000);
 
 
-    // Prevent sleeping if next send is within 1 minute
-    if (min_delay_ms < 60 * 1000) {
+    // 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);
         return;
     }
 
-    uint32_t prep_time_ms = g_setup_duration + g_wakeup_earlier;
+    uint32_t prep_time_ms = g_setup_duration + g_wakeup_earlier_sensor;
     uint32_t sleep_time_ms = (min_delay_ms > prep_time_ms)
                            ? (min_delay_ms - prep_time_ms)
                            : 0;
@@ -714,7 +714,17 @@ void send_DataToPeer(size_t config_id, uint32_t value) {
         send_ack_process_complete = true;
     }
     while (!send_ack_process_complete) delay(100);
-
-    delay(5000);
 }
 
+
+void send_NextSensorReadToPeer(const uint8_t* mac, int64_t unix_time) {
+    char message[64];
+
+    snprintf(message, sizeof(message), "next_read:%lld", unix_time);
+
+    DBG_PRINT("Sending to peer: ");
+    printMac(mac);
+    if (!send_Message(mac, message)) {
+        DBG_PRINTLN("Delivery failed or peer offline!");
+    }
+}
diff --git a/client_sensor/ClientSensor.h b/client_sensor/ClientSensor.h
index 5592260..a874281 100644
--- a/client_sensor/ClientSensor.h
+++ b/client_sensor/ClientSensor.h
@@ -67,6 +67,7 @@ void process_PendingSensorConfigs();
 
 bool is_TimeToReadSensor(size_t config_id);
 void send_DataToPeer(size_t config_id, uint32_t value);
+void send_NextSensorReadToPeer(const uint8_t* mac, int64_t unix_time);
 
 
 #endif
diff --git a/client_sensor/client_sensor.ino b/client_sensor/client_sensor.ino
index cfbd688..d2269d6 100644
--- a/client_sensor/client_sensor.ino
+++ b/client_sensor/client_sensor.ino
@@ -79,5 +79,6 @@ void loop() {
 
     int64_t next_read = get_NextSensorReadsUnixTime();
 
+    send_NextSensorReadToPeer(PEER_SERVER, next_read);
     sleep_UntilNextSend(next_read);
 }
diff --git a/globals.cpp b/globals.cpp
index 6e813c3..404af4f 100644
--- a/globals.cpp
+++ b/globals.cpp
@@ -1,7 +1,8 @@
 #include "globals.h"
 
 uint32_t g_setup_duration = 0;
-uint32_t g_wakeup_earlier = 2000;
+uint32_t g_wakeup_earlier_server = 20000;
+uint32_t g_wakeup_earlier_sensor = 2000;
 
 SensorEntry g_buffer[BUFFER_SIZE]; 
 uint8_t g_buffer_count = 0;
@@ -15,7 +16,7 @@ bool g_received_ok_from_server = false;
 
 
 // Client sensor stuff
-const uint32_t min_sleep_time = 60000;
+const uint32_t g_min_sleep_time = 60000;
 RTC_DATA_ATTR bool all_init_configs_received = false;
 
 constexpr uint8_t PEER_SERVER[] = {0x58,0xcf,0x79,0x1e,0xed,0x18};
diff --git a/globals.h b/globals.h
index a885c74..c6918e1 100644
--- a/globals.h
+++ b/globals.h
@@ -36,7 +36,8 @@
 
 
 extern uint32_t g_setup_duration; // getting set automaticall in setup so we know how long it takes
-extern uint32_t g_wakeup_earlier; // some safety space if setup takes longere (maybe 20sec safety?)
+extern uint32_t g_wakeup_earlier_server; // some safety space if setup takes longere (maybe 20sec safety?)
+extern uint32_t g_wakeup_earlier_sensor; // some safety space if setup takes longere (maybe 20sec safety?)
 
 struct SensorConfigServer_s {
     char sensor_name[32];
@@ -44,7 +45,7 @@ struct SensorConfigServer_s {
     bool is_active;
     int  pin;
     int  min_moisture;
-    char notification_name[64];
+    char notification_name[32];
     int  pumping_delay_sec;
     int  pumping_duration;
     char pump_mac[18];       // "AA:BB:CC:DD:EE:FF"
@@ -59,7 +60,7 @@ struct SensorConfig_s {
     bool is_active;
     int  pin;
     int  min_moisture;
-    char notification_name[64];
+    char notification_name[32];
     int  pumping_delay_sec;
     int  pumping_duration;
     uint8_t pump_mac[6];       // {0x51,0xc1,0x79,0x1e,0xed,0x18}
@@ -71,6 +72,13 @@ struct SensorConfig_s {
     int64_t next_sensor_read; // Unix time
 };
 
+struct PumpInformation_s {
+    char notifiaction_name[32];
+    int  pumping_delay_sec;
+    int  pumping_duration; // set to 0 if you just want to notify next messaging time
+    int64_t next_message;  // Unix time
+};
+
 struct SensorEntry {
     char table[TABLE_SIZE];
     char value[VALUE_SIZE];
@@ -89,7 +97,7 @@ extern bool    g_received_ok_from_server;
 
 
 
-extern const uint32_t min_sleep_time;
+extern const uint32_t g_min_sleep_time;
 extern RTC_DATA_ATTR bool all_init_configs_received;
 extern const uint8_t PEER_SERVER[];
 extern const uint8_t PEER_PUMP[];
diff --git a/post_server/WiFiManager.cpp b/post_server/WiFiManager.cpp
index 77690a1..c2c1a5e 100644
--- a/post_server/WiFiManager.cpp
+++ b/post_server/WiFiManager.cpp
@@ -32,7 +32,7 @@ bool WIFI_GetSensorConfigServer(const char* sensor_name, SensorConfigServer_s &c
     char host_buf[64];
     snprintf(host_buf, sizeof(host_buf), "%s", server_host);
 
-    char name_enc[64];
+    char name_enc[32];
     encode_UrlToBuf(sensor_name, name_enc, sizeof(name_enc));
 
     char path_buf[128];
@@ -107,7 +107,7 @@ bool WIFI_GetSensorConfigServer(const char* sensor_name, SensorConfigServer_s &c
     };
 
     auto extractString = [&](const char* key, char* out, size_t out_size) {
-        char pattern[64];
+        char pattern[32];
         snprintf(pattern, sizeof(pattern), "\"%s\":\"", key);
         int start_idx = body.indexOf(pattern);
         if (start_idx == -1) { out[0] = '\0'; return; }
diff --git a/server/server.ino b/server/server.ino
index 3fd0797..e7206d0 100644
--- a/server/server.ino
+++ b/server/server.ino
@@ -9,6 +9,9 @@
 
 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];
@@ -126,7 +129,16 @@ void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
     }
 
     // Queue config request instead of calling HTTP directly
-    if (strncmp(msg, "get_config:", 11) == 0 && !pending_config.active) {
+    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);
@@ -181,8 +193,9 @@ void init_EspNow() {
 // ----------------------------------------------------------------------------
 
 void setup() {
+    uint32_t setup_start = millis();
+
     DBG_BEGIN();
-    delay(500);
 
     init_WiFi();
     WIFI_SyncTime();
@@ -214,6 +227,11 @@ if (WIFI_GetSensorConfigServer("moisture_1", cfg)) {
     DBG_PRINTLN("Failed to get cfg!");
 }
 */
+
+    go_to_sleep = false;
+    next_connection_unix = 0;
+    g_setup_duration = millis() - setup_start;
+    DBG_PRINTF("Setup duration: %u ms\n", g_setup_duration);
 }
 
 // ----------------------------------------------------------------------------
@@ -300,5 +318,38 @@ void loop() {
 
       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;
+
+
+            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();
+        }
+
+    }
 }