Nimbin[12]?Embedded / esp_garden / commits / 8f00a16

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

Cleanup a bit

Christian Immanuel · 2025-10-23 07:38 · 8f00a16732ec8d051cb254fbf90b4a7a05fdd57f

 client_sensor/client_sensor.ino | 311 +++++++++++++++++++++-------------------
 1 file changed, 160 insertions(+), 151 deletions(-)

diff --git a/client_sensor/client_sensor.ino b/client_sensor/client_sensor.ino
index 6ae5211..37709f7 100644
--- a/client_sensor/client_sensor.ino
+++ b/client_sensor/client_sensor.ino
@@ -15,6 +15,18 @@ volatile bool send_ack_process_complete = false;
 
 const uint32_t min_sleep_time = 60000;
 
+
+// ----------------------------------------------------------------------------
+// Helper
+// ----------------------------------------------------------------------------
+void print_Mac(const uint8_t* mac) {
+    for (size_t i = 0; i < 6; i++) {
+        if (i > 0) DBG_PRINT(":");
+        DBG_PRINTF("%02X", mac[i]);
+    }
+    DBG_PRINTLN();
+}
+
 // ----------------------------------------------------------------------------
 // WiFi handling
 // ----------------------------------------------------------------------------
@@ -88,6 +100,7 @@ Preferences prefs;
 
 bool load_SensorConfigs() {
     DBG_PRINTLN("Loading sensor configs from NVS...");
+
     prefs.begin("sensors", true);
     size_t stored_size = prefs.getBytesLength("configs");
     DBG_PRINTF("Stored size: %u bytes\n", (unsigned)stored_size);
@@ -96,23 +109,25 @@ bool load_SensorConfigs() {
         prefs.getBytes("configs", sensor_configs, sizeof(sensor_configs));
         ok = true;
         DBG_PRINTLN("Config read successfully.");
-    } else {
-        DBG_PRINTLN("No valid stored config found.");
-    }
+    } else DBG_PRINTLN("No valid stored config found.");
     prefs.end();
