feat: ui rework and gear generator
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:abawo_bt_app/controller/bluetooth.dart';
|
||||
import 'package:abawo_bt_app/model/gear_ratio_codec.dart';
|
||||
import 'package:abawo_bt_app/model/shifter_types.dart';
|
||||
import 'package:anyhow/anyhow.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
@ -43,7 +44,6 @@ class ShifterService {
|
||||
static const int _gearRatioSlots = 32;
|
||||
static const int _defaultGearIndexOffset = _gearRatioSlots;
|
||||
static const int _gearRatioPayloadBytes = _gearRatioSlots + 1;
|
||||
static const double _maxGearRatio = 255 / 64;
|
||||
static const int _gearRatioWriteMtu = 64;
|
||||
|
||||
Future<Result<void>> writeConnectToAddress(String bikeDeviceId) async {
|
||||
@ -166,12 +166,61 @@ class ShifterService {
|
||||
}
|
||||
|
||||
try {
|
||||
return Ok(CentralStatus.fromCborBytes(readRes.unwrap()));
|
||||
return Ok(CentralStatus.fromBytes(readRes.unwrap()));
|
||||
} catch (e) {
|
||||
return bail('Failed to decode status payload: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<Result<ShifterDeviceTelemetry>> readDeviceTelemetry() async {
|
||||
int? batteryPercent;
|
||||
String? firmwareRevision;
|
||||
final errors = <String>[];
|
||||
|
||||
final batteryResult = await _requireBluetooth.readCharacteristic(
|
||||
buttonDeviceId,
|
||||
batteryServiceUuid,
|
||||
batteryLevelCharacteristicUuid,
|
||||
);
|
||||
if (batteryResult.isOk()) {
|
||||
try {
|
||||
batteryPercent = parseBatteryLevelPercent(batteryResult.unwrap());
|
||||
} catch (error) {
|
||||
errors.add('battery parse failed: $error');
|
||||
}
|
||||
} else {
|
||||
errors.add('battery read failed: ${batteryResult.unwrapErr()}');
|
||||
}
|
||||
|
||||
final firmwareResult = await _requireBluetooth.readCharacteristic(
|
||||
buttonDeviceId,
|
||||
deviceInformationServiceUuid,
|
||||
firmwareRevisionCharacteristicUuid,
|
||||
);
|
||||
if (firmwareResult.isOk()) {
|
||||
try {
|
||||
firmwareRevision = parseGattUtf8String(firmwareResult.unwrap());
|
||||
} catch (error) {
|
||||
errors.add('firmware parse failed: $error');
|
||||
}
|
||||
} else {
|
||||
errors.add('firmware read failed: ${firmwareResult.unwrapErr()}');
|
||||
}
|
||||
|
||||
if (batteryPercent == null &&
|
||||
firmwareRevision == null &&
|
||||
errors.isNotEmpty) {
|
||||
return bail('Could not read battery or firmware: ${errors.join('; ')}');
|
||||
}
|
||||
|
||||
return Ok(
|
||||
ShifterDeviceTelemetry(
|
||||
batteryPercent: batteryPercent,
|
||||
firmwareRevision: firmwareRevision,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<Result<DfuPreflightResult>> runDfuPreflight({
|
||||
int requestedMtu = universalShifterDfuPreferredMtu,
|
||||
}) async {
|
||||
@ -253,7 +302,7 @@ class ShifterService {
|
||||
.listen(
|
||||
(data) {
|
||||
try {
|
||||
final status = CentralStatus.fromCborBytes(data);
|
||||
final status = CentralStatus.fromBytes(data);
|
||||
_statusController.add(status);
|
||||
} catch (error, st) {
|
||||
_log.warning(
|
||||
@ -284,19 +333,11 @@ class ShifterService {
|
||||
}
|
||||
|
||||
int _encodeGearRatio(double value) {
|
||||
if (value <= 0) {
|
||||
return 0;
|
||||
}
|
||||
final clamped = value.clamp(0, _maxGearRatio);
|
||||
final scaled = (clamped * 64).round();
|
||||
if (scaled <= 0) {
|
||||
return 1;
|
||||
}
|
||||
return scaled.clamp(1, 255);
|
||||
return encodeGearRatioByte(value);
|
||||
}
|
||||
|
||||
double _decodeGearRatio(int raw) {
|
||||
return raw / 64.0;
|
||||
return decodeGearRatioByte(raw);
|
||||
}
|
||||
|
||||
String _formatBytes(List<int> bytes) {
|
||||
|
||||
Reference in New Issue
Block a user