summaryrefslogtreecommitdiffstats
path: root/lib/data
diff options
context:
space:
mode:
Diffstat (limited to 'lib/data')
-rw-r--r--lib/data/data_providers/app_config_provider.dart162
-rw-r--r--lib/data/data_providers/app_provider.dart17
-rw-r--r--lib/data/data_providers/audio_notifier.dart129
-rw-r--r--lib/data/data_providers/hybrid_notifier.dart42
-rw-r--r--lib/data/data_providers/val_client.dart118
-rw-r--r--lib/data/data_providers/vehicle_notifier.dart253
-rw-r--r--lib/data/models/audio.dart35
-rw-r--r--lib/data/models/hybrid.dart2
-rw-r--r--lib/data/models/vehicle.dart139
9 files changed, 543 insertions, 354 deletions
diff --git a/lib/data/data_providers/app_config_provider.dart b/lib/data/data_providers/app_config_provider.dart
new file mode 100644
index 0000000..7e0ddc6
--- /dev/null
+++ b/lib/data/data_providers/app_config_provider.dart
@@ -0,0 +1,162 @@
+import 'dart:io';
+import 'package:flutter/foundation.dart';
+import 'package:flutter_ics_homescreen/core/constants/constants.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:yaml/yaml.dart';
+
+class KuksaConfig {
+ final String hostname;
+ final int port;
+ final String authorization;
+ final bool use_tls;
+ final List<int> ca_certificate;
+ final String tls_server_name;
+
+ static String defaultHostname = 'localhost';
+ static int defaultPort = 55555;
+ static String defaultCaCertPath = '/etc/kuksa-val/CA.pem';
+
+ KuksaConfig(
+ {required this.hostname,
+ required this.port,
+ required this.authorization,
+ required this.use_tls,
+ required this.ca_certificate,
+ required this.tls_server_name});
+
+ static KuksaConfig defaultConfig() {
+ return KuksaConfig(
+ hostname: KuksaConfig.defaultHostname,
+ port: KuksaConfig.defaultPort,
+ authorization: "",
+ use_tls: false,
+ ca_certificate: [],
+ tls_server_name: "");
+ }
+}
+
+class AppConfig {
+ final bool disableBkgAnimation;
+ final bool randomHybridAnimation;
+ final KuksaConfig kuksaConfig;
+
+ static String configFilePath = '/etc/xdg/AGL/ics-homescreen.yaml';
+
+ AppConfig({required this.disableBkgAnimation, required this.randomHybridAnimation, required this.kuksaConfig});
+
+ static KuksaConfig parseKuksaConfig(YamlMap kuksaMap) {
+ try {
+ String hostname = KuksaConfig.defaultHostname;
+ if (kuksaMap.containsKey('hostname')) {
+ hostname = kuksaMap['hostname'];
+ }
+
+ int port = KuksaConfig.defaultPort;
+ if (kuksaMap.containsKey('port')) {
+ port = kuksaMap['port'];
+ }
+
+ String token = "";
+ if (kuksaMap.containsKey('authorization')) {
+ String s = kuksaMap['authorization'];
+ if (s.isNotEmpty) {
+ if (s.startsWith("/")) {
+ debugPrint("Reading authorization token $s");
+ try {
+ token = File(s).readAsStringSync();
+ } on Exception catch (_) {
+ print("ERROR: Could not read authorization token file $token");
+ token = "";
+ }
+ } else {
+ token = s;
+ }
+ }
+ }
+ //debugPrint("authorization = $token");
+
+ bool use_tls = false;
+ if (kuksaMap.containsKey('use-tls')) {
+ var value = kuksaMap['use-tls'];
+ if (value is bool) use_tls = value;
+ }
+ //debugPrint("Use TLS = $use_tls");
+
+ List<int> ca_cert = [];
+ String ca_path = KuksaConfig.defaultCaCertPath;
+ if (kuksaMap.containsKey('ca-certificate')) {
+ ca_path = kuksaMap['ca-certificate'];
+ }
+ try {
+ ca_cert = File(ca_path).readAsBytesSync();
+ } on Exception catch (_) {
+ print("ERROR: Could not read CA certificate file $ca_path");
+ ca_cert = [];
+ }
+ //debugPrint("CA cert = $ca_cert");
+
+ String tls_server_name = "";
+ if (kuksaMap.containsKey('tls-server-name')) {
+ tls_server_name = kuksaMap['tls_server_name'];
+ }
+
+ return KuksaConfig(
+ hostname: hostname,
+ port: port,
+ authorization: token,
+ use_tls: use_tls,
+ ca_certificate: ca_cert,
+ tls_server_name: tls_server_name);
+ } on Exception catch (_) {
+ return KuksaConfig.defaultConfig();
+ }
+ }
+}
+
+final appConfigProvider = Provider((ref) {
+ final configFile = File(AppConfig.configFilePath);
+ try {
+ print("Reading configuration ${AppConfig.configFilePath}");
+ String content = configFile.readAsStringSync();
+ final dynamic yamlMap = loadYaml(content);
+
+ KuksaConfig kuksaConfig;
+ if (yamlMap.containsKey('kuksa')) {
+ kuksaConfig = AppConfig.parseKuksaConfig(yamlMap['kuksa']);
+ } else {
+ kuksaConfig = KuksaConfig(
+ hostname: KuksaConfig.defaultHostname,
+ port: KuksaConfig.defaultPort,
+ authorization: "",
+ use_tls: false,
+ ca_certificate: [],
+ tls_server_name: "");
+ }
+
+ bool disableBkgAnimation = disableBkgAnimationDefault;
+ if (yamlMap.containsKey('disable-bg-animation')) {
+ var value = yamlMap['disable-bg-animation'];
+ if (value is bool) {
+ disableBkgAnimation = value;
+ }
+ }
+
+ bool randomHybridAnimation = randomHybridAnimationDefault;
+ if (yamlMap.containsKey('random-hybrid-animation')) {
+ var value = yamlMap['random-hybrid-animation'];
+ if (value is bool) {
+ randomHybridAnimation = value;
+ }
+ }
+
+ return AppConfig(
+ disableBkgAnimation: disableBkgAnimation,
+ randomHybridAnimation: randomHybridAnimation,
+ kuksaConfig: kuksaConfig);
+ } on Exception catch (_) {
+ return AppConfig(
+ disableBkgAnimation: false,
+ randomHybridAnimation: false,
+ kuksaConfig: KuksaConfig.defaultConfig());
+ }
+});
diff --git a/lib/data/data_providers/app_provider.dart b/lib/data/data_providers/app_provider.dart
index fb0a447..cfda370 100644
--- a/lib/data/data_providers/app_provider.dart
+++ b/lib/data/data_providers/app_provider.dart
@@ -4,6 +4,7 @@ import 'package:flutter_ics_homescreen/data/data_providers/time_notifier.dart';
import 'package:flutter_ics_homescreen/data/data_providers/units_notifier.dart';
import 'package:flutter_ics_homescreen/data/data_providers/audio_notifier.dart';
import 'package:flutter_ics_homescreen/data/data_providers/users_notifier.dart';
+import 'package:flutter_ics_homescreen/data/data_providers/val_client.dart';
import 'package:flutter_ics_homescreen/export.dart';
import '../models/users.dart';
@@ -36,9 +37,15 @@ enum AppState {
}
final appProvider = StateProvider<AppState>((ref) => AppState.splash);
-final vehicleProvider = StateNotifierProvider<VehicleNotifier, Vehicle>((ref) {
- return VehicleNotifier(const Vehicle.initial());
+
+final valClientProvider = Provider((ref) {
+ KuksaConfig config = ref.watch(appConfigProvider).kuksaConfig;
+ return ValClient(config: config, ref: ref);
});
+
+final vehicleProvider =
+ NotifierProvider<VehicleNotifier, Vehicle>(VehicleNotifier.new);
+
final signalsProvider = StateNotifierProvider<SignalNotifier, Signals>((ref) {
return SignalNotifier(const Signals.initial());
});
@@ -46,9 +53,9 @@ final signalsProvider = StateNotifierProvider<SignalNotifier, Signals>((ref) {
final unitStateProvider = StateNotifierProvider<UnitsNotifier, Units>((ref) {
return UnitsNotifier(const Units.initial());
});
-final audioStateProvider = StateNotifierProvider<AudioNotifier, Audio>((ref) {
- return AudioNotifier(const Audio.initial());
-});
+
+final audioStateProvider =
+ NotifierProvider<AudioNotifier, Audio>(AudioNotifier.new);
final usersProvider = StateNotifierProvider<UsersNotifier, Users>((ref) {
return UsersNotifier(Users.initial());
diff --git a/lib/data/data_providers/audio_notifier.dart b/lib/data/data_providers/audio_notifier.dart
index 1f8c1a9..32ab409 100644
--- a/lib/data/data_providers/audio_notifier.dart
+++ b/lib/data/data_providers/audio_notifier.dart
@@ -1,22 +1,131 @@
import 'package:flutter_ics_homescreen/export.dart';
+import 'package:protos/protos.dart';
-class AudioNotifier extends StateNotifier<Audio> {
- AudioNotifier(super.state);
+class AudioNotifier extends Notifier<Audio> {
+ @override
+ Audio build() {
+ return Audio.initial();
+ }
void resetToDefaults() {
- state = state.copyWith(treble: 5.0, bass: 5.0, rearFront: 5.0);
+ state = state.copyWith(balance: 5.0, fade: 5.0, treble: 5.0, bass: 5.0);
+ var valClient = ref.read(valClientProvider);
+ int value = (state.balance * 20).toInt() - 100;
+ valClient.setInt32(
+ VSSPath.vehicleMediaBalance,
+ value,
+ true,
+ );
+ value = (state.fade * 20).toInt() - 100;
+ valClient.setInt32(
+ VSSPath.vehicleMediaFade,
+ value,
+ true,
+ );
+ value = (state.treble * 20).toInt() - 100;
+ valClient.setInt32(
+ VSSPath.vehicleMediaTreble,
+ value,
+ true,
+ );
+ value = (state.bass * 20).toInt() - 100;
+ valClient.setInt32(
+ VSSPath.vehicleMediaBass,
+ value,
+ true,
+ );
}
- void setTreble(double newVal) {
- state = state.copyWith(treble: newVal);
+ bool handleSignalsUpdate(EntryUpdate update) {
+ bool handled = true;
+ switch (update.entry.path) {
+ case VSSPath.vehicleMediaVolume:
+ if (update.entry.value.hasUint32()) {
+ double value = update.entry.value.uint32.toDouble();
+ state = state.copyWith(volume: value);
+ }
+ break;
+ case VSSPath.vehicleMediaBalance:
+ if (update.entry.value.hasInt32()) {
+ double value = (update.entry.value.int32 + 100) / 20.0;
+ state = state.copyWith(balance: value);
+ }
+ break;
+ case VSSPath.vehicleMediaFade:
+ if (update.entry.value.hasInt32()) {
+ double value = (update.entry.value.int32 + 100) / 20.0;
+ state = state.copyWith(fade: value);
+ }
+ break;
+ case VSSPath.vehicleMediaTreble:
+ if (update.entry.value.hasInt32()) {
+ double value = (update.entry.value.int32 + 100) / 20.0;
+ state = state.copyWith(treble: value);
+ }
+ break;
+ case VSSPath.vehicleMediaBass:
+ if (update.entry.value.hasInt32()) {
+ double value = (update.entry.value.int32 + 100) / 20.0;
+ state = state.copyWith(bass: value);
+ }
+ break;
+ default:
+ handled = false;
+ }
+ return handled;
}
- void setBass(double newVal) {
- state = state.copyWith(bass: newVal);
+ void setVolume(double newValue) {
+ state = state.copyWith(volume: newValue);
+ var valClient = ref.read(valClientProvider);
+ valClient.setUint32(
+ VSSPath.vehicleMediaVolume,
+ newValue.toInt(),
+ true,
+ );
}
- void setRearFront(double newVal) {
- state = state.copyWith(rearFront: newVal);
+ void setBalance(double newValue) {
+ state = state.copyWith(balance: newValue);
+ int value = (newValue * 20).toInt() - 100;
+ var valClient = ref.read(valClientProvider);
+ valClient.setInt32(
+ VSSPath.vehicleMediaBalance,
+ value,
+ true,
+ );
+ }
+
+ void setFade(double newValue) {
+ state = state.copyWith(fade: newValue);
+ int value = (newValue * 20).toInt() - 100;
+ var valClient = ref.read(valClientProvider);
+ valClient.setInt32(
+ VSSPath.vehicleMediaFade,
+ value,
+ true,
+ );
}
-}
+ void setTreble(double newValue) {
+ state = state.copyWith(treble: newValue);
+ int value = (newValue * 20).toInt() - 100;
+ var valClient = ref.read(valClientProvider);
+ valClient.setInt32(
+ VSSPath.vehicleMediaTreble,
+ value,
+ true,
+ );
+ }
+
+ void setBass(double newValue) {
+ state = state.copyWith(bass: newValue);
+ int value = (newValue * 20).toInt() - 100;
+ var valClient = ref.read(valClientProvider);
+ valClient.setInt32(
+ VSSPath.vehicleMediaBass,
+ value,
+ true,
+ );
+ }
+}
diff --git a/lib/data/data_providers/hybrid_notifier.dart b/lib/data/data_providers/hybrid_notifier.dart
index 3668f61..7381f5c 100644
--- a/lib/data/data_providers/hybrid_notifier.dart
+++ b/lib/data/data_providers/hybrid_notifier.dart
@@ -1,6 +1,6 @@
// ignore_for_file: unused_local_variable
-import '../../export.dart';
+import 'package:flutter_ics_homescreen/export.dart';
class HybridNotifier extends StateNotifier<Hybrid> {
HybridNotifier(super.state);
@@ -9,38 +9,44 @@ class HybridNotifier extends StateNotifier<Hybrid> {
switch (hybridState) {
case HybridState.idle:
state = state.copyWith(
- topArrowState: ArrowState.blue,
- leftArrowState: ArrowState.blue,
- rightArrowState: ArrowState.blue,
- batteryState: BatteryState.white,
+ hybridState: hybridState,
+ topArrowState: ArrowState.blue,
+ leftArrowState: ArrowState.blue,
+ rightArrowState: ArrowState.blue,
+ batteryState: BatteryState.white,
);
break;
case HybridState.engineOutput:
state = state.copyWith(
- topArrowState: ArrowState.red,
- leftArrowState: ArrowState.red,
- rightArrowState: ArrowState.blue,
- batteryState: BatteryState.red,
+ hybridState: hybridState,
+ topArrowState: ArrowState.red,
+ leftArrowState: ArrowState.red,
+ rightArrowState: ArrowState.blue,
+ batteryState: BatteryState.red,
);
break;
case HybridState.regenerativeBreaking:
state = state.copyWith(
+ hybridState: hybridState,
topArrowState: ArrowState.blue,
leftArrowState: ArrowState.blue,
rightArrowState: ArrowState.green,
- batteryState: BatteryState.green);
-
+ batteryState: BatteryState.green
+ );
break;
- case HybridState.baterryOutput:
+ case HybridState.batteryOutput:
state = state.copyWith(
+ hybridState: hybridState,
topArrowState: ArrowState.blue,
leftArrowState: ArrowState.blue,
rightArrowState: ArrowState.yellow,
- batteryState: BatteryState.yellow);
+ batteryState: BatteryState.yellow
+ );
break;
default:
+ state = state.copyWith(hybridState: hybridState);
+ break;
}
- state = state.copyWith(hybridState: hybridState);
}
void updateHybridState(double speed, double engineSpeed, bool brake) {
@@ -55,25 +61,23 @@ class HybridNotifier extends StateNotifier<Hybrid> {
// Variable for storing the average value of RPM
double avgRpm = 0.0;
-
if (speed == 0 && engineSpeed == 0) {
// Set idle state.
currentState = HybridState.idle;
} else if (engineSpeed > 0 && speed > 0) {
- // Set stan na engine output state..
+ // Set engine output state..
currentState = HybridState.engineOutput;
} else if (speed < 0 && brake) {
- // Set regenerative breaking state
+ // Set regenerative breaking state
currentState = HybridState.regenerativeBreaking;
} else if (speed > 0 && engineSpeed <= 0) {
// Set battery output state
- currentState = HybridState.baterryOutput;
+ currentState = HybridState.batteryOutput;
}
// Update hybrid state
if (currentState != previousState) {
- //state = state.copyWith(hybridState: currentState);
setHybridState(currentState);
}
}
diff --git a/lib/data/data_providers/val_client.dart b/lib/data/data_providers/val_client.dart
new file mode 100644
index 0000000..28bb480
--- /dev/null
+++ b/lib/data/data_providers/val_client.dart
@@ -0,0 +1,118 @@
+import 'package:flutter_ics_homescreen/export.dart';
+import 'package:protos/protos.dart';
+
+class ValClient {
+ final KuksaConfig config;
+ final Ref ref;
+ late ClientChannel channel;
+ late VALClient stub;
+ late String authorization;
+
+ ValClient({required this.config, required this.ref}) {
+ debugPrint("Using ${config.hostname}:${config.port}");
+ ChannelCredentials creds;
+ if (config.use_tls && config.ca_certificate.isNotEmpty) {
+ print("Using TLS");
+ if (config.tls_server_name.isNotEmpty) {
+ creds = ChannelCredentials.secure(
+ certificates: config.ca_certificate,
+ authority: config.tls_server_name);
+ } else {
+ creds = ChannelCredentials.secure(certificates: config.ca_certificate);
+ }
+ } else {
+ creds = const ChannelCredentials.insecure();
+ }
+ channel = ClientChannel(config.hostname,
+ port: config.port, options: ChannelOptions(credentials: creds));
+ debugPrint('Start Listen on port: ${config.port}');
+ stub = VALClient(channel);
+ }
+
+ void startListen() async {
+ List<String> fewSignals = VSSPath().getSignalsList();
+ var request = SubscribeRequest();
+ Map<String, String> metadata = {};
+ if (config.authorization.isNotEmpty) {
+ metadata = {'authorization': "Bearer ${config.authorization}"};
+ }
+ for (int i = 0; i < fewSignals.length; i++) {
+ var entry = SubscribeEntry();
+ entry.path = fewSignals[i];
+ entry.fields.add(Field.FIELD_PATH);
+ entry.fields.add(Field.FIELD_VALUE);
+ request.entries.add(entry);
+ }
+ try {
+ var responseStream =
+ stub.subscribe(request, options: CallOptions(metadata: metadata));
+ responseStream.listen((value) async {
+ for (var update in value.updates) {
+ if (!(update.hasEntry() && update.entry.hasPath())) continue;
+ handleSignalsUpdate(update);
+ }
+ }, onError: (stacktrace, errorDescriptor) {
+ debugPrint(stacktrace.toString());
+ });
+ } catch (e) {
+ debugPrint(e.toString());
+ }
+ }
+
+ bool handleSignalsUpdate(EntryUpdate update) {
+ if (ref.read(vehicleProvider.notifier).handleSignalsUpdate(update)) {
+ return true;
+ }
+ return ref.read(audioStateProvider.notifier).handleSignalsUpdate(update);
+ }
+
+ void setUint32(String path, int value, [bool actuator = true]) async {
+ var dp = Datapoint()..uint32 = value;
+ set(path, dp, actuator);
+ }
+
+ void setInt32(String path, int value, [bool actuator = true]) async {
+ var dp = Datapoint()..int32 = value;
+ set(path, dp, actuator);
+ }
+
+ void setBool(String path, bool value, [bool actuator = true]) async {
+ var dp = Datapoint()..bool_12 = value;
+ set(path, dp, actuator);
+ }
+
+ void setString(String path, String value, [bool actuator = true]) async {
+ var dp = Datapoint()..string = value;
+ set(path, dp, actuator);
+ }
+
+ void setFloat(String path, double value, [bool actuator = true]) async {
+ var dp = Datapoint()..float = value;
+ set(path, dp, actuator);
+ }
+
+ void setDouble(String path, double value, [bool actuator = true]) async {
+ var dp = Datapoint()..double_18 = value;
+ set(path, dp, actuator);
+ }
+
+ void set(String path, Datapoint dp, bool actuator) async {
+ var entry = DataEntry()..path = path;
+ var update = EntryUpdate();
+ if (actuator) {
+ entry.actuatorTarget = dp;
+ update.fields.add(Field.FIELD_ACTUATOR_TARGET);
+ } else {
+ entry.value = dp;
+ update.fields.add(Field.FIELD_VALUE);
+ }
+ update.entry = entry;
+ var request = SetRequest();
+ request.updates.add(update);
+ Map<String, String> metadata = {};
+ if (config.authorization.isNotEmpty) {
+ metadata = {'authorization': "Bearer ${config.authorization}"};
+ }
+ await stub.set(request, options: CallOptions(metadata: metadata));
+ }
+}
diff --git a/lib/data/data_providers/vehicle_notifier.dart b/lib/data/data_providers/vehicle_notifier.dart
index 3a385a3..78c5328 100644
--- a/lib/data/data_providers/vehicle_notifier.dart
+++ b/lib/data/data_providers/vehicle_notifier.dart
@@ -3,43 +3,20 @@
import 'dart:async';
import 'package:flutter_ics_homescreen/export.dart';
-import 'package:flutter/services.dart';
import 'package:protos/protos.dart';
-class KuksaConfig {
- final String hostname;
- final int port;
- final String authorization;
- final bool use_tls;
- final List<int> ca_certificate;
- final String tls_server_name;
-
- static String configFilePath = '/etc/xdg/AGL/ics-homescreen.yaml';
- static String defaultHostname = 'localhost';
- static int defaultPort = 55555;
- static String defaultCaCertPath = '/etc/kuksa-val/CA.pem';
-
- KuksaConfig(
- {required this.hostname,
- required this.port,
- required this.authorization,
- required this.use_tls,
- required this.ca_certificate,
- required this.tls_server_name});
-}
-
-class VehicleNotifier extends StateNotifier<Vehicle> {
- VehicleNotifier(super.state);
-
- late ClientChannel channel;
- late String authorization;
- late VALClient stub;
+class VehicleNotifier extends Notifier<Vehicle> {
+ @override
+ Vehicle build() {
+ return Vehicle.initial();
+ }
void updateSpeed(double newValue) {
state = state.copyWith(speed: newValue);
}
- void handleSignalsUpdate(EntryUpdate update) {
+ bool handleSignalsUpdate(EntryUpdate update) {
+ bool handled = true;
switch (update.entry.path) {
case VSSPath.vehicleSpeed:
if (update.entry.value.hasFloat()) {
@@ -66,11 +43,6 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
state = state.copyWith(fuelLevel: update.entry.value.uint32);
}
break;
- case VSSPath.vehicleMediaVolume:
- if (update.entry.value.hasUint32()) {
- state = state.copyWith(mediaVolume: update.entry.value.uint32);
- }
- break;
case VSSPath.vehicleIsChildLockActiveLeft:
if (update.entry.value.hasBool_12()) {
state =
@@ -108,7 +80,6 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
state = state.copyWith(rearRightTire: update.entry.value.uint32);
}
break;
-
case VSSPath.vehicleIsAirConditioningActive:
if (update.entry.value.hasBool_12()) {
state = state.copyWith(
@@ -142,8 +113,7 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
fanSpeed = 3;
else if (value > 33)
fanSpeed = 2;
- else if (value > 0)
- fanSpeed = 1;
+ else if (value > 0) fanSpeed = 1;
state = state.copyWith(fanSpeed: fanSpeed);
}
break;
@@ -158,183 +128,18 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
state.copyWith(passengerTemperature: update.entry.value.int32);
}
break;
- // default:
- // debugPrint("ERROR: Unexpected path ${update.entry.path}");
- // break;
- }
- }
-
- Future<KuksaConfig> readConfig() async {
- String hostname = KuksaConfig.defaultHostname;
- int port = KuksaConfig.defaultPort;
- bool useTls = false;
- String caPath = KuksaConfig.defaultCaCertPath;
- List<int> caCert = [];
- String tlsServerName = "";
- String token = "";
-
- // Read build time configuration from bundle
- try {
- var data = await rootBundle.loadString('app-config/config.yaml');
- final dynamic yamlMap = loadYaml(data);
-
- if (yamlMap.containsKey('hostname')) {
- hostname = yamlMap['hostname'];
- }
-
- if (yamlMap.containsKey('port')) {
- port = yamlMap['port'];
- }
-
- if (yamlMap.containsKey('use-tls')) {
- var value = yamlMap['use-tls'];
- if (value is bool) {
- useTls = value;
- }
- }
-
- if (useTls) {
- if (yamlMap.containsKey('ca-certificate')) {
- caPath = yamlMap['ca-certificate'];
- }
-
- if (yamlMap.containsKey('tls-server-name')) {
- tlsServerName = yamlMap['tls_server_name'];
- }
- }
-
- if (yamlMap.containsKey('authorization')) {
- token = yamlMap['authorization'];
- }
- } catch (e) {
- //debugPrint('ERROR: Could not read from file: $configFile');
- debugPrint(e.toString());
- }
-
- // Try reading from configuration file in /etc
- final configFile = File(KuksaConfig.configFilePath);
- try {
- print("Reading configuration ${KuksaConfig.configFilePath}");
- String content = await configFile.readAsString();
- final dynamic yamlMap = loadYaml(content);
-
- if (yamlMap.containsKey('hostname')) {
- hostname = yamlMap['hostname'];
- }
-
- if (yamlMap.containsKey('port')) {
- port = yamlMap['port'];
- }
-
- if (yamlMap.containsKey('use-tls')) {
- var value = yamlMap['use-tls'];
- if (value is bool) {
- useTls = value;
- }
- }
- //debugPrint("Use TLS = $use_tls");
-
- if (useTls) {
- if (yamlMap.containsKey('ca-certificate')) {
- caPath = yamlMap['ca-certificate'];
- }
- try {
- caCert = File(caPath).readAsBytesSync();
- } on Exception catch (_) {
- print("ERROR: Could not read CA certificate file $caPath");
- caCert = [];
- }
- //debugPrint("CA cert = $ca_cert");
-
- if (yamlMap.containsKey('tls-server-name')) {
- tlsServerName = yamlMap['tls_server_name'];
- }
- }
-
- if (yamlMap.containsKey('authorization')) {
- token = yamlMap['authorization'];
- }
- if (token.isNotEmpty) {
- if (token.startsWith("/")) {
- debugPrint("Reading authorization token $token");
- String tokenFile = token;
- try {
- token = await File(tokenFile).readAsString();
- } on Exception catch (_) {
- print("ERROR: Could not read authorization token file $token");
- token = "";
- }
- }
- }
- //debugPrint("authorization = $token");
- } catch (e) {
- debugPrint('WARNING: Could not read from file: $configFile');
- //debugPrint(e.toString());
- }
- return KuksaConfig(
- hostname: hostname,
- port: port,
- authorization: token,
- use_tls: useTls,
- ca_certificate: caCert,
- tls_server_name: tlsServerName);
- }
-
- void startListen() async {
- KuksaConfig config = await readConfig();
- ChannelCredentials creds;
- if (config.use_tls && config.ca_certificate.isNotEmpty) {
- print("Using TLS");
- if (config.tls_server_name.isNotEmpty) {
- creds = ChannelCredentials.secure(
- certificates: config.ca_certificate,
- authority: config.tls_server_name);
- } else {
- creds = ChannelCredentials.secure(certificates: config.ca_certificate);
- }
- } else {
- creds = const ChannelCredentials.insecure();
- }
- channel = ClientChannel(config.hostname,
- port: config.port, options: ChannelOptions(credentials: creds));
- debugPrint('Start Listen on port: ${config.port}');
- stub = VALClient(channel);
- authorization = config.authorization;
- List<String> fewSignals = VSSPath().getSignalsList();
- var request = SubscribeRequest();
- Map<String, String> metadata = {};
- if (authorization.isNotEmpty) {
- metadata = {'authorization': "Bearer ${authorization}"};
- }
- for (int i = 0; i < fewSignals.length; i++) {
- var entry = SubscribeEntry();
- entry.path = fewSignals[i];
- entry.fields.add(Field.FIELD_PATH);
- entry.fields.add(Field.FIELD_VALUE);
- request.entries.add(entry);
- }
- try {
- var responseStream = stub.subscribe(request, options: CallOptions(metadata: metadata));
- responseStream.listen((value) async {
- for (var update in value.updates) {
- if (!(update.hasEntry() && update.entry.hasPath())) continue;
- handleSignalsUpdate(update);
- }
- }, onError: (stacktrace, errorDescriptor) {
- debugPrint(stacktrace.toString());
- state = const Vehicle.initialForDebug();
- });
- } catch (e) {
- debugPrint(e.toString());
+ default:
+ handled = false;
}
+ return handled;
}
void setChildLock({required String side}) async {
- var helper = ValClientHelper(stub: stub, authorization: authorization);
+ var valClient = ref.read(valClientProvider);
try {
switch (side) {
case 'left':
- helper.setBool(
+ valClient.setBool(
VSSPath.vehicleIsChildLockActiveLeft,
!state.isChildLockActiveLeft,
false,
@@ -343,7 +148,7 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
isChildLockActiveLeft: !state.isChildLockActiveLeft);
break;
case 'right':
- helper.setBool(
+ valClient.setBool(
VSSPath.vehicleIsChildLockActiveRight,
!state.isChildLockActiveRight,
false,
@@ -360,22 +165,12 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
}
}
- void setVolume(double newVal) {
- state = state.copyWith(mediaVolume: newVal.toInt());
- var helper = ValClientHelper(stub: stub, authorization: authorization);
- helper.setUint32(
- VSSPath.vehicleMediaVolume,
- newVal.toInt(),
- true,
- );
- }
-
void setTemperature({required Side side, required int value}) {
- var helper = ValClientHelper(stub: stub, authorization: authorization);
+ var valClient = ref.read(valClientProvider);
try {
switch (side) {
case Side.left:
- helper.setInt32(
+ valClient.setInt32(
VSSPath.vehicleDriverTemperature,
value,
true,
@@ -383,7 +178,7 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
state = state.copyWith(driverTemperature: value);
break;
case Side.right:
- helper.setInt32(
+ valClient.setInt32(
VSSPath.vehiclePassengerTemperature,
value,
true,
@@ -419,8 +214,8 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
default:
break;
}
- var helper = ValClientHelper(stub: stub, authorization: authorization);
- helper.setUint32(
+ var valClient = ref.read(valClientProvider);
+ valClient.setUint32(
VSSPath.vehicleFanSpeed,
targetFanSpeed,
true,
@@ -429,11 +224,11 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
}
void setHVACMode({required String mode}) {
- var helper = ValClientHelper(stub: stub, authorization: authorization);
+ var valClient = ref.read(valClientProvider);
try {
switch (mode) {
case 'airCondition':
- helper.setBool(
+ valClient.setBool(
VSSPath.vehicleIsAirConditioningActive,
!state.isAirConditioningActive,
true,
@@ -442,7 +237,7 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
isAirConditioningActive: !state.isAirConditioningActive);
break;
case 'frontDefrost':
- helper.setBool(
+ valClient.setBool(
VSSPath.vehicleIsFrontDefrosterActive,
!state.isFrontDefrosterActive,
true,
@@ -451,7 +246,7 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
isFrontDefrosterActive: !state.isFrontDefrosterActive);
break;
case 'rearDefrost':
- helper.setBool(
+ valClient.setBool(
VSSPath.vehicleIsRearDefrosterActive,
!state.isRearDefrosterActive,
true,
@@ -460,7 +255,7 @@ class VehicleNotifier extends StateNotifier<Vehicle> {
isRearDefrosterActive: !state.isRearDefrosterActive);
break;
case 'recirculation':
- helper.setBool(
+ valClient.setBool(
VSSPath.vehicleIsRecirculationActive,
!state.isRecirculationActive,
true,
diff --git a/lib/data/models/audio.dart b/lib/data/models/audio.dart
index 69df18b..65490f9 100644
--- a/lib/data/models/audio.dart
+++ b/lib/data/models/audio.dart
@@ -5,52 +5,59 @@ import 'package:flutter_ics_homescreen/export.dart';
@immutable
class Audio {
final double volume;
+ final double balance;
+ final double fade;
final double treble;
final double bass;
- final double rearFront;
const Audio({
required this.volume,
+ required this.balance,
+ required this.fade,
required this.treble,
required this.bass,
- required this.rearFront,
});
const Audio.initial()
: volume = 5.0,
+ balance = 5.0,
+ fade = 5.0,
treble = 5.0,
- bass = 5.0,
- rearFront = 5.0;
+ bass = 5.0;
Audio copyWith({
double? volume,
+ double? balance,
+ double? fade,
double? treble,
double? bass,
- double? rearFront,
}) {
return Audio(
volume: volume ?? this.volume,
+ balance: balance ?? this.balance,
+ fade: fade ?? this.fade,
treble: treble ?? this.treble,
bass: bass ?? this.bass,
- rearFront: rearFront ?? this.rearFront,
);
}
Map<String, dynamic> toMap() {
return {
'volume': volume,
+ 'balance': balance,
+ 'fade': fade,
'treble': treble,
'bass': bass,
- 'rearFront': rearFront,
};
}
factory Audio.fromMap(Map<String, dynamic> map) {
return Audio(
volume: map['volume']?.toDouble() ?? 0.0,
+ balance: map['balance']?.toDouble() ?? 0.0,
+ fade: map['fade']?.toDouble() ?? 0.0,
treble: map['treble']?.toDouble() ?? 0.0,
bass: map['bass']?.toDouble() ?? 0.0,
- rearFront: map['rearFront']?.toDouble() ?? 0.0,
);
}
@@ -60,7 +67,7 @@ class Audio {
@override
String toString() {
- return 'Audio(volume: $volume, treble: $treble, bass: $bass, rearFront: $rearFront)';
+ return 'Audio(volume: $volume, balance: $balance, fade: $fade, treble: $treble, bass: $bass)';
}
@override
@@ -69,16 +76,18 @@ class Audio {
return other is Audio &&
other.volume == volume &&
+ other.balance == balance &&
+ other.fade == fade &&
other.treble == treble &&
- other.bass == bass &&
- other.rearFront == rearFront;
+ other.bass == bass;
}
@override
int get hashCode {
return volume.hashCode ^
+ balance.hashCode ^
+ fade.hashCode ^
treble.hashCode ^
- bass.hashCode ^
- rearFront.hashCode;
+ bass.hashCode;
}
}
diff --git a/lib/data/models/hybrid.dart b/lib/data/models/hybrid.dart
index d567f14..5746033 100644
--- a/lib/data/models/hybrid.dart
+++ b/lib/data/models/hybrid.dart
@@ -2,7 +2,7 @@ enum HybridState {
idle,
engineOutput,
regenerativeBreaking,
- baterryOutput,
+ batteryOutput,
}
enum ArrowState { blue, red, green, yellow }
diff --git a/lib/data/models/vehicle.dart b/lib/data/models/vehicle.dart
index 2dea928..ad76620 100644
--- a/lib/data/models/vehicle.dart
+++ b/lib/data/models/vehicle.dart
@@ -10,7 +10,6 @@ class Vehicle {
final double outsideTemperature;
final int range;
final int fuelLevel;
- final int mediaVolume;
final bool isChildLockActiveLeft;
final bool isChildLockActiveRight;
final int frontLeftTire;
@@ -27,27 +26,26 @@ class Vehicle {
final bool temperatureSynced;
const Vehicle(
- this.speed,
- this.engineSpeed,
- this.insideTemperature,
- this.outsideTemperature,
- this.range,
- this.fuelLevel,
- this.mediaVolume,
- this.isChildLockActiveLeft,
- this.isChildLockActiveRight,
- this.frontLeftTire,
- this.frontRightTire,
- this.rearLeftTire,
- this.rearRightTire,
- this.isAirConditioningActive,
- this.isFrontDefrosterActive,
- this.isRearDefrosterActive,
- this.isRecirculationActive,
- this.fanSpeed,
- this.driverTemperature,
- this.passengerTemperature,
- this.temperatureSynced,
+ this.speed,
+ this.engineSpeed,
+ this.insideTemperature,
+ this.outsideTemperature,
+ this.range,
+ this.fuelLevel,
+ this.isChildLockActiveLeft,
+ this.isChildLockActiveRight,
+ this.frontLeftTire,
+ this.frontRightTire,
+ this.rearLeftTire,
+ this.rearRightTire,
+ this.isAirConditioningActive,
+ this.isFrontDefrosterActive,
+ this.isRearDefrosterActive,
+ this.isRecirculationActive,
+ this.fanSpeed,
+ this.driverTemperature,
+ this.passengerTemperature,
+ this.temperatureSynced,
);
const Vehicle.initial()
@@ -57,7 +55,6 @@ class Vehicle {
outsideTemperature = 0,
range = 0,
fuelLevel = 0,
- mediaVolume = 50,
isChildLockActiveLeft = false,
isChildLockActiveRight = true,
frontLeftTire = 33,
@@ -80,7 +77,6 @@ class Vehicle {
outsideTemperature = 32.0,
range = 21,
fuelLevel = 49,
- mediaVolume = 50,
isChildLockActiveLeft = false,
isChildLockActiveRight = true,
frontLeftTire = 33,
@@ -96,51 +92,49 @@ class Vehicle {
passengerTemperature = 26,
temperatureSynced = true;
- Vehicle copyWith(
- {double? speed,
- double? engineSpeed,
- double? insideTemperature,
- double? outsideTemperature,
- int? range,
- int? fuelLevel,
- int? mediaVolume,
- bool? isChildLockActiveLeft,
- bool? isChildLockActiveRight,
- int? frontLeftTire,
- int? frontRightTire,
- int? rearLeftTire,
- int? rearRightTire,
- bool? isAirConditioningActive,
- bool? isFrontDefrosterActive,
- bool? isRearDefrosterActive,
- bool? isRecirculationActive,
- int? fanSpeed,
- int? driverTemperature,
- int? passengerTemperature,
- bool? temperatureSynced,
+ Vehicle copyWith({
+ double? speed,
+ double? engineSpeed,
+ double? insideTemperature,
+ double? outsideTemperature,
+ int? range,
+ int? fuelLevel,
+ bool? isChildLockActiveLeft,
+ bool? isChildLockActiveRight,
+ int? frontLeftTire,
+ int? frontRightTire,
+ int? rearLeftTire,
+ int? rearRightTire,
+ bool? isAirConditioningActive,
+ bool? isFrontDefrosterActive,
+ bool? isRearDefrosterActive,
+ bool? isRecirculationActive,
+ int? fanSpeed,
+ int? driverTemperature,
+ int? passengerTemperature,
+ bool? temperatureSynced,
}) {
return Vehicle(
- speed ?? this.speed,
- engineSpeed ?? this.engineSpeed,
- insideTemperature ?? this.insideTemperature,
- outsideTemperature ?? this.outsideTemperature,
- range ?? this.range,
- fuelLevel ?? this.fuelLevel,
- mediaVolume ?? this.mediaVolume,
- isChildLockActiveLeft ?? this.isChildLockActiveLeft,
- isChildLockActiveRight ?? this.isChildLockActiveRight,
- frontLeftTire ?? this.frontLeftTire,
- frontRightTire ?? this.frontRightTire,
- rearLeftTire ?? this.rearLeftTire,
- rearRightTire ?? this.rearRightTire,
- isAirConditioningActive ?? this.isAirConditioningActive,
- isFrontDefrosterActive ?? this.isFrontDefrosterActive,
- isRearDefrosterActive ?? this.isRearDefrosterActive,
- isRecirculationActive ?? this.isRecirculationActive,
- fanSpeed ?? this.fanSpeed,
- driverTemperature ?? this.driverTemperature,
- passengerTemperature ?? this.passengerTemperature,
- temperatureSynced ?? this.temperatureSynced,
+ speed ?? this.speed,
+ engineSpeed ?? this.engineSpeed,
+ insideTemperature ?? this.insideTemperature,
+ outsideTemperature ?? this.outsideTemperature,
+ range ?? this.range,
+ fuelLevel ?? this.fuelLevel,
+ isChildLockActiveLeft ?? this.isChildLockActiveLeft,
+ isChildLockActiveRight ?? this.isChildLockActiveRight,
+ frontLeftTire ?? this.frontLeftTire,
+ frontRightTire ?? this.frontRightTire,
+ rearLeftTire ?? this.rearLeftTire,
+ rearRightTire ?? this.rearRightTire,
+ isAirConditioningActive ?? this.isAirConditioningActive,
+ isFrontDefrosterActive ?? this.isFrontDefrosterActive,
+ isRearDefrosterActive ?? this.isRearDefrosterActive,
+ isRecirculationActive ?? this.isRecirculationActive,
+ fanSpeed ?? this.fanSpeed,
+ driverTemperature ?? this.driverTemperature,
+ passengerTemperature ?? this.passengerTemperature,
+ temperatureSynced ?? this.temperatureSynced,
);
}
@@ -152,7 +146,6 @@ class Vehicle {
'outsideTemperature': outsideTemperature,
'range': range,
'fuelLevel': fuelLevel,
- 'mediaVolume': mediaVolume,
'isChildLockActiveLeft': isChildLockActiveLeft,
'isChildLockActiveRight': isChildLockActiveRight,
'frontLeftTire': frontLeftTire,
@@ -178,7 +171,6 @@ class Vehicle {
map['outsideTemperature']?.toDouble() ?? 0.0,
map['range']?.toInt() ?? 0,
map['fuelLevel']?.toDouble() ?? 0.0,
- map['mediaVolume']?.toInt() ?? 0,
map['isChildLockActiveLeft'] ?? false,
map['isChildLockActiveRight'] ?? false,
map['frontLeftTire']?.toInt() ?? 0,
@@ -203,7 +195,7 @@ class Vehicle {
@override
String toString() {
- return 'Vehicle(speed: $speed, insideTemperature: $insideTemperature, outsideTemperature: $outsideTemperature, range: $range, fuelLevel: $fuelLevel, mediaVolume: $mediaVolume, isChildLockActiveLeft: $isChildLockActiveLeft, isChildLockActiveRight: $isChildLockActiveRight, engineSpeed: $engineSpeed, frontLeftTire: $frontLeftTire, frontRightTire: $frontRightTire, rearLeftTire: $rearLeftTire, rearRightTire: $rearRightTire, isAirConditioningActive: $isAirConditioningActive, isFrontDefrosterActive: $isFrontDefrosterActive, isRearDefrosterActive: $isRearDefrosterActive, isRecirculationActive: $isRecirculationActive,fanSpeed:$fanSpeed,driverTemperature:$driverTemperature, passengerTemperature:$passengerTemperature)';
+ return 'Vehicle(speed: $speed, insideTemperature: $insideTemperature, outsideTemperature: $outsideTemperature, range: $range, fuelLevel: $fuelLevel, isChildLockActiveLeft: $isChildLockActiveLeft, isChildLockActiveRight: $isChildLockActiveRight, engineSpeed: $engineSpeed, frontLeftTire: $frontLeftTire, frontRightTire: $frontRightTire, rearLeftTire: $rearLeftTire, rearRightTire: $rearRightTire, isAirConditioningActive: $isAirConditioningActive, isFrontDefrosterActive: $isFrontDefrosterActive, isRearDefrosterActive: $isRearDefrosterActive, isRecirculationActive: $isRecirculationActive,fanSpeed:$fanSpeed,driverTemperature:$driverTemperature, passengerTemperature:$passengerTemperature)';
}
@override
@@ -216,7 +208,6 @@ class Vehicle {
other.outsideTemperature == outsideTemperature &&
other.range == range &&
other.fuelLevel == fuelLevel &&
- other.mediaVolume == mediaVolume &&
other.isChildLockActiveLeft == isChildLockActiveLeft &&
other.isChildLockActiveRight == isChildLockActiveRight &&
other.engineSpeed == engineSpeed &&
@@ -241,7 +232,6 @@ class Vehicle {
outsideTemperature.hashCode ^
range.hashCode ^
fuelLevel.hashCode ^
- mediaVolume.hashCode ^
isChildLockActiveLeft.hashCode ^
isChildLockActiveRight.hashCode ^
engineSpeed.hashCode ^
@@ -258,9 +248,4 @@ class Vehicle {
passengerTemperature.hashCode ^
temperatureSynced.hashCode;
}
-// }
-// / class VehicleNotifier extends StateNotifier<Vehicle> {
-// // VehicleNotifier() : super(Vehicle());
-
-// // }
}