From 10945b8056eb2b228c156918a3505882a49a79b8 Mon Sep 17 00:00:00 2001 From: Hritik Chouhan Date: Thu, 1 Sep 2022 20:46:09 +0200 Subject: Upload Flutter-Dashboard app for IVI Flutter Dashboard app which shows Tyres Pressure, Child lock status , Current Location,Speed,RPM,outside and inside Temperature , Average fuel Consumption. update UI and Removed Unused code. Moved kuksa authtoken and mapbox access token and other things to config file. Bug-AGL: SPEC-4547 Signed-off-by: Hritik Chouhan Change-Id: I14f42ed453c8279a1e89f8835d2b24e07e4ce376 --- lib/Kuksa-server/intial_connection.dart | 38 ++++++ lib/Kuksa-server/onBoarding_page.dart | 61 ++++++++++ lib/Kuksa-server/vehicle_class.dart | 75 ++++++++++++ lib/Kuksa-server/vehicle_config.dart | 39 ++++++ lib/Kuksa-server/vehicle_methods.dart | 190 ++++++++++++++++++++++++++++++ lib/Kuksa-server/vehicle_provider.dart | 64 ++++++++++ lib/Kuksa-server/vehicle_server_path.dart | 34 ++++++ 7 files changed, 501 insertions(+) create mode 100644 lib/Kuksa-server/intial_connection.dart create mode 100644 lib/Kuksa-server/onBoarding_page.dart create mode 100644 lib/Kuksa-server/vehicle_class.dart create mode 100644 lib/Kuksa-server/vehicle_config.dart create mode 100644 lib/Kuksa-server/vehicle_methods.dart create mode 100644 lib/Kuksa-server/vehicle_provider.dart create mode 100644 lib/Kuksa-server/vehicle_server_path.dart (limited to 'lib/Kuksa-server') diff --git a/lib/Kuksa-server/intial_connection.dart b/lib/Kuksa-server/intial_connection.dart new file mode 100644 index 0000000..dfac031 --- /dev/null +++ b/lib/Kuksa-server/intial_connection.dart @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:io'; +import 'package:dashboard_app/Kuksa-server/vehicle_config.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'onBoarding_page.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); + ref.refresh(sockConnectprovider(client)); + return const Scaffold( + backgroundColor: Colors.black, + body: Center(child: Text('error',style: TextStyle(color: Colors.white),)), + ); + }, + loading: () => const Scaffold( + backgroundColor: Colors.black, + body: Center(child: Text('loading',style: TextStyle(color: Colors.white))), + ), + ); + } +} \ No newline at end of file diff --git a/lib/Kuksa-server/onBoarding_page.dart b/lib/Kuksa-server/onBoarding_page.dart new file mode 100644 index 0000000..264c7a0 --- /dev/null +++ b/lib/Kuksa-server/onBoarding_page.dart @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:async'; +import 'dart:io'; + +import 'package:dashboard_app/Kuksa-server/vehicle_config.dart'; +import 'package:dashboard_app/Kuksa-server/vehicle_methods.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import '../HomePage.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 createState() => _OnBoardingPageState(); +} + +class _OnBoardingPageState extends ConsumerState { + 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) { + 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) { + return const HomePage(); + } +} \ No newline at end of file diff --git a/lib/Kuksa-server/vehicle_class.dart b/lib/Kuksa-server/vehicle_class.dart new file mode 100644 index 0000000..c2f2ac2 --- /dev/null +++ b/lib/Kuksa-server/vehicle_class.dart @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +class VehicleSignal { + VehicleSignal({ + required this.speed, + required this.rpm, + required this.fuelLevel, + required this.frontLeftTP, + required this.frontRightTP, + required this.rearLeftTP, + required this.rearRightTP, + required this.isBatteryCharging, + required this.isChildLockActiveLeft, + required this.isChildLockActiveRight, + required this.currentLatitude, + required this.currentLongitude, + required this.fuelRate, + required this.insideTemperature, + required this.outsideTemperature, + }); + + final double speed; + final double rpm; + final double fuelLevel; + final double frontLeftTP; + final double frontRightTP; + final double rearLeftTP; + final double rearRightTP; + final bool isChildLockActiveLeft; + final bool isChildLockActiveRight; + final double currentLongitude; + final double currentLatitude; + final double fuelRate; + final int insideTemperature; + final int outsideTemperature; + + final bool isBatteryCharging; + + VehicleSignal copyWith({ + double? speed, + double? rpm, + double? fuelLevel, + double? frontLeftTP, + double? frontRightTP, + double? rearLeftTP, + double? rearRightTP, + bool? isBatteryCharging, + bool? isChildLockActiveLeft, + bool? isChildLockActiveRight, + double? currentLongitude, + double? currentLatitude, + double? fuelRate, + int? insideTemperature, + int? outsideTemperature, + }) { + return VehicleSignal( + speed: speed ?? this.speed, + rpm: rpm ?? this.rpm, + fuelLevel: fuelLevel ?? this.fuelLevel, + frontLeftTP: frontLeftTP ?? this.frontLeftTP, + frontRightTP: frontRightTP ?? this.frontRightTP, + rearLeftTP: rearLeftTP ?? this.rearLeftTP, + rearRightTP: rearRightTP ?? this.rearRightTP, + isChildLockActiveLeft: + isChildLockActiveLeft ?? this.isChildLockActiveLeft, + isChildLockActiveRight: + isChildLockActiveRight ?? this.isChildLockActiveRight, + isBatteryCharging: isBatteryCharging ?? this.isBatteryCharging, + currentLatitude: currentLatitude ?? this.currentLatitude, + currentLongitude: currentLongitude ?? this.currentLongitude, + fuelRate: fuelRate ?? this.fuelRate, + insideTemperature: insideTemperature ?? this.insideTemperature, + outsideTemperature: outsideTemperature ?? this.outsideTemperature, + ); + } +} diff --git a/lib/Kuksa-server/vehicle_config.dart b/lib/Kuksa-server/vehicle_config.dart new file mode 100644 index 0000000..59682c4 --- /dev/null +++ b/lib/Kuksa-server/vehicle_config.dart @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:convert'; +import 'dart:io'; + +import 'package:dashboard_app/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:http/http.dart' as http; + + + +final sockConnectprovider = FutureProvider.family( + (ref, client) => connect(client,ref)); + + + +Future initializeClient() async { + + + SecurityContext ctx = SecurityContext.defaultContext; + + HttpClient client = HttpClient(context: ctx) + ..findProxy = null + ..badCertificateCallback = (cert, host, port) { + return true; + }; + return client; +} + + + +Future connect(HttpClient client, ref) async { + final config = ref.read(ConfigStateprovider); + WebSocket socket = await WebSocket.connect( + "wss://${config.hostname}:${config.port}", + customClient: client); + return socket; +} + + diff --git a/lib/Kuksa-server/vehicle_methods.dart b/lib/Kuksa-server/vehicle_methods.dart new file mode 100644 index 0000000..500f694 --- /dev/null +++ b/lib/Kuksa-server/vehicle_methods.dart @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:convert'; +import 'dart:io'; + +import 'package:dashboard_app/Kuksa-server/vehicle_provider.dart'; +import 'package:dashboard_app/Kuksa-server/vehicle_server_path.dart'; +import 'package:dashboard_app/config.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +class VISS { + static const requestId = "test-id"; + static void init(WebSocket socket, WidgetRef ref) { + authorize(socket,ref); + subscribe(socket,ref, VSPath.vehicleSpeed); + subscribe(socket,ref, VSPath.vehicleEngineRPM); + subscribe(socket,ref, VSPath.vehicleFuelLevel); + subscribe(socket,ref, VSPath.vehicleFrontLeftTier); + subscribe(socket, ref,VSPath.vehicleFrontRightTier); + subscribe(socket, ref,VSPath.vehicleRearLeftTier); + subscribe(socket,ref, VSPath.vehicleRearRightTier); + subscribe(socket, ref,VSPath.vehicleIsChildLockActiveLeft); + subscribe(socket,ref, VSPath.vehicleIsChildLockActiveRight); + subscribe(socket,ref, VSPath.vehicleCurrentLatitude); + subscribe(socket,ref, VSPath.vehicleCurrentLongitude); + subscribe(socket,ref, VSPath.vehicleFuelRate); + subscribe(socket,ref, VSPath.vehicleInsideTemperature); + subscribe(socket, ref,VSPath.vehicleAmbientAirTemperature); + } + + static void update(WebSocket socket, WidgetRef ref) { + get(socket,ref, VSPath.vehicleSpeed); + get(socket,ref, VSPath.vehicleEngineRPM); + get(socket,ref, VSPath.vehicleFuelLevel); + get(socket,ref,VSPath.vehicleAmbientAirTemperature); + get(socket,ref,VSPath.vehicleFrontLeftTier); + get(socket,ref, VSPath.vehicleFrontRightTier); + get(socket,ref, VSPath.vehicleRearLeftTier); + get(socket,ref, VSPath.vehicleRearRightTier); + get(socket,ref,VSPath.vehicleIsChildLockActiveLeft); + get(socket,ref, VSPath.vehicleIsChildLockActiveRight); + get(socket,ref,VSPath.vehicleCurrentLatitude); + get(socket,ref,VSPath.vehicleCurrentLongitude); + get(socket,ref,VSPath.vehicleFuelRate); + get(socket,ref, VSPath.vehicleInsideTemperature); + } + + static void authorize(WebSocket socket,WidgetRef ref) { + final config = ref.read(ConfigStateprovider); + + Map 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(ConfigStateprovider); + + Map 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(ConfigStateprovider); + Map 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(ConfigStateprovider); + + Map 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); + Map dataMap = jsonDecode(data); + if (dataMap["action"] == "subscription" || dataMap["action"] == "get") { + if (dataMap.containsKey("data")) { + if ((dataMap["data"] as Map).containsKey("dp") && + (dataMap["data"] as Map).containsKey("path")) { + String path = dataMap["data"]["path"]; + Map 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.vehicleFrontLeftTier: + vehicleSignal.update(frontLeftTP: double.parse(dp["value"])); + break; + case VSPath.vehicleFrontRightTier: + vehicleSignal.update(frontRightTP: double.parse(dp["value"])); + break; + case VSPath.vehicleRearLeftTier: + vehicleSignal.update(rearLeftTP: double.parse(dp["value"])); + break; + case VSPath.vehicleRearRightTier: + vehicleSignal.update(rearRightTP: double.parse(dp["value"])); + break; + + + case VSPath.vehicleIsChildLockActiveLeft: + vehicleSignal.update(isChildLockActiveLeft: dp['value']); + break; + case VSPath.vehicleIsChildLockActiveRight: + vehicleSignal.update(isChildLockActiveRight: dp['value']); + break; + case VSPath.vehicleCurrentLatitude: + vehicleSignal.update( + currentLatitude: double.parse(dp["value"])); + break; + case VSPath.vehicleCurrentLongitude: + vehicleSignal.update( + currentLongitude: double.parse(dp["value"])); + break; + case VSPath.vehicleFuelRate: + vehicleSignal.update(fuelRate: double.parse(dp["value"])); + break; + case VSPath.vehicleInsideTemperature: + vehicleSignal.update( + insideTemperature: int.parse(dp["value"])); + break; + case VSPath.vehicleAmbientAirTemperature: + vehicleSignal.update( + outsideTemperature: int.parse(dp["value"])); + 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) + .containsKey("path")) { + print("ERROR:'path':key not found !"); + } else if ((dataMap["data"] as Map) + .containsKey("dp")) { + print("ERROR:'dp':key not found !"); + } + } else { + print("ERROR:'data':key not found!"); + } + } + } +} diff --git a/lib/Kuksa-server/vehicle_provider.dart b/lib/Kuksa-server/vehicle_provider.dart new file mode 100644 index 0000000..e7b67df --- /dev/null +++ b/lib/Kuksa-server/vehicle_provider.dart @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:dashboard_app/Kuksa-server/vehicle_class.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final vehicleSignalProvider = + StateNotifierProvider( + (ref) => VehicleSignalNotifier(), +); + +class VehicleSignalNotifier extends StateNotifier { + VehicleSignalNotifier() : super(_initialValue); + static final VehicleSignal _initialValue = VehicleSignal( + speed: 140, + rpm: 7000, + fuelLevel: 90, + frontRightTP: 32, + frontLeftTP: 32, + rearRightTP: 33, + rearLeftTP: 34, + isChildLockActiveLeft: true, + isChildLockActiveRight: true, + isBatteryCharging: true, + currentLatitude: 37.772701, + currentLongitude: -122.416626, + fuelRate: 21, + insideTemperature: 25, + outsideTemperature: 32, + ); + void update({ + double? speed, + double? rpm, + double? fuelLevel, + double? frontLeftTP, + double? frontRightTP, + double? rearLeftTP, + double? rearRightTP, + bool? isBatteryCharging, + bool? isChildLockActiveLeft, + bool? isChildLockActiveRight, + double? currentLatitude, + double? currentLongitude, + double? fuelRate, + int? insideTemperature, + int? outsideTemperature, + }) { + state = state.copyWith( + speed: speed, + rpm: rpm, + fuelLevel: fuelLevel, + frontLeftTP: frontLeftTP, + frontRightTP: frontRightTP, + rearLeftTP: rearLeftTP, + rearRightTP: rearRightTP, + isChildLockActiveLeft: isChildLockActiveLeft, + isChildLockActiveRight: isChildLockActiveRight, + isBatteryCharging: isBatteryCharging, + currentLatitude: currentLatitude, + currentLongitude: currentLongitude, + fuelRate: fuelRate, + insideTemperature: insideTemperature, + outsideTemperature: outsideTemperature, + ); + } +} diff --git a/lib/Kuksa-server/vehicle_server_path.dart b/lib/Kuksa-server/vehicle_server_path.dart new file mode 100644 index 0000000..9854320 --- /dev/null +++ b/lib/Kuksa-server/vehicle_server_path.dart @@ -0,0 +1,34 @@ +// 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 vehicleAmbientAirTemperature = + "Vehicle.AmbientAirTemperature"; + + static const String vehicleFrontLeftTier = + "Vehicle.Chassis.Axle.Row1.Wheel.Left.Tire.Pressure"; + static const String vehicleFrontRightTier = + "Vehicle.Chassis.Axle.Row1.Wheel.Right.Tire.Pressure"; + static const String vehicleRearLeftTier = + "Vehicle.Chassis.Axle.Row2.Wheel.Left.Tire.Pressure"; + + static const String vehicleRearRightTier = + "Vehicle.Chassis.Axle.Row2.Wheel.Right.Tire.Pressure"; + static const String vehicleIsChildLockActiveLeft = + "Vehicle.Cabin.Door.Row2.Left.IsChildLockActive"; + static const String vehicleIsChildLockActiveRight = + "Vehicle.Cabin.Door.Row2.Right.IsChildLockActive"; + static const String vehicleCurrentLongitude = + "Vehicle.CurrentLocation.Longitude"; + static const String vehicleCurrentLatitude = + "Vehicle.CurrentLocation.Latitude"; + static const String vehicleFuelRate = "Vehicle.OBD.FuelRate"; + static const String vehicleInsideTemperature = + "Vehicle.Cabin.HVAC.AmbientAirTemperature"; +} -- cgit