187 lines
5.0 KiB
Dart
187 lines
5.0 KiB
Dart
import 'dart:convert';
|
|
import 'package:http/http.dart' as http;
|
|
import '../models/device.dart';
|
|
import '../models/user_info.dart';
|
|
import '../models/static_talkgroup.dart';
|
|
import '../models/device_profile.dart';
|
|
|
|
class BrandmeisterError implements Exception {
|
|
final String message;
|
|
final int? statusCode;
|
|
|
|
BrandmeisterError(this.message, {this.statusCode});
|
|
|
|
@override
|
|
String toString() {
|
|
if (statusCode != null) {
|
|
return 'BrandmeisterError (HTTP $statusCode): $message';
|
|
}
|
|
return 'BrandmeisterError: $message';
|
|
}
|
|
}
|
|
|
|
class BrandmeisterClient {
|
|
static const String baseUrl = 'https://api.brandmeister.network/v2';
|
|
final String apiToken;
|
|
|
|
BrandmeisterClient({required this.apiToken});
|
|
|
|
Map<String, String> get _headers => {
|
|
'Authorization': 'Bearer $apiToken',
|
|
'Content-Type': 'application/json',
|
|
};
|
|
|
|
Future<T> _handleResponse<T>(
|
|
http.Response response,
|
|
T Function(dynamic) parser,
|
|
) async {
|
|
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
try {
|
|
final dynamic decoded = jsonDecode(response.body);
|
|
return parser(decoded);
|
|
} catch (e) {
|
|
throw BrandmeisterError('Failed to decode response: $e');
|
|
}
|
|
} else {
|
|
throw BrandmeisterError(
|
|
'HTTP request failed: ${response.body}',
|
|
statusCode: response.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
// User Endpoints
|
|
Future<UserInfo> whoami() async {
|
|
final response = await http.post(
|
|
Uri.parse('$baseUrl/user/whoAmI'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(response, (json) => UserInfo.fromJson(json));
|
|
}
|
|
|
|
Future<UserInfo> getUser(int id) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/user/byID/$id'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(response, (json) => UserInfo.fromJson(json));
|
|
}
|
|
|
|
Future<List<UserInfo>> getUsersByCallsign(String callsign) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/user/byCall/$callsign'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(
|
|
response,
|
|
(json) => (json as List).map((e) => UserInfo.fromJson(e)).toList(),
|
|
);
|
|
}
|
|
|
|
// Device Endpoints
|
|
Future<Device> getDevice(int dmrId) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/device/$dmrId'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(response, (json) => Device.fromJson(json));
|
|
}
|
|
|
|
Future<DeviceProfile> getDeviceProfile(int dmrId) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/device/$dmrId/profile'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(response, (json) => DeviceProfile.fromJson(json));
|
|
}
|
|
|
|
Future<List<Device>> getDevicesByCallsign(String callsign) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/device/byCall?callsign=$callsign'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(
|
|
response,
|
|
(json) => (json as List).map((e) => Device.fromJson(e)).toList(),
|
|
);
|
|
}
|
|
|
|
Future<List<Device>> getDevicesByMaster(int masterId) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/device/byMaster/$masterId'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(
|
|
response,
|
|
(json) => (json as List).map((e) => Device.fromJson(e)).toList(),
|
|
);
|
|
}
|
|
|
|
Future<List<StaticTalkgroup>> getDeviceTalkgroups(int dmrId) async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/device/$dmrId/talkgroup'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(
|
|
response,
|
|
(json) =>
|
|
(json as List).map((e) => StaticTalkgroup.fromJson(e)).toList(),
|
|
);
|
|
}
|
|
|
|
// Talkgroup Management
|
|
Future<void> addTalkgroup({
|
|
required int dmrId,
|
|
required int talkgroupId,
|
|
required int slot,
|
|
}) async {
|
|
final response = await http.post(
|
|
Uri.parse('$baseUrl/device/$dmrId/talkgroup'),
|
|
headers: _headers,
|
|
body: jsonEncode({
|
|
'slot': slot,
|
|
'group': talkgroupId,
|
|
}),
|
|
);
|
|
|
|
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
throw BrandmeisterError(
|
|
'Failed to add talkgroup: ${response.body}',
|
|
statusCode: response.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> removeTalkgroup({
|
|
required int dmrId,
|
|
required int talkgroupId,
|
|
required int slot,
|
|
}) async {
|
|
final response = await http.delete(
|
|
Uri.parse('$baseUrl/device/$dmrId/talkgroup/$slot/$talkgroupId'),
|
|
headers: _headers,
|
|
);
|
|
|
|
if (response.statusCode < 200 || response.statusCode >= 300) {
|
|
throw BrandmeisterError(
|
|
'Failed to remove talkgroup: ${response.body}',
|
|
statusCode: response.statusCode,
|
|
);
|
|
}
|
|
}
|
|
|
|
// Talkgroup Endpoints
|
|
Future<Map<String, String>> getTalkgroups() async {
|
|
final response = await http.get(
|
|
Uri.parse('$baseUrl/talkgroup'),
|
|
headers: _headers,
|
|
);
|
|
return _handleResponse(
|
|
response,
|
|
(json) => (json as Map<String, dynamic>).map(
|
|
(key, value) => MapEntry(key, value.toString()),
|
|
),
|
|
);
|
|
}
|
|
}
|