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.gzAdd is pump active; Set sensor MAC on first connection
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(); }