Firmware na ESP32-S3 (ESP-IDF)
Moduły z czujnikiem SC01-O3 czytają stężenie ozonu po UART i publikują pomiary przez MQTT z TLS w konfigurowalnym interwale. Watchdog z ochroną przed pętlą restartów i automatyczne ponowne łączenie z Wi-Fi po zerwaniu połączenia.
Parowanie wyłącznie przez BLE, bez klawiatury
Nowe urządzenie paruje się z aplikacją mobilną przez Bluetooth Low Energy: telefon przekazuje dane Wi-Fi i jednorazowy token rejestracyjny, a urządzenie samo zgłasza się do systemu i pojawia na dashboardzie — bez podłączania czegokolwiek do komputera.
Zdalne aktualizacje OTA
Dwa sloty firmware i automatyczne wycofanie do poprzedniej wersji przy błędnej sumie kontrolnej — aktualizacje floty urządzeń bez ryzyka trwałego zablokowania sprzętu w terenie.
Backend: FastAPI + PostgreSQL + WebSocket
Async API (FastAPI, SQLAlchemy 2.0, Alembic) z mostem MQTT → baza danych i aktualizacjami w czasie rzeczywistym przez WebSocket. Osobne dane logowania MQTT per urządzenie i ACL blokujące podszywanie się pod inne urządzenie.
Panel WWW (React) i aplikacja iOS (SwiftUI)
Oba klienty korzystają z tego samego REST API i WebSocketa — jedno źródło prawdy, brak duplikacji logiki. Aplikacja iOS obsługuje cały proces dodawania urządzenia: skanowanie BLE, wybór sieci Wi-Fi, identyfikację modułu i przypisanie lokalizacji.
Tryb symulacji bez fizycznego sprzętu
Realistyczny model rozprzestrzeniania się ozonu z pięcioma wirtualnymi czujnikami pozwala uruchomić i testować cały system — backend, panel WWW i aplikację mobilną — równolegle, bez czekania na dostępność fizycznych urządzeń.
ESP-IDF udostępnia gotowy komponent do parowania urządzeń przez BLE, ale jedynym gotowym klientem jest aplikacja referencyjna Espressif — nie istniał gotowy klient dla iOS pasujący do wymagań tego projektu. Cały protokół trzeba było zaimplementować od podstaw w Swift.
- Handshake Security1: wymiana kluczy X25519 (ECDH), dowód posiadania urządzenia i sesyjne szyfrowanie AES-256-CTR.
- Ręcznie napisany, minimalny koder/dekoder protobuf bez zależności zewnętrznych, dopasowany dokładnie do wiadomości firmware.
- Odkryty i rozwiązany na prawdziwym sprzęcie limit CoreBluetooth: odkrywanie charakterystyk GATT po stronie iOS po cichu urywało się przy ośmiu charakterystykach — rozwiązane przez scalenie kilku endpointów firmware w jeden.
- Dwa subtelne błędy w dekodowaniu protobuf wychwycone dopiero przy testach na fizycznym urządzeniu: proto3 pomija na drucie pola z wartością domyślną, więc poprawna odpowiedź „sukces” bywa dosłownie pustą wiadomością.
„Zbudowałem od podstaw system IoT do monitorowania ozonu — firmware, backend, panel WWW i aplikację iOS — w którym pełne parowanie urządzenia, od wykrycia przez Bluetooth po zarejestrowanie w systemie, dzieje się wyłącznie z poziomu telefonu, bez podłączania czegokolwiek do komputera.”