hondavert-dev/lib/ui/screens/dashboard/dashboard_slots_provider.dart
metatroncubeswdev 6b8d069ef4 O2 in volts, injector duty, Fuel Pump default flag, raw frame log
Checked against the USB tool on the bench (3210 rpm):
- O2: raw x 5/256 V (raw 195 -> 3.81 V, as the USB tool shows).
- New derived sensor: injector duty = INJ ms x RPM / 1200
  (16.67 ms @ 3210 rpm -> 44 %, as the USB tool shows).
- Default dashboard flags: MIL, Fuel Pump, FAN Out, VTEC Out (the
  requirement's "FuelCut" is the fuel pump flag on the S300).
- Log one raw frame (bytes 0-63) every 5 s so USB-tool readings can be
  matched to bytes; INJ, IGN, TPS, MIL, AF and PA still need that check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:47:12 -04:00

126 lines
3.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../../core/models/sensor_defs.dart';
/// What the dashboard shows, per the requirement document: a selectable
/// main sensor (gauge) + sub sensor, 10 selectable values (landscape: 5 left
/// + 5 right; portrait: 2×5) and 4 selectable flags. Persisted.
class DashboardConfig {
static const valueCount = 10;
static const flagCount = 4;
final String main;
final String sub;
final List<String> values;
final List<String> flags;
const DashboardConfig({
required this.main,
required this.sub,
required this.values,
required this.flags,
});
static const defaults = DashboardConfig(
main: 'rpm',
sub: 'vss',
values: [
'vss', 'ect', 'iat', 'map', 'o2', // left
'tps', 'bat', 'ign', 'inj', 'eth', // right
],
// Requirement picture: MIL, FuelCut, FAN Out, VTEC Out. On the S300
// the fuel flag is the fuel pump relay (client).
flags: ['mil', 'fuelpump', 'fanout', 'vtec'],
);
DashboardConfig copyWith({
String? main,
String? sub,
List<String>? values,
List<String>? flags,
}) =>
DashboardConfig(
main: main ?? this.main,
sub: sub ?? this.sub,
values: values ?? this.values,
flags: flags ?? this.flags,
);
}
const _kMain = 'dash.main';
const _kSub = 'dash.sub';
const _kValues = 'dash.values';
const _kFlags = 'dash.flags';
class DashboardConfigNotifier extends StateNotifier<DashboardConfig> {
DashboardConfigNotifier() : super(DashboardConfig.defaults) {
_load();
}
static bool _isSensor(String id) => sensorDefs.any((d) => d.id == id);
static bool _isFlag(String id) => flagDefs.any((f) => f.id == id);
Future<void> _load() async {
try {
final p = await SharedPreferences.getInstance();
const d = DashboardConfig.defaults;
List<String> list(String key, int n, bool Function(String) valid,
List<String> fallback) {
final saved = p.getStringList(key);
if (saved == null || saved.length != n || !saved.every(valid)) {
return fallback;
}
return saved;
}
final main = p.getString(_kMain);
final sub = p.getString(_kSub);
final next = DashboardConfig(
main: main != null && _isSensor(main) ? main : d.main,
sub: sub != null && _isSensor(sub) ? sub : d.sub,
values: list(_kValues, DashboardConfig.valueCount, _isSensor, d.values),
flags: list(_kFlags, DashboardConfig.flagCount, _isFlag, d.flags),
);
if (mounted) state = next;
} catch (_) {
// Keep defaults if preferences can't be read.
}
}
void _persist() {
final s = state;
SharedPreferences.getInstance().then((p) {
p.setString(_kMain, s.main);
p.setString(_kSub, s.sub);
p.setStringList(_kValues, s.values);
p.setStringList(_kFlags, s.flags);
}).catchError((Object _) {});
}
void setMain(String id) {
state = state.copyWith(main: id);
_persist();
}
void setSub(String id) {
state = state.copyWith(sub: id);
_persist();
}
void setValue(int index, String id) {
state = state.copyWith(values: [...state.values]..[index] = id);
_persist();
}
void setFlag(int index, String id) {
state = state.copyWith(flags: [...state.flags]..[index] = id);
_persist();
}
}
final dashboardConfigProvider =
StateNotifierProvider<DashboardConfigNotifier, DashboardConfig>(
(ref) => DashboardConfigNotifier(),
);