# OTA Update процедура — Retro фърмуер

## Предварителни изисквания

1. Достъп до MQTT брокера на хотела
2. Компилиран нов `.bin` файл (виж секция "Компилация")
3. Устройствата са свързани към хотелския WiFi и MQTT брокер

---

## Стъпка 1 — Компилация на нов фърмуер

Преди да се прави OTA, трябва да се компилира фиксираната версия.

**Два бъга за оправяне преди компилация:**

### 1a. Смяна на deprecated ElegantOTA библиотека

В `platformio.ini` смени:
```ini
; ПРЕДИ (не компилира — deprecated):
https://github.com/ayushsharma82/AsyncElegantOTA

; СЛЕД:
ayushsharma82/ElegantOTA@^3.1.0
```

Добави build flag и lib_ignore:
```ini
build_flags = -D ELEGANTOTA_USE_ASYNC_WEBSERVER=1

lib_ignore =
    ESPAsyncWebServer
    AsyncTCP
```

В `src/main.cpp` смени include и извикването:
```cpp
// ПРЕДИ:
#include <AsyncElegantOTA.h>
AsyncElegantOTA.begin(&server);

// СЛЕД:
#include <ElegantOTA.h>
ElegantOTA.begin(&server);
```

Добави `ElegantOTA.loop()` в `loop()`.

### 1b. Fix на бъга с проверката на стаята

Виж `docs/bugfix-room-access.md` — разкоментирай блока `else if (room != config.room)`.

### Компилация:
```
platformio run
```
Резултатът е `.pio/build/esp32doit-devkit-v1/firmware.bin`

---

## Стъпка 2 — Намиране на IP адреса на устройството

Устройствата публикуват на MQTT топик `alive` при всяко събуждане.

**Формат на съобщението:**
```
[MAC]/[type]/[IP]/[version]/[name][room]/[battery%]/[RSSI]/[datetime]
```

**Пример:**
```
58bf2528fc00/olock/192.168.1.105/H3V_1.0.5/Room3614/29/-65/25-06-2026 11:36:13
```

**За да получиш IP на конкретно устройство:**

```bash
# Изпрати ping команда на конкретното устройство (по MAC):
mosquitto_pub -h [MQTT_HOST] -t "58bf2528fc00" -m "ping"

# Устройството отговаря на топик "alive" с IP адреса
mosquitto_sub -h [MQTT_HOST] -t "alive"
```

Устройствата се събуждат **на всеки 60 секунди** (timer wakeup), така че ако не отговори на ping веднага, ще отговори при следващото събуждане.

---

## Стъпка 3 — Активиране на OTA режим

Изпрати **retained** MQTT съобщение до конкретното устройство:

```bash
mosquitto_pub -h [MQTT_HOST] -t "58bf2528fc00" -m "start_web" --retain
```

> **Защо retained?** Устройствата са в deep sleep по-голямата част от времето.
> Retained съобщение се запазва в брокера и се доставя веднага при
> следващото събуждане, когато устройството се абонира за своя MAC топик.

**Какво прави устройството след получаване на `start_web`:**
1. Стартира уеб сървъра (`startServer()`)
2. Остава будно **5 минути** (`UPDATE_TIME = 300000 ms`)
3. IP адресът вече е публикуван на топик `alive` — преди обработката на `start_web`

> **Защо `alive`, не `update`?** `update` топикът се използва само при физическа карта
> (`activateUpdate()` сетва `awake_update = true`). При MQTT тригер `awake_update`
> остава `false` и `responseAlive()` публикува на `alive`.

**Следи топик `alive` за IP адреса:**
```bash
mosquitto_sub -h [MQTT_HOST] -t "alive"
```

---

## Стъпка 4 — Качване на фърмуера

В рамките на **5 минути** от получаването на `start_web`:

1. Отвори браузър и отиди на:
   ```
   http://[IP_НА_УСТРОЙСТВОТО]/update
   ```

2. В ElegantOTA интерфейса избери файла:
   ```
   .pio/build/esp32doit-devkit-v1/firmware.bin
   ```

3. Качи и изчакай рестартирането.

---

## Стъпка 5 — Изчистване на retained съобщението

**Задължително** — изтрий retained командата след успешен update,
иначе устройството ще влиза в update режим при всяко следващо събуждане:

```bash
mosquitto_pub -h [MQTT_HOST] -t "58bf2528fc00" -m "" --retain
```

---

## Масов update на всички устройства

За update на много устройства едновременно:

```bash
# 1. Изпрати start_web до всички устройства наведнъж
mosquitto_pub -h [MQTT_HOST] -t "all" -m "start_web"
```

> **Внимание:** При масов update всички устройства се будят едновременно
> и стартират уеб сървър. Всяко устройство е достъпно на своя IP.
> Следи топик `update` за да видиш кои устройства са се вдигнали.

---

## Времева схема

```
t=0          retained "start_web" публикувано
t=0..60s     устройство се събужда (timer на 60 сек)
t~60s        устройство получава "start_web", стартира web server
t~60s        устройство публикува на "update" топика своя IP
t~60s..5min  прозорец за качване на firmware.bin
t+5min       ако не е качен фърмуер, устройството заспива
```

---

## Ако нещо се обърка

### Устройството не отговаря на ping
- Провери дали MAC адресът е правилен (виж `alive` топика)
- Провери дали устройството е включено (батерия)
- Провери WiFi и MQTT конекцията

### Прозорецът от 5 минути изтече
- Изпрати отново `start_web` retained съобщението
- Изчакай следващото събуждане (макс. 60 сек)

### Устройството заспа по средата на upload
- Файлът `.bin` е бил качен само частично
- Устройството ще остане с **стария** фърмуер (ESP32 прави rollback автоматично)
- Повтори процедурата

### Не знаеш кой IP за коя стая е
- Погледни `name` и `room` полето в `alive` съобщението:
  ```
  58bf2528fc00/olock/192.168.1.105/H3V_1.0.5/Room3614/...
                                               ↑    ↑
                                              name  room
  ```

---

## Свързани файлове

- `docs/bugfix-room-access.md` — описание и fix на бъга с проверката на стаята
- `src/main.cpp:541` — `responseAlive()` — формат на alive съобщението
- `src/main.cpp:768` — `mac_subscriber()` — MQTT команди (`start_web`, `ping`, `restart`)
- `src/main.cpp:1610` — `startServer()` — стартира OTA web сървъра
- `src/main.cpp:85` — `UPDATE_TIME = 300000` — прозорец за OTA (5 мин)
- `src/main.cpp:119` — `time_for_sleep = 60` — периодично събуждане (1 мин)
