Nimbin[12]?Embedded / esp_garden / commits / 954b368

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 pump reached

Christian Immanuel · 2025-10-27 08:13 · 954b3689d7620c734050054c1cf82f8f8e43547b

 client_pump/ClientPump.cpp     | 29 +++++++++++++++++++++++++
 client_sensor/ClientSensor.cpp | 48 +++++++++++++++++++++++++++++++++++++++---
 database.sql                   |  3 ++-
 globals.h                      |  1 +
 post_server/WiFiManager.cpp    |  4 ++--
 post_server/WiFiManager.h      |  2 +-
 server/Server.cpp              | 24 ++++++++++++---------
 7 files changed, 94 insertions(+), 17 deletions(-)

diff --git a/client_pump/ClientPump.cpp b/client_pump/ClientPump.cpp
index 81307f9..41cc2f4 100644
--- a/client_pump/ClientPump.cpp
+++ b/client_pump/ClientPump.cpp
@@ -85,6 +85,33 @@ void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
                 if (strcmp(pump_configs[i].pump_name, pump_config.pump_name) != 0)
                     continue;
 
+                // --- Response to sender ---
+                // register peer
+                uint8_t primary;
+                wifi_second_chan_t second;
+                esp_wifi_get_channel(&primary, &second);
+
+                esp_now_peer_info_t peer = {};
+                memcpy(peer.peer_addr, info->src_addr, 6);
+                peer.channel = primary;
+                peer.encrypt = false;
+
+                if (!esp_now_is_peer_exist(info->src_addr)) {
+                    esp_err_t add_status = esp_now_add_peer(&peer);
+                    if (add_status != ESP_OK) {
+                        DBG_PRINTF("Failed to add peer before sending ACK, err=%d\n", add_status);
+                        return;
+                    }
+                }
+                // send acknowledgment
+                const char ack_msg[] = "thanks";
+                esp_err_t result = esp_now_send(info->src_addr, (const uint8_t *)ack_msg, sizeof(ack_msg));
+                if (result == ESP_OK)
+                    DBG_PRINTLN("Sent acknowledgment: thanks");
+                else
+                    DBG_PRINTF("Failed to send acknowledgment, err=%d\n", result);
+
+                // --- Copy data from message ---
                 // make sure we keep old data before memcpy
                 pump_config.pumping_started_at_unix = pump_configs[i].pumping_started_at_unix;
                 pump_config.pumping_status = pump_configs[i].pumping_status;
@@ -104,7 +131,9 @@ void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
                 else
                     received_starting_message = false;
 
+                // --- Update local time ---
                 set_LocalTime(unix_now);
