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 --- .gitreview | 5 + License.md | 201 +++++++++++++ images/car_img.png | Bin 0 -> 259879 bytes images/cloud.png | Bin 0 -> 7918 bytes images/thermostate.png | Bin 0 -> 5721 bytes lib/HomePage.dart | 469 ++++++++++++++++++++++++++++++ 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 +++ lib/Tier_pressure.dart | 60 ++++ lib/config.dart | 111 +++++++ lib/drawArrow.dart | 81 ++++++ lib/main.dart | 28 ++ lib/provider.dart | 41 +++ lib/size.dart | 48 +++ lib/widgets/child_lock.dart | 61 ++++ lib/widgets/fuel_and_speed.dart | 111 +++++++ lib/widgets/weather.dart | 84 ++++++ pubspec.yaml | 93 ++++++ 23 files changed, 1894 insertions(+) create mode 100644 .gitreview create mode 100644 License.md create mode 100644 images/car_img.png create mode 100644 images/cloud.png create mode 100644 images/thermostate.png create mode 100644 lib/HomePage.dart 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 create mode 100644 lib/Tier_pressure.dart create mode 100644 lib/config.dart create mode 100644 lib/drawArrow.dart create mode 100644 lib/main.dart create mode 100644 lib/provider.dart create mode 100644 lib/size.dart create mode 100644 lib/widgets/child_lock.dart create mode 100644 lib/widgets/fuel_and_speed.dart create mode 100644 lib/widgets/weather.dart create mode 100644 pubspec.yaml diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..ace7bf1 --- /dev/null +++ b/.gitreview @@ -0,0 +1,5 @@ +[gerrit] +host=gerrit.automotivelinux.org +port=29418 +project=apps/flutter-dashboard +defaultbranch=master diff --git a/License.md b/License.md new file mode 100644 index 0000000..a0b7d15 --- /dev/null +++ b/License.md @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [2022] [Hritik Chouhan] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/images/car_img.png b/images/car_img.png new file mode 100644 index 0000000..9283e0b Binary files /dev/null and b/images/car_img.png differ diff --git a/images/cloud.png b/images/cloud.png new file mode 100644 index 0000000..fb713e8 Binary files /dev/null and b/images/cloud.png differ diff --git a/images/thermostate.png b/images/thermostate.png new file mode 100644 index 0000000..a481d1e Binary files /dev/null and b/images/thermostate.png differ diff --git a/lib/HomePage.dart b/lib/HomePage.dart new file mode 100644 index 0000000..c583fbf --- /dev/null +++ b/lib/HomePage.dart @@ -0,0 +1,469 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:dashboard_app/Tier_pressure.dart'; +import 'package:dashboard_app/drawArrow.dart'; +import 'package:dashboard_app/provider.dart'; +import 'package:dashboard_app/size.dart'; +import 'package:dashboard_app/widgets/child_lock.dart'; +import 'package:dashboard_app/widgets/fuel_and_speed.dart'; +import 'package:dashboard_app/widgets/weather.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:latlng/latlng.dart'; + + + +import 'Kuksa-server/vehicle_provider.dart'; + + +class HomePage extends ConsumerStatefulWidget { + const HomePage({Key? key}) : super(key: key); + + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends ConsumerState { + @override + Widget build(BuildContext context) { + SizeConfig().init(context); + final vehicle = ref.watch(vehicleSignalProvider); + LatLng pos = LatLng(vehicle.currentLatitude, vehicle.currentLongitude); + + DateTime _now = ref.watch(DateTimeProvider); + + + + return Scaffold( + backgroundColor: Colors.black87, + body: OrientationBuilder( + builder: (context, orientation) { + if (orientation == Orientation.landscape) { + return Stack( + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + child: Container( + color: Colors.black87, + ), + ), + + + + + Positioned( + right: SizeConfig.safeBlockHorizontal * 41, + top: SizeConfig.safeBlockVertical * 58, + child: ChildLockStatus( + isChildLockActiveLeft: vehicle.isChildLockActiveLeft, + isChildLockActiveRight: vehicle.isChildLockActiveRight), + ), + + Positioned( + top: SizeConfig.safeBlockVertical * 18, + right: SizeConfig.safeBlockHorizontal * 38, + child: Column( + + children: [ + TierPressure( + tname: 'L Front Tier', + tpress: vehicle.frontLeftTP, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + ), + Container( + height: SizeConfig.safeBlockVertical * 10, + width: SizeConfig.safeBlockHorizontal * 12, + child: CustomPaint( + painter: Arrowpaint2(), + ), + ) + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 65, + right: SizeConfig.safeBlockHorizontal * 38, + child: Column( + + children: [ + RotatedBox( + quarterTurns: 2, + child: Container( + height: SizeConfig.safeBlockVertical * 10, + width: SizeConfig.safeBlockHorizontal * 12, + child: CustomPaint( + painter: Arrowpaint(), + ), + ), + ), + TierPressure( + tname: 'L Rear Tier', + tpress: vehicle.rearLeftTP, + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisAlignment: MainAxisAlignment.start, + ), + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 18, + right: SizeConfig.safeBlockHorizontal * 7, + child: Column( + children: [ + TierPressure( + tname: 'R Front Tier', + tpress: vehicle.frontRightTP, + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + ), + Container( + height: SizeConfig.safeBlockVertical * 10, + width: SizeConfig.safeBlockHorizontal * 12, + child: CustomPaint( + painter: Arrowpaint(), + ), + ), + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 65, + right: SizeConfig.safeBlockHorizontal * 7, + child: Column( + children: [ + RotatedBox( + quarterTurns: 2, + child: Container( + height: SizeConfig.safeBlockVertical * 10, + width: SizeConfig.safeBlockHorizontal * 12, + child: CustomPaint( + painter: Arrowpaint2(), + ), + ), + ), + TierPressure( + tname: 'R Rear Tier', + tpress: vehicle.rearRightTP, + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + ), + ], + ), + ), + Positioned( + top: SizeConfig.safeBlockVertical * 20, + right: SizeConfig.blockSizeHorizontal * 13, + bottom: SizeConfig.blockSizeVertical * 20, + child: SizedBox( + height: SizeConfig.screenHeight * 0.6, + width: SizeConfig.screenWidth * 0.30, + child: AnimatedContainer( + duration: Duration(milliseconds: 10), + child: Image.asset('images/car_img.png'), + ), + ), + ), + + Positioned( + top: SizeConfig.safeBlockVertical * 7, + left: SizeConfig.safeBlockHorizontal * 2, + bottom: SizeConfig.safeBlockVertical * 4, + child: Container( + width: SizeConfig.screenWidth / 2, + height: SizeConfig.screenHeight * 0.75, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Rpm(rpm: vehicle.rpm), + + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Avg. Fuel Consumtion', + style: SizeConfig.smallnormalfont, + ), + Text( + vehicle.fuelRate.toString() + ' KM/Litre', + style: SizeConfig.smallnormalfont, + ), + ], + ), + // ignore: prefer_const_constructors + weather( + insideTemperatue: vehicle.insideTemperature, + outsideTempearure: vehicle.outsideTemperature, + ), + SpeedAndFuel( + fuel: vehicle.fuelLevel, speed: vehicle.speed), + ], + ), + )) + ], + ); + } + //--------------------------Portrait mode ------------------------------------------------ + else { + return Stack( + children: [ + Positioned( + top: 0, + bottom: 0, + left: 0, + right: 0, + child: Padding( + padding: EdgeInsets.fromLTRB( + SizeConfig.safeBlockHorizontal * 2, + SizeConfig.safeBlockVertical * 2, + SizeConfig.safeBlockHorizontal * 2, + 0), + + child: Column( + children: [ + Flexible(flex: 1, child: SizedBox()), + SizedBox( + height: SizeConfig.safeBlockVertical, + ), + Flexible( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + ], + ), + ), + + SizedBox( + height: SizeConfig.safeBlockVertical, + ), + Flexible( + flex: 2, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Flexible( + flex: 1, + child: weather( + insideTemperatue: vehicle.insideTemperature, + outsideTempearure: + vehicle.outsideTemperature, + ), + ), + Flexible( + flex: 2, + child: SpeedAndFuel( + fuel: vehicle.fuelLevel, + speed: vehicle.speed), + ), + ], + ), + ), + SizedBox( + height: SizeConfig.safeBlockVertical * 6, + ), + Flexible( + flex: 5, + child: Container( + + + // color: Colors.red, + height: SizeConfig.screenHeight * 0.6, + width: SizeConfig.screenWidth * 0.53, + child: Stack( + children: [ + Positioned( + top: 0, + left: 0, + child: Column( + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + TierPressure( + tname: 'L Front Tire', + tpress: vehicle.frontLeftTP, + mainAxisAlignment: + MainAxisAlignment.end, + crossAxisAlignment: + CrossAxisAlignment.end, + ), + Container( + height: + SizeConfig.safeBlockVertical * 6, + width: + SizeConfig.safeBlockHorizontal * + 12, + child: CustomPaint( + painter: Arrowpaint2(), + ), + ), + ], + ), + ), + Positioned( + bottom: 0, + left: 0, + child: Column( + children: [ + ChildLockStatus( + isChildLockActiveLeft: + vehicle.isChildLockActiveLeft, + isChildLockActiveRight: + vehicle.isChildLockActiveRight), + RotatedBox( + quarterTurns: 2, + child: Container( + height: + SizeConfig.safeBlockVertical * + 6, + width: + SizeConfig.safeBlockHorizontal * + 12, + child: CustomPaint( + painter: Arrowpaint(), + ), + ), + ), + TierPressure( + tname: 'L Rear Tire', + tpress: vehicle.rearLeftTP, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.end, + ), + ], + ), + ), + Positioned( + top: 0, + bottom: 0, + left: SizeConfig.safeBlockHorizontal * 12, + right: SizeConfig.safeBlockHorizontal * 12, + child: SizedBox( + + child: AnimatedContainer( + duration: Duration(milliseconds: 10), + child: Image.asset( + 'images/car_img.png', + fit: BoxFit.fill, + ), + ), + ), + ), + Positioned( + right: 0, + top: 0, + child: Column( + children: [ + TierPressure( + tname: 'R Front Tire', + tpress: vehicle.frontRightTP, + mainAxisAlignment: + MainAxisAlignment.end, + crossAxisAlignment: + CrossAxisAlignment.start, + ), + Container( + height: + SizeConfig.safeBlockVertical * 6, + width: + SizeConfig.safeBlockHorizontal * + 12, + child: CustomPaint( + painter: Arrowpaint(), + ), + ), + ], + ), + ), + Positioned( + bottom: 0, + right: 0, + child: Column( + children: [ + ChildLockStatus( + isChildLockActiveLeft: + vehicle.isChildLockActiveLeft, + isChildLockActiveRight: + vehicle.isChildLockActiveRight), + RotatedBox( + quarterTurns: 2, + child: Container( + height: + SizeConfig.safeBlockVertical * + 6, + width: + SizeConfig.safeBlockHorizontal * + 12, + child: CustomPaint( + painter: Arrowpaint2(), + ), + ), + ), + TierPressure( + tname: 'R Rear Tire', + tpress: vehicle.rearRightTP, + mainAxisAlignment: + MainAxisAlignment.start, + crossAxisAlignment: + CrossAxisAlignment.start, + ), + ], + ), + ), + ], + ), + ), + ), + SizedBox( + height: SizeConfig.safeBlockVertical, + ), + Flexible( + flex: 1, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Flexible( + flex: 1, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + Text( + 'Avg. Fuel Consumtion', + style: SizeConfig.smallnormalfont2, + ), + Text( + vehicle.fuelRate.toString() + + ' KM/Litre', + style: SizeConfig.smallnormalfont, + ), + ], + ), + ), + Flexible(flex: 1, child: Rpm(rpm: vehicle.rpm)), + ], + ), + ), + + ], + ), + ), + ) + ], + ); + + } + }, + )); + } +} 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"; +} diff --git a/lib/Tier_pressure.dart b/lib/Tier_pressure.dart new file mode 100644 index 0000000..cb8ace5 --- /dev/null +++ b/lib/Tier_pressure.dart @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:dashboard_app/size.dart'; +import 'package:flutter/material.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; + + + +class TierPressure extends StatefulWidget { + String tname; + double tpress; + CrossAxisAlignment crossAxisAlignment; + MainAxisAlignment mainAxisAlignment; + TierPressure( + {Key? key, + required this.tname, + required this.tpress, + required this.crossAxisAlignment, + required this.mainAxisAlignment}) + : super(key: key); + + @override + State createState() => _TierPressureState(); +} + +class _TierPressureState extends State { + @override + Widget build(BuildContext context) { + return SizedBox( + height: SizeConfig.safeBlockVertical * 12, + width: SizeConfig.safeBlockHorizontal * 14, + child: Column( + mainAxisAlignment: widget.mainAxisAlignment, + + children: [ + Text( + '${widget.tname}', + style: SizeConfig.smallnormalfont2, + ), + Text( + widget.tpress.toString() + ' PSI', + style: SizeConfig.smallnormalfont, + ), + LinearPercentIndicator( + width: SizeConfig.safeBlockHorizontal * 11, + + progressColor: widget.tpress / 50 > 0.6 ? Colors.green : Colors.red, + lineHeight: SizeConfig.safeBlockVertical * 1.5, + alignment: MainAxisAlignment.center, + animateFromLastPercent: true, + animation: true, + percent: widget.tpress / 50, + + barRadius: Radius.circular(SizeConfig.fontsize / 4), + backgroundColor: Colors.grey, + ), + ], + ), + ); + } +} diff --git a/lib/config.dart b/lib/config.dart new file mode 100644 index 0000000..963f798 --- /dev/null +++ b/lib/config.dart @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'dart:io'; +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:yaml/yaml.dart'; + +import 'Kuksa-server/intial_connection.dart'; + +class GetConfig extends ConsumerStatefulWidget { + const GetConfig({Key? key, required this.client}) : super(key: key); + final HttpClient client; + + @override + ConsumerState createState() => _GetConfigState(); +} + +class _GetConfigState extends ConsumerState { + @override + void initState() { + super.initState(); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) { + final configStateProvider = ref.read(ConfigStateprovider.notifier); + + String configFilePath = '/etc/xdg/AGL/dashboard_config.yaml'; + + + + final configFile = File(configFilePath); + configFile.readAsString().then((content) { + final dynamic yamlMap = loadYaml(content); + configStateProvider.update( + hostname: yamlMap['hostname'], + port: yamlMap['port'], + kuksaAuthToken: yamlMap['kuskaAuthToken'], + ); + }); + }); + } + + @override + Widget build(BuildContext context) { + final config = ref.watch(ConfigStateprovider); + if (config.hostname == "" || + config.port == 0 || + config.kuksaAuthToken == "" + ) { + return Scaffold( + body: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: const [ + Text("ERROR", + style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), + Text( + "Something Wrong with config file! Check config.yaml file and restart"), + ], + )), + ); + } + return InitialScreen(client: widget.client); + } +} + +class Config { + Config({ + required this.hostname, + required this.port, + required this.kuksaAuthToken, + + }); + final String hostname; + final int port; + final String kuksaAuthToken; + + Config copywith({ + String? hostname, + int? port, + String? kuksaAuthToken, + }) => + Config( + hostname: hostname ?? this.hostname, + port: port ?? this.port, + kuksaAuthToken: kuksaAuthToken ?? this.kuksaAuthToken, + ); +} + +final ConfigStateprovider = +StateNotifierProvider( + (ref) => ConfigStateNotifier()); + +class ConfigStateNotifier extends StateNotifier { + ConfigStateNotifier() : super(_initialValue); + static final Config _initialValue = Config( + hostname: "", + port: 0, + kuksaAuthToken: "", + ); + void update({ + String? hostname, + int? port, + String? kuksaAuthToken, + }) { + state = state.copywith( + hostname: hostname, + port: port, + kuksaAuthToken: kuksaAuthToken, + ); + } +} + diff --git a/lib/drawArrow.dart b/lib/drawArrow.dart new file mode 100644 index 0000000..71b751f --- /dev/null +++ b/lib/drawArrow.dart @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class Arrowpaint extends CustomPainter{ + @override + void paint(Canvas canvas, Size size) { + var paint = Paint(); + var path = Path(); + paint.color = Colors.grey; + paint.style = PaintingStyle.stroke; + paint.strokeWidth = 1; + path.moveTo(0, size.height*0.8); + path.lineTo(size.width*0.8, size.height*0.8); + path.lineTo(size.width*0.8, size.height*0.2); + path.moveTo(size.width*0.75, size.height*0.25); + path.lineTo(size.width*0.8, size.height*0.15); + path.lineTo(size.width*0.85, size.height*0.25); + canvas.drawPath(path, paint); + // TODO: implement paint + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + // TODO: implement shouldRepaint + // throw UnimplementedError(); + return false; + } + +} +class Arrowpaint2 extends CustomPainter{ + @override + void paint(Canvas canvas, Size size) { + var paint = Paint(); + var path = Path(); + paint.color = Colors.grey; + paint.style = PaintingStyle.stroke; + paint.strokeWidth = 1; + path.moveTo(size.width, size.height*0.8); + path.lineTo(size.width*0.2, size.height*0.8); + path.lineTo(size.width*0.2, size.height*0.2); + path.moveTo(size.width*0.15, size.height*0.25); + path.lineTo(size.width*0.2, size.height*0.15); + path.lineTo(size.width*0.25, size.height*0.25); + canvas.drawPath(path, paint); + // TODO: implement paint + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + // TODO: implement shouldRepaint + // throw UnimplementedError(); + return false; + } + +} + +class simplearrow extends CustomPainter{ + @override + void paint(Canvas canvas, Size size) { + var paint = Paint(); + var path = Path(); + paint.color = Colors.grey; + paint.strokeWidth = 1; + paint.style = PaintingStyle.stroke; + path.moveTo(0, size.height*0.5); + path.lineTo(size.width*0.8, size.height*0.5); + path.moveTo(size.width*0.75, size.height*0.40); + path.lineTo(size.width*0.85, size.height*0.5); + path.lineTo(size.width*0.75, size.height*0.60); + canvas.drawPath(path, paint); + // TODO: implement paint + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + // TODO: implement shouldRepaint + return false; + } + +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..27ba557 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +import 'Kuksa-server/intial_connection.dart'; +import 'Kuksa-server/vehicle_config.dart'; +import 'config.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + HttpClient client = await initializeClient(); + + + runApp( + + ProviderScope( + child: MaterialApp( + debugShowCheckedModeBanner: false, + home: GetConfig(client: client), + ), + ), + ); +} + + diff --git a/lib/provider.dart b/lib/provider.dart new file mode 100644 index 0000000..4c9ed0a --- /dev/null +++ b/lib/provider.dart @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: Apache-2.0 + +import 'dart:async'; +import 'dart:math'; + +import 'package:flutter_riverpod/flutter_riverpod.dart'; + +final fuelProvider = StateNotifierProvider((ref) => + fuel(), +); + +class fuel extends StateNotifier{ + late Timer timer; + fuel() : super(0.2){ + + Timer.periodic(Duration(seconds: 5), (timer) { + double num = Random().nextInt(100).toDouble(); + update(num); + }); + } + void update(value){ + state = value; + } +} + +final DateTimeProvider = StateNotifierProvider((ref) => + datetime(), +); + +class datetime extends StateNotifier{ + datetime() : super(DateTime.now()){ + + Timer.periodic(Duration(seconds: 30), (timer) { + DateTime _now = DateTime.now(); + update(_now); + }); + } + void update(value){ + state = value; + } +} diff --git a/lib/size.dart b/lib/size.dart new file mode 100644 index 0000000..2bcbcd9 --- /dev/null +++ b/lib/size.dart @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; + +class SizeConfig { + static late MediaQueryData _mediaQueryData; + static late double screenWidth; + static late double screenHeight; + static late double blockSizeHorizontal; + static late double blockSizeVertical; + static late double _safeAreaHorizontal; + static late double _safeAreaVertical; + static late double safeBlockHorizontal; + static late double safeBlockVertical; + static late double fontsize; + static late TextStyle normalfont; + static late TextStyle smallnormalfont; + static late TextStyle smallnormalfont2; + + void init(BuildContext context) { + _mediaQueryData = MediaQuery.of(context); + screenWidth = _mediaQueryData.size.width; + screenHeight = _mediaQueryData.size.height; + blockSizeHorizontal = screenWidth / 100; + blockSizeVertical = screenHeight / 100; + _safeAreaHorizontal = + _mediaQueryData.padding.left + _mediaQueryData.padding.right; + _safeAreaVertical = + _mediaQueryData.padding.top + _mediaQueryData.padding.bottom; + safeBlockHorizontal = (screenWidth - _safeAreaHorizontal) / 100; + safeBlockVertical = (screenHeight - _safeAreaVertical) / 100; + fontsize = screenHeight * screenWidth * 0.01 * 0.01 * 0.3; + normalfont = TextStyle( + fontSize: fontsize * 0.8, + fontWeight: FontWeight.w700, + color: Colors.white, + ); + smallnormalfont = TextStyle( + fontSize: fontsize / 2, + fontWeight: FontWeight.w700, + color: Colors.white, + ); + smallnormalfont2 = TextStyle( + fontSize: fontsize * 0.4, + color: Colors.white, + ); + } +} diff --git a/lib/widgets/child_lock.dart b/lib/widgets/child_lock.dart new file mode 100644 index 0000000..c2efb0d --- /dev/null +++ b/lib/widgets/child_lock.dart @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:dashboard_app/size.dart'; +import 'package:flutter/src/foundation/key.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/material.dart'; + +class ChildLockStatus extends StatelessWidget { + bool isChildLockActiveLeft; + bool isChildLockActiveRight; + ChildLockStatus( + {Key? key, + required this.isChildLockActiveLeft, + required this.isChildLockActiveRight}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return isChildLockActiveLeft && isChildLockActiveRight + ? Column( + children: [ + Text( + "Child Lock", + style: TextStyle( + fontSize: SizeConfig.fontsize / 3, color: Colors.green), + ), + Text( + "Activated", + style: TextStyle( + fontSize: SizeConfig.fontsize / 3, color: Colors.green), + ), + SizedBox( + width: SizeConfig.safeBlockVertical / 2, + ), + Icon( + Icons.lock, + size: SizeConfig.fontsize / 3, + color: Colors.green, + ), + ], + ) + : Column( + children: [ + Text( + 'No child Lock', + style: TextStyle( + fontSize: SizeConfig.fontsize / 2, + color: Colors.redAccent, + ), + ), + SizedBox( + height: SizeConfig.safeBlockVertical / 2, + ), + Icon( + Icons.lock_open_outlined, + size: SizeConfig.fontsize / 4, + color: Colors.red, + ), + ], + ); + } +} diff --git a/lib/widgets/fuel_and_speed.dart b/lib/widgets/fuel_and_speed.dart new file mode 100644 index 0000000..2ee902e --- /dev/null +++ b/lib/widgets/fuel_and_speed.dart @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:dashboard_app/size.dart'; +import 'package:flutter/src/foundation/key.dart'; +import 'package:flutter/src/widgets/framework.dart'; +import 'package:flutter/material.dart'; +import 'package:percent_indicator/circular_percent_indicator.dart'; +import 'package:percent_indicator/linear_percent_indicator.dart'; + + + +class SpeedAndFuel extends StatelessWidget { + double fuel; + double speed; + SpeedAndFuel({Key? key, required this.fuel, required this.speed}) + : super(key: key); + + @override + Widget build(BuildContext context) { + double width = MediaQuery.of(context).size.width; + return SizedBox( + width: width * 0.4, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + CircularPercentIndicator( + radius: SizeConfig.fontsize * 1.6, + percent: fuel / 100, + lineWidth: SizeConfig.fontsize / 2, + + backgroundColor: Colors.lightBlue.shade100, + progressColor: fuel < 25 + ? Colors.redAccent + : fuel < 50 + ? Colors.orange + : Colors.green, + animation: true, + circularStrokeCap: CircularStrokeCap.round, + animateFromLastPercent: true, + center: Text( + fuel.toString() + ' %', + style: SizeConfig.smallnormalfont, + ), + footer: Text( + 'fuel', + style: SizeConfig.smallnormalfont2, + ), + ), + CircularPercentIndicator( + radius: SizeConfig.fontsize * 1.6, + percent: speed / 300, + lineWidth: SizeConfig.fontsize / 2, + backgroundColor: Color.fromARGB(255, 176, 213, 195), + progressColor: Colors.lightBlueAccent, + animation: true, + circularStrokeCap: CircularStrokeCap.round, + animateFromLastPercent: true, + center: Text( + speed.toString(), + style: SizeConfig.smallnormalfont, + ), + footer: Text( + 'Speed in KM/H', + style: SizeConfig.smallnormalfont2, + ), + ), + ], + ), + ); + } +} + +class Rpm extends StatelessWidget { + double rpm; + Rpm({Key? key, required this.rpm}) : super(key: key); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: SizeConfig.safeBlockVertical * 9, + width: SizeConfig.safeBlockHorizontal * 35, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "Engine Status", + style: SizeConfig.smallnormalfont2, + ), + LinearPercentIndicator( + backgroundColor: Colors.white70, + addAutomaticKeepAlive: true, + progressColor: Colors.lightBlueAccent, + animateFromLastPercent: true, + animation: true, + animationDuration: 500, + percent: rpm / 8000, + barRadius: Radius.circular(15), + leading: Text( + 'RPM', + style: SizeConfig.smallnormalfont, + ), + trailing: Text( + rpm.toString(), + style: SizeConfig.smallnormalfont2, + ), + ), + ], + ), + ); + } +} diff --git a/lib/widgets/weather.dart b/lib/widgets/weather.dart new file mode 100644 index 0000000..fe31c72 --- /dev/null +++ b/lib/widgets/weather.dart @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: Apache-2.0 +import 'package:dashboard_app/size.dart'; +import 'package:flutter/src/foundation/key.dart'; +import 'package:flutter/src/widgets/framework.dart'; + +import 'package:flutter/material.dart'; + +class weather extends StatelessWidget { + int insideTemperatue; + int outsideTempearure; + weather( + {Key? key, + required this.insideTemperatue, + required this.outsideTempearure}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(SizeConfig.safeBlockVertical * 2), + ), + height: SizeConfig.safeBlockVertical * 20, + width: SizeConfig.blockSizeHorizontal * 20, + child: Column( + mainAxisAlignment: MainAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Flexible( + flex: 1, + child: Text( + 'Weather', + style: SizeConfig.smallnormalfont, + textAlign: TextAlign.left, + )), + Flexible( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + height: SizeConfig.safeBlockVertical * 5, + width: SizeConfig.blockSizeHorizontal * 5, + child: Image.asset( + 'images/thermostate.png', + color: Colors.orangeAccent, + )), + SizedBox( + height: SizeConfig.safeBlockVertical, + ), + Row( + children: [ + Column( + children: [ + Text(insideTemperatue.toString() + ' \u00B0', + style: SizeConfig.normalfont), + Text('Inside', style: SizeConfig.smallnormalfont2), + ], + ), + SizedBox( + width: SizeConfig.safeBlockHorizontal, + ), + Column( + children: [ + Text( + outsideTempearure.toString() + ' \u00B0', + style: SizeConfig.normalfont, + ), + Text( + 'Outside', + style: SizeConfig.smallnormalfont2, + ), + ], + ) + ], + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..0d40344 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,93 @@ +name: dashboard_app +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.16.2 <3.0.0" + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +dependencies: + flutter: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.2 + flutter_riverpod: ^1.0.3 + percent_indicator: ^4.2.1 + latlng: ^0.2.0 + http: ^0.13.4 + yaml: ^3.1.1 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # activated in the `analysis_options.yaml` file located at the root of your + # package. See that file for information about deactivating specific lint + # rules and activating additional ones. + flutter_lints: ^1.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - images/ + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages -- cgit 1.2.3-korg