feat: offer to calibrate sensor after provisioning
This commit is contained in:
@@ -4,7 +4,9 @@ import 'package:go_router/go_router.dart';
|
|||||||
|
|
||||||
import '../../data/sources/ble/ble_provisioner.dart';
|
import '../../data/sources/ble/ble_provisioner.dart';
|
||||||
import '../../data/sources/local/credential_store.dart';
|
import '../../data/sources/local/credential_store.dart';
|
||||||
|
import '../../domain/models/sensor.dart';
|
||||||
import '../../providers.dart';
|
import '../../providers.dart';
|
||||||
|
import '../sensors/calibration_sheet.dart';
|
||||||
|
|
||||||
enum _Step { scan, configure, done }
|
enum _Step { scan, configure, done }
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ class _BleProvisionSheetState extends ConsumerState<BleProvisionSheet> {
|
|||||||
|
|
||||||
_Step _step = _Step.scan;
|
_Step _step = _Step.scan;
|
||||||
BleScanResult? _selected;
|
BleScanResult? _selected;
|
||||||
|
Sensor? _provisionedSensor;
|
||||||
bool _provisioning = false;
|
bool _provisioning = false;
|
||||||
bool _mqttOverrideEnabled = false;
|
bool _mqttOverrideEnabled = false;
|
||||||
bool _usingNewWifiConnection = true;
|
bool _usingNewWifiConnection = true;
|
||||||
@@ -102,7 +105,7 @@ class _BleProvisionSheetState extends ConsumerState<BleProvisionSheet> {
|
|||||||
mqttHost: mqttHost,
|
mqttHost: mqttHost,
|
||||||
mqttPort: mqttPort,
|
mqttPort: mqttPort,
|
||||||
);
|
);
|
||||||
await ref
|
_provisionedSensor = await ref
|
||||||
.read(sensorRepositoryProvider)
|
.read(sensorRepositoryProvider)
|
||||||
.createSensor(_selected!.name, name: _selected!.name);
|
.createSensor(_selected!.name, name: _selected!.name);
|
||||||
|
|
||||||
@@ -254,12 +257,26 @@ class _BleProvisionSheetState extends ConsumerState<BleProvisionSheet> {
|
|||||||
),
|
),
|
||||||
_DoneStep(
|
_DoneStep(
|
||||||
onGoToFloorPlan: () {
|
onGoToFloorPlan: () {
|
||||||
final router = GoRouter.of(context);
|
if (_provisionedSensor != null) {
|
||||||
Navigator.of(context).pop();
|
_placeOnFloorPlan(context, _provisionedSensor!);
|
||||||
router.go('/floorplan');
|
}
|
||||||
},
|
},
|
||||||
onAddAnother: _reset,
|
onAddAnother: _reset,
|
||||||
onDone: () => Navigator.of(context).pop(),
|
onDone: () => Navigator.of(context).pop(),
|
||||||
|
onCalibrate: _provisionedSensor == null
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
final sensor = _provisionedSensor!;
|
||||||
|
Navigator.of(
|
||||||
|
context,
|
||||||
|
rootNavigator: true,
|
||||||
|
).pop();
|
||||||
|
showCalibrationSheet(
|
||||||
|
context,
|
||||||
|
sensor.id,
|
||||||
|
sensor.sensorId,
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
.map(
|
.map(
|
||||||
@@ -276,6 +293,16 @@ class _BleProvisionSheetState extends ConsumerState<BleProvisionSheet> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _placeOnFloorPlan(BuildContext context, Sensor sensor) {
|
||||||
|
final router = GoRouter.of(context);
|
||||||
|
final fromSensors =
|
||||||
|
router.routeInformationProvider.value.uri.path == '/sensors';
|
||||||
|
ref.read(sensorPlacementProvider.notifier).state = sensor;
|
||||||
|
ref.read(sensorPlacementOriginSensorsProvider.notifier).state = fromSensors;
|
||||||
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
|
router.go('/floorplan');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ScanPage extends StatefulWidget {
|
class _ScanPage extends StatefulWidget {
|
||||||
@@ -491,9 +518,7 @@ class _ConfigurePageState extends State<_ConfigurePage> {
|
|||||||
border: const OutlineInputBorder(),
|
border: const OutlineInputBorder(),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
_obscurePassword
|
_obscurePassword ? Icons.visibility_off : Icons.visibility,
|
||||||
? Icons.visibility_off
|
|
||||||
: Icons.visibility,
|
|
||||||
),
|
),
|
||||||
onPressed: () =>
|
onPressed: () =>
|
||||||
setState(() => _obscurePassword = !_obscurePassword),
|
setState(() => _obscurePassword = !_obscurePassword),
|
||||||
@@ -595,14 +620,17 @@ class _DoneStep extends StatelessWidget {
|
|||||||
required this.onGoToFloorPlan,
|
required this.onGoToFloorPlan,
|
||||||
required this.onAddAnother,
|
required this.onAddAnother,
|
||||||
required this.onDone,
|
required this.onDone,
|
||||||
|
this.onCalibrate,
|
||||||
});
|
});
|
||||||
|
|
||||||
final VoidCallback onGoToFloorPlan;
|
final VoidCallback onGoToFloorPlan;
|
||||||
final VoidCallback onAddAnother;
|
final VoidCallback onAddAnother;
|
||||||
final VoidCallback onDone;
|
final VoidCallback onDone;
|
||||||
|
final VoidCallback? onCalibrate;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final theme = Theme.of(context);
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
child: Column(
|
child: Column(
|
||||||
@@ -613,22 +641,36 @@ class _DoneStep extends StatelessWidget {
|
|||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
'Sensor provisioned!',
|
'Sensor provisioned!',
|
||||||
style: Theme.of(context).textTheme.titleLarge,
|
style: theme.textTheme.titleLarge,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
'The sensor will appear in the list once it connects to the network. '
|
'The sensor will appear in the list once it connects to the network. '
|
||||||
'Open the floor plan to place it.',
|
'Open the floor plan to place it.',
|
||||||
style: Theme.of(context).textTheme.bodyMedium,
|
style: theme.textTheme.bodyMedium,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 32),
|
const SizedBox(height: 32),
|
||||||
FilledButton.icon(
|
FilledButton.icon(
|
||||||
icon: const Icon(Icons.map_outlined),
|
icon: const Icon(Icons.gps_fixed),
|
||||||
label: const Text('Place on floor plan'),
|
label: const Text('Place on floor plan'),
|
||||||
onPressed: onGoToFloorPlan,
|
onPressed: onGoToFloorPlan,
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
OutlinedButton.icon(
|
||||||
|
icon: const Icon(Icons.tune),
|
||||||
|
label: const Text('Calibrate sensor'),
|
||||||
|
onPressed: onCalibrate,
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
Text(
|
||||||
|
'For best accuracy, calibrate after mounting the sensor in its intended position.',
|
||||||
|
style: theme.textTheme.bodySmall?.copyWith(
|
||||||
|
color: theme.colorScheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 12),
|
||||||
OutlinedButton.icon(
|
OutlinedButton.icon(
|
||||||
icon: const Icon(Icons.add),
|
icon: const Icon(Icons.add),
|
||||||
|
|||||||
Reference in New Issue
Block a user