Initial commit

This commit is contained in:
2026-03-21 01:34:22 +01:00
parent 8ec17d5ed4
commit 6805f4a3f4
144 changed files with 7312 additions and 13 deletions

View File

@@ -0,0 +1,99 @@
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<Map<String, dynamic>> _get(String path) async {
try {
final res = await http.get(_uri(path)).timeout(timeout);
_checkStatus(res);
return jsonDecode(res.body) as Map<String, dynamic>;
} on BusylightException {
rethrow;
} catch (e) {
throw BusylightException('Network error: $e');
}
}
Future<Map<String, dynamic>> _post(String path, [Map<String, dynamic>? 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<String, dynamic>;
} 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<BusylightStatus> getStatus() async {
final json = await _get('/api/status');
return BusylightStatus.fromString(json['status'] as String);
}
Future<BusylightStatus> setStatus(BusylightStatus status) async {
final json = await _post(status.apiPath);
return BusylightStatus.fromString(json['status'] as String);
}
Future<BusylightStatus> turnOn() => setStatus(BusylightStatus.on);
Future<BusylightStatus> turnOff() => setStatus(BusylightStatus.off);
Future<BusylightStatus> setAvailable() => setStatus(BusylightStatus.available);
Future<BusylightStatus> setAway() => setStatus(BusylightStatus.away);
Future<BusylightStatus> setBusy() => setStatus(BusylightStatus.busy);
// ── Color ───────────────────────────────────────────────────────────────────
Future<BusylightColor> getColor() async {
final json = await _get('/api/color');
return BusylightColor.fromJson(json);
}
Future<void> 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<void> setBrightness(double brightness) async {
await _post('/api/brightness', {'brightness': brightness.clamp(0.0, 1.0)});
}
// ── Debug ───────────────────────────────────────────────────────────────────
Future<Map<String, dynamic>> getDebug() => _get('/api/debug');
}