Nimbin[12]?Embedded / esp_garden / commits / 721536b

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

Christian Immanuel · 2025-10-26 18:57 · 721536bd0138bec5a15247b5b46f2483b3cab73a

 client_pump/client_pump.ino    | 192 +++--------------------------------------
 client_sensor/ClientSensor.cpp |  46 ++++++----
 client_sensor/ClientSensor.h   |   9 +-
 3 files changed, 42 insertions(+), 205 deletions(-)

diff --git a/client_pump/client_pump.ino b/client_pump/client_pump.ino
index c175419..2b8f923 100644
--- a/client_pump/client_pump.ino
+++ b/client_pump/client_pump.ino
@@ -1,209 +1,36 @@
-#include "globals.h"
-#include "secrets.h"
-
-#include <Arduino.h>
-#include <WiFi.h>
-#include <esp_wifi.h>
-#include <esp_now.h>
-#include <esp_sleep.h>
-#include <sys/time.h>
-
+#include "ClientPump.h"
 
 #include "esp_system.h"
 extern "C" esp_err_t esp_base_mac_addr_set(const uint8_t mac[6]);
 
-long long next_message_unix = 0;
-bool go_to_sleep = false;
 
 
-enum PumpSatatus_e {
-    INACTIVE,
-    START,
-    RUNNING,
-    FINISHED
-};
 
-struct PumpConfig_s {
-    char pump_name[32];
-    int pumping_delay_sec;
-    int pumping_duration;
-    long long next_message_unix;
-    long long pumping_started_at_unix;
-    PumpSatatus_e pumping_status;
-};
+long long next_message_unix = 0;
+bool received_starting_message = false;
 
-#define PUMP_COUNT 2
 PumpConfig_s pump_configs[PUMP_COUNT] = {
     {"pump_1", 0, 0, 0, 0, INACTIVE},
     {"pump_2", 0, 0, 0, 0, INACTIVE},
 };
 