+
     return ok;
 }
 
 void save_SensorConfigs() {
     DBG_PRINTLN("Saving sensor configs to NVS...");
+
     prefs.begin("sensors", false);
     prefs.putBytes("configs", sensor_configs, sizeof(sensor_configs));
     prefs.end();
+
     DBG_PRINTLN("Save complete.");
 }
 
 void restore_SensorConfigs() {
-  DBG_PRINTLN("Trying to load old config!");
+    DBG_PRINTLN("Trying to load old config!");
+
     bool restored = load_SensorConfigs();
     if (restored) {
         DBG_PRINTLN("Sensor configs restored from flash.");
@@ -186,11 +201,10 @@ void on_DataSent(const wifi_tx_info_t* info, esp_now_send_status_t status) {
         if (i < 5) DBG_PRINT(":");
     }
 
-    if (status == ESP_NOW_SEND_SUCCESS) {
+    if (status == ESP_NOW_SEND_SUCCESS)
         DBG_PRINTLN(" queued successfully (waiting for ACK)");
-    } else {
+    else
         DBG_PRINTLN(" failed to queue!");
-    }
 }
 
 void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
@@ -294,14 +308,14 @@ void init_EspNow() {
 
 bool send_Message(const uint8_t* peer, const char* message) {
     if (!esp_now_is_peer_exist(peer)) {
-      DBG_PRINTLN("ERROR: peer doese not exist!");
-      return false;
+        DBG_PRINTLN("ERROR: peer doese not exist!");
+        return false;
     }
     esp_err_t result = esp_now_send(peer, (uint8_t*)message, strlen(message));
     return result == ESP_OK;
 }
 
-bool send_And_wait_Ack(const uint8_t* peer, const char* message, uint32_t timeout_ms = 32000) {
+bool send_And_wait_Ack(const uint8_t* peer, const char* message, uint32_t timeout_ms = 5000) {
     send_ack_process_complete = false;
     ack_received = false;
 
@@ -347,8 +361,8 @@ void sleep_UntilNextSend() {
             }
         } else {
             uint32_t delta_ms = (p.delay_ms > (ms_now - last_sent_array[i]))
-                               ? (p.delay_ms - (ms_now - last_sent_array[i]))
-                               : 0;
+                ? (p.delay_ms - (ms_now - last_sent_array[i]))
+                : 0;
             if (delta_ms < min_delay_ms) min_delay_ms = delta_ms;
         }
     }
@@ -375,12 +389,10 @@ void sleep_UntilNextSend() {
 // Request sensor config from server via ESP-NOW
 // ----------------------------------------------------------------------------
 RTC_DATA_ATTR bool all_init_configs_received = false;
-RTC_DATA_ATTR bool init_configs_received[num_sensor_configs] = { false };
-volatile bool waiting_for_config = false;
 volatile bool sensor_config_received = false;
 char sensor_config_message[256] = {0};
 
-void on_DataRecvSensorConfig_s(const esp_now_recv_info* info, const uint8_t* data, int len) {
+void on_DataRecvSensorConfig(const esp_now_recv_info* info, const uint8_t* data, int len) {
     if (!info || !data || len <= 0) return;
     if (memcmp(info->src_addr, PEER_SERVER, 6) != 0) return;
 
@@ -400,7 +412,7 @@ bool request_SensorConfig(const char* sensor_name) {
     sensor_config_received = false;
     memset(sensor_config_message, 0, sizeof(sensor_config_message));
 
-    esp_now_register_recv_cb(on_DataRecvSensorConfig_s);
+    esp_now_register_recv_cb(on_DataRecvSensorConfig);
 
     char msg[64];
     snprintf(msg, sizeof(msg), "get_config:%s", sensor_name);
@@ -446,24 +458,23 @@ bool request_SensorConfig(const char* sensor_name) {
 
 
     if (count_token < 9) {
-      DBG_PRINTLN("Incomplete config data");
-      return false;
+        DBG_PRINTLN("Incomplete config data");
+        return false;
     }
 
-    // find target config by name
     SensorConfig_s *cfg = NULL;
     size_t config_id = 0;
     for (size_t i = 0; i < sizeof(sensor_configs) / sizeof(sensor_configs[0]); i++) {
-      if (strcmp(sensor_configs[i].sensor_name, tokens[0]) == 0) {
-        config_id = i;
-        cfg = &sensor_configs[i];
-        break;
-      }
+        if (strcmp(sensor_configs[i].sensor_name, tokens[0]) == 0) {
+            config_id = i;
+            cfg = &sensor_configs[i];
+            break;
+        }
     }
 
     if (!cfg) {
-      DBG_PRINTF("Unknown sensor name in config: %s\n", tokens[0]);
-      return false;
+        DBG_PRINTF("Unknown sensor name in config: %s\n", tokens[0]);
+        return false;
     }
 
     // basic fields
@@ -483,182 +494,180 @@ bool request_SensorConfig(const char* sensor_name) {
     // times
     cfg->time_count = 0;
     if (cfg->use_time && count_token > 9 && strncmp(tokens[9], "times=", 6) == 0) {
-      char *time_str = tokens[9] + 6;
-      char *time_tok = strtok(time_str, "|");
-      while (time_tok && cfg->time_count < 8) {
-        cfg->times[cfg->time_count++] = (uint16_t)atoi(time_tok);
-        time_tok = strtok(NULL, "|");
-      }
+        char *time_str = tokens[9] + 6;
+        char *time_tok = strtok(time_str, "|");
+        while (time_tok && cfg->time_count < 8) {
+            cfg->times[cfg->time_count++] = (uint16_t)atoi(time_tok);
+            time_tok = strtok(NULL, "|");
+        }
     }
 
-    init_configs_received[config_id] = true;
     config_request_attempts = 0;
     return true;
 }
 
+void process_PendingSensorConfigs() {
+    config_request_attempts = 0;
+    DBG_PRINTF("NEW CONFIGS: %d\n", g_pending_sensor_configs_count);
 
-// ----------------------------------------------------------------------------
-// Helper
-// ----------------------------------------------------------------------------
-void print_Mac(const uint8_t* mac) {
-    for (size_t i = 0; i < 6; i++) {
-        if (i > 0) DBG_PRINT(":");
-        DBG_PRINTF("%02X", mac[i]);
+    size_t config_id = 0;
+    bool save_new_configs = false;
+    while (config_id < g_pending_sensor_configs_count) {
+        DBG_PRINTF("SENSOR: %s\n", g_pending_sensor_configs[config_id]);
+
+        bool success = false;
+        for (config_request_attempts = 0;
+                config_request_attempts < config_request_attempts_max;
+                config_request_attempts++) {
+
+            DBG_PRINTF("Requesting config attempt %u...\n", config_request_attempts + 1);
+            if (request_SensorConfig(g_pending_sensor_configs[config_id])) {
+                success = true;
+                break;
+            }
+            delay(2000);
+        }
+
+        if (success) {
+            DBG_PRINTF("Config %s processed successfully, removing.\n",
+                    g_pending_sensor_configs[config_id]);
+            if (config_id >= g_pending_sensor_configs_count) return;
+            for (size_t i = config_id; i < g_pending_sensor_configs_count - 1; i++)
+                strcpy(g_pending_sensor_configs[i], g_pending_sensor_configs[i + 1]);
+            g_pending_sensor_configs_count--;
+            save_new_configs = true;
+        } else {
+            DBG_PRINTLN("Config request failed repeatedly, aborting loop.");
+            break;
+        }
     }
-    DBG_PRINTLN();
-}
 
-// ----------------------------------------------------------------------------
-// Setup
-// ----------------------------------------------------------------------------
-void setup() {
-    DBG_BEGIN();
-    setup_Timezone();
-    init_WiFi();
-    init_EspNow();
+    if (save_new_configs) save_SensorConfigs();
+}
 
-    DBG_PRINTLN("Requesting time sync...");
-    if (request_TimeSync()) DBG_PRINTLN("done");
-    else DBG_PRINTLN("failed (timeout)");
+void get_AllSensorConfigs() {
+    g_pending_sensor_configs_count = 0;
 
-    restore_SensorConfigs();
+    for (size_t i = 0; i < num_sensor_configs; ++i) {
+        strncpy(
+            g_pending_sensor_configs[g_pending_sensor_configs_count],
+            sensor_configs[i].sensor_name,
+            sizeof(g_pending_sensor_configs[0]) - 1
+        );
 
-    //all_init_configs_received = false;
-    //waiting_for_config = false;
-    DBG_PRINTF("----------------------\n");
+        g_pending_sensor_configs[g_pending_sensor_configs_count][sizeof(g_pending_sensor_configs[0]) - 1] = '\0';
 
-    config_request_attempts = 0;
+        ++g_pending_sensor_configs_count;
+    }
 
-    if (!all_init_configs_received) {
-      if (!waiting_for_config) {
-        waiting_for_config = true;
-        for (size_t config_id = 0; config_id < num_sensor_configs; config_id++) {
-          DBG_PRINTF("SENSOR: %s\n", sensor_configs[config_id].sensor_name);
-          if (init_configs_received[config_id]) {
-            DBG_PRINTLN("INIT CONFIG ALREADY RECEIVED!");
-            continue;
-          }
-          for (config_request_attempts = 0;
-               config_request_attempts < config_request_attempts_max; config_request_attempts++) {
-            DBG_PRINTF("Requesting config attempt %u...\n", config_request_attempts + 1);
-            if (request_SensorConfig(sensor_configs[config_id].sensor_name)) break;
-            delay(2000);
-          }
 
-          // no need to go on testing if we already failed 3 times
-          if (config_request_attempts >= config_request_attempts_max) {
-            break;
-          } else config_request_attempts = 0;
-        }
+    process_PendingSensorConfigs();
+    if (g_pending_sensor_configs_count == 0)
         all_init_configs_received = true;
-        waiting_for_config = false;
-        save_SensorConfigs();
-      }
-    }
-    DBG_PRINTF("----------------------\n");
 }
 
 // ----------------------------------------------------------------------------
-// Loop
+// Send Data to peers
 // ----------------------------------------------------------------------------
 
-void loop() {
-    ensure_Peers();
-
-    DBG_PRINTF("## Unix time: %llu\n", (unsigned long long)get_CurrentUnixMs() / 1000);
-    for (size_t i = 0; i < num_sensor_configs; i++) {
-      uint64_t ms_now = get_CurrentUnixMs();
+void send_DataToPeer(size_t config_id, uint32_t value) {
+    uint64_t ms_now = get_CurrentUnixMs();
 
-      SensorConfig_s& p = sensor_configs[i];
+    SensorConfig_s& p = sensor_configs[config_id];
 
-      DBG_PRINTF("SENSOR: %s\n", p.sensor_name);
-      printSensorConfig(p);
-      if (!p.is_active) { 
+    DBG_PRINTF("SENSOR: %s\n", p.sensor_name);
+    printSensorConfig(p);
+    if (!p.is_active) { 
         DBG_PRINTLN("Sensor is inactive!");
-        continue;
-      }
+        return;
+    }
 
-      bool should_send = false;
+    bool should_send = false;
 
-      if (p.use_time) {
+    if (p.use_time) {
         uint16_t min_current = get_CurrentMinutes();
         for (size_t j = 0; j < p.time_count; j++) {
-          if (min_current == p.times[j] &&
-              ms_now - last_sent_array[i] > 60000) {
-            should_send = true;
-            break;
-          }
+            if (min_current == p.times[j] &&
+                    ms_now - last_sent_array[config_id] > 60000) {
+                should_send = true;
+                break;
+            }
         }
-      } else {
-        if (ms_now - last_sent_array[i] >= p.delay_ms) should_send = true;
-      }
+    } else {
+        if (ms_now - last_sent_array[config_id] >= p.delay_ms) should_send = true;
+    }
 
-      if (should_send) {
+    if (should_send) {
         char message[32];
-        snprintf(message, sizeof(message), "%s:%u", p.sensor_name, value_to_send);
+        snprintf(message, sizeof(message), "%s:%u", p.sensor_name, value);
 
         DBG_PRINT("Sending to peer: ");
         print_Mac(p.pump_mac);
         send_ack_process_complete = false;
         if (!send_And_wait_Ack(p.pump_mac, message)) {
-          DBG_PRINTLN("Delivery failed or peer offline!");
-          send_ack_process_complete = true;
+            DBG_PRINTLN("Delivery failed or peer offline!");
+            send_ack_process_complete = true;
         } else {
-          last_sent_array[i] = get_CurrentUnixMs();
-          value_to_send++;
+            last_sent_array[config_id] = get_CurrentUnixMs();
+            value++;
         }
 
-        while (!send_ack_process_complete) {
-          delay(100);
-        };
+        while (!send_ack_process_complete) delay(100);
 
         DBG_PRINT("Sending to peer: ");
         print_Mac(PEER_SERVER);
         send_ack_process_complete = false;
         if (!send_And_wait_Ack(PEER_SERVER, message)) {
-          DBG_PRINTLN("Failed to get ack from server!");
-          send_ack_process_complete = true;
+            DBG_PRINTLN("Failed to get ack from server!");
+            send_ack_process_complete = true;
         }
-        while (!send_ack_process_complete) {
-          delay(100);
-        };
+        while (!send_ack_process_complete) delay(100);
+
         delay(5000);
-      }
     }
+}
 
-    config_request_attempts = 0;
-    DBG_PRINTF("NEW CONFIGS: %d\n", g_pending_sensor_configs_count);
+// ----------------------------------------------------------------------------
+// Setup
+// ----------------------------------------------------------------------------
+void setup() {
+    DBG_BEGIN();
+    setup_Timezone();
+    init_WiFi();
+    init_EspNow();
 
-    size_t config_id = 0;
-    while (config_id < g_pending_sensor_configs_count) {
-      DBG_PRINTF("SENSOR: %s\n", g_pending_sensor_configs[config_id]);
+    DBG_PRINTLN("Requesting time sync...");
+    if (request_TimeSync()) DBG_PRINTLN("done");
+    else DBG_PRINTLN("failed (timeout)");
+
+    restore_SensorConfigs();
+
+    //all_init_configs_received = false;
+    DBG_PRINTF("----------------------\n");
+
+    // Add all known configs to an array so we can request thoose from server
+    if (!all_init_configs_received)
+        get_AllSensorConfigs();
+
+    DBG_PRINTF("----------------------\n");
+}
+
+// ----------------------------------------------------------------------------
+// Loop
+// ----------------------------------------------------------------------------
+
+void loop() {
+    ensure_Peers();
+
+    DBG_PRINTF("## Unix time: %llu\n", (unsigned long long)get_CurrentUnixMs() / 1000);
+    for (size_t config_id = 0; config_id < num_sensor_configs; config_id++) {
+        send_DataToPeer(config_id, value_to_send);
+    }
+
+    if (g_pending_sensor_configs_count > 0)
+        process_PendingSensorConfigs();
 
-      bool success = false;
-      for (config_request_attempts = 0;
-          config_request_attempts < config_request_attempts_max;
-          config_request_attempts++) {
 
-        DBG_PRINTF("Requesting config attempt %u...\n", config_request_attempts + 1);
-        if (request_SensorConfig(g_pending_sensor_configs[config_id])) {
-          success = true;
-          break;
-        }
-        delay(2000);
-      }
-
-      if (success) {
-        DBG_PRINTF("Config %s processed successfully, removing.\n", g_pending_sensor_configs[config_id]);
-        if (config_id >= g_pending_sensor_configs_count) return;
-        for (size_t i = config_id; i < g_pending_sensor_configs_count - 1; i++)
-          strcpy(g_pending_sensor_configs[i], g_pending_sensor_configs[i + 1]);
-        g_pending_sensor_configs_count--;
-      } else {
-        DBG_PRINTLN("Config request failed repeatedly, aborting loop.");
-        break;
-      }
-    }
-
-  
     /*
      * Tell server some infos
      * how long am i gonna sleep, which configurations have i updated