diff options
Diffstat (limited to 'lib/data/data_providers/vehicle_notifier.dart')
-rw-r--r-- | lib/data/data_providers/vehicle_notifier.dart | 253 |
1 files changed, 24 insertions, 229 deletions
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, |