esp_garden git · master
Distributed ESP sensor and actuator system (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.gzUpdate DeepSleep also for server now
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(); + } + + } }