-// ----------------------------------------------------------------------------
-// Time handling
-// ----------------------------------------------------------------------------
-
-int64_t get_CurrentUnix() {
-    return (int64_t)time(nullptr);
-}
-
-void setup_Timezone() {
-    setenv("TZ", "CET-1CEST,M3.5.0,M10.5.0/3", 1);
-    tzset();
-}
-
-void set_LocalTime(long long unix_now) {
-    struct timeval tv;
-    tv.tv_sec = unix_now;   // seconds since epoch
-    tv.tv_usec = 0;         // microseconds
-
-    settimeofday(&tv, nullptr);  // set system time
-}
-
-// ----------------------------------------------------------------------------
-// WiFi handling
-// ----------------------------------------------------------------------------
-int32_t get_WiFiChannel() {
-    DBG_PRINTLN(ssid);
-    int32_t n = WiFi.scanNetworks();
-    if (n <= 0) return 0;
-    for (uint8_t i = 0; i < n; i++) {
-        if (!strcmp(ssid, WiFi.SSID(i).c_str())) return WiFi.channel(i);
-    }
-    return 0;
-}
-
-void init_WiFi() {
-    WiFi.mode(WIFI_MODE_STA);
-    int32_t channel = get_WiFiChannel();
-    if (channel > 0) {
-        esp_wifi_set_promiscuous(true);
-        esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE);
-        esp_wifi_set_promiscuous(false);
-    }
-}
-
-
-// ----------------------------------------------------------------------------
-// ESP-NOW handling
-// ----------------------------------------------------------------------------
-
-void on_DataRecv(const esp_now_recv_info *info, const uint8_t *data, int len) {
-    if (!info || !data || len <= 0) return;
-    if (memcmp(info->src_addr, PEER_SENSOR, 6) != 0) return;
-
-    PumpConfig_s pump_config;
-    char msg[64];
-    long long unix_now = 0;
-    memcpy(msg, data, len);
-    msg[len] = '\0';
-
-    DBG_PRINTF("Received from server: %s\n", msg);
-
-    if (strncmp(msg, "p:", 2) == 0) {
-
-        int n = sscanf(msg, "p:%lld:%31[^:]:%d:%d:%lld",
-                &unix_now,
-                pump_config.pump_name,
-                &pump_config.pumping_delay_sec,
-                &pump_config.pumping_duration,
-                &pump_config.next_message_unix);
-
-        if (n == 5) {
-            for (size_t i = 0; i < PUMP_COUNT; i++) {
-                if (strcmp(pump_configs[i].pump_name, pump_config.pump_name) != 0)
-                    continue;
-
-                memcpy(&pump_configs[i], &pump_config, sizeof(PumpConfig_s));
-                next_message_unix = pump_config.next_message_unix;
-
-                DBG_PRINTF("unix_now: %lld\n", unix_now);
-                DBG_PRINTF("pump_name: %s\n", pump_configs[i].pump_name);
-                DBG_PRINTF("pumping_delay_sec: %d\n", pump_configs[i].pumping_delay_sec);
-                DBG_PRINTF("pumping_duration:  %d\n", pump_configs[i].pumping_duration);
-                DBG_PRINTF("next_message_unix: %lld\n", pump_configs[i].next_message_unix);
-
-                set_LocalTime(unix_now);
-
-                if (pump_configs[i].pumping_duration > 0) {
-                    pump_configs[i].pumping_status = START;
-                } else {
-                    go_to_sleep = true;
-                }
-                break;
-            }
-        } else {
-            DBG_PRINTLN("Failed to parse message");
-        }
-    }
-}
-
-
-void init_EspNow() {
-    if (esp_now_init() != ESP_OK) {
-        DBG_PRINTLN("ESP NOW init failed");
-        while (true);
-    }
-    esp_now_register_recv_cb(on_DataRecv);
-}
-
-
-// ----------------------------------------------------------------------------
-// Deep sleep scheduler
-// ----------------------------------------------------------------------------
-
-void sleep_UntilNextSend(int64_t next_read) {
-    go_to_sleep = false;
-
-    int64_t now_sec = get_CurrentUnix();
-
-    int64_t delta_sec = next_read - now_sec;
-    if (delta_sec <= 0) delta_sec = 0;
-
-    uint32_t min_delay_ms = delta_sec > UINT32_MAX / 1000
-                          ? UINT32_MAX
-                          : (uint32_t)(delta_sec * 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_pump;
-    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();
-}
-
-
 
 
 void start_Pump(PumpConfig_s& pump_data) {
+    DBG_PRINTF("Starting Pump %s\n", pump_data.pump_name);
     pump_data.pumping_started_at_unix = get_CurrentUnix();
     pump_data.pumping_status = RUNNING;
-    DBG_PRINTF("Starting Pump %s\n", pump_data.pump_name);
     // whatever we have to do to make the pump running
 }
 
 void stop_Pump(PumpConfig_s& pump_data) {
-    pump_data.pumping_status = INACTIVE;
     DBG_PRINTF("Stopped Pump %s\n", pump_data.pump_name);
+    pump_data.pumping_status = INACTIVE;
     // whatever we have to do to stop the pump
 }
 
 void setup() {
     uint32_t setup_start = millis();
-    go_to_sleep = false;
 
     DBG_BEGIN();
 
@@ -213,6 +40,9 @@ void setup() {
     init_WiFi();
     init_EspNow();
 
+    next_message_unix = 0;
+    received_starting_message = false;
+
     g_setup_duration = millis() - setup_start;
     DBG_PRINTF("Setup duration: %u ms\n", g_setup_duration);
 }
@@ -225,20 +55,22 @@ void loop() {
 
         if (START == cfg.pumping_status) {
 
-            start_Pump(cfg);
             pumping = true;
+            received_starting_message = false;
+            start_Pump(cfg);
 
         } else
         if (RUNNING == cfg.pumping_status) {
 
             long long stop_time = cfg.pumping_started_at_unix + cfg.pumping_duration;
             long long now = get_CurrentUnix();
+            // maybe we should add a safety here so we dont pump longer than n seconds,...
             if (stop_time <= now)
                 stop_Pump(cfg);
             else pumping = true;
 
         }
     }
-    if (go_to_sleep && !pumping)
+    if (!pumping && next_message_unix != 0 && !received_starting_message)
         sleep_UntilNextSend(next_message_unix);
 }
diff --git a/client_sensor/ClientSensor.cpp b/client_sensor/ClientSensor.cpp
index eb8fd6c..4d4993d 100644
--- a/client_sensor/ClientSensor.cpp
+++ b/client_sensor/ClientSensor.cpp
@@ -1,6 +1,12 @@
 #include "ClientSensor.h"
 #include "secrets.h"
 
+#include <WiFi.h>
+#include <esp_wifi.h>
+#include <esp_now.h>
+#include <esp_sleep.h>
+#include <sys/time.h>
+
 volatile bool rtc_synced_with_server = false;
 volatile bool response_received = false;
 volatile bool send_process_complete = false;
@@ -135,7 +141,7 @@ void on_DataSent(const wifi_tx_info_t* info, esp_now_send_status_t status) {
     }
 
     if (status == ESP_NOW_SEND_SUCCESS)
-        DBG_PRINTLN(" queued successfully (waiting for Response)");
+        DBG_PRINTLN(" queued successfully");
     else
         DBG_PRINTLN(" failed to queue!");
 }
