feat: implement sensor calibration flow

This commit is contained in:
2026-05-21 16:19:43 +02:00
parent acbba735a0
commit cf3019f484
9 changed files with 1370 additions and 8 deletions
@@ -59,4 +59,36 @@ class PhoenixSensorRepository implements SensorRepository {
Stream<Map<String, dynamic>> sensorEvents() => realtime
.channelMessages('sensors')
.map((m) => {'event': m.event, ...m.payload});
@override
Future<int> beginCalibration(int id) async {
final json = await client.beginCalibration(id);
return json['samples_needed'] as int;
}
@override
Future<void> startStage(int id, double distance) =>
client.startStage(id, distance);
@override
Future<({double rssiRef, double pathLossExp})> finishCalibration(
int id) async {
final json = await client.finishCalibration(id);
return (
rssiRef: (json['rssi_ref'] as num).toDouble(),
pathLossExp: (json['path_loss_exp'] as num).toDouble(),
);
}
@override
Future<void> cancelCalibration(int id) => client.cancelCalibration(id);
@override
Stream<({String event, Map<String, dynamic> payload})> calibrationEvents(
String sensorDeviceId) =>
realtime.channelMessages('calibration:$sensorDeviceId');
@override
void leaveCalibrationChannel(String sensorDeviceId) =>
realtime.leaveChannel('calibration:$sensorDeviceId');
}
@@ -16,4 +16,30 @@ abstract class SensorRepository {
/// Stream of raw SensorsChannel messages. Each map contains an `event` key
/// (`sensor_announced` or `sensor_enrollment_timeout`) plus the payload.
Stream<Map<String, dynamic>> sensorEvents();
// ---------------------------------------------------------------------------
// Calibration
// ---------------------------------------------------------------------------
/// Enters calibration mode on the sensor. Returns the number of samples the
/// server will collect per stage.
Future<int> beginCalibration(int id);
/// Starts a collection stage at [distance] metres.
Future<void> startStage(int id, double distance);
/// Runs least-squares regression over all completed stages and persists the
/// result. Returns the fitted (rssiRef, pathLossExp) pair.
Future<({double rssiRef, double pathLossExp})> finishCalibration(int id);
/// Aborts calibration and discards all accumulated stage data.
Future<void> cancelCalibration(int id);
/// Real-time events from the server's CalibrationChannel.
/// Topic: `calibration:{sensorDeviceId}` (the string BLE device ID).
Stream<({String event, Map<String, dynamic> payload})> calibrationEvents(
String sensorDeviceId);
/// Leaves the calibration Phoenix channel for [sensorDeviceId].
void leaveCalibrationChannel(String sensorDeviceId);
}