import 'package:dio/dio.dart'; /// HTTP-клиент для одного сервера Ignis. /// Покрывает все эндпоинты из openapi.json. class IgnisApi { final Dio _dio = Dio(); Dio get dioInstance => _dio; /// Инициализация базового URL и API-ключа void init(String baseUrl, String apiKey) { String url = baseUrl.trim(); if (!url.startsWith('http')) { url = 'https://$url'; } // Убираем trailing slash if (url.endsWith('/')) url = url.substring(0, url.length - 1); _dio.options.baseUrl = url; _dio.options.headers['X-API-Key'] = apiKey; // Бэкенд WiZ ламп тормозит -- даём запас _dio.options.connectTimeout = const Duration(seconds: 15); _dio.options.receiveTimeout = const Duration(seconds: 15); } // ─── Авторизация ─────────────────────────────────────────── /// Проверка текущего ключа: возвращает {is_admin, name} Future getAuthMe() => _dio.get('/auth/me'); // ─── Устройства и группы ─────────────────────────────────── /// Все устройства (лампы) Future getDevices() => _dio.get('/devices'); /// Все группы Future getGroups() => _dio.get('/devices/groups'); /// Все доступные сцены Future getScenes() => _dio.get('/devices/scenes'); /// Создать группу Future createGroup(String id, String name, List macs) => _dio.post('/devices/groups', data: {'id': id, 'name': name, 'macs': macs}); /// Удалить группу Future deleteGroup(String groupId) => _dio.delete('/devices/groups/$groupId'); /// Пересканировать сеть (найти новые лампы) Future rescanNetwork() => _dio.post('/devices/rescan'); // ─── Управление ──────────────────────────────────────────── /// Управление группой: state, brightness, temp, scene, r/g/b Future controlGroup(String id, Map params) => _dio.post('/control/group/$id', queryParameters: params); /// Управление одной лампой Future controlDevice(String id, Map params) => _dio.post('/control/device/$id', queryParameters: params); /// Мигнуть лампой (для идентификации) Future blinkDevice(String id) => _dio.post('/control/device/$id/blink'); /// Статус группы (реальный опрос ламп) Future getGroupStatus(String id) => _dio.get('/control/group/$id/status'); /// Статус одной лампы Future getDeviceStatus(String id) => _dio.get('/control/device/$id/status'); // ─── Расписания ──────────────────────────────────────────── /// Одноразовое расписание (таймер) Future scheduleOnce(Map params) => _dio.post('/schedules/once', queryParameters: params); /// Cron-расписание (повторяющееся) Future scheduleCron(Map params) => _dio.post('/schedules/cron', queryParameters: params); /// Все активные задачи расписания Future getTasks() => _dio.get('/schedules/tasks'); /// Отменить задачу расписания Future cancelTask(String jobId) => _dio.delete('/schedules/$jobId'); // ─── API-ключи ───────────────────────────────────────────── /// Список всех гостевых ключей Future getApiKeys() => _dio.get('/api-keys'); /// Создать гостевой ключ Future createApiKey(String name, {bool isAdmin = false}) => _dio.post('/api-keys', queryParameters: { 'name': name, 'is_admin': isAdmin, }); /// Отозвать ключ (body: {key: ...}) Future revokeApiKey(String key) => _dio.post('/api-keys/revoke', data: {'key': key}); /// Активировать ключ (body: {key: ...}) Future activateApiKey(String key) => _dio.post('/api-keys/activate', data: {'key': key}); // ─── Статистика ──────────────────────────────────────────── /// Сводная статистика за N дней Future getStatsSummary({int days = 7}) => _dio.get('/stats/summary', queryParameters: {'days': days}); /// Лог последних N событий Future getStatsLog({int limit = 100}) => _dio.get('/stats/log', queryParameters: {'limit': limit}); }