@@ -420,13 +426,15 @@ int64_t get_NextSensorReadFor(const char* sensor_name) {
     return -1;
 }
 
-int64_t get_NextSensorReadsUnixTime() {
+int64_t get_NextSensorReadsUnixTime(const uint8_t* mac) {
     int64_t unix_now = get_CurrentUnix();
     int64_t unix_next = INT64_MAX;
 
     for (size_t i = 0; i < SENSOR_CONFIG_COUNT; i++) {
         SensorConfig_s &p = sensor_configs[i];
         if (!p.is_active) continue;
+        if (mac != nullptr && memcmp(mac, p.pump_mac, 6) != 0) continue;
+
 
         int64_t next_time = get_NextSensorReadFor(p.sensor_name);
 
@@ -692,28 +700,30 @@ void get_AllSensorConfigs() {
 // ----------------------------------------------------------------------------
 
 
-void send_DataToPeer(size_t config_id, uint32_t value) {
-    char message[64];
-
-
+void send_DataToPumpAndServer(size_t config_id, uint32_t value, bool shall_pump) {
     SensorConfig_s& p = sensor_configs[config_id];
+    DBG_PRINTF("send_DataToPumpAndServer: %s\n", p.sensor_name);
 
-    DBG_PRINTF("send_DataToPeer: %s\n", p.sensor_name);
+    int pumping_duration = shall_pump ? p.pumping_duration : 0;
 
-    snprintf(message, sizeof(message), "%s:%u:%lld", p.sensor_name, value, p.last_sensor_read);
+    char message[64];
 
-    DBG_PRINT("Sending to peer: ");
-    printMac(p.pump_mac);
-    send_response_process_complete = false;
-    if (!send_AndWaitResponse(p.pump_mac, message)) {
-        DBG_PRINTLN("Delivery failed or peer offline!");
-        send_response_process_complete = true;
-    }
+    DBG_PRINT("Sending to Pump: "); printMac(p.pump_mac);
+    snprintf(message, sizeof(message), "p:%lld:%s:%d:%d:%lld",
+            get_CurrentUnix(),
+            p.notification_name,
+            p.pumping_delay_sec,
+            pumping_duration,
+            get_NextSensorReadsUnixTime(p.pump_mac));
 
-    while (!send_response_process_complete) delay(100);
+    if (!send_Message(p.pump_mac, message))
+        DBG_PRINTLN("Delivery failed or peer offline!");
 
-    DBG_PRINT("Sending to peer: ");
-    printMac(PEER_SERVER);
+    DBG_PRINT("Sending to Server: "); printMac(PEER_SERVER);
+    snprintf(message, sizeof(message), "%s:%u:%lld",
+            p.sensor_name,
+            value,
+            p.last_sensor_read);
     send_response_process_complete = false;
     if (!send_AndWaitResponse(PEER_SERVER, message)) {
         DBG_PRINTLN("Failed to get response from server!");
diff --git a/client_sensor/ClientSensor.h b/client_sensor/ClientSensor.h
index a874281..0161912 100644
--- a/client_sensor/ClientSensor.h
+++ b/client_sensor/ClientSensor.h
@@ -4,11 +4,6 @@
 #include "globals.h"
 
 #include <Arduino.h>
-#include <WiFi.h>
-#include <esp_wifi.h>
-#include <esp_now.h>
-#include <esp_sleep.h>
-#include <sys/time.h>
 
 
 
@@ -51,7 +46,7 @@ void setup_Timezone();
 // Deep sleep scheduler
 // ----------------------------------------------------------------------------
 int64_t get_NextSensorReadFor(const char* sensor_name);
-int64_t get_NextSensorReadsUnixTime();
+int64_t get_NextSensorReadsUnixTime(const uint8_t* mac = nullptr);
 void    sleep_UntilNextSend(int64_t next_read);
 
 // ----------------------------------------------------------------------------
@@ -66,7 +61,7 @@ void process_PendingSensorConfigs();
 // ----------------------------------------------------------------------------
 
 bool is_TimeToReadSensor(size_t config_id);
-void send_DataToPeer(size_t config_id, uint32_t value);
+void send_DataToPumpAndServer(size_t config_id, uint32_t value, bool shall_pump);
 void send_NextSensorReadToPeer(const uint8_t* mac, int64_t unix_time);