import 'dart:convert'; import 'package:http/http.dart' as http; import '../models/busylight_color.dart'; import '../models/busylight_status.dart'; class BusylightException implements Exception { final String message; const BusylightException(this.message); @override String toString() => 'BusylightException: $message'; } class BusylightService { final String baseUrl; final Duration timeout; BusylightService({ required this.baseUrl, this.timeout = const Duration(seconds: 5), }); Uri _uri(String path) => Uri.parse('$baseUrl$path'); Future> _get(String path) async { try { final res = await http.get(_uri(path)).timeout(timeout); _checkStatus(res); return jsonDecode(res.body) as Map; } on BusylightException { rethrow; } catch (e) { throw BusylightException('Network error: $e'); } } Future> _post(String path, [Map? body]) async { try { final res = await http .post( _uri(path), headers: {'Content-Type': 'application/json'}, body: body != null ? jsonEncode(body) : null, ) .timeout(timeout); _checkStatus(res); return jsonDecode(res.body) as Map; } on BusylightException { rethrow; } catch (e) { throw BusylightException('Network error: $e'); } } void _checkStatus(http.Response res) { if (res.statusCode < 200 || res.statusCode >= 300) { throw BusylightException('HTTP ${res.statusCode}: ${res.body}'); } } // ── Status ────────────────────────────────────────────────────────────────── Future getStatus() async { final json = await _get('/api/status'); return BusylightStatus.fromString(json['status'] as String); } Future setStatus(BusylightStatus status) async { final json = await _post(status.apiPath); return BusylightStatus.fromString(json['status'] as String); } Future turnOn() => setStatus(BusylightStatus.on); Future turnOff() => setStatus(BusylightStatus.off); Future setAvailable() => setStatus(BusylightStatus.available); Future setAway() => setStatus(BusylightStatus.away); Future setBusy() => setStatus(BusylightStatus.busy); // ── Color ─────────────────────────────────────────────────────────────────── Future getColor() async { final json = await _get('/api/color'); return BusylightColor.fromJson(json); } Future setColor(BusylightColor color) async { await _post('/api/color', color.toJson()); } // ── Brightness ────────────────────────────────────────────────────────────── // Note: brightness is read from GET /api/color response, no separate endpoint needed. Future setBrightness(double brightness) async { await _post('/api/brightness', {'brightness': brightness.clamp(0.0, 1.0)}); } // ── Debug ─────────────────────────────────────────────────────────────────── Future> getDebug() => _get('/api/debug'); }