diff options
Diffstat (limited to 'lib/vehicle-signals/vss_provider.dart')
-rw-r--r-- | lib/vehicle-signals/vss_provider.dart | 270 |
1 files changed, 270 insertions, 0 deletions
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); +}); |