From acbba735a0fdcbccf1d5c7c267307d20e855a826 Mon Sep 17 00:00:00 2001 From: dvdrw Date: Wed, 20 May 2026 19:43:15 +0200 Subject: [PATCH] feat: grab sensor firmware version for detail sheet --- .../phoenix_sensor_repository.dart | 3 ++ lib/data/repositories/sensor_repository.dart | 2 + lib/data/sources/localiser/sensor_client.dart | 38 +++++++++++++------ lib/domain/models/sensor.dart | 6 ++- lib/features/sensors/sensor_detail_sheet.dart | 7 ++++ lib/providers.dart | 5 +++ 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/lib/data/repositories/phoenix_sensor_repository.dart b/lib/data/repositories/phoenix_sensor_repository.dart index 5d07ace..3b94198 100644 --- a/lib/data/repositories/phoenix_sensor_repository.dart +++ b/lib/data/repositories/phoenix_sensor_repository.dart @@ -52,6 +52,9 @@ class PhoenixSensorRepository implements SensorRepository { Future unplaceSensor(int id) async => Sensor.fromJson(await client.unplaceSensor(id)); + @override + Future getVersion(int id) => client.getVersion(id); + @override Stream> sensorEvents() => realtime .channelMessages('sensors') diff --git a/lib/data/repositories/sensor_repository.dart b/lib/data/repositories/sensor_repository.dart index 6612b30..0f807b3 100644 --- a/lib/data/repositories/sensor_repository.dart +++ b/lib/data/repositories/sensor_repository.dart @@ -11,6 +11,8 @@ abstract class SensorRepository { {required int roomId, required double x, required double y}); Future unplaceSensor(int id); + Future getVersion(int id); + /// Stream of raw SensorsChannel messages. Each map contains an `event` key /// (`sensor_announced` or `sensor_enrollment_timeout`) plus the payload. Stream> sensorEvents(); diff --git a/lib/data/sources/localiser/sensor_client.dart b/lib/data/sources/localiser/sensor_client.dart index 9eda0fd..c52dba4 100644 --- a/lib/data/sources/localiser/sensor_client.dart +++ b/lib/data/sources/localiser/sensor_client.dart @@ -13,30 +13,46 @@ class SensorClient extends LocaliserdClient { await get('/api/sensors/$id') as Map; Future> updateSensor( - int id, Map params) async => - await put('/api/sensors/$id', params) as Map; + int id, + Map params, + ) async => await put('/api/sensors/$id', params) as Map; Future deleteSensor(int id) => delete('/api/sensors/$id'); Future> placeSensor( - int id, Map params) async => + int id, + Map params, + ) async => await put('/api/sensors/$id/place', params) as Map; Future> unplaceSensor(int id) async => await deleteBody('/api/sensors/$id/place') as Map; - Future> createSensor(String sensorId, - {String? name}) async => + Future> createSensor( + String sensorId, { + String? name, + }) async => await post('/api/sensors', { - 'sensor_id': sensorId, - if (name != null) 'name': name, - }) as Map; + 'sensor_id': sensorId, + if (name != null) 'name': name, + }) + as Map; Future> startCalibration( - int id, double referenceDistance) async => - await post('/api/sensors/$id/calibration/start', - {'reference_distance': referenceDistance}) as Map; + int id, + double referenceDistance, + ) async => + await post('/api/sensors/$id/calibration/start', { + 'reference_distance': referenceDistance, + }) + as Map; Future> stopCalibration(int id) async => await post('/api/sensors/$id/calibration/stop') as Map; + + Future getVersion(int id) async { + final response = + (await get('/api/sensors/$id/version') as Map); + return response['version']!; + } } diff --git a/lib/domain/models/sensor.dart b/lib/domain/models/sensor.dart index f73705d..7e8ffc1 100644 --- a/lib/domain/models/sensor.dart +++ b/lib/domain/models/sensor.dart @@ -7,6 +7,7 @@ class Sensor { this.roomId, this.x, this.y, + this.version, }); final int id; @@ -16,6 +17,7 @@ class Sensor { final int? roomId; final double? x; // room relative final double? y; // room relative + final String? version; bool get isPlaced => roomId != null && x != null && y != null; String get displayName => name ?? sensorId; @@ -28,6 +30,7 @@ class Sensor { roomId: json['room_id'] as int?, x: (json['x'] as num?)?.toDouble(), y: (json['y'] as num?)?.toDouble(), + version: json['version'] as String?, ); Sensor copyWith({ @@ -35,7 +38,7 @@ class Sensor { int? roomId, double? x, double? y, - double? rssiRef, + String? version, }) => Sensor( id: id, @@ -45,5 +48,6 @@ class Sensor { roomId: roomId ?? this.roomId, x: x ?? this.x, y: y ?? this.y, + version: version ?? this.version, ); } diff --git a/lib/features/sensors/sensor_detail_sheet.dart b/lib/features/sensors/sensor_detail_sheet.dart index 97a2025..9749ff8 100644 --- a/lib/features/sensors/sensor_detail_sheet.dart +++ b/lib/features/sensors/sensor_detail_sheet.dart @@ -89,6 +89,7 @@ class _SensorDetailSheetState extends ConsumerState { Widget build(BuildContext context) { final sensorAsync = ref.watch(sensorProvider(widget.sensorId)); final roomsAsync = ref.watch(roomsProvider); + final versionAsync = ref.watch(sensorVersionProvider(widget.sensorId)); return sensorAsync.when( loading: () => const SizedBox( @@ -110,9 +111,12 @@ class _SensorDetailSheetState extends ConsumerState { ?.name, ); + final version = versionAsync.whenOrNull(data: (v) => v); + return _SheetBody( sensor: sensor, roomName: roomName, + version: version, editing: _editing, nameCtrl: _nameCtrl, onEditToggle: () => setState(() { @@ -132,6 +136,7 @@ class _SheetBody extends StatelessWidget { const _SheetBody({ required this.sensor, required this.roomName, + required this.version, required this.editing, required this.nameCtrl, required this.onEditToggle, @@ -142,6 +147,7 @@ class _SheetBody extends StatelessWidget { final Sensor sensor; final String? roomName; + final String? version; final bool editing; final TextEditingController nameCtrl; final VoidCallback onEditToggle; @@ -210,6 +216,7 @@ class _SheetBody extends StatelessWidget { ? '(${sensor.x!.toStringAsFixed(2)}, ${sensor.y!.toStringAsFixed(2)})' : 'Not placed', ), + _InfoRow(label: 'Firmware', value: version ?? '—'), const SizedBox(height: 24), FilledButton.icon( icon: Icon(Icons.my_location), diff --git a/lib/providers.dart b/lib/providers.dart index 13da862..53edcb2 100644 --- a/lib/providers.dart +++ b/lib/providers.dart @@ -145,6 +145,11 @@ final sensorProvider = return ref.watch(sensorRepositoryProvider).getSensor(id); }); +final sensorVersionProvider = + FutureProvider.autoDispose.family((ref, id) { + return ref.watch(sensorRepositoryProvider).getVersion(id); +}); + // --------------------------------------------------------------------------- // Tag data // ---------------------------------------------------------------------------