# Device Behavior ## Конечный автомат устройства ```mermaid stateDiagram-v2 [*] --> Booting: Включение питания Booting --> WiFiConnect: Инициализация периферии WiFiConnect --> MQTTConnect: WiFi OK WiFiConnect --> WiFiConnect: Retry (exponential backoff) MQTTConnect --> Connected: MQTT OK MQTTConnect --> MQTTConnect: Retry (exponential backoff) Connected --> Publishing: Таймер сбора данных Publishing --> Connected: Данные отправлены Connected --> ExecutingCmd: Получена команда MQTT ExecutingCmd --> Connected: Команда выполнена Connected --> OTA: Получена cmd/ota OTA --> [*]: Перезагрузка после обновления Connected --> Disconnected: Потеря связи Disconnected --> MQTTConnect: Reconnect (exponential backoff) Connected --> [*]: cmd/reboot или WDT reset ``` --- ## Последовательность запуска 1. **Boot** — инициализация I2C, SPI, OneWire, MCP23017 2. **WiFi** — подключение, получение IP (exponential backoff при неудаче) 3. **MQTT connect** — handshake с брокером 4. **LWT настройка** — `{UID}/availability = "offline"` при разрыве 5. **Publish `{UID}/status = "connected"`** — уведомление сервера 6. **Получить preferences** — сервер отвечает `{UID}/set/preferences/all` 7. **Применить калибровку** — записать коэффициенты в NVS/RAM без перезагрузки 8. **Запуск основного цикла** — периодический сбор и публикация данных --- ## Периодичность публикации данных | Датчик | Интервал | |--------|----------| | pH, EC, wNTC | ~10 сек | | AirTemp, AirHum, AirPress | ~30 сек | | RootTemp (DS18B20) | ~15 сек | | RSSI, CPUTemp, FreeHeap, Vcc | ~60 сек | | uptime | ~60 сек | | MixerWeight | ~5 сек (если mixer_enabled) | | mcp/gpio | при изменении состояния | --- ## Обработка команд Все команды **fire-and-forget** — ответ не отправляется. ### `cmd/reboot` 1. Завершить активные операции помп (стоп) 2. `ESP.restart()` ### `cmd/gpio/{pin}` - Проверить pin ∈ [0, 15], payload ∈ {"0", "1"} - MCP23017 → setPin(pin, state) ### `set/pump/{id}/run` - Проверить id ∈ [1, 8], time ∈ [1, 60000] - Включить помпу → таймер → выключить ### `set/pump/{id}/dispense` - Проверить id ∈ [1, 8], grams ∈ [0.1, 1000] - Рассчитать время через ml/sec калибровку помпы - Включить → таймер → выключить - Обновить счётчик `total_dispensed` ### `cmd/pump/{id}/stop` - Проверить id ∈ [1, 8] - Немедленно выключить помпу, сбросить таймер ### `set/preferences/all` - Разобрать JSON, обновить только пришедшие поля в NVS / RAM - Применить новые коэффициенты без перезагрузки ### `cmd/ota` - Payload: пустой (использует `preferences.updateUrl`) или URL строка (override) - Скачать и прошить firmware.bin - Перезагрузиться ### `cmd/ota-storage` - Аналогично `cmd/ota` но для LittleFS (`preferences.updateFsUrl`) --- ## Pump ID: единый стандарт 1–8 Сервер и прошивка используют 1-based индексацию (1–8). Исправлено в прошивке: commit `aa5db288` — валидация `0-7` → `1-8` в `mqtt_callbacks.cpp`. --- ## Reconnect логика - WiFi: встроенный авто-реконнект ESP-IDF - MQTT: экспоненциальный backoff (1s → 2s → 4s → ... → max 60s) - При восстановлении: публикует `{UID}/status = "connected"` → сервер снова шлёт preferences --- ## Home Assistant интеграция (отдельный канал) Прошивка поддерживает параллельную интеграцию с Home Assistant через MQTT. Топики (не используются сервером ponics.online): - `{UID}/availability` — online/offline - `{UID}/pin/{i}/cmd` — управление GPIO - `{UID}/pin/{i}/state` — состояние GPIO - `{UID}/mixer/cmd` — управление миксером - Autodiscovery топики для HA