+
                 return;
             }
         } else {
diff --git a/client_sensor/ClientSensor.cpp b/client_sensor/ClientSensor.cpp
index 4d4993d..7211776 100644
--- a/client_sensor/ClientSensor.cpp
+++ b/client_sensor/ClientSensor.cpp
@@ -149,6 +149,15 @@ void on_DataSent(const wifi_tx_info_t* info, esp_now_send_status_t status) {
 void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
     if (!info || !data || len <= 0) return;
 
+    // --- Filter by source MAC ---
+    const uint8_t *src = info->src_addr;
+
+    if (memcmp(src, PEER_SERVER, 6) == 0) {
+        DBG_PRINTLN("Ignoring message: unknown sender");
+        return;
+    }
+
+    // --- Handle message ---
     char msg[256];
     memcpy(msg, data, len);
     msg[len] = '\0';
@@ -171,6 +180,23 @@ void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
 void on_DataRecvResponse(const esp_now_recv_info *info, const uint8_t *data, int len) {
     if (!info || !data || len <= 0) return;
 
+    // --- Filter by source MAC ---
+    const uint8_t *src = info->src_addr;
+    bool from_server = memcmp(src, PEER_SERVER, 6) == 0;
+    bool from_pump = false;
+
+    for (uint8_t i = 0; i < SENSOR_CONFIG_COUNT; i++) {
+        if (memcmp(sensor_configs[i].pump_mac, src, 6) == 0) {
+            from_pump = true;
+            break;
+        }
+    }
+
+    if (!from_server && !from_pump) {
+        DBG_PRINTLN("Ignoring message: unknown sender");
+        return;
+    }
+
     char msg[256];
     int copylen = len < (int)sizeof(msg) - 1 ? len : (int)sizeof(msg) - 1;
     memcpy(msg, data, copylen);
@@ -178,6 +204,16 @@ void on_DataRecvResponse(const esp_now_recv_info *info, const uint8_t *data, int
 
     DBG_PRINTF("Response received: %s\n", msg);
 
+    if (from_pump) {
+        DBG_PRINTF("Received from Pump: %s\n", msg);
+        if (strncmp(msg, "thanks", 6) == 0) {
+            response_received = true;
+            DBG_PRINTLN("Setting send_response_process_complete to TRUE");
+            send_response_process_complete = true;
+        }
+        return;
+    }
+
     const char *time_ptr = strstr(msg, "time:");
     if (time_ptr) {
         time_t server_unix = strtoul(time_ptr + 5, nullptr, 10);
@@ -716,14 +752,20 @@ void send_DataToPumpAndServer(size_t config_id, uint32_t value, bool shall_pump)
             pumping_duration,
             get_NextSensorReadsUnixTime(p.pump_mac));
 
-    if (!send_Message(p.pump_mac, message))
+    bool reached_pump = false;
+    if (!send_AndWaitResponse(p.pump_mac, message)) {
         DBG_PRINTLN("Delivery failed or peer offline!");
+        send_response_process_complete = true;
+    } else reached_pump = true;
+
+    while (!send_response_process_complete) delay(100);
 
     DBG_PRINT("Sending to Server: "); printMac(PEER_SERVER);
-    snprintf(message, sizeof(message), "%s:%u:%lld",
+    snprintf(message, sizeof(message), "%s:%u:%lld:%d",
             p.sensor_name,
             value,
-            p.last_sensor_read);
+            p.last_sensor_read,
+            reached_pump);
     send_response_process_complete = false;
     if (!send_AndWaitResponse(PEER_SERVER, message)) {
         DBG_PRINTLN("Failed to get response from server!");
diff --git a/database.sql b/database.sql
index b33199d..aba0ac4 100644
--- a/database.sql
+++ b/database.sql
@@ -2,7 +2,8 @@
 CREATE TABLE moisture_2 (
     id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
     time INT UNSIGNED DEFAULT NULL,
-    value VARCHAR(255) NOT NULL
+    value VARCHAR(255) NOT NULL,
+    pump_reached TINYINT(1) NOT NULL DEFAULT 0
 );
 INSERT INTO test (value) VALUES ('817273');
 
diff --git a/globals.h b/globals.h
index de85a5c..bd38c44 100644
--- a/globals.h
+++ b/globals.h
@@ -83,6 +83,7 @@ struct SensorEntry {
     char table[TABLE_SIZE];
     char value[VALUE_SIZE];
     int64_t time;
+    bool pump_reached;
 };
 
 
diff --git a/post_server/WiFiManager.cpp b/post_server/WiFiManager.cpp
index c29fd48..2c91ee6 100644
--- a/post_server/WiFiManager.cpp
+++ b/post_server/WiFiManager.cpp
@@ -287,8 +287,8 @@ bool WIFI_PostBufferSync() {
     for (uint8_t i = 0; i < g_buffer_count; i++) {
         if (i) len += snprintf(json + len, sizeof(json) - len, ",");
         len += snprintf(json + len, sizeof(json) - len,
-                        "{\"table\":\"%s\",\"value\":\"%s\",\"time\":%lld}",
-                        g_buffer[i].table, g_buffer[i].value, g_buffer[i].time);
+                        "{\"table\":\"%s\",\"value\":\"%s\",\"time\":%lld,\"pump_reached\":%d}",
+                        g_buffer[i].table, g_buffer[i].value, g_buffer[i].time, g_buffer[i].pump_reached);
     }
     len += snprintf(json + len, sizeof(json) - len, "]");
 
diff --git a/post_server/WiFiManager.h b/post_server/WiFiManager.h
index d93362a..f80a2f7 100644
--- a/post_server/WiFiManager.h
+++ b/post_server/WiFiManager.h
@@ -7,7 +7,7 @@
 
 bool WIFI_GetSensorConfigServer(const char* sensor_name, SensorConfigServer_s &cfg);
 
-using  WIFI_ReadingCallback = void(*)(const char* table, const char* value, const int64_t time);
+using  WIFI_ReadingCallback = void(*)(const char* table, const char* value, const int64_t time, const bool pump_reached);
 extern WIFI_ReadingCallback WIFI_OnAddReading;
 
 int64_t now();
diff --git a/server/Server.cpp b/server/Server.cpp
index 30e5952..bb03fec 100644
--- a/server/Server.cpp
+++ b/server/Server.cpp
@@ -37,7 +37,7 @@ void print_SensorConfigServer(const SensorConfigServer_s& cfg) {
 // Server handling (g_buffer)
  // ----------------------------------------------------------------------------
 
-void add_ReadingCallback(const char* table, const char* value, const int64_t time) {
+void add_ReadingCallback(const char* table, const char* value, const int64_t time, const bool pump_reached) {
     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--;
@@ -46,6 +46,7 @@ void add_ReadingCallback(const char* table, const char* value, const int64_t tim
     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[g_buffer_count].pump_reached = pump_reached;
     g_buffer_count++;
 }
 
@@ -162,25 +163,28 @@ void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
         return;
     }
 
-    // --- Normal table:value:time handling ---
+    // --- Normal table:value:time:pump_reached 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;
+    char *first  = strchr(msg, ':');
+    char *second = first  ? strchr(first  + 1, ':') : NULL;
+    char *third  = second ? strchr(second + 1, ':') : NULL;
 
-    if (first && second) {
+    if (first && second && third) {
         *first = '\0';
         *second = '\0';
+        *third = '\0';
 
-        const char *sensor_name = msg;
-        const char *value_str   = first + 1;
-        const int64_t time = atoll(second + 1);
+        const char *sensor_name  = msg;
+        const char *value_str    = first + 1;
+        const int64_t time       = atoll(second + 1);
+        const bool pump_reached  = (*(third + 1) == '1');
 
-        add_ReadingCallback(sensor_name, value_str, time);
+        add_ReadingCallback(sensor_name, value_str, time, pump_reached);
     } else {
-        DBG_PRINTLN("Invalid message format (expected <name>:<value>:<time>)");
+        DBG_PRINTLN("Invalid message format (expected <name>:<value>:<time>:<reached_pump>)");
     }
 
     /*