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 pump reached
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>)"); } /*