summaryrefslogtreecommitdiffstats
path: root/lib/vehicle_signal
diff options
context:
space:
mode:
authorAakash Solanki <tech2aks@gmail.com>2022-08-31 15:23:53 +0200
committerAakash Solanki <tech2aks@gmail.com>2022-09-14 11:50:03 +0200
commite39f2a69fde316b4e260c151757fb739494fbd56 (patch)
tree3ea8a65eee101457264d0000b5bcf122d428b0b8 /lib/vehicle_signal
parent5957cfa0609ff57adfafa4538fb151d00f3c72e3 (diff)
Upload Flutter Instrument Cluster app
Instrument Cluster demo app which shows speedometer tachometer guages, temperature and fuel bars and some indicators like turn indicators, engine malfunction, lights, cruise control, lane assist. KUKSA.VAL is the data source for the widgets. This app depends on several plugins and all the plugins have an OSI-approved license. Bug-AGL: SPEC-4543 Change-Id: I2698c66f9d8d824690ae7e567ca7c93ceeb17e08 Signed-off-by: Aakash Solanki <tech2aks@gmail.com>
Diffstat (limited to 'lib/vehicle_signal')
-rw-r--r--lib/vehicle_signal/initial_socket_connection.dart116
-rw-r--r--lib/vehicle_signal/listen_stream.dart56
-rw-r--r--lib/vehicle_signal/vehicle_signal_config.dart35
-rw-r--r--lib/vehicle_signal/vehicle_signal_methods.dart325
-rw-r--r--lib/vehicle_signal/vehicle_signal_model.dart152
-rw-r--r--lib/vehicle_signal/vehicle_signal_path.dart62
-rw-r--r--lib/vehicle_signal/vehicle_signal_provider.dart120
7 files changed, 866 insertions, 0 deletions
diff --git a/lib/vehicle_signal/initial_socket_connection.dart b/lib/vehicle_signal/initial_socket_connection.dart
new file mode 100644
index 0000000..6b9305a
--- /dev/null
+++ b/lib/vehicle_signal/initial_socket_connection.dart
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: Apache-2.0
+
+import 'dart:io';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/listen_stream.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_config.dart';
+
+class InitialScreen extends ConsumerWidget {
+ InitialScreen({Key? key, required this.client}) : super(key: key);
+ final HttpClient client;
+ late WebSocket socket;
+
+ @override
+ Widget build(BuildContext context, ref) {
+ final sockConnect = ref.watch(sockConnectprovider(client));
+
+ return sockConnect.when(
+ data: (socket) {
+ this.socket = socket;
+ this.socket.pingInterval = const Duration(seconds: 2);
+ return OnBoardingPage(client: client, socket: this.socket);
+ },
+ error: (e, stk) {
+ print(e);
+ Future.delayed(const Duration(milliseconds: 700), (() {
+ ref.refresh(sockConnectprovider(client));
+ }));
+ return const Scaffold(
+ backgroundColor: Colors.black,
+ body: NoticeWidget(
+ assetImageName: "images/server_error.png",
+ text1: "Server Unavailable",
+ text2: "Retrying to conncect!",
+ ),
+ );
+ },
+ loading: () => const Scaffold(
+ backgroundColor: Colors.black,
+ body: NoticeWidget(
+ assetImageName: "images/server.png",
+ text1: "Hi!",
+ text2: "Connecting...!",
+ ),
+ ),
+ );
+ }
+}
+
+class NoticeWidget extends StatelessWidget {
+ const NoticeWidget({
+ Key? key,
+ required this.assetImageName,
+ required this.text1,
+ required this.text2,
+ this.loadingColor,
+ }) : super(key: key);
+
+ final String assetImageName;
+ final String text1;
+ final String text2;
+ final Color? loadingColor;
+
+ @override
+ Widget build(BuildContext context) {
+ return LoadingContainer(
+ child: Flex(
+ mainAxisSize: MainAxisSize.min,
+ mainAxisAlignment: MainAxisAlignment.spaceAround,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ direction: Axis.vertical,
+ children: [
+ Flexible(
+ child: SizedBox(
+ height: 100,
+ child:
+ Image(image: AssetImage(assetImageName), fit: BoxFit.fitWidth),
+ ),
+ ),
+ Flexible(
+ child: Text(text1,
+ style: const TextStyle(fontWeight: FontWeight.bold))),
+ Flexible(
+ child: Text(text2,
+ style: const TextStyle(fontWeight: FontWeight.bold))),
+ Flexible(
+ child: Padding(
+ padding: const EdgeInsets.fromLTRB(25, 0, 25, 20),
+ child: LinearProgressIndicator(color: loadingColor ?? Colors.red),
+ ),
+ )
+ ],
+ ));
+ }
+}
+
+class LoadingContainer extends StatelessWidget {
+ const LoadingContainer({Key? key, required this.child}) : super(key: key);
+ final Widget child;
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Center(
+ child: Container(
+ width: MediaQuery.of(context).size.width / 2,
+ height: MediaQuery.of(context).size.height * 3 / 4,
+ decoration: BoxDecoration(
+ color: Colors.white, borderRadius: BorderRadius.circular(40)),
+ child: child,
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/vehicle_signal/listen_stream.dart b/lib/vehicle_signal/listen_stream.dart
new file mode 100644
index 0000000..0e2772d
--- /dev/null
+++ b/lib/vehicle_signal/listen_stream.dart
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: Apache-2.0
+
+import 'dart:async';
+import 'dart:io';
+import 'package:flutter/material.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_cluster_dashboard/screen/home.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_config.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_methods.dart';
+
+class OnBoardingPage extends ConsumerStatefulWidget {
+ const OnBoardingPage({Key? key, required this.client, required this.socket})
+ : super(key: key);
+ final WebSocket socket;
+ final HttpClient client;
+
+ @override
+ ConsumerState<OnBoardingPage> createState() => _OnBoardingPageState();
+}
+
+class _OnBoardingPageState extends ConsumerState<OnBoardingPage> {
+ late Timer _timer;
+
+ @override
+ void initState() {
+ super.initState();
+ VISS.init(widget.socket, ref);
+ _timer = Timer.periodic(const Duration(seconds: 2), (timer) {
+ if (widget.socket.readyState == 3) {
+ ref.refresh(sockConnectprovider(widget.client));
+ }
+ });
+ WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
+ widget.socket.listen(
+ (data) {
+ // print(data);
+ VISS.parseData(ref, data);
+ },
+ onError: (e, stk) {
+ print(e.toString());
+ ref.refresh(sockConnectprovider(widget.client));
+ },
+ );
+ });
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ _timer.cancel();
+ widget.socket.close(786887, "Connection lost with server!");
+ }
+
+ @override
+ Widget build(BuildContext context) => const Home();
+}
diff --git a/lib/vehicle_signal/vehicle_signal_config.dart b/lib/vehicle_signal/vehicle_signal_config.dart
new file mode 100644
index 0000000..3f0ff1d
--- /dev/null
+++ b/lib/vehicle_signal/vehicle_signal_config.dart
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: Apache-2.0
+
+import 'dart:io';
+import 'package:flutter/services.dart';
+import 'package:flutter_cluster_dashboard/cluster_config.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+
+final sockConnectprovider = FutureProvider.family<WebSocket, HttpClient>(
+ (ref, client) => connect(client, ref));
+
+// load certificates and set context and returns http client
+Future<HttpClient> initializeClient() async {
+ ByteData dataCA = await rootBundle.load('assets/cert/CA.pem');
+ ByteData dataCert = await rootBundle.load('assets/cert/Client.pem');
+ ByteData dataKey = await rootBundle.load('assets/cert/Client.key');
+
+ SecurityContext ctx = SecurityContext.defaultContext;
+ ctx.useCertificateChainBytes(dataCert.buffer.asUint8List());
+ ctx.usePrivateKeyBytes(dataKey.buffer.asUint8List());
+ ctx.setTrustedCertificatesBytes(dataCA.buffer.asUint8List());
+ HttpClient client = HttpClient(context: ctx)
+ ..findProxy = null
+ ..badCertificateCallback = (cert, host, port) {
+ return true;
+ };
+ return client;
+}
+
+Future<WebSocket> connect(HttpClient client, ref) async {
+ final config = ref.read(clusterConfigStateprovider);
+ WebSocket socket = await WebSocket.connect(
+ "wss://${config.hostname}:${config.port}",
+ customClient: client);
+ return socket;
+}
diff --git a/lib/vehicle_signal/vehicle_signal_methods.dart b/lib/vehicle_signal/vehicle_signal_methods.dart
new file mode 100644
index 0000000..21341c2
--- /dev/null
+++ b/lib/vehicle_signal/vehicle_signal_methods.dart
@@ -0,0 +1,325 @@
+// SPDX-License-Identifier: Apache-2.0
+
+import 'dart:convert';
+import 'dart:io';
+import 'package:flutter_cluster_dashboard/cluster_config.dart';
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_cluster_dashboard/map/networkPolyline.dart';
+import 'package:flutter_cluster_dashboard/provider.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_path.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_provider.dart';
+import 'package:latlong2/latlong.dart';
+
+class VISS {
+ static const requestId = "flutter-cluster-app";
+ static void init(WebSocket socket, WidgetRef ref) {
+ authorize(socket, ref);
+ subscribe(socket, ref, VSPath.vehicleSpeed);
+ subscribe(socket, ref, VSPath.vehicleEngineRPM);
+ subscribe(socket, ref, VSPath.vehicleLeftIndicator);
+ subscribe(socket, ref, VSPath.vehicleRightIndicator);
+ subscribe(socket, ref, VSPath.vehicleFuelLevel);
+ subscribe(socket, ref, VSPath.vehicleCoolantTemp);
+ subscribe(socket, ref, VSPath.vehicleHazardLightOn);
+ subscribe(socket, ref, VSPath.vehicleHighBeamOn);
+ subscribe(socket, ref, VSPath.vehicleLowBeamOn);
+ subscribe(socket, ref, VSPath.vehicleSelectedGear);
+ subscribe(socket, ref, VSPath.vehiclePerformanceMode);
+ subscribe(socket, ref, VSPath.vehicleAmbientAirTemperature);
+ subscribe(socket, ref, VSPath.vehicleParkingLightOn);
+ subscribe(socket, ref, VSPath.vehicleTrunkLocked);
+ subscribe(socket, ref, VSPath.vehicleTrunkOpen);
+ subscribe(socket, ref, VSPath.vehicleAmbientAirTemperature);
+ subscribe(socket, ref, VSPath.vehicleMIL);
+ subscribe(socket, ref, VSPath.vehicleCruiseControlError);
+ subscribe(socket, ref, VSPath.vehicleCruiseControlSpeedSet);
+ subscribe(socket, ref, VSPath.vehicleCruiseControlSpeedisActive);
+ subscribe(socket, ref, VSPath.vehicleBatteryChargingStatus);
+
+ //
+ subscribe(socket, ref, VSPath.steeringCruiseEnable);
+ subscribe(socket, ref, VSPath.steeringCruiseSet);
+ subscribe(socket, ref, VSPath.steeringCruiseResume);
+ subscribe(socket, ref, VSPath.steeringCruiseCancel);
+ subscribe(socket, ref, VSPath.steeringInfo);
+ subscribe(socket, ref, VSPath.steeringLaneDepWarn);
+ subscribe(socket, ref, VSPath.vehicleDistanceUnit);
+ //
+ subscribe(socket, ref, VSPath.vehicleCurrLat);
+ subscribe(socket, ref, VSPath.vehicleCurrLng);
+ subscribe(socket, ref, VSPath.vehicleDesLat);
+ subscribe(socket, ref, VSPath.vehicleDesLng);
+
+ update(socket, ref);
+ }
+
+ static void update(WebSocket socket, WidgetRef ref) {
+ get(socket, ref, VSPath.vehicleSpeed);
+ get(socket, ref, VSPath.vehicleEngineRPM);
+ get(socket, ref, VSPath.vehicleLeftIndicator);
+ get(socket, ref, VSPath.vehicleRightIndicator);
+ get(socket, ref, VSPath.vehicleFuelLevel);
+ get(socket, ref, VSPath.vehicleCoolantTemp);
+ get(socket, ref, VSPath.vehicleHazardLightOn);
+ get(socket, ref, VSPath.vehicleHighBeamOn);
+ get(socket, ref, VSPath.vehicleLowBeamOn);
+ get(socket, ref, VSPath.vehicleSelectedGear);
+ get(socket, ref, VSPath.vehiclePerformanceMode);
+ get(socket, ref, VSPath.vehicleAmbientAirTemperature);
+ get(socket, ref, VSPath.vehicleParkingLightOn);
+ get(socket, ref, VSPath.vehicleTrunkLocked);
+ get(socket, ref, VSPath.vehicleTrunkOpen);
+ get(socket, ref, VSPath.vehicleAmbientAirTemperature);
+ get(socket, ref, VSPath.vehicleMIL);
+ get(socket, ref, VSPath.vehicleCruiseControlError);
+ get(socket, ref, VSPath.vehicleCruiseControlSpeedSet);
+ get(socket, ref, VSPath.vehicleCruiseControlSpeedisActive);
+ get(socket, ref, VSPath.vehicleBatteryChargingStatus);
+ get(socket, ref, VSPath.vehicleDistanceUnit);
+ //
+ get(socket, ref, VSPath.vehicleCurrLat);
+ get(socket, ref, VSPath.vehicleCurrLng);
+ get(socket, ref, VSPath.vehicleDesLat);
+ get(socket, ref, VSPath.vehicleDesLng);
+ }
+
+ static void authorize(WebSocket socket, WidgetRef ref) {
+ final config = ref.read(clusterConfigStateprovider);
+ Map<String, dynamic> map = {
+ "action": "authorize",
+ "tokens": config.kuksaAuthToken,
+ "requestId": requestId
+ };
+ socket.add(jsonEncode(map));
+ }
+
+ static void get(WebSocket socket, WidgetRef ref, String path) {
+ final config = ref.read(clusterConfigStateprovider);
+ Map<String, dynamic> map = {
+ "action": "get",
+ "tokens": config.kuksaAuthToken,
+ "path": path,
+ "requestId": requestId
+ };
+ socket.add(jsonEncode(map));
+ }
+
+ static void set(WebSocket socket, WidgetRef ref, String path, String value) {
+ final config = ref.read(clusterConfigStateprovider);
+ Map<String, dynamic> map = {
+ "action": "set",
+ "tokens": config.kuksaAuthToken,
+ "path": path,
+ "requestId": requestId,
+ "value": value
+ };
+ socket.add(jsonEncode(map));
+ }
+
+ static void subscribe(WebSocket socket, WidgetRef ref, String path) {
+ final config = ref.read(clusterConfigStateprovider);
+ Map<String, dynamic> map = {
+ "action": "subscribe",
+ "tokens": config.kuksaAuthToken,
+ "path": path,
+ "requestId": requestId
+ };
+ socket.add(jsonEncode(map));
+ }
+
+ 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;
+ }
+ }
+
+ static void parseData(WidgetRef ref, String data) {
+ final vehicleSignal = ref.read(vehicleSignalProvider.notifier);
+ final polylineDBNotifier = ref.read(polyLineStateProvider.notifier);
+ Map<String, dynamic> dataMap = jsonDecode(data);
+ if (dataMap["action"] == "subscription" || dataMap["action"] == "get") {
+ if (dataMap.containsKey("data")) {
+ if ((dataMap["data"] as Map<String, dynamic>).containsKey("dp") &&
+ (dataMap["data"] as Map<String, dynamic>).containsKey("path")) {
+ String path = dataMap["data"]["path"];
+ Map<String, dynamic> dp = dataMap["data"]["dp"];
+ if (dp.containsKey("value")) {
+ if (dp["value"] != "---") {
+ switch (path) {
+ case VSPath.vehicleSpeed:
+ vehicleSignal.update(speed: double.parse(dp["value"]));
+ break;
+ case VSPath.vehicleEngineRPM:
+ vehicleSignal.update(rpm: double.parse(dp["value"]));
+ break;
+ case VSPath.vehicleFuelLevel:
+ vehicleSignal.update(fuelLevel: double.parse(dp["value"]));
+ break;
+ case VSPath.vehicleCoolantTemp:
+ vehicleSignal.update(coolantTemp: double.parse(dp["value"]));
+ break;
+ case VSPath.vehicleLeftIndicator:
+ vehicleSignal.update(isLeftIndicator: dp["value"]);
+ break;
+ case VSPath.vehicleRightIndicator:
+ vehicleSignal.update(isRightIndicator: dp["value"]);
+ break;
+ case VSPath.vehicleHighBeamOn:
+ if (dp["value"]) {
+ vehicleSignal.update(isHighBeam: true);
+ vehicleSignal.update(isLowBeam: false);
+ } else {
+ vehicleSignal.update(isHighBeam: dp["value"]);
+ }
+ break;
+ case VSPath.vehicleParkingLightOn:
+ vehicleSignal.update(isParkingOn: dp["value"]);
+ break;
+ case VSPath.vehicleLowBeamOn:
+ if (dp["value"]) {
+ vehicleSignal.update(isHighBeam: false);
+ vehicleSignal.update(isLowBeam: true);
+ } else {
+ vehicleSignal.update(isLowBeam: dp["value"]);
+ }
+ break;
+ case VSPath.vehicleHazardLightOn:
+ vehicleSignal.update(isHazardLightOn: dp["value"]);
+ break;
+ case VSPath.vehicleSelectedGear:
+ vehicleSignal.update(
+ selectedGear: numToGear(int.parse(dp["value"])));
+ break;
+ case VSPath.vehiclePerformanceMode:
+ vehicleSignal.update(performanceMode: dp['value']);
+ break;
+ case VSPath.vehicleTravelledDistance:
+ vehicleSignal.update(travelledDistance: dp['value']);
+ break;
+ case VSPath.vehicleTrunkLocked:
+ vehicleSignal.update(isTrunkLocked: dp['value']);
+ break;
+ case VSPath.vehicleTrunkOpen:
+ vehicleSignal.update(isTrunkOpen: dp['value']);
+ break;
+ case VSPath.vehicleAmbientAirTemperature:
+ vehicleSignal.update(ambientAirTemp: dp['value']);
+ break;
+ case VSPath.vehicleMIL:
+ vehicleSignal.update(isMILon: dp['value']);
+ break;
+ case VSPath.vehicleCruiseControlError:
+ vehicleSignal.update(isCruiseControlError: dp['value']);
+ break;
+ case VSPath.vehicleCruiseControlSpeedSet:
+ vehicleSignal.update(
+ cruiseControlSpeed: double.parse(dp['value']));
+ break;
+ case VSPath.vehicleCruiseControlSpeedisActive:
+ vehicleSignal.update(isCruiseControlActive: dp['value']);
+ break;
+ case VSPath.vehicleBatteryChargingStatus:
+ vehicleSignal.update(isBatteryCharging: dp['value']);
+ break;
+ //
+ case VSPath.steeringCruiseEnable:
+ if (dp['value']) {
+ if (vehicleSignal.state.isSteeringCruiseEnable) {
+ vehicleSignal.update(isSteeringCruiseEnable: false);
+ vehicleSignal.update(isSteeringCruiseSet: false);
+ } else {
+ vehicleSignal.update(isSteeringCruiseEnable: dp['value']);
+ }
+ }
+ break;
+ case VSPath.steeringCruiseSet:
+ if (dp['value'] &&
+ vehicleSignal.state.isSteeringCruiseEnable) {
+ vehicleSignal.update(isSteeringCruiseSet: dp['value']);
+ }
+ break;
+ case VSPath.steeringCruiseResume:
+ if (dp['value'] &&
+ vehicleSignal.state.isSteeringCruiseEnable) {
+ vehicleSignal.update(isSteeringCruiseSet: dp['value']);
+ }
+ break;
+ case VSPath.steeringCruiseCancel:
+ if (dp['value']) {
+ vehicleSignal.update(isSteeringCruiseSet: false);
+ }
+ break;
+ case VSPath.steeringInfo:
+ if (dp['value']) {
+ vehicleSignal.update(
+ isSteeringInfo: !vehicleSignal.state.isSteeringInfo);
+ }
+ break;
+ case VSPath.steeringLaneDepWarn:
+ if (dp['value']) {
+ vehicleSignal.update(
+ isSteeringLaneWarning:
+ !(vehicleSignal.state.isSteeringLaneWarning));
+ }
+ break;
+ case VSPath.vehicleDistanceUnit:
+ vehicleSignal.update(vehicleDistanceUnit: dp['value']);
+ break;
+ //
+ case VSPath.vehicleCurrLat:
+ vehicleSignal.update(currLat: double.parse(dp['value']));
+ break;
+ case VSPath.vehicleCurrLng:
+ vehicleSignal.update(currLng: double.parse(dp['value']));
+ break;
+ case VSPath.vehicleDesLat:
+ vehicleSignal.update(desLat: double.parse(dp['value']));
+ polylineDBNotifier.update(currPolyLineList: []);
+
+ break;
+ case VSPath.vehicleDesLng:
+ vehicleSignal.update(desLng: double.parse(dp['value']));
+ polylineDBNotifier.update(currPolyLineList: []);
+ break;
+ default:
+ print("$path Not Available yet!");
+ }
+ } else {
+ print("ERROR:Value not available yet! Set Value of $path");
+ }
+ } else {
+ print("ERROR:'value': Key not found!");
+ }
+ } else if ((!dataMap["data"] as Map<String, dynamic>)
+ .containsKey("path")) {
+ print("ERROR:'path':key not found !");
+ } else if ((dataMap["data"] as Map<String, dynamic>)
+ .containsKey("dp")) {
+ print("ERROR:'dp':key not found !");
+ }
+ } else {
+ print("ERROR:'data':key not found!");
+ }
+ }
+ }
+}
+
+void updatePolyline(WidgetRef ref, vehicleSignal, polyLineState) {
+ getJsonData(ref, vehicleSignal.state.currLat, vehicleSignal.state.currLng,
+ vehicleSignal.state.desLat, vehicleSignal.state.desLng)
+ .then((polylineList) {
+ polyLineState.update(
+ currPolyLineList: polylineList
+ .map((element) => LatLng(element[1], element[0]))
+ .toList());
+ });
+}
diff --git a/lib/vehicle_signal/vehicle_signal_model.dart b/lib/vehicle_signal/vehicle_signal_model.dart
new file mode 100644
index 0000000..90f76e7
--- /dev/null
+++ b/lib/vehicle_signal/vehicle_signal_model.dart
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: Apache-2.0
+
+class VehicleSignal {
+ VehicleSignal({
+ 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,
+ // map coordinates
+ required this.currLat,
+ required this.currLng,
+ required this.desLat,
+ required this.desLng,
+ });
+ 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 String 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;
+
+ final double currLat;
+ final double currLng;
+ final double desLat;
+ final double desLng;
+
+ VehicleSignal copyWith({
+ double? speed,
+ double? rpm,
+ double? fuelLevel,
+ double? coolantTemp,
+ bool? isLeftIndicator,
+ bool? isRightIndicator,
+ String? selectedGear,
+ String? performanceMode,
+ String? 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,
+ // map coordinates
+ double? currLat,
+ double? currLng,
+ double? desLat,
+ double? desLng,
+ }) {
+ return VehicleSignal(
+ 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,
+ //
+ currLat: currLat ?? this.currLat,
+ currLng: currLng ?? this.currLng,
+ desLat: desLat ?? this.desLat,
+ desLng: desLng ?? this.desLng,
+ );
+ }
+}
diff --git a/lib/vehicle_signal/vehicle_signal_path.dart b/lib/vehicle_signal/vehicle_signal_path.dart
new file mode 100644
index 0000000..72b016d
--- /dev/null
+++ b/lib/vehicle_signal/vehicle_signal_path.dart
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: Apache-2.0
+
+class VSPath {
+ static const String vehicleSpeed = "Vehicle.Speed";
+ static const String vehicleEngineRPM =
+ "Vehicle.Powertrain.CombustionEngine.Engine.Speed";
+ static const String vehicleFuelLevel = "Vehicle.Powertrain.FuelSystem.Level";
+ static const String vehicleCoolantTemp =
+ "Vehicle.Powertrain.CombustionEngine.Engine.ECT";
+ static const String vehicleLeftIndicator =
+ "Vehicle.Body.Lights.IsLeftIndicatorOn";
+ static const String vehicleRightIndicator =
+ "Vehicle.Body.Lights.IsRightIndicatorOn";
+ //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.IsLowBeamOn";
+ static const String vehicleHighBeamOn = "Vehicle.Body.Lights.IsHighBeamOn";
+ static const String vehicleParkingLightOn = "Vehicle.Body.Lights.IsParkingOn";
+ static const String vehicleHazardLightOn = "Vehicle.Body.Lights.IsHazardOn";
+ static const String vehicleTravelledDistance = "Vehicle.TravelledDistance";
+ static const String vehicleTrunkLocked = "Vehicle.Body.Trunk.IsLocked";
+ static const String vehicleTrunkOpen = "Vehicle.Body.Trunk.IsOpen";
+ // \"normal\",\"sport\",\"economy\",\"snow\",\"rain\"]
+ static const String vehiclePerformanceMode =
+ "Vehicle.Powertrain.Transmission.PerformanceMode";
+ static const String vehicleAmbientAirTemperature =
+ "Vehicle.AmbientAirTemperature";
+ static const String vehicleMIL = "Vehicle.OBD.Status.MIL";
+ static const String vehicleCruiseControlError =
+ "Vehicle.ADAS.CruiseControl.Error";
+ static const String vehicleCruiseControlSpeedSet =
+ "Vehicle.ADAS.CruiseControl.SpeedSet";
+ static const String vehicleCruiseControlSpeedisActive =
+ "Vehicle.ADAS.CruiseControl.IsActive";
+ static const String vehicleBatteryChargingStatus =
+ "Vehicle.Powertrain.Battery.Charging.Status";
+
+ 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.Cabin.Infotainment.Navigation.CurrentLocation.Latitude";
+ static const String vehicleCurrLng =
+ "Vehicle.Cabin.Infotainment.Navigation.CurrentLocation.Longitude";
+ static const String vehicleDesLat =
+ "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude";
+ static const String vehicleDesLng =
+ "Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude";
+}
diff --git a/lib/vehicle_signal/vehicle_signal_provider.dart b/lib/vehicle_signal/vehicle_signal_provider.dart
new file mode 100644
index 0000000..e75afff
--- /dev/null
+++ b/lib/vehicle_signal/vehicle_signal_provider.dart
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: Apache-2.0
+
+import 'package:flutter_riverpod/flutter_riverpod.dart';
+import 'package:flutter_cluster_dashboard/vehicle_signal/vehicle_signal_model.dart';
+
+final vehicleSignalProvider =
+ StateNotifierProvider<VehicleSignalNotifier, VehicleSignal>(
+ (ref) => VehicleSignalNotifier(),
+);
+
+class VehicleSignalNotifier extends StateNotifier<VehicleSignal> {
+ VehicleSignalNotifier() : super(_initialValue);
+ static final VehicleSignal _initialValue = VehicleSignal(
+ 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',
+ currLat: 31.71,
+ currLng: 76.95,
+ desLat: 31.71,
+ desLng: 76.95,
+ );
+ void update({
+ double? speed,
+ double? rpm,
+ double? fuelLevel,
+ double? coolantTemp,
+ bool? isLeftIndicator,
+ bool? isRightIndicator,
+ String? selectedGear,
+ String? performanceMode,
+ String? 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,
+ //
+ double? currLat,
+ double? currLng,
+ double? desLat,
+ double? desLng,
+ }) {
+ 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,
+ //
+ currLat: currLat,
+ currLng: currLng,
+ desLat: desLat,
+ desLng: desLng,
+ );
+ }
+}