156 lines
6.7 KiB
Markdown
156 lines
6.7 KiB
Markdown
# Ignis App
|
||
|
||
`ignis_app` — Android-first Flutter-клиент для локального backend-проекта `../ignis-core`.
|
||
|
||
## Что умеет сейчас
|
||
|
||
- хранить несколько домов с разными URL и API-ключами;
|
||
- переключать активный дом и проверять `auth/me` при выборе;
|
||
- управлять группами света: `on/off`, яркость, температура, RGB, сцены;
|
||
- ставить быстрый таймер на 4 часа;
|
||
- создавать one-shot и cron-расписания;
|
||
- смотреть stats summary и event log;
|
||
- управлять гостевыми API-ключами;
|
||
- показывать состояние geofence/permissions/notifications;
|
||
- включать Android geofence для активного дома.
|
||
|
||
## Архитектура
|
||
|
||
- `lib/app/` — bootstrap, build info, load/error helpers.
|
||
- `lib/features/*` — feature-specific providers и domain logic.
|
||
- `lib/models/` — typed models для backend payloads.
|
||
- `lib/screens/` — экраны приложения.
|
||
- `lib/services/` — API client, settings, credentials storage.
|
||
- `android/app/src/main/kotlin/...` — platform channel, geofence manager, worker, notifications.
|
||
|
||
Ключевые точки:
|
||
|
||
- `SettingsService` хранит список домов в `SharedPreferences`.
|
||
- API-ключи лежат отдельно в `flutter_secure_storage`.
|
||
- `CurrentHomeNotifier` переключает активный дом и переинициализирует `IgnisApi`.
|
||
- `MainGate` делает bootstrap и отправляет пользователя либо в `HomesScreen`, либо в `RemoteScreen`.
|
||
- `GeofenceAutomationService` синхронизирует активный дом с Android-side geofence.
|
||
|
||
## Технологии
|
||
|
||
- Flutter / Dart
|
||
- Material UI
|
||
- Riverpod
|
||
- Dio
|
||
- SharedPreferences
|
||
- flutter_secure_storage
|
||
- Geolocator
|
||
- Android Geofencing API
|
||
- Android WorkManager
|
||
|
||
## Запуск
|
||
|
||
```bash
|
||
flutter pub get
|
||
flutter run
|
||
```
|
||
|
||
## Документы
|
||
|
||
- `docs/wiz_provisioning_master_plan.md` — подробный план добавления мастера первичной посадки новых WiZ-ламп на Wi-Fi без официального приложения.
|
||
|
||
## WiZ Provisioning Status
|
||
|
||
Что уже есть:
|
||
|
||
- Android-first мастер подключения новых WiZ-ламп;
|
||
- environment inspection, permissions, smart pairing и post-provision `rescan` в `Ignis`.
|
||
|
||
Что важно понимать:
|
||
|
||
- это пока не универсальный onboarding для всех поколений WiZ;
|
||
- `SoftAP / WiZConfig_xxxx`, commissioning через `UDP 18266`, `BLE` и `Matter` fallback ещё не реализованы;
|
||
- реальная проверка на железе остаётся обязательной.
|
||
|
||
## Release APK
|
||
|
||
```bash
|
||
flutter build apk --release \
|
||
--dart-define=IGNIS_BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
|
||
--dart-define=IGNIS_GIT_SHA="$(git rev-parse --short HEAD)"
|
||
```
|
||
|
||
Артефакт:
|
||
|
||
```text
|
||
build/app/outputs/flutter-apk/app-release.apk
|
||
```
|
||
|
||
Без `IGNIS_BUILD_DATE` и `IGNIS_GIT_SHA` экран настроек покажет `build info unavailable`.
|
||
|
||
## Настройка дома
|
||
|
||
1. Добавить дом: имя, URL backend и API-ключ.
|
||
2. При необходимости добавить координаты дома.
|
||
3. Выбрать дом активным.
|
||
4. Для geofence выдать Android-доступ к геолокации, включая background location.
|
||
5. Для подтверждающих уведомлений выдать permission на notifications.
|
||
|
||
URL нормализуется в `IgnisApi.normalizeBaseUrl()`:
|
||
|
||
- если схема не указана, добавляется `https://`;
|
||
- хвостовые `/` убираются.
|
||
|
||
## Geofence и Android-side логика
|
||
|
||
Что есть:
|
||
|
||
- platform channel `ignis/geofence_automation`;
|
||
- нативная регистрация geofence;
|
||
- восстановление geofence после `BOOT_COMPLETED` и `MY_PACKAGE_REPLACED`;
|
||
- delayed exit worker через WorkManager;
|
||
- локальные уведомления о фоновой обработке;
|
||
- Android-side шифрование geofence config и активного API-ключа.
|
||
|
||
Что важно понимать:
|
||
|
||
- это самая рискованная часть приложения;
|
||
- поведение зависит от Android permissions, OEM battery policy и фоновых ограничений;
|
||
- после изменений backend-контракта EXIT-поток нужно перепроверять вручную на устройстве.
|
||
|
||
## Хранение данных
|
||
|
||
- список домов, активный дом и тема — `SharedPreferences`;
|
||
- API-ключи домов — `flutter_secure_storage`;
|
||
- Android geofence config и активный API-ключ для worker'а дополнительно шифруются в native storage;
|
||
- legacy `apiKey` внутри JSON списка домов мигрируется автоматически при чтении.
|
||
|
||
## Проверки
|
||
|
||
```bash
|
||
flutter analyze
|
||
flutter test
|
||
```
|
||
|
||
На 2026-05-16 в `test/` лежит 74 unit/widget-теста.
|
||
|
||
Покрыто:
|
||
|
||
- `IgnisApi` и нормализация base URL;
|
||
- сериализация `HomeConfig`;
|
||
- миграция и хранение настроек;
|
||
- bootstrap и auth/load-state;
|
||
- provider mutations для групп, расписаний и API-ключей;
|
||
- widget-потоки для `GroupCard`, форм домов/групп/расписаний и error/retry;
|
||
- geofence sync на уровне Flutter-side provider/service логики;
|
||
- permission/status providers для geofence и notifications.
|
||
|
||
Не покрыто как следует:
|
||
|
||
- нативный Android geofence path;
|
||
- `MainActivity` и platform-channel flow;
|
||
- реальное фоновое поведение WorkManager на устройстве.
|
||
|
||
## Ограничения
|
||
|
||
- продукт по факту поддерживается как Android-first клиент;
|
||
- iOS, web, desktop каталоги присутствуют как Flutter scaffold, но не считаются поддерживаемыми продуктными платформами;
|
||
- `apiProvider` конфигурируется мутирующим `init()`, поэтому переключение домов требует аккуратности;
|
||
- крупные экраны вроде `SettingsScreen` и `SchedulesScreen` всё ещё держат много UI-ответственности;
|
||
- release signing в репозитории не настроен.
|