9#include <WiFiClientSecure.h>
10#include <WiFiClient.h>
20#include <esp_task_wdt.h>
26#include <esp_ota_ops.h>
56 static unsigned long buttonPressTime = 0;
57 static bool buttonPressed =
false;
63 if (currentState && !buttonPressed)
67 buttonPressTime = millis();
68 logWarn(
"Кнопка сброса нажата! Сброс настроек через 2 сек...");
70 else if (!currentState && buttonPressed)
73 buttonPressed =
false;
76 else if (currentState && buttonPressed && (millis() - buttonPressTime >=
BUTTON_HOLD_TIME_MS))
79 logError(
"Выполняется сброс настроек!");
85 vTaskDelay(50 / portTICK_PERIOD_MS);
89#ifndef PIO_UNIT_TESTING
97 Serial.println(
"*** ЕСЛИ ВЫ ВИДИТЕ ЭТО СООБЩЕНИЕ, ПРОШИВКА ОБНОВИЛАСЬ УСПЕШНО ***");
106 const esp_partition_t* runningNow = esp_ota_get_running_partition();
107 esp_ota_img_states_t otaStateNow;
108 if (esp_ota_get_state_partition(runningNow, &otaStateNow) == ESP_OK && otaStateNow == ESP_OTA_IMG_PENDING_VERIFY)
110 logSystem(
"OTA image pending verify → подтверждаем (ранний этап)");
111 if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK)
112 logSuccess(
"OTA image подтверждена, откат отменён");
114 logError(
"Не удалось подтвердить OTA image (ранний этап)!");
120 logSystem(
"Настройка Watchdog Timer (30 сек)...");
122 esp_task_wdt_add(NULL);
128 logError(
"Ошибка инициализации Preferences!");
138 logSystem(
"Режим датчика: %s",
config.flags.useRealSensor ?
"РЕАЛЬНЫЙ" :
"ЭМУЛЯЦИЯ");
145 if (
config.flags.thingSpeakEnabled)
153 if (
config.flags.mqttEnabled)
160 static WiFiClientSecure otaClient;
161 otaClient.setInsecure();
165 setupOTA(
"https://github.com/Gfermoto/soil-sensor-7in1/releases/latest/download/manifest.json", otaClient);
172 if (
config.flags.useRealSensor)
181 const esp_partition_t* running = esp_ota_get_running_partition();
182 esp_ota_img_states_t ota_state;
183 if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK && ota_state == ESP_OTA_IMG_PENDING_VERIFY)
185 logSystem(
"OTA image pending verify → помечаем как valid");
186 if (esp_ota_mark_app_valid_cancel_rollback() == ESP_OK)
187 logSuccess(
"OTA image подтверждена, откат отменён");
189 logError(
"Не удалось подтвердить OTA image!");
192 logSuccess(
"Инициализация завершена успешно!");
205 unsigned long currentTime = millis();
208 esp_task_wdt_reset();
226 logSystem(
"Режим датчика: %s",
config.flags.useRealSensor ?
"РЕАЛЬНЫЙ" :
"ЭМУЛЯЦИЯ");
231 logData(
"Последние измерения получены %.1f сек назад", (currentTime -
sensorData.last_update) / 1000.0);
235 logWarn(
"Данные датчика недоступны");
243 static unsigned long mqttBatchTimer = 0;
244 static unsigned long thingspeakBatchTimer = 0;
245 static bool pendingMqttPublish =
false;
246 static bool pendingThingspeakPublish =
false;
252 pendingMqttPublish =
true;
253 pendingThingspeakPublish =
true;
256 DEBUG_PRINTLN(
"[BATCH] Новые данные помечены для групповой отправки");
260 if (pendingMqttPublish && (currentTime - mqttBatchTimer >=
config.mqttPublishInterval))
263 pendingMqttPublish =
false;
264 mqttBatchTimer = currentTime;
269 if (pendingThingspeakPublish && (currentTime - thingspeakBatchTimer >=
config.thingSpeakInterval))
272 pendingThingspeakPublish =
false;
275 thingspeakBatchTimer = currentTime;
276 DEBUG_PRINTLN(
"[BATCH] ThingSpeak данные отправлены группой");
280 DEBUG_PRINTLN(
"[BATCH] ThingSpeak отправка не удалась, повтор через следующий интервал");
285 static unsigned long lastMqttCheck = 0;
286 if (currentTime - lastMqttCheck >= 100)
289 lastMqttCheck = currentTime;
293 static unsigned long lastWiFiCheck = 0;
294 if (currentTime - lastWiFiCheck >= 20)
297 lastWiFiCheck = currentTime;
301 static unsigned long lastOtaCheck = 0;
302 if (
config.flags.autoOtaEnabled && (currentTime - lastOtaCheck >= 3600000UL))
305 lastOtaCheck = currentTime;
309 vTaskDelay(10 / portTICK_PERIOD_MS);
#define BUTTON_HOLD_TIME_MS
#define WATCHDOG_TIMEOUT_SEC
void logWarn(const char *format,...)
void logPrintHeader(const char *title, const char *color)
void logPrintSeparator(const char *symbol, int length)
void logSuccess(const char *format,...)
void logError(const char *format,...)
void logSystem(const char *format,...)
void logPrintBanner(const char *text)
void logData(const char *format,...)
Система логгирования с красивым форматированием
void setupModbus()
Инициализация Modbus и SP3485E.
unsigned long lastStatusPrint
unsigned long lastDataPublish
void startRealSensorTask()
void resetButtonTask(void *parameter)
const unsigned long STATUS_PRINT_INTERVAL
void startFakeSensorTask()
unsigned long lastNtpUpdate
void setupOTA(const char *manifestUrl, WiFiClient &client)
static std::unique_ptr< ISensor > createSensorInstance()
bool sendDataToThingSpeak()
void setupThingSpeak(WiFiClient &client)
#define JXCT_FULL_VERSION_STRING
#define JXCT_VERSION_STRING