diff options
Diffstat (limited to 'lib/vehicle-signals')
-rw-r--r-- | lib/vehicle-signals/vehicle_status_provider.dart | 238 | ||||
-rw-r--r-- | lib/vehicle-signals/vss_client.dart | 113 | ||||
-rw-r--r-- | lib/vehicle-signals/vss_path.dart | 89 | ||||
-rw-r--r-- | lib/vehicle-signals/vss_path.dart.hvac | 60 | ||||
-rw-r--r-- | lib/vehicle-signals/vss_provider.dart | 270 |
5 files changed, 770 insertions, 0 deletions
diff --git a/lib/vehicle-signals/vehicle_status_provider.dart b/lib/vehicle-signals/vehicle_status_provider.dart new file mode 100644 index 0000000..9518f59 --- /dev/null +++ b/lib/vehicle-signals/vehicle_status_provider.dart @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: Apache-2.0
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+class VehicleStatus {
+ VehicleStatus({
+ required this.speed,
+ required this.rpm,
+ required this.fuelLevel,
+ required this.coolantTemp,
+ required this.isLeftIndicator,
+ required this.isRightIndicator,
+ required this.selectedGear,
+ required this.isLowBeam,
+ required this.isHighBeam,
+ required this.isHazardLightOn,
+ required this.travelledDistance,
+ required this.isParkingOn,
+ required this.performanceMode,
+ required this.ambientAirTemp,
+ required this.cruiseControlSpeed,
+ required this.isCruiseControlActive,
+ required this.isCruiseControlError,
+ required this.isMILon,
+ required this.isTrunkLocked,
+ required this.isTrunkOpen,
+ required this.isBatteryCharging,
+
+ // steering switches
+ required this.vehicleDistanceUnit,
+ required this.isSteeringCruiseEnable,
+ required this.isSteeringCruiseSet,
+ required this.isSteeringCruiseResume,
+ required this.isSteeringCruiseCancel,
+ required this.isSteeringLaneWarning,
+ required this.isSteeringInfo,
+ });
+
+ final double speed;
+ final double rpm;
+ final double fuelLevel;
+ final double coolantTemp;
+ final double cruiseControlSpeed;
+ final bool isLeftIndicator;
+ final bool isRightIndicator;
+ final String selectedGear;
+ final String performanceMode;
+ final double ambientAirTemp;
+ final bool isLowBeam;
+ final bool isHighBeam;
+ final bool isParkingOn;
+ final bool isHazardLightOn;
+ final bool isTrunkOpen;
+ final bool isTrunkLocked;
+ final bool isMILon;
+ final bool isCruiseControlActive;
+ final bool isCruiseControlError;
+ final bool isBatteryCharging;
+ final double travelledDistance;
+
+ final String vehicleDistanceUnit;
+ final bool isSteeringCruiseEnable;
+ final bool isSteeringCruiseSet;
+ final bool isSteeringCruiseResume;
+ final bool isSteeringCruiseCancel;
+ final bool isSteeringLaneWarning;
+ final bool isSteeringInfo;
+
+ VehicleStatus copyWith({
+ double? speed,
+ double? rpm,
+ double? fuelLevel,
+ double? coolantTemp,
+ bool? isLeftIndicator,
+ bool? isRightIndicator,
+ String? selectedGear,
+ String? performanceMode,
+ double? ambientAirTemp,
+ bool? isLowBeam,
+ bool? isHighBeam,
+ bool? isHazardLightOn,
+ bool? isParkingOn,
+ bool? isTrunkLocked,
+ bool? isTrunkOpen,
+ bool? isMILon,
+ bool? isCruiseControlError,
+ bool? isCruiseControlActive,
+ bool? isBatteryCharging,
+ double? travelledDistance,
+ double? cruiseControlSpeed,
+ // Steering
+ String? vehicleDistanceUnit,
+ bool? isSteeringCruiseEnable,
+ bool? isSteeringCruiseSet,
+ bool? isSteeringCruiseResume,
+ bool? isSteeringCruiseCancel,
+ bool? isSteeringLaneWarning,
+ bool? isSteeringInfo,
+ }) {
+ return VehicleStatus(
+ speed: speed ?? (this.speed),
+ rpm: rpm ?? this.rpm,
+ fuelLevel: fuelLevel ?? this.fuelLevel,
+ coolantTemp: coolantTemp ?? this.coolantTemp,
+ isLeftIndicator: isLeftIndicator ?? this.isLeftIndicator,
+ isRightIndicator: isRightIndicator ?? this.isRightIndicator,
+ selectedGear: selectedGear ?? this.selectedGear,
+ isLowBeam: isLowBeam ?? this.isLowBeam,
+ isHighBeam: isHighBeam ?? this.isHighBeam,
+ isHazardLightOn: isHazardLightOn ?? this.isHazardLightOn,
+ travelledDistance: travelledDistance ?? this.travelledDistance,
+ isParkingOn: isParkingOn ?? this.isParkingOn,
+ performanceMode: performanceMode ?? this.performanceMode,
+ isTrunkLocked: isTrunkLocked ?? this.isTrunkLocked,
+ isTrunkOpen: isTrunkOpen ?? this.isTrunkOpen,
+ ambientAirTemp: ambientAirTemp ?? this.ambientAirTemp,
+ isMILon: isMILon ?? this.isMILon,
+ isCruiseControlActive:
+ isCruiseControlActive ?? this.isCruiseControlActive,
+ cruiseControlSpeed: cruiseControlSpeed ?? this.cruiseControlSpeed,
+ isCruiseControlError: isCruiseControlError ?? this.isCruiseControlError,
+ isBatteryCharging: isBatteryCharging ?? this.isBatteryCharging,
+ isSteeringCruiseEnable:
+ isSteeringCruiseEnable ?? this.isSteeringCruiseEnable,
+ isSteeringCruiseSet: isSteeringCruiseSet ?? this.isSteeringCruiseSet,
+ isSteeringCruiseResume:
+ isSteeringCruiseResume ?? this.isSteeringCruiseResume,
+ isSteeringCruiseCancel:
+ isSteeringCruiseCancel ?? this.isSteeringCruiseCancel,
+ isSteeringInfo: isSteeringInfo ?? this.isSteeringInfo,
+ isSteeringLaneWarning:
+ isSteeringLaneWarning ?? this.isSteeringLaneWarning,
+ vehicleDistanceUnit: vehicleDistanceUnit ?? this.vehicleDistanceUnit,
+ );
+ }
+}
+
+final vehicleStatusProvider =
+ StateNotifierProvider<VehicleStatusNotifier, VehicleStatus>(
+ (ref) => VehicleStatusNotifier(),
+);
+
+class VehicleStatusNotifier extends StateNotifier<VehicleStatus> {
+ VehicleStatusNotifier() : super(_initialValue);
+ static final VehicleStatus _initialValue = VehicleStatus(
+ speed: 140,
+ rpm: 7000,
+ fuelLevel: 90,
+ coolantTemp: 90,
+ isLeftIndicator: false,
+ isRightIndicator: false,
+ selectedGear: "P",
+ performanceMode: "normal",
+ isHazardLightOn: false,
+ isHighBeam: true,
+ isLowBeam: false,
+ isParkingOn: true,
+ travelledDistance: 888,
+ ambientAirTemp: 25,
+ cruiseControlSpeed: 60,
+ isCruiseControlActive: false,
+ isCruiseControlError: false,
+ isMILon: false,
+ isTrunkLocked: true,
+ isTrunkOpen: false,
+ isBatteryCharging: true,
+ isSteeringCruiseEnable: false,
+ isSteeringCruiseSet: false,
+ isSteeringCruiseResume: false,
+ isSteeringCruiseCancel: false,
+ isSteeringInfo: false,
+ isSteeringLaneWarning: false,
+ vehicleDistanceUnit: 'km',
+ );
+ void update({
+ double? speed,
+ double? rpm,
+ double? fuelLevel,
+ double? coolantTemp,
+ bool? isLeftIndicator,
+ bool? isRightIndicator,
+ String? selectedGear,
+ String? performanceMode,
+ double? ambientAirTemp,
+ bool? isLowBeam,
+ bool? isHighBeam,
+ bool? isHazardLightOn,
+ bool? isMILon,
+ bool? isParkingOn,
+ bool? isTrunkOpen,
+ bool? isTrunkLocked,
+ bool? isCruiseControlActive,
+ bool? isCruiseControlError,
+ bool? isBatteryCharging,
+ double? travelledDistance,
+ double? cruiseControlSpeed,
+ //
+ String? vehicleDistanceUnit,
+ bool? isSteeringCruiseEnable,
+ bool? isSteeringCruiseSet,
+ bool? isSteeringCruiseResume,
+ bool? isSteeringCruiseCancel,
+ bool? isSteeringLaneWarning,
+ bool? isSteeringInfo,
+ }) {
+ state = state.copyWith(
+ speed: speed,
+ rpm: rpm,
+ fuelLevel: fuelLevel,
+ coolantTemp: coolantTemp,
+ isLeftIndicator: isLeftIndicator,
+ isRightIndicator: isRightIndicator,
+ selectedGear: selectedGear,
+ isLowBeam: isLowBeam,
+ isHighBeam: isHighBeam,
+ isHazardLightOn: isHazardLightOn,
+ travelledDistance: travelledDistance,
+ performanceMode: performanceMode,
+ isParkingOn: isParkingOn,
+ isTrunkOpen: isTrunkOpen,
+ isTrunkLocked: isTrunkLocked,
+ isMILon: isMILon,
+ ambientAirTemp: ambientAirTemp,
+ isCruiseControlActive: isCruiseControlActive,
+ isCruiseControlError: isCruiseControlError,
+ cruiseControlSpeed: cruiseControlSpeed,
+ isBatteryCharging: isBatteryCharging,
+ //
+ isSteeringCruiseEnable: isSteeringCruiseEnable,
+ isSteeringCruiseSet: isSteeringCruiseSet,
+ isSteeringCruiseResume: isSteeringCruiseResume,
+ isSteeringCruiseCancel: isSteeringCruiseCancel,
+ isSteeringInfo: isSteeringInfo,
+ isSteeringLaneWarning: isSteeringLaneWarning,
+ vehicleDistanceUnit: vehicleDistanceUnit,
+ );
+ }
+}
diff --git a/lib/vehicle-signals/vss_client.dart b/lib/vehicle-signals/vss_client.dart new file mode 100644 index 0000000..e416d87 --- /dev/null +++ b/lib/vehicle-signals/vss_client.dart @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:io'; +import 'package:meta/meta.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:grpc/grpc.dart'; +import 'package:flutter_cluster_dashboard/generated/kuksa/val/v1/val.pbgrpc.dart'; +import 'package:flutter_cluster_dashboard/generated/kuksa/val/v1/types.pb.dart'; +import 'package:flutter_cluster_dashboard/config.dart'; + +abstract class VssClient { + final KuksaConfig config; + final ClientChannel channel; + final VALClient stub; + final Ref ref; + + // Extenders will likely override this + final List<String> signals = []; + + VssClient({required this.config, required this.channel, required this.stub, required this.ref}); + + // Abstract method extenders must implement + void handleSignalUpdates(EntryUpdate update); + + void run() async { + if (signals.isEmpty) + return; + + var request = SubscribeRequest(); + for (var i = 0; i < signals.length; i++) { + var entry = SubscribeEntry(); + entry.path = signals[i]; + entry.fields.add(Field.FIELD_PATH); + entry.fields.add(Field.FIELD_VALUE); + request.entries.add(entry); + } + + try { + Map<String, String> metadata = {}; + if (config.authorization.isNotEmpty) { + metadata = {'authorization': "Bearer ${config.authorization}" }; + } + var responseStream = stub.subscribe(request, options: CallOptions(metadata: metadata)); + await for (var response in responseStream) { + for (var update in response.updates) { + if (!(update.hasEntry() && update.entry.hasPath())) + continue; + handleSignalUpdates(update); + } + } + } catch (e) { + print(e); + } + } + + 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/vehicle-signals/vss_path.dart b/lib/vehicle-signals/vss_path.dart new file mode 100644 index 0000000..78538b9 --- /dev/null +++ b/lib/vehicle-signals/vss_path.dart @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: Apache-2.0
+
+class VSSPath {
+ static const String vehicleSpeed = "Vehicle.Speed";
+
+ static const String vehicleEngineRPM =
+ "Vehicle.Powertrain.CombustionEngine.Speed";
+
+ static const String vehicleFuelLevel = "Vehicle.Powertrain.FuelSystem.Level";
+
+ static const String vehicleCoolantTemp =
+ "Vehicle.Powertrain.CombustionEngine.ECT";
+
+ static const String vehicleAmbientAirTemperature =
+ "Vehicle.Exterior.AirTemperature";
+
+ static const String vehicleLeftIndicator =
+ "Vehicle.Body.Lights.DirectionIndicator.Left.IsSignaling";
+
+ static const String vehicleRightIndicator =
+ "Vehicle.Body.Lights.DirectionIndicator.Right.IsSignaling";
+
+ //Selected Gear output=> 0=Neutral, 1/2/..=Forward, -1/..=Reverse, 126=Park, 127=Drive
+ static const String vehicleSelectedGear =
+ "Vehicle.Powertrain.Transmission.SelectedGear";
+
+ static const String vehicleLowBeamOn = "Vehicle.Body.Lights.Beam.Low.IsOn";
+
+ static const String vehicleHighBeamOn = "Vehicle.Body.Lights.Beam.High.IsOn";
+
+ static const String vehicleParkingLightOn = "Vehicle.Body.Lights.Parking.IsOn";
+
+ static const String vehicleHazardLightOn = "Vehicle.Body.Lights.Hazard.IsSignaling";
+
+ static const String vehicleTravelledDistance = "Vehicle.TravelledDistance";
+
+ static const String vehicleTrunkLocked = "Vehicle.Body.Trunk.Rear.IsLocked";
+
+ static const String vehicleTrunkOpen = "Vehicle.Body.Trunk.Rear.IsOpen";
+
+ // \"normal\",\"sport\",\"economy\",\"snow\",\"rain\"]
+ static const String vehiclePerformanceMode =
+ "Vehicle.Powertrain.Transmission.PerformanceMode";
+
+ static const String vehicleMIL = "Vehicle.OBD.Status.IsMILOn";
+
+ static const String vehicleCruiseControlError =
+ "Vehicle.ADAS.CruiseControl.IsError";
+
+ static const String vehicleCruiseControlSpeedSet =
+ "Vehicle.ADAS.CruiseControl.SpeedSet";
+
+ static const String vehicleCruiseControlActive =
+ "Vehicle.ADAS.CruiseControl.IsActive";
+
+ static const String vehicleBatteryChargingStatus =
+ "Vehicle.Powertrain.TractionBattery.Charging.IsCharging";
+
+ static const String steeringCruiseEnable =
+ "Vehicle.Cabin.SteeringWheel.Switches.CruiseEnable";
+
+ static const String steeringCruiseSet =
+ "Vehicle.Cabin.SteeringWheel.Switches.CruiseSet";
+
+ static const String steeringCruiseResume =
+ "Vehicle.Cabin.SteeringWheel.Switches.CruiseResume";
+
+ static const String steeringCruiseCancel =
+ "Vehicle.Cabin.SteeringWheel.Switches.CruiseCancel";
+
+ static const String steeringLaneDepWarn =
+ "Vehicle.Cabin.SteeringWheel.Switches.LaneDepartureWarning";
+
+ static const String steeringInfo =
+ "Vehicle.Cabin.SteeringWheel.Switches.Info";
+
+ static const String vehicleDistanceUnit =
+ "Vehicle.Cabin.Infotainment.HMI.DistanceUnit";
+
+ static const String vehicleCurrLat = "Vehicle.CurrentLocation.Latitude";
+
+ static const String vehicleCurrLon = "Vehicle.CurrentLocation.Longitude";
+
+ static const String vehicleDestLat =
+ "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude";
+
+ static const String vehicleDestLon =
+ "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude";
+}
diff --git a/lib/vehicle-signals/vss_path.dart.hvac b/lib/vehicle-signals/vss_path.dart.hvac new file mode 100644 index 0000000..df90a48 --- /dev/null +++ b/lib/vehicle-signals/vss_path.dart.hvac @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 + + +class VSSPath { + + static const String vehicleOutsideTemperature = + "Vehicle.AmbientAirTemperature"; + + static const String vehicleInsideTemperature = + "Vehicle.Cabin.HVAC.AmbientAirTemperature"; + + static const String vehicleIsAirConditioningActive = + "Vehicle.Cabin.HVAC.IsAirConditioningActive"; + + static const String vehicleIsFrontDefrosterActive = + "Vehicle.Cabin.HVAC.IsFrontDefrosterActive"; + + static const String vehicleIsRearDefrosterActive = + "Vehicle.Cabin.HVAC.IsRearDefrosterActive"; + + static const String vehicleIsRecirculationActive = + "Vehicle.Cabin.HVAC.IsRecirculationActive"; + + static const String vehicleFrontLeftAirDistribution = + "Vehicle.Cabin.HVAC.Station.Row1.Left.AirDistribution"; + + static const String vehicleFrontLeftFanSpeed = + "Vehicle.Cabin.HVAC.Station.Row1.Left.FanSpeed"; + + static const String vehicleFrontLeftTemp = + "Vehicle.Cabin.HVAC.Station.Row1.Left.Temperature"; + + static const String vehicleFrontRightAirDistribution = + "Vehicle.Cabin.HVAC.Station.Row1.Right.AirDistribution"; + + static const String vehicleFrontRightFanSpeed = + "Vehicle.Cabin.HVAC.Station.Row1.Right.FanSpeed"; + + static const String vehicleFrontRightTemp = + "Vehicle.Cabin.HVAC.Station.Row1.Right.Temperature"; + + static const String vehicleRearLeftAirDistribution = + "Vehicle.Cabin.HVAC.Station.Row2.Left.AirDistribution"; + + static const String vehicleRearLeftFanSpeed = + "Vehicle.Cabin.HVAC.Station.Row2.Left.FanSpeed"; + + static const String vehicleRearLeftTemp = + "Vehicle.Cabin.HVAC.Station.Row2.Left.Temperature"; + + static const String vehicleRearRightAirDistribution = + "Vehicle.Cabin.HVAC.Station.Row2.Right.AirDistribution"; + + static const String vehicleRearRightFanSpeed = + "Vehicle.Cabin.HVAC.Station.Row2.Right.FanSpeed"; + + static const String vehicleRearRightTemp = + "Vehicle.Cabin.HVAC.Station.Row2.Right.Temperature"; + +} diff --git a/lib/vehicle-signals/vss_provider.dart b/lib/vehicle-signals/vss_provider.dart new file mode 100644 index 0000000..7820a52 --- /dev/null +++ b/lib/vehicle-signals/vss_provider.dart @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:io'; +import 'package:meta/meta.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:grpc/grpc.dart'; +import 'package:flutter_cluster_dashboard/generated/kuksa/val/v1/val.pbgrpc.dart'; +import 'package:flutter_cluster_dashboard/generated/kuksa/val/v1/types.pb.dart'; +import 'package:flutter_cluster_dashboard/config.dart'; +import 'package:flutter_cluster_dashboard/vehicle-signals/vss_client.dart'; +import 'package:flutter_cluster_dashboard/vehicle-signals/vss_path.dart'; +import 'package:flutter_cluster_dashboard/vehicle-signals/vehicle_status_provider.dart'; + +class DashboardVssClient extends VssClient { + @override + final List<String> signals = [ + VSSPath.vehicleSpeed, + VSSPath.vehicleEngineRPM, + VSSPath.vehicleFuelLevel, + VSSPath.vehicleCoolantTemp, + VSSPath.vehicleAmbientAirTemperature, + VSSPath.vehicleLeftIndicator, + VSSPath.vehicleRightIndicator, + VSSPath.vehicleHazardLightOn, + VSSPath.vehicleHighBeamOn, + VSSPath.vehicleLowBeamOn, + VSSPath.vehicleSelectedGear, + VSSPath.vehiclePerformanceMode, + VSSPath.vehicleParkingLightOn, + VSSPath.vehicleTrunkLocked, + VSSPath.vehicleTrunkOpen, + VSSPath.vehicleMIL, + VSSPath.vehicleCruiseControlError, + VSSPath.vehicleCruiseControlSpeedSet, + VSSPath.vehicleCruiseControlActive, + VSSPath.vehicleBatteryChargingStatus, + VSSPath.vehicleDistanceUnit, + VSSPath.steeringCruiseEnable, + VSSPath.steeringCruiseSet, + VSSPath.steeringCruiseResume, + VSSPath.steeringCruiseCancel, + VSSPath.steeringInfo, + VSSPath.steeringLaneDepWarn + ]; + + DashboardVssClient({required super.config, required super.channel, required super.stub, required super.ref}); + + static String? numToGear(int? number) { + switch (number) { + case -1: + return 'R'; + case 0: + return 'N'; + case 126: + return 'P'; + case 127: + return 'D'; + default: + return null; + } + } + + @override + void handleSignalUpdates(EntryUpdate update) { + var vehicleStatus = ref.read(vehicleStatusProvider.notifier); + switch (update.entry.path) { + case VSSPath.vehicleSpeed: + if (update.entry.value.hasFloat()) { + vehicleStatus.update(speed: update.entry.value.float); + } + break; + case VSSPath.vehicleEngineRPM: + if (update.entry.value.hasFloat()) { + vehicleStatus.update(rpm: update.entry.value.float); + } + break; + case VSSPath.vehicleFuelLevel: + if (update.entry.value.hasUint32()) { + vehicleStatus.update(fuelLevel: update.entry.value.uint32.toDouble()); + } + break; + case VSSPath.vehicleCoolantTemp: + if (update.entry.value.hasFloat()) { + vehicleStatus.update(coolantTemp: update.entry.value.float); + } + break; + case VSSPath.vehicleAmbientAirTemperature: + if (update.entry.value.hasFloat()) { + vehicleStatus.update(ambientAirTemp: update.entry.value.float); + } + break; + case VSSPath.vehicleLeftIndicator: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isLeftIndicator: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleRightIndicator: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isRightIndicator: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleHighBeamOn: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12) { + vehicleStatus.update(isHighBeam: true); + vehicleStatus.update(isLowBeam: false); + } else { + vehicleStatus.update(isHighBeam: false); + } + } + break; + case VSSPath.vehicleParkingLightOn: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isParkingOn: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleLowBeamOn: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12) { + vehicleStatus.update(isHighBeam: false); + vehicleStatus.update(isLowBeam: true); + } else { + vehicleStatus.update(isLowBeam: false); + } + } + break; + case VSSPath.vehicleHazardLightOn: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isHazardLightOn: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleSelectedGear: + if (update.entry.value.hasInt32()) { + vehicleStatus.update( + selectedGear: numToGear(update.entry.value.int32)); + } + break; + case VSSPath.vehiclePerformanceMode: + if (update.entry.value.hasString()) { + vehicleStatus.update(performanceMode: update.entry.value.string); + } + break; + case VSSPath.vehicleTravelledDistance: + if (update.entry.value.hasFloat()) { + vehicleStatus.update(travelledDistance: update.entry.value.float); + } + break; + case VSSPath.vehicleTrunkLocked: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isTrunkLocked: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleTrunkOpen: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isTrunkOpen: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleMIL: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isMILon: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleCruiseControlError: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isCruiseControlError: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleCruiseControlSpeedSet: + if (update.entry.value.hasFloat()) { + vehicleStatus.update(cruiseControlSpeed: update.entry.value.float); + } + break; + case VSSPath.vehicleCruiseControlActive: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isCruiseControlActive: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleBatteryChargingStatus: + if (update.entry.value.hasBool_12()) { + vehicleStatus.update(isBatteryCharging: update.entry.value.bool_12); + } + break; + case VSSPath.vehicleDistanceUnit: + if (update.entry.value.hasString()) { + vehicleStatus.update(vehicleDistanceUnit: update.entry.value.string); + } + break; + + // Steering wheel switches + case VSSPath.steeringCruiseEnable: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12) { + if (vehicleStatus.state.isSteeringCruiseEnable) { + vehicleStatus.update(isSteeringCruiseEnable: false); + vehicleStatus.update(isSteeringCruiseSet: false); + } else { + vehicleStatus.update(isSteeringCruiseEnable: true); + } + } + } + break; + case VSSPath.steeringCruiseSet: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12 && + vehicleStatus.state.isSteeringCruiseEnable) { + vehicleStatus.update(isSteeringCruiseSet: true); + } + } + break; + case VSSPath.steeringCruiseResume: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12 && + vehicleStatus.state.isSteeringCruiseEnable) { + vehicleStatus.update(isSteeringCruiseSet: true); + } + } + break; + case VSSPath.steeringCruiseCancel: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12) { + vehicleStatus.update(isSteeringCruiseSet: false); + } + } + break; + case VSSPath.steeringInfo: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12) { + vehicleStatus.update( + isSteeringInfo: !vehicleStatus.state.isSteeringInfo); + } + } + break; + case VSSPath.steeringLaneDepWarn: + if (update.entry.value.hasBool_12()) { + if (update.entry.value.bool_12) { + vehicleStatus.update( + isSteeringLaneWarning: + !(vehicleStatus.state.isSteeringLaneWarning)); + } + } + break; + + default: + print("ERROR: Unexpected path ${update.entry.path}"); + break; + } + } +} + +final vssClientProvider = Provider((ref) { + var config = ref.read(kuksaConfigProvider); + 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 = ChannelCredentials.insecure(); + } + final channel = ClientChannel(config.hostname, + port: config.port, + options: ChannelOptions(credentials: creds)); + + final stub = VALClient(channel); + + return DashboardVssClient(config: config, channel: channel, stub: stub, ref: ref); +}); |