#include "ClientSensor.h" #include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" #include "esp_timer.h" #include extern "C" esp_err_t esp_base_mac_addr_set(const uint8_t mac[6]); // this is going to be a sensor read value! // RTC_DATA_ATTR is not required than! RTC_DATA_ATTR uint32_t fake_value_to_send = 0; // ---------------------------------------------------------------------------- // Fix time after power loss and no server connection // ---------------------------------------------------------------------------- void restore_TimeBackup() { int64_t stored_epoch_ref = 0; int64_t stored_uptime_ref = 0; // load persisted values from NVS load_time_reference(&stored_epoch_ref, &stored_uptime_ref); struct timeval tv; gettimeofday(&tv, NULL); int64_t now_unix = tv.tv_sec; int64_t now_uptime = esp_timer_get_time() / 1000000LL; if (now_unix < stored_epoch_ref && stored_epoch_ref > 100000 && stored_uptime_ref > 0) { int64_t reconstructed = stored_epoch_ref + (now_uptime - stored_uptime_ref); struct timeval new_tv = { .tv_sec = reconstructed, .tv_usec = 0 }; settimeofday(&new_tv, NULL); ESP_LOGW("restore_TimeBackup", "System time restored from reference: %lld", get_CurrentUnix()); ESP_LOGW("restore_TimeBackup", "Resetting next sensor reads!"); set_AllNextSensorReads(); } } // ---------------------------------------------------------------------------- // Sensor task loop // ---------------------------------------------------------------------------- void sensor_loop(void*) { static const char *TAG = "sensor_loop"; while (true) { ESP_LOGI(TAG, "## Unix time: %lld", get_CurrentUnix()); for (size_t config_id = 0; config_id < SENSOR_CONFIG_COUNT; config_id++) { SensorConfig_s& cfg = sensor_configs[config_id]; ESP_LOGI(TAG, "LOOP checking config: %s", cfg.sensor_name); print_SensorConfig(cfg); if (is_TimeToReadSensor(cfg)) { ESP_LOGI(TAG, "ITS TIME FOR THIS SENSOR!"); uint32_t value_to_send = fake_value_to_send; // set last and next read times cfg.last_sensor_read = get_CurrentUnix(); cfg.next_sensor_read = get_NextSensorReadFor(cfg.sensor_name); // decide if pump should run bool shall_pump = fake_value_to_send % 2; send_DataToPumpAndServer(config_id, value_to_send, shall_pump); fake_value_to_send++; } } if (g_pending_sensor_configs_count > 0) process_PendingSensorConfigs(); // tell server when next read will happen int64_t next_read = get_NextSensorReadsUnixTime(); send_NextSensorReadToPeer(PEER_SERVER, next_read - (g_setup_duration + g_wakeup_earlier_sensor)/1000); sleep_UntilNextSend(next_read); // allow other tasks to run vTaskDelay(pdMS_TO_TICKS(100)); ESP_LOGI(TAG, "\n\n"); } } // ---------------------------------------------------------------------------- // ESP-IDF entry point // ---------------------------------------------------------------------------- extern "C" void app_main(void) { static const char *TAG = "app_main"; uint32_t setup_start = esp_timer_get_time() / 1000ULL; esp_base_mac_addr_set(PEER_SENSOR); setup_Timezone(); init_WiFi(); init_EspNow(); restore_SensorConfigs(); restore_TimeBackup(); ESP_LOGI(TAG, "Requesting time sync..."); if (request_TimeSync()) ESP_LOGI(TAG, "done"); else ESP_LOGE(TAG, "failed (timeout)"); ESP_LOGI(TAG, "----------------------"); if (!all_init_configs_received) get_AllSensorConfigs(); ESP_LOGI(TAG, "----------------------"); ensure_Peers(); g_setup_duration = (esp_timer_get_time() / 1000ULL) - setup_start; ESP_LOGI(TAG, "Setup duration: %u ms", g_setup_duration); // start sensor loop task xTaskCreate(sensor_loop, "sensor_loop", 8192, nullptr, 5, nullptr); }