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

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

Add is pump active; Set sensor MAC on first connection

Christian Immanuel · 2025-10-26 08:15 · f0255f242e070387e9619f52812d356e2066d811

 client_sensor/ClientSensor.cpp  | 10 +++--
 client_sensor/client_sensor.ino |  4 +-
 globals.cpp                     | 10 ++++-
 globals.h                       |  8 +++-
 server/Server.cpp               | 90 +++++++++++++++++++++++++++++++++++++----
 server/Server.h                 |  6 +++
 server/server.ino               |  4 +-
 7 files changed, 115 insertions(+), 17 deletions(-)

diff --git a/client_sensor/ClientSensor.cpp b/client_sensor/ClientSensor.cpp
index 6b36039..3f48519 100644
--- a/client_sensor/ClientSensor.cpp
+++ b/client_sensor/ClientSensor.cpp
@@ -6,6 +6,9 @@ volatile bool response_received = false;
 volatile bool send_process_complete = false;
 volatile bool send_response_process_complete = false;
 
+
+bool pump_unreachable = true;
+
 uint8_t config_request_attempts = 0;
 
 // ----------------------------------------------------------------------------
@@ -338,7 +341,7 @@ bool request_TimeSync(uint32_t timeout_ms) {
     const uint8_t* server_mac = PEER_SERVER;
     unsigned long start = millis();
     esp_now_register_recv_cb(on_DataRecv);
-    send_Message(server_mac, "time?");
+    send_Message(server_mac, "time?sensor");
     while (millis() - start < timeout_ms) {
         if (rtc_synced_with_server) return true;
         delay(50);
@@ -701,8 +704,9 @@ void send_DataToPeer(size_t config_id, uint32_t value) {
     send_response_process_complete = false;
     if (!send_AndWaitResponse(p.pump_mac, message)) {
         DBG_PRINTLN("Delivery failed or peer offline!");
+        pump_unreachable = true;
         send_response_process_complete = true;
-    }
+    } else pump_unreachable = false;
 
     while (!send_response_process_complete) delay(100);
 
@@ -720,7 +724,7 @@ void send_DataToPeer(size_t config_id, uint32_t value) {
 void send_NextSensorReadToPeer(const uint8_t* mac, int64_t unix_time) {
     char message[64];
 
-    snprintf(message, sizeof(message), "next_read:%lld", unix_time);
+    snprintf(message, sizeof(message), "next_read:%lld:reached_pump:%d", unix_time, !pump_unreachable);
 
     DBG_PRINT("Sending to peer: ");
     printMac(mac);
diff --git a/client_sensor/client_sensor.ino b/client_sensor/client_sensor.ino
index d2269d6..ab0ad28 100644
--- a/client_sensor/client_sensor.ino
+++ b/client_sensor/client_sensor.ino
@@ -16,12 +16,12 @@ void setup() {
     init_WiFi();
     init_EspNow();
 
+    restore_SensorConfigs();
+
     DBG_PRINTLN("Requesting time sync...");
     if (request_TimeSync()) DBG_PRINTLN("done");
     else DBG_PRINTLN("failed (timeout)");
 
-    restore_SensorConfigs();
-
     DBG_PRINTF("----------------------\n");
 
     // Add all known configs to an array so we can request thoose from server
diff --git a/globals.cpp b/globals.cpp
index ef8f493..05b4328 100644
--- a/globals.cpp
+++ b/globals.cpp
@@ -20,8 +20,14 @@ 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};
-constexpr uint8_t PEER_SERVER[] = {0x54,0xca,0x29,0x1f,0x3d,0xa8};
-constexpr uint8_t PEER_PUMP[]   = {0x51,0xc1,0x79,0x1e,0xed,0x18};
+constexpr
+uint8_t PEER_SERVER[]  = {0x54,0xca,0x29,0x1f,0x3d,0xa8};
+uint8_t PEER_PUMP[6]   = {0x51,0xc1,0x79,0x1e,0xed,0x18};
+uint8_t PEER_SENSOR[6] = {0xcc,0x8d,0xa2,0x69,0xf9,0x0c};
+
+bool init_sensor_mac_received = false;
+bool init_pump_mac_received   = false;
+
 
 RTC_DATA_ATTR SensorConfig_s sensor_configs[] = {
     {"moisture_1", true, 11, 10, "pump_1", 0, 0, {0},  90000, true,  {465, 466}, 2, 0, 0},
diff --git a/globals.h b/globals.h
index c6918e1..a734ef8 100644
--- a/globals.h
+++ b/globals.h
@@ -99,8 +99,14 @@ extern bool    g_received_ok_from_server;
 
 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[];
+extern uint8_t PEER_PUMP[];
+extern uint8_t PEER_SENSOR[];
+
+extern bool init_sensor_mac_received;
+extern bool init_pump_mac_received;
+
 extern RTC_DATA_ATTR SensorConfig_s sensor_configs[];
 extern uint8_t config_request_attempts_max;
 
diff --git a/server/Server.cpp b/server/Server.cpp
index 1581809..b301b96 100644
--- a/server/Server.cpp
+++ b/server/Server.cpp
@@ -36,9 +36,54 @@ void print_SensorConfigServer(const SensorConfigServer_s& cfg) {
     DBG_PRINTLN("----------------------------");
 }
 
+void copy_Mac(const uint8_t* src, uint8_t* dest) {
+    memcpy(dest, src, 6);
+}
+
+// ----------------------------------------------------------------------------
+// Save/Restore to flash NVS
+// ----------------------------------------------------------------------------
+
+#include <Preferences.h>
+
+Preferences prefs;
+
+void save_ToFlash() {
+    DBG_PRINTLN("Saving configs to NVS...");
+
+    prefs.begin("peers", false);
+    prefs.putBytes("pump_mac", PEER_PUMP, 6);
+    prefs.putBytes("sensor_mac", PEER_SENSOR, 6);
+    prefs.putBool("sensor_received", init_sensor_mac_received);
+    prefs.putBool("pump_received", init_pump_mac_received);
+    prefs.end();
+
+    DBG_PRINTLN("Save complete.");
+}
+
+void restore_FromFlash() {
+    DBG_PRINTLN("Restoring configs from NVS...");
+
+    prefs.begin("peers", true);
+
+    size_t pump_len   = prefs.getBytes("pump_mac", PEER_PUMP, 6);
+    size_t sensor_len = prefs.getBytes("sensor_mac", PEER_SENSOR, 6);
+
+    init_sensor_mac_received = prefs.getBool("sensor_received", false);
+    init_pump_mac_received   = prefs.getBool("pump_received", false);
+
+    prefs.end();
+
+    if (pump_len == 6 && sensor_len == 6) {
+        DBG_PRINTLN("Peer MACs restored from flash.");
+    } else {
+        DBG_PRINTLN("No stored peer MACs found, using defaults.");
+    }
+}
+
 // ----------------------------------------------------------------------------
 // Server handling (g_buffer)
- // ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
 
 void add_ReadingCallback(const char* table, const char* value, const int64_t time) {
     if (g_buffer_count >= BUFFER_SIZE) {
@@ -138,22 +183,51 @@ void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
                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) {
+    if (strncmp(msg, "time?", 5) == 0) {
         char time_msg[32];
         snprintf(time_msg, sizeof(time_msg), "time:%lld", now());
+
+        // Set senders MAC address if not already set
+        if (!init_sensor_mac_received && strcmp(msg, "time?sensor") == 0) {
+            copy_Mac(received_from_mac_addr, PEER_SENSOR);
+            init_sensor_mac_received = true;
+            save_ToFlash();
+        } else if (!init_pump_mac_received && strcmp(msg, "time?pump") == 0) {
+            copy_Mac(received_from_mac_addr, PEER_PUMP);
+            init_pump_mac_received = true;
+            save_ToFlash();
+        }
+
+        esp_now_send(received_from_mac_addr, (uint8_t*)time_msg, strlen(time_msg));
+        return;
+    }
+    if (strcmp(msg, "time_sensor?") == 0) {
+        char time_msg[32];
+        snprintf(time_msg, sizeof(time_msg), "time:%lld", now());
+        copy_Mac(received_from_mac_addr, PEER_SENSOR);
         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;
+        char* sep = strchr(value_str, ':');
+        if (sep != nullptr && strncmp(sep, ":reached_pump:", 14) == 0) {
+            *sep = '\0';
+            next_connection_unix = atoll(value_str);
 
+            const char* reached_pump_str = sep + 14;
+            int reached_pump = atoi(reached_pump_str);
+
+            init_pump_mac_received = (reached_pump != 0);
+
+            if (!init_pump_mac_received)
+                save_ToFlash();
+
+            go_to_sleep = true;
+            DBG_PRINTF("Received next_read: %lld, reached_pump: %d\n", next_connection_unix, reached_pump);
+            return;
+        }
     } else if (strncmp(msg, "get_config:", 11) == 0 && !pending_config.active) {
 
         pending_config.active = true;
diff --git a/server/Server.h b/server/Server.h
index a17c1be..02483dd 100644
--- a/server/Server.h
+++ b/server/Server.h
@@ -23,6 +23,12 @@ extern PendingConfigRequest_s pending_config;
 
 void print_SensorConfigServer(const SensorConfigServer_s& cfg);
 
+// ----------------------------------------------------------------------------
+// Save/Restore to flash NVS
+// ----------------------------------------------------------------------------
+
+void restore_FromFlash();
+
 // ----------------------------------------------------------------------------
 // Server handling (g_buffer)
 // ----------------------------------------------------------------------------
diff --git a/server/server.ino b/server/server.ino
index a342986..39c53e3 100644
--- a/server/server.ino
+++ b/server/server.ino
@@ -12,6 +12,8 @@ void setup() {
 
     DBG_BEGIN();
 
+    restore_FromFlash();
+
     init_WiFi();
     WIFI_SyncTime();
     init_Server();
@@ -41,7 +43,7 @@ void loop() {
     if (g_received_ok_from_server)
         send_ConfigToEsp();
 
-    if (go_to_sleep)
+    if (go_to_sleep && init_sensor_mac_received)
         sleep_UntilNextReceive();
 }