#include "Server.h" #include "secrets.h" #include "WiFiManager.h" #include #include "esp_wifi_types.h" #include "esp_now.h" #include "esp_log.h" #include #include #include #include #include uint8_t received_from_mac_addr[6]; // ---------------------------------------------------------------------------- // Helper // ---------------------------------------------------------------------------- int64_t get_CurrentUnix() { return (int64_t)time(nullptr); } void printMac(const uint8_t* mac) { if (!mac) return; ESP_LOGI("APP", "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } void print_SensorConfigServer(const SensorConfigServer_s& cfg) { static const char *TAG = "print_SensorConfig"; ESP_LOGI(TAG, "----------------------------"); ESP_LOGI(TAG, "Got cfg for moisture_1:"); ESP_LOGI(TAG, "Pin: %d", cfg.pin); ESP_LOGI(TAG, "Use Time: %d", cfg.use_time); ESP_LOGI(TAG, "Delay: %d", cfg.delay_ms); ESP_LOGI(TAG, "Notification Name: %s", cfg.notification_name); ESP_LOGI(TAG, "Min Moisture: %d", cfg.min_moisture); ESP_LOGI(TAG, "Active: %d", cfg.is_active); ESP_LOGI(TAG, "Pumping Delay: %d", cfg.pumping_delay_sec); ESP_LOGI(TAG, "Pumping Duration: %d", cfg.pumping_duration); for (uint8_t i = 0; i < cfg.time_count; i++) { uint16_t minutes = cfg.times[i]; uint8_t hh = minutes / 60; uint8_t mm = minutes % 60; ESP_LOGI(TAG, "Time[%d]: %02u:%02u (%u min)", i, hh, mm, minutes); } ESP_LOGI(TAG, "----------------------------"); } // ---------------------------------------------------------------------------- // ESP-NOW helpers // ---------------------------------------------------------------------------- void on_DataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) { static const char *TAG = "on_DataSent"; if (!info) return; const uint8_t *mac_addr = info->des_addr; // destination MAC ESP_LOGI(TAG, "Delivery to %02X:%02X:%02X:%02X:%02X:%02X %s", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5], status == ESP_NOW_SEND_SUCCESS ? "OK" : "FAIL"); } void add_Peer(const uint8_t *addr) { if (!addr) return; if (esp_now_is_peer_exist(addr)) return; esp_now_peer_info_t peer = {0}; memcpy(peer.peer_addr, addr, 6); peer.ifidx = WIFI_IF_STA; peer.channel = 0; // auto-select current Wi-Fi channel peer.encrypt = false; esp_now_add_peer(&peer); } // ---------------------------------------------------------------------------- // ESP-NOW receive callback // ---------------------------------------------------------------------------- void add_Reading(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--; } strncpy(g_buffer[g_buffer_count].table, table, TABLE_SIZE-1); 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++; } void on_DataRecv(const esp_now_recv_info_t *info, const uint8_t *data, int len) { static const char *TAG = "on_DataRecv"; if (!info || !data || len <= 0) return; memcpy(received_from_mac_addr, info->src_addr, 6); add_Peer(received_from_mac_addr); char msg[128]; int copylen = len < (int)sizeof(msg) - 1 ? len : (int)sizeof(msg) - 1; memcpy(msg, data, copylen); msg[copylen] = '\0'; ESP_LOGI(TAG, "Received from %02X:%02X:%02X:%02X:%02X:%02X: %s", 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) { char time_msg[32]; snprintf(time_msg, sizeof(time_msg), "time:%lld", get_CurrentUnix()); esp_now_send(received_from_mac_addr, (uint8_t *)time_msg, strlen(time_msg)); return; } if (strncmp(msg, "next_read:", 10) == 0) { const char *value_str = msg + 10; next_connection_unix = atoll(value_str); go_to_sleep = true; ESP_LOGI(TAG, "Received next_read: %lld", next_connection_unix); return; } 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); pending_config.sensor_name[sizeof(pending_config.sensor_name) - 1] = '\0'; ESP_LOGI(TAG, "Queued config request for %s", pending_config.sensor_name); return; } ESP_LOGI(TAG, "Message: %s", msg); g_received_ok_from_server = false; char *first = strchr(msg, ':'); char *second = first ? strchr(first + 1, ':') : NULL; char *third = second ? strchr(second + 1, ':') : NULL; if (first && second && third) { *first = '\0'; *second = '\0'; *third = '\0'; const char *sensor_name = msg; const char *value_str = first + 1; int64_t time = atoll(second + 1); bool pump_reached = (*(third + 1) == '1'); add_Reading(sensor_name, value_str, time, pump_reached); } else { ESP_LOGW(TAG, "Invalid message format (expected ::