summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsuchinton2001 <suchinton.2001@gmail.com>2023-10-09 16:00:58 +0530
committersuchinton2001 <suchinton.2001@gmail.com>2023-10-09 16:00:58 +0530
commitdb862e32df7f31e6453d7f05a6f011091b96ffab (patch)
tree6abcc3a2eceb79a43b7836d1d23a8594da375826
parent260bbf89836ff9ce98054e5166699a163a0d7c11 (diff)
agl-demo-control-panel: Add grpc support for databroker
- Add grpc support for databroker (set default protocol) - Add virtual car for script mode in IC app - Refine UI elements - Use specific grpc/ws jwt tokens - Simplify settings menu Bug-AGL: SPEC-4905 Signed-off-by: suchinton2001 <suchinton.2001@gmail.com> Change-Id: I59c4b1de80e280fe22993b2d2f7c92d6b41a89c7
-rw-r--r--Widgets/ICPage.py373
-rw-r--r--Widgets/SteeringCtrlPage.py206
-rw-r--r--Widgets/settings.py137
-rw-r--r--extras/FeedCAN.py10
-rw-r--r--extras/FeedKuksa.py6
-rw-r--r--extras/Kuksa_Instance.py41
-rw-r--r--extras/config.py12
-rw-r--r--ui/Dashboard.ui35
-rw-r--r--ui/Settings_Window.ui586
9 files changed, 813 insertions, 593 deletions
diff --git a/Widgets/ICPage.py b/Widgets/ICPage.py
index 64fa2d3..2d11cdf 100644
--- a/Widgets/ICPage.py
+++ b/Widgets/ICPage.py
@@ -18,10 +18,12 @@ import os
import sys
from PyQt5 import uic, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication
-from PyQt5.QtWidgets import QSlider, QLCDNumber, QPushButton
from PyQt5.QtGui import QIcon, QPixmap, QPainter
+from PyQt5.QtCore import QObject, pyqtSignal
import time
-from PyQt5.QtCore import QThread
+from PyQt5.QtWidgets import QWidget
+from qtwidgets import AnimatedToggle
+import threading
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -49,35 +51,40 @@ class IC_Paths():
class ICWidget(Base, Form):
+ """
+ This class represents the ICWidget which is a widget for the AGL Demo Control Panel.
+ It inherits from the Base and Form classes.
+ """
+
def __init__(self, parent=None):
+ """
+ Initializes the ICWidget object.
+
+ Args:
+ - parent: The parent widget. Defaults to None.
+ """
super(self.__class__, self).__init__(parent)
self.setupUi(self)
self.IC = IC_Paths()
+ #self.vehicle_simulator = VehicleSimulator(self)
self.feed_kuksa = FeedKuksa()
self.feed_kuksa.start()
+ self.vehicle_simulator = VehicleSimulator()
- # # load the stylesheet
- # theme = open(os.path.join(current_dir, "../ui/styles/Tron/ICPage.qss"), 'r')
- # self.setStyleSheet(theme.read())
- # theme.close()
-
- self.scriptBtn = self.findChild(QPushButton, "scriptBtn")
+ header_frame = self.findChild(QWidget, "header_frame")
+ layout = header_frame.layout()
- self.Speed_slider = self.findChild(QSlider, "Speed_slider")
- self.Speed_monitor = self.findChild(QLCDNumber, "Speed_monitor")
- self.RPM_slider = self.findChild(QSlider, "RPM_slider")
- self.RPM_monitor = self.findChild(QLCDNumber, "RPM_monitor")
+ self.IC_Frame = self.findChild(QWidget, "frame_1")
- self.coolantTemp_slider = self.findChild(QSlider, "coolantTemp_slider")
- self.fuelLevel_slider = self.findChild(QSlider, "fuelLevel_slider")
+ self.Script_toggle = AnimatedToggle(
+ checked_color="#4BD7D6",
+ pulse_checked_color="#00ffff"
+ )
- self.accelerationBtn = self.findChild(QPushButton, "accelerationBtn")
-
- self.leftIndicatorBtn = self.findChild(QPushButton, "leftIndicatorBtn")
- self.rightIndicatorBtn = self.findChild(QPushButton, "rightIndicatorBtn")
- self.hazardBtn = self.findChild(QPushButton, "hazardBtn")
+ layout.replaceWidget(self.demoToggle, self.Script_toggle)
+ self.demoToggle.deleteLater()
buttons = [self.parkBtn,
self.reverseBtn,
@@ -85,6 +92,10 @@ class ICWidget(Base, Form):
self.driveBtn]
# group for the buttons for mutual exclusion
+
+ self.vehicle_simulator.speed_changed.connect(self.set_Vehicle_Speed)
+ self.vehicle_simulator.rpm_changed.connect(self.set_Vehicle_RPM)
+
self.driveGroupBtns = QtWidgets.QButtonGroup(self)
self.driveGroupBtns.setExclusive(True)
@@ -93,8 +104,6 @@ class ICWidget(Base, Form):
self.driveGroupBtns.buttonClicked.connect(self.driveBtnClicked)
- self.scriptBtn.clicked.connect(self.scriptBtnClicked)
-
self.Speed_slider.valueChanged.connect(self.update_Speed_monitor)
self.Speed_slider.setMinimum(0)
self.Speed_slider.setMaximum(240)
@@ -112,107 +121,136 @@ class ICWidget(Base, Form):
self.accelerationBtn.released.connect(self.accelerationBtnReleased)
# make both buttons checkable
+ self.Script_toggle.clicked.connect(self.handle_Script_toggle)
self.leftIndicatorBtn.setCheckable(True)
self.rightIndicatorBtn.setCheckable(True)
self.hazardBtn.setCheckable(True)
- self.leftIndicatorBtn.clicked.connect(self.leftIndicatorBtnClicked)
- self.rightIndicatorBtn.clicked.connect(self.rightIndicatorBtnClicked)
- self.hazardBtn.clicked.connect(self.hazardBtnClicked)
+ self.leftIndicatorBtn.toggled.connect(self.leftIndicatorBtnClicked)
+ self.rightIndicatorBtn.toggled.connect(self.rightIndicatorBtnClicked)
+ self.hazardBtn.toggled.connect(self.hazardBtnClicked)
- def scriptBtnClicked(self):
- if self.scriptBtn.isChecked():
- ICScript.start_script()
+ def set_Vehicle_Speed(self, speed):
+ self.Speed_slider.setValue(speed)
- if not self.ScriptBtn.isChecked():
- ICScript.stop_script()
+ def set_Vehicle_RPM(self, rpm):
+ self.RPM_slider.setValue(rpm)
def update_Speed_monitor(self):
+ """
+ Updates the speed monitor with the current speed value.
+ """
speed = int(self.Speed_slider.value())
self.Speed_monitor.display(speed)
- self.feed_kuksa.send_values(self.IC.speed, str(speed), 'value')
+ try: self.feed_kuksa.send_values(self.IC.speed, str(speed), 'value')
+ except Exception as e: print(e)
def update_RPM_monitor(self):
+ """
+ Updates the RPM monitor with the current RPM value.
+ """
rpm = int(self.RPM_slider.value())
self.RPM_monitor.display(rpm)
- self.feed_kuksa.send_values(self.IC.engineRPM, str(rpm), 'value')
+ try: self.feed_kuksa.send_values(self.IC.engineRPM, str(rpm), 'value')
+ except Exception as e: print(e)
def update_coolantTemp_monitor(self):
+ """
+ Updates the coolant temperature monitor with the current coolant temperature value.
+ """
coolantTemp = int(self.coolantTemp_slider.value())
- self.feed_kuksa.send_values(self.IC.coolantTemp, str(coolantTemp), 'value')
+ try: self.feed_kuksa.send_values(self.IC.coolantTemp, str(coolantTemp), 'value')
+ except Exception as e: print(e)
def update_fuelLevel_monitor(self):
+ """
+ Updates the fuel level monitor with the current fuel level value.
+ """
fuelLevel = int(self.fuelLevel_slider.value())
- self.feed_kuksa.send_values(self.IC.fuelLevel, str(fuelLevel))
+ try: self.feed_kuksa.send_values(self.IC.fuelLevel, str(fuelLevel))
+ except Exception as e: print(e)
def hazardBtnClicked(self):
+ """
+ Handles the hazard button click event.
+ """
hazardIcon = QPixmap(":/Images/Images/hazard.png")
+ painter = QPainter(hazardIcon)
+ painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
+
if self.hazardBtn.isChecked():
- painter = QPainter(hazardIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter.fillRect(hazardIcon.rect(), QtCore.Qt.yellow)
- painter.end()
- self.hazardBtn.setIcon(QIcon(hazardIcon))
-
- self.leftIndicatorBtn.setChecked(True)
- self.rightIndicatorBtn.setChecked(True)
- self.feed_kuksa.send_values(self.IC.leftIndicator, "true")
- self.feed_kuksa.send_values(self.IC.rightIndicator, "true")
- self.feed_kuksa.send_values(self.IC.hazard, "true")
+ color = QtCore.Qt.yellow
+ value = "true"
else:
- painter = QPainter(hazardIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter.fillRect(hazardIcon.rect(), QtCore.Qt.black)
- painter.end()
- self.hazardBtn.setIcon(QIcon(hazardIcon))
-
- self.leftIndicatorBtn.setChecked(False)
- self.rightIndicatorBtn.setChecked(False)
- self.feed_kuksa.send_values(self.IC.leftIndicator, "false")
- self.feed_kuksa.send_values(self.IC.rightIndicator, "false")
- self.feed_kuksa.send_values(self.IC.hazard, "false")
+ color = QtCore.Qt.black
+ value = "false"
+
+ painter.fillRect(hazardIcon.rect(), color)
+ painter.end()
+ self.hazardBtn.setIcon(QIcon(hazardIcon))
+
+ self.leftIndicatorBtn.setChecked(self.hazardBtn.isChecked())
+ self.rightIndicatorBtn.setChecked(self.hazardBtn.isChecked())
+
+ try:
+ self.feed_kuksa.send_values(self.IC.leftIndicator, value)
+ self.feed_kuksa.send_values(self.IC.rightIndicator, value)
+ self.feed_kuksa.send_values(self.IC.hazard, value)
+ except Exception as e:
+ print(e)
+
def leftIndicatorBtnClicked(self):
+ """
+ Handles the left indicator button click event.
+ """
leftIndicatorIcon = QPixmap(":/Images/Images/left.png")
- if self.leftIndicatorBtn.isChecked():
+ painter = QPainter(leftIndicatorIcon)
+ painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter = QPainter(leftIndicatorIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter.fillRect(leftIndicatorIcon.rect(), QtCore.Qt.green)
- painter.end()
-
- self.leftIndicatorBtn.setIcon(QIcon(leftIndicatorIcon))
- self.feed_kuksa.send_values(self.IC.leftIndicator, "true")
+ if self.leftIndicatorBtn.isChecked():
+ color = QtCore.Qt.green
+ value = "true"
else:
+ color = QtCore.Qt.black
+ value = "false"
- painter = QPainter(leftIndicatorIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter.fillRect(leftIndicatorIcon.rect(), QtCore.Qt.black)
- painter.end()
+ painter.fillRect(leftIndicatorIcon.rect(), color)
+ painter.end()
+ self.leftIndicatorBtn.setIcon(QIcon(leftIndicatorIcon))
- self.leftIndicatorBtn.setIcon(QIcon(leftIndicatorIcon))
- self.feed_kuksa.send_values(self.IC.leftIndicator, "false")
+ try: self.feed_kuksa.send_values(self.IC.leftIndicator, value)
+ except Exception as e: print(e)
def rightIndicatorBtnClicked(self):
+ """
+ Handles the right indicator button click event.
+ """
rightIndicatorIcon = QPixmap(":/Images/Images/right.png")
- if self.rightIndicatorBtn.isChecked():
+ painter = QPainter(rightIndicatorIcon)
+ painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter = QPainter(rightIndicatorIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter.fillRect(rightIndicatorIcon.rect(), QtCore.Qt.green)
- painter.end()
- self.rightIndicatorBtn.setIcon(QIcon(rightIndicatorIcon))
- self.feed_kuksa.send_values(self.IC.rightIndicator, "true")
+ if self.rightIndicatorBtn.isChecked():
+ color = QtCore.Qt.green
+ value = "true"
else:
+ color = QtCore.Qt.black
+ value = "false"
+
+ painter.fillRect(rightIndicatorIcon.rect(), color)
+ painter.end()
+ self.rightIndicatorBtn.setIcon(QIcon(rightIndicatorIcon))
+
+ try:
+ self.feed_kuksa.send_values(self.IC.rightIndicator, value)
+ except Exception as e:
+ print(e)
- painter = QPainter(rightIndicatorIcon)
- painter.setCompositionMode(QPainter.CompositionMode_SourceIn)
- painter.fillRect(rightIndicatorIcon.rect(), QtCore.Qt.black)
- painter.end()
- self.rightIndicatorBtn.setIcon(QIcon(rightIndicatorIcon))
- self.feed_kuksa.send_values(self.IC.rightIndicator, "false")
def accelerationBtnPressed(self):
+ """
+ Handles the acceleration button press event.
+ """
self.startTime = QtCore.QTime.currentTime()
self.acceleration_timer = QtCore.QTimer()
self.acceleration_timer.timeout.connect(
@@ -227,6 +265,14 @@ class ICWidget(Base, Form):
lambda: self.updateSpeedAndEngineRpm("Decelerate"))
self.acceleration_timer.start(100)
+ def handle_Script_toggle(self):
+ if self.Script_toggle.isChecked():
+ self.set_Vehicle_RPM(1000)
+ self.set_Vehicle_Speed(0)
+ self.vehicle_simulator.start()
+ else:
+ self.vehicle_simulator.stop()
+
def updateSpeedAndEngineRpm(self, action, acceleration=(60/5)):
if action == "Accelerate":
pass
@@ -257,33 +303,26 @@ class ICWidget(Base, Form):
self.update_RPM_monitor()
def driveBtnClicked(self):
- # // Selected Gear output = > 0 = Neutral, 1/2/.. = Forward, -1/.. = Reverse, 126 = Park, 127 = Drive
- # #859287 ; /* light green */
-
- if self.driveGroupBtns.checkedButton() == self.driveBtn:
+ gear_mapping = {
+ self.driveBtn: "127",
+ self.parkBtn: "126",
+ self.reverseBtn: "-1",
+ self.neutralBtn: "0"
+ }
+
+ checked_button = self.driveGroupBtns.checkedButton()
+
+ if checked_button in gear_mapping:
+ gear_value = gear_mapping[checked_button]
self.accelerationBtn.setEnabled(True)
- self.Speed_slider.setEnabled(True)
- self.RPM_slider.setEnabled(True)
- self.feed_kuksa.send_values(self.IC.selectedGear, "127")
-
- if self.driveGroupBtns.checkedButton() == self.parkBtn:
- self.accelerationBtn.setEnabled(False)
- self.Speed_slider.setEnabled(False)
- self.RPM_slider.setEnabled(False)
- self.feed_kuksa.send_values(self.IC.selectedGear, "126")
-
- if self.driveGroupBtns.checkedButton() == self.reverseBtn:
- self.accelerationBtn.setEnabled(True)
- self.Speed_slider.setEnabled(True)
- self.RPM_slider.setEnabled(True)
- self.feed_kuksa.send_values(self.IC.selectedGear, "-1")
-
- if self.driveGroupBtns.checkedButton() == self.neutralBtn:
- self.accelerationBtn.setEnabled(False)
- self.Speed_slider.setEnabled(False)
+ self.Speed_slider.setEnabled(checked_button != self.neutralBtn)
self.RPM_slider.setEnabled(True)
- self.feed_kuksa.send_values(self.IC.selectedGear, "0")
-
+ try:
+ self.feed_kuksa.send_values(self.IC.selectedGear, gear_value)
+ except Exception as e:
+ print(e)
+ else:
+ print("Unknown button checked!")
class AccelerationFns():
def calculate_speed(time, acceleration) -> int:
@@ -314,37 +353,105 @@ class AccelerationFns():
engine_rpm = wheel_rps * gear_ratios[current_gear - 1] * 60
return int(engine_rpm)
+
+class VehicleSimulator(QObject):
+ # Define signals for updating speed and rpm
+ speed_changed = pyqtSignal(int)
+ rpm_changed = pyqtSignal(int)
+ DEFAULT_IDLE_RPM = 1000
-class ICScript(ICWidget):
- def start_script(self):
- ICWidget.reset()
-
- # disable all widgets in the scroll area
- for widget in ICWidget.scrollAreaWidgetContents.children():
- widget.setEnabled(False)
-
- rates = [(60/5), (60/4), (60/3)]
+ def __init__(self):
+ super().__init__()
+ self.freq = 10
+ self.vehicle_speed = 0
+ self.engine_speed = self.DEFAULT_IDLE_RPM
+ self.running = False
+ self.lock = threading.Lock()
+ self.thread = threading.Thread(target=self.run, daemon=True)
+
+ def start(self):
+ if not self.running:
+ self.reset()
+ self.running = True
+ self.thread.start()
+
+ def stop(self):
+ self.running = False
+
+ def reset(self):
+ with self.lock:
+ self.vehicle_speed = 0
+ self.engine_speed = self.DEFAULT_IDLE_RPM
+
+ def run(self):
+ while self.running:
+ if not self.running:
+ break
- # start assigning values to the speed and rpm sliders and send them to the IC do this in a loop for each rate
- for rate in rates:
- ICWidget.accelerationBtnPressed()
- ICWidget.acceleration_timer.timeout.connect(
- lambda: ICWidget.updateSpeedAndEngineRpm("Accelerate"), rate)
- ICWidget.acceleration_timer.start(100)
- time.sleep(5)
- ICWidget.accelerationBtnReleased()
- ICWidget.acceleration_timer.timeout.connect(
- lambda: ICWidget.updateSpeedAndEngineRpm("Decelerate"), rate)
- ICWidget.acceleration_timer.start(100)
+ # Simulate acceleration and update speed and rpm
+ self.accelerate(60, 1800, 3)
+ self.accelerate(65, 1700, 1)
+ self.accelerate(80, 2500, 6)
+ self.accelerate(100, 3000, 4)
+ self.brake(80, 3000, 3)
+ self.accelerate(104, 4000, 6)
+ self.brake(40, 2000, 4)
+ self.accelerate(90, 3000, 5)
+ self.brake(1, 650, 5)
+
+ # Ensure reset is called when not in cruise mode
+ if not self.running:
+ self.reset()
+
time.sleep(5)
- def stop_script(self):
- ICWidget.reset()
-
- # enable all widgets in the scroll area
- for widget in ICWidget.scrollAreaWidgetContents.children():
- widget.setEnabled(True)
+ def accelerate(self, target_speed, target_rpm, duration):
+ if target_speed <= self.vehicle_speed:
+ return
+ v = (target_speed - self.vehicle_speed) / (duration * self.freq)
+ r = (target_rpm - self.engine_speed) / (duration * self.freq)
+ while self.vehicle_speed < target_speed and self.running:
+ with self.lock:
+ self.vehicle_speed += v
+ self.engine_speed += r
+ self.speed_changed.emit(int(self.vehicle_speed))
+ self.rpm_changed.emit(int(self.engine_speed))
+ time.sleep(1 / self.freq)
+
+ def brake(self, target_speed, target_rpm, duration):
+ if target_speed >= self.vehicle_speed:
+ return
+ v = (self.vehicle_speed - target_speed) / (duration * self.freq)
+ r = (self.engine_speed - target_rpm) / (duration * self.freq)
+ while self.vehicle_speed > target_speed and self.running:
+ with self.lock:
+ self.vehicle_speed -= v
+ self.engine_speed -= r
+ self.speed_changed.emit(int(self.vehicle_speed))
+ self.rpm_changed.emit(int(self.engine_speed))
+ time.sleep(1 / self.freq)
+
+ def increase(self, bycruise = True):
+ if self.CRUISEACTIVE:
+ target_speed = self.vehicle_speed + 5
+ target_rpm = self.engine_speed * 1.1
+ self.accelerate(target_speed, target_rpm, 2, bycruise)
+
+ def decrease(self, bycruise = True):
+ if self.CRUISEACTIVE:
+ target_speed = self.vehicle_speed - 5
+ target_rpm = self.engine_speed * 0.9
+ self.brake(target_speed, target_rpm, 2, bycruise)
+
+ def resume(self, bycruise = True):
+ target_speed = self.CRUISESPEED
+ target_rpm = self.CRUISERPM
+ current_speed = self.get_vehicle_speed()
+ if target_speed > current_speed:
+ self.accelerate(target_speed, target_rpm, 2, bycruise)
+ else:
+ self.brake(target_speed, target_rpm, 2, bycruise)
if __name__ == '__main__':
app = QApplication(sys.argv)
diff --git a/Widgets/SteeringCtrlPage.py b/Widgets/SteeringCtrlPage.py
index 61271c2..696c6c9 100644
--- a/Widgets/SteeringCtrlPage.py
+++ b/Widgets/SteeringCtrlPage.py
@@ -28,7 +28,9 @@ current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(current_dir))
-import extras.Kuksa_Instance as kuksa_instance
+from extras.FeedKuksa import FeedKuksa
+import extras.FeedCAN as feed_can
+from . import settings
Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/SteeringControls.ui"))
@@ -36,31 +38,62 @@ Form, Base = uic.loadUiType(os.path.join(current_dir, "../ui/SteeringControls.ui
class Steering_Paths():
def __init__(self):
- self.VolumeUp = "Vehicle.Cabin.SteeringWheel.Switches.VolumeUp"
- self.VolumeDown = "Vehicle.Cabin.SteeringWheel.Switches.VolumeDown"
- self.VolumeMute = "Vehicle.Cabin.SteeringWheel.Switches.VolumeMute"
-
- self.Mode = "Vehicle.Cabin.SteeringWheel.Switches.Mode"
-
- self.NextTrack = "Vehicle.Cabin.SteeringWheel.Switches.Next"
- self.PreviousTrack = "Vehicle.Cabin.SteeringWheel.Switches.Previous"
-
- self.Info = "Vehicle.Cabin.SteeringWheel.Switches.Info"
-
- self.PhoneCall = "Vehicle.Cabin.SteeringWheel.Switches.PhoneCall"
- self.PhoneHangup = "Vehicle.Cabin.SteeringWheel.Switches.PhoneHangup"
- self.Voice = "Vehicle.Cabin.SteeringWheel.Switches.Voice"
- self.LaneDeparture = "Vehicle.Cabin.SteeringWheel.Switches.LaneDepartureWarning"
-
- self.Horn = "Vehicle.Cabin.SteeringWheel.Switches.Horn"
-
- self.CruiseEnable = "Vehicle.Cabin.SteeringWheel.Switches.CruiseEnable"
- self.CruseSet = "Vehicle.Cabin.SteeringWheel.Switches.CruiseSet"
- self.CruiseResume = "Vehicle.Cabin.SteeringWheel.Switches.CruiseResume"
- self.CruiseCancel = "Vehicle.Cabin.SteeringWheel.Switches.CruiseCancel"
-
- self.CruiseLimit = "Vehicle.Cabin.SteeringWheel.Switches.CruiseLimit"
- self.CruiseDistance = "Vehicle.Cabin.SteeringWheel.Switches.CruiseDistance"
+ self.switches = {
+ "VolumeUp": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.VolumeUp",
+ "CAN": "021#FFFFFFFF40000000"},
+ "VolumeDown": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.VolumeDown",
+ "CAN": "021#FFFFFFFF10000000"},
+ "VolumeMute": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.VolumeMute",
+ "CAN": "021#FFFFFFFF01000000"},
+ "Mode": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.Mode",
+ "CAN": "021#FFFFFFFF20000000"},
+ "NextTrack": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.Next",
+ "CAN": "021#FFFFFFFF08000000"},
+ "PreviousTrack": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.Previous",
+ "CAN": "021#FFFFFFFF80000000"},
+ "Info": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.Info",
+ "CAN": "021#FFFFFFFF02000000"},
+ "PhoneCall": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.PhoneCall",
+ "CAN": "021#FFFFFFFF00010000"},
+ "PhoneHangup": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.PhoneHangup",
+ "CAN": "021#FFFFFFFF00020000"},
+ "Voice": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.Voice",
+ "CAN": "021#FFFFFFFF00040000"},
+ "LaneDeparture": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.LaneDepartureWarning",
+ "CAN": "021#FFFFFFFF00000001"},
+ "Horn": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.Horn",
+ "CAN": "021#FFFFFFFF00000080"},
+ "CruiseEnable": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.CruiseEnable",
+ "CAN": "021#FFFFFFFF00008000"},
+ "CruiseSet": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.CruiseSet",
+ "CAN": "021#FFFFFFFF00001000"},
+ "CruiseResume": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.CruiseResume",
+ "CAN": "021#FFFFFFFF00004000"},
+ "CruiseCancel": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.CruiseCancel",
+ "CAN": "021#FFFFFFFF00000800"},
+ "CruiseLimit": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.CruiseLimit",
+ "CAN": "021#FFFFFFFF00000200"},
+ "CruiseDistance": {
+ "Kuksa": "Vehicle.Cabin.SteeringWheel.Switches.CruiseDistance",
+ "CAN": "021#FFFFFFFF00000100"}
+ }
class SteeringCtrlWidget(Base, Form):
def __init__(self, parent=None):
@@ -69,94 +102,49 @@ class SteeringCtrlWidget(Base, Form):
self.Steering = Steering_Paths()
self.feed_kuksa = FeedKuksa()
+ self.settings = settings
+
self.add_buttons()
def add_buttons(self):
# Define button groups and actions
- LeftControlsBtns = [self.VolUpBtn,
- self.VolDownBtn,
- self.ModeBtn,
- self.VolMuteBtn,
- self.NextTrackBtn,
- self.PrevTrackBtn,
- self.InfoBtn]
-
-
- PhoneBtns = [self.PhoneCallBtn, self.PhoneHangupBtn]
- ExtraContolsBtns = [self.VoiceBtn, self.LaneDepartureBtn]
-
- RightControlsBtns = [self.CruiseEnableBtn,
- self.CruiseSetBtn,
- self.CruiseResumeBtn,
- self.CruiseCancelBtn,
- self.CruiseLimitBtn,
- self.CruiseDistanceBtn]
-
- self.LeftControlsBtnsGroup = QButtonGroup()
- self.PhoneBtnsGroup = QButtonGroup()
- self.ExtraContolsBtnsGroup = QButtonGroup()
- self.RiqhtControlsBtnsGroup = QButtonGroup()
-
- for btn in LeftControlsBtns:
- self.LeftControlsBtnsGroup.addButton(btn)
-
- for btn in PhoneBtns:
- self.PhoneBtnsGroup.addButton(btn)
-
-
- for btn in RightControlsBtns:
- self.RiqhtControlsBtnsGroup.addButton(btn)
-
- self.LeftControlsBtnsGroup.buttonClicked.connect(self.left_controls_clicked)
- self.RiqhtControlsBtnsGroup.buttonClicked.connect(self.right_controls_clicked)
-
- self.HornBtn.clicked.connect(self.horn_clicked)
-
- def left_controls_clicked(self):
- print("Left controls clicked")
-
- def right_controls_clicked(self):
- print("Right controls clicked")
-
- def horn_clicked(self):
- print("Horn clicked")
-
-class FeedKuksa(QThread):
- def __init__(self, parent=None):
- QThread.__init__(self,parent)
- self.stop_flag = False
- self.set_instance()
-
- def run(self):
- print("Starting thread")
- self.set_instance()
- while not self.stop_flag:
- self.send_values()
-
- def stop(self):
- self.stop_flag = True
- print("Stopping thread")
-
- def set_instance(self):
- self.kuksa = kuksa_instance.KuksaClientSingleton.get_instance()
- self.client = self.kuksa.get_client()
-
- def send_values(self, Path=None, Value=None, Attribute=None):
- if self.client is not None:
- if self.client.checkConnection() is True:
-
- if Attribute is not None:
- self.client.setValue(Path, Value, Attribute)
- else:
- self.client.setValue(Path, Value)
- else:
- print("Could not connect to Kuksa")
- self.set_instance()
- else:
- print("Kuksa client is None, try reconnecting")
- time.sleep(2)
- self.set_instance()
+ ControlsBtns = [self.VolumeUp,
+ self.VolumeDown,
+ self.Mode,
+ self.VolumeMute,
+ self.NextTrack,
+ self.PreviousTrack,
+ self.Info,
+ self.PhoneCall,
+ self.PhoneHangup,
+ self.Voice,
+ self.LaneDeparture,
+ self.CruiseEnable,
+ self.CruiseSet,
+ self.CruiseResume,
+ self.CruiseCancel,
+ self.CruiseLimit,
+ self.CruiseDistance]
+
+ self.ControlsBtnsGroup = QButtonGroup()
+
+ for btn in ControlsBtns:
+ self.ControlsBtnsGroup.addButton(btn)
+
+ self.ControlsBtnsGroup.buttonClicked.connect(self.controls_clicked)
+
+ def controls_clicked(self, button):
+ button_clicked = button.objectName()
+ signal_type = settings.Steering_Signal_Type
+ if signal_type == "Kuksa":
+ self.feed_kuksa.send_values(self.Steering.switches[button_clicked]["Kuksa"], 1)
+ self.feed_kuksa.send_values(self.Steering.switches[button_clicked]["Kuksa"], 0)
+ elif signal_type == "CAN":
+ feed_can.send_can_signal(self.Steering.switches[button_clicked]["CAN"])
+ # Making sure button state goes back to off
+ feed_can.send_can_signal("021#FFFFFFFF00000000")
+ print(button_clicked + " button clicked")
if __name__ == '__main__':
import sys
diff --git a/Widgets/settings.py b/Widgets/settings.py
index 11800a2..17ea7f6 100644
--- a/Widgets/settings.py
+++ b/Widgets/settings.py
@@ -12,12 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import extras.Kuksa_Instance as kuksa_instance
+
import os
import sys
import time
from PyQt5 import uic
-from PyQt5.QtWidgets import QApplication, QLineEdit, QPushButton, QLabel, QCheckBox
+from PyQt5.QtWidgets import QApplication, QLineEdit, QPushButton, QLabel
+from qtwidgets import AnimatedToggle
+from PyQt5.QtWidgets import QWidget
+from PyQt5.QtCore import QThread
+from PyQt5 import QtGui
+import logging
current_dir = os.path.dirname(os.path.abspath(__file__))
@@ -25,47 +30,115 @@ current_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.dirname(current_dir))
+import extras.Kuksa_Instance as kuksa_instance
Form, Base = uic.loadUiType(os.path.join(
current_dir, "../ui/Settings_Window.ui"))
# ========================================
+Steering_Signal_Type = "Kuksa"
class settings(Base, Form):
+ """
+ A class representing the settings widget of the AGL Demo Control Panel.
+
+ Attributes:
+ - SSL_toggle: An AnimatedToggle object representing the SSL toggle button.
+ - CAN_Kuksa_toggle: An AnimatedToggle object representing the CAN/Kuksa toggle button.
+ - connectionStatus: A QLabel object representing the connection status label.
+ - connectionLogo: A QLabel object representing the connection logo label.
+ - IPAddrInput: A QLineEdit object representing the IP address input field.
+ - reconnectBtn: A QPushButton object representing the reconnect button.
+ - refreshBtn: A QPushButton object representing the refresh button.
+ - startClientBtn: A QPushButton object representing the start client button.
+ """
+
def __init__(self, parent=None):
+ """
+ Initializes the settings widget of the AGL Demo Control Panel.
+ """
super(self.__class__, self).__init__(parent)
self.setupUi(self)
- self.SSLToggle = self.findChild(QCheckBox, "SSLToggle")
+ self.SSL_toggle = AnimatedToggle(
+ checked_color="#4BD7D6",
+ pulse_checked_color="#00ffff",
+ )
+
+ self.Protocol_toggle = AnimatedToggle(
+ checked_color="#4BD7D6",
+ pulse_checked_color="#00ffff"
+ )
+
+ self.CAN_Kuksa_toggle = AnimatedToggle(
+ checked_color="#4BD7D6",
+ pulse_checked_color="#00ffff"
+ )
self.connectionStatus = self.findChild(QLabel, "connectionStatus")
self.connectionLogo = self.findChild(QLabel, "connectionLogo")
self.IPAddrInput = self.findChild(QLineEdit, "IPAddrInput")
- self.tokenPathInput = self.findChild(QLineEdit, "tokenPathInput")
self.reconnectBtn = self.findChild(QPushButton, "reconnectBtn")
- self.refreshBtn = self.findChild(QPushButton, "refreshBtn")
self.startClientBtn = self.findChild(QPushButton, "startClientBtn")
self.startClientBtn.clicked.connect(self.set_instance)
self.reconnectBtn.clicked.connect(self.reconnectClient)
- self.refreshBtn.clicked.connect(self.refreshStatus)
+ self.SSL_toggle.clicked.connect(self.toggleSSL)
+ self.CAN_Kuksa_toggle.clicked.connect(self.toggle_CAN_Kuksa)
+
+ Frame_GS = self.findChild(QWidget, "frame_general_settings")
+ Frame_PS = self.findChild(QWidget, "frame_page_settings")
+ GS_layout = Frame_GS.layout()
+ PS_layout = Frame_PS.layout()
+
+ GS_layout.replaceWidget(self.place_holder_toggle_1, self.SSL_toggle)
+ GS_layout.replaceWidget(self.place_holder_toggle_2, self.Protocol_toggle)
+ PS_layout.replaceWidget(self.place_holder_toggle_3, self.CAN_Kuksa_toggle)
+
+ self.place_holder_toggle_1.deleteLater()
+ self.place_holder_toggle_2.deleteLater()
+ self.place_holder_toggle_3.deleteLater()
self.refreshStatus()
- self.show()
+
+ def toggleSSL(self):
+ """
+ Toggles the SSL connection.
+ """
+ self.kuksa_config["insecure"] = not self.SSL_toggle.isChecked()
+ print(self.kuksa_config)
+
+ def toggle_CAN_Kuksa(self):
+ """
+ Toggles the CAN/Kuksa connection.
+ """
+ global Steering_Signal_Type
+ if (self.CAN_Kuksa_toggle.isChecked()):
+ Steering_Signal_Type = "CAN"
+ else:
+ Steering_Signal_Type = "Kuksa"
+
+ def get_protocol(self):
+ if (not self.Protocol_toggle.isChecked()):
+ return "ws"
+ else:
+ return "grpc"
def set_instance(self):
- self.kuksa = kuksa_instance.KuksaClientSingleton.get_instance()
+ """
+ Sets the instance of the Kuksa client.
+ """
+ self.kuksa = kuksa_instance.KuksaClientSingleton.instance()
self.client = self.kuksa.get_client()
- self.config = self.kuksa.get_config()
- self.token = self.kuksa.get_token()
+ self.kuksa_config = self.kuksa.get_config()
- self.IPAddrInput.setText(self.config["ip"])
- self.SSLToggle.setChecked(self.config["insecure"])
- self.tokenPathInput.setText(self.token)
+ self.IPAddrInput.setText(self.kuksa_config["ip"])
+ self.SSL_toggle.setChecked(not self.kuksa_config["insecure"])
+ self.Protocol_toggle.setChecked(self.kuksa_config["protocol"] == 'grpc')
time.sleep(2)
@@ -76,16 +149,21 @@ class settings(Base, Form):
self.refreshStatus()
def refreshStatus(self):
+ """
+ Refreshes the connection status.
+ """
try:
if (self.client is None):
self.connectionStatus.setText('Not Connected')
self.connectionLogo.setStyleSheet("background-color: red")
+ self.connectionLogo.setPixmap(QtGui.QPixmap(":/Carbon_Icons/carbon_icons/connection-signal--off.svg"))
return None
if (self.client.checkConnection() == True):
self.connectionStatus.setText('Connected')
- self.connectionLogo.setPixmap(":/icons/feather/check-circle.svg")
self.connectionLogo.setStyleSheet("background-color: green")
+ # change cnnection logo pixmap to connected.svf from resources
+ self.connectionLogo.setPixmap(QtGui.QPixmap(":/Carbon_Icons/carbon_icons/connection-signal.svg"))
self.client.start()
return True
@@ -93,20 +171,41 @@ class settings(Base, Form):
self.client.stop()
self.connectionStatus.setText('Disconnected')
self.connectionLogo.setStyleSheet("background-color: yellow")
+ self.connectionLogo.setPixmap(QtGui.QPixmap(":/Carbon_Icons/carbon_icons/connection-signal--off.svg"))
return False
except:
pass
def reconnectClient(self):
+ """
+ Reconnects the client.
+ """
try:
- self.config["ip"] = self.IPAddrInput.text()
- self.config["insecure"] = self.SSLToggle.isChecked()
- self.token = self.tokenPathInput.text()
- self.client = self.kuksa.reconnect_client(self.config, self.token)
+ self.kuksa_config["ip"] = self.IPAddrInput.text()
+ self.kuksa_config["insecure"] = not self.SSL_toggle.isChecked()
+ self.kuksa_config["protocol"] = self.get_protocol()
+ if self.kuksa_config["protocol"] == 'ws':
+ self.kuksa_config["port"] = "8090"
+ if self.kuksa_config["protocol"] == 'grpc':
+ self.kuksa_config["port"] = "55555"
+ self.client = self.kuksa.reconnect(self.kuksa_config)
self.client.start()
self.refreshStatus()
+
+ self.refreshThread = RefreshThread(self)
+ self.refreshThread.start()
+
except Exception as e:
- print(e)
+ logging.error(e)
+
+class RefreshThread(QThread):
+ def __init__(self, settings):
+ QThread.__init__(self)
+ self.settings = settings
+
+ def run(self):
+ time.sleep(2)
+ self.settings.refreshStatus()
if __name__ == '__main__':
import sys
diff --git a/extras/FeedCAN.py b/extras/FeedCAN.py
index 92649f4..9cd01d5 100644
--- a/extras/FeedCAN.py
+++ b/extras/FeedCAN.py
@@ -15,6 +15,7 @@
"""
import can
+import logging
def send_can_signal(frame):
"""
@@ -25,8 +26,13 @@ def send_can_signal(frame):
None
"""
msg = separate_can_frame(frame)
- bus = can.interface.Bus(channel='can0', bustype='socketcan')
- #msg = can.Message(arbitration_id=can_id, data=data, is_extended_id=False)
+
+ try:
+ bus = can.interface.Bus(channel='can0', bustype='socketcan')
+ except Exception as e:
+ logging.error(f"Failed to initialize bus with channel 'can0': {e}")
+ return
+
try:
bus.send(msg)
print("CAN signal sent successfully:")
diff --git a/extras/FeedKuksa.py b/extras/FeedKuksa.py
index 903b442..56e902e 100644
--- a/extras/FeedKuksa.py
+++ b/extras/FeedKuksa.py
@@ -57,6 +57,7 @@ class FeedKuksa(QThread):
Stops the thread.
"""
self.stop_flag = True
+
logging.info("Stopping thread")
def set_instance(self):
@@ -64,7 +65,7 @@ class FeedKuksa(QThread):
Sets the instance of the Kuksa client.
"""
self.kuksa = kuksa_instance.KuksaClientSingleton.instance()
- self.client = self.kuksa.client
+ self.client = self.kuksa.get_client()
def send_values(self, path=None, value=None, attribute=None):
"""
@@ -94,6 +95,9 @@ class FeedKuksa(QThread):
except Exception as e:
logging.error(f"Error sending values to kuksa {e}")
self.set_instance()
+ else:
+ logging.error("Kuksa client is not connected, try reconnecting")
+ self.set_instance()
else:
logging.error("Kuksa client is None, try reconnecting")
time.sleep(2)
diff --git a/extras/Kuksa_Instance.py b/extras/Kuksa_Instance.py
index 49662bd..500e039 100644
--- a/extras/Kuksa_Instance.py
+++ b/extras/Kuksa_Instance.py
@@ -30,7 +30,7 @@ class KuksaClientSingleton:
Attributes:
_instance (Optional[KuksaClientSingleton]): The instance of the class.
_lock (threading.Lock): A lock to ensure thread-safety.
- config (dict): The configuration for KuksaClientThread.
+ kuksa_config (dict): The configuration for KuksaClientThread.
token (str): The path to the token file.
client (KuksaClientThread): The instance of KuksaClientThread.
@@ -73,12 +73,19 @@ class KuksaClientSingleton:
if KuksaClientSingleton._instance is not None:
raise Exception("This class is a singleton!")
- self.config = config.KUKSA_CONFIG
- self.token = config.TOKEN_PATH
+ self.kuksa_config = config.KUKSA_CONFIG
+ self.ws_token = config.WS_TOKEN
+ self.grpc_token = config.GRPC_TOKEN
+
+ if self.kuksa_config["protocol"] == 'ws':
+ self.token = self.ws_token
+ if self.kuksa_config["protocol"] == 'grpc':
+ self.token = self.grpc_token
try:
- self.client = kuksa.KuksaClientThread(self.config)
+ self.client = kuksa.KuksaClientThread(self.kuksa_config)
self.client.authorize(self.token)
+ self.client.start()
time.sleep(2)
if not self.client.checkConnection():
self.client = None
@@ -87,7 +94,7 @@ class KuksaClientSingleton:
KuksaClientSingleton._instance = self
- def reconnect(self, config, token):
+ def reconnect(self, config):
"""
Reconnects the client with the given configuration and token.
@@ -100,8 +107,17 @@ class KuksaClientSingleton:
"""
if self.client:
self.client.stop()
- self.client = kuksa.KuksaClientThread(config)
- self.client.authorize(token)
+
+ if self.kuksa_config["protocol"] == 'ws':
+ self.token = self.ws_token
+ self.kuksa_config["port"] = "8090"
+ if self.kuksa_config["protocol"] == 'grpc':
+ self.token = self.grpc_token
+ self.kuksa_config["port"] = "55555"
+
+ self.client = kuksa.KuksaClientThread(self.kuksa_config)
+ self.client.authorize(self.token)
+ self.client.start()
return self.client
def get_client(self):
@@ -123,16 +139,7 @@ class KuksaClientSingleton:
Returns:
dict: The configuration for KuksaClientThread.
"""
- return self.config
-
- def get_token(self):
- """
- Returns the path to the token file.
-
- Returns:
- str: The path to the token file.
- """
- return self.token
+ return self.kuksa_config
def status(self):
"""
diff --git a/extras/config.py b/extras/config.py
index cc61c57..2ea749c 100644
--- a/extras/config.py
+++ b/extras/config.py
@@ -19,16 +19,16 @@ import platform
python_version = f"python{'.'.join(platform.python_version_tuple()[:2])}"
-CA = os.path.abspath(os.path.join(os.path.dirname(__file__), "../assets/CA.pem"))
+CA = os.path.abspath(os.path.join(os.path.dirname(__file__), "../assets/cert/CA.pem"))
KUKSA_CONFIG = {
- "ip": 'localhost',
- "port": "8090",
- 'protocol': 'ws',
+ "ip": '10.42.0.95',
+ "port": "55555",
+ 'protocol': 'grpc',
'insecure': False,
'cacertificate': CA,
'tls_server_name': "Server",
}
-TOKEN_PATH = os.path.join(os.path.expanduser("~"),
- f".local/lib/{python_version}/site-packages/kuksa_certificates/jwt/super-admin.json.token")
+WS_TOKEN = os.path.join(os.path.expanduser("~"), f".local/lib/{python_version}/site-packages/kuksa_certificates/jwt/super-admin.json.token")
+GRPC_TOKEN = os.path.abspath(os.path.join(os.path.dirname(__file__), "../assets/token/grpc/actuate-provide-all.token")) \ No newline at end of file
diff --git a/ui/Dashboard.ui b/ui/Dashboard.ui
index 51f913a..ef30cf6 100644
--- a/ui/Dashboard.ui
+++ b/ui/Dashboard.ui
@@ -84,8 +84,8 @@ QPushButton:pressed {
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QPushButton" name="DB_IC_Tile">
+ <item row="0" column="1">
+ <widget class="QPushButton" name="DB_HVAC_Tile">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -96,11 +96,11 @@ QPushButton:pressed {
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
- <string>Instrument Cluster</string>
+ <string>HVAC</string>
</property>
<property name="icon">
<iconset resource="../assets/res.qrc">
- <normaloff>:/Carbon_Icons/carbon_icons/meter.svg</normaloff>:/Carbon_Icons/carbon_icons/meter.svg</iconset>
+ <normaloff>:/Carbon_Icons/carbon_icons/windy--strong.svg</normaloff>:/Carbon_Icons/carbon_icons/windy--strong.svg</iconset>
</property>
<property name="iconSize">
<size>
@@ -113,8 +113,8 @@ QPushButton:pressed {
</property>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QPushButton" name="DB_HVAC_Tile">
+ <item row="1" column="0">
+ <widget class="QPushButton" name="DB_Steering_Tile">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -125,11 +125,11 @@ QPushButton:pressed {
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
- <string>HVAC</string>
+ <string>Steering Controls</string>
</property>
<property name="icon">
<iconset resource="../assets/res.qrc">
- <normaloff>:/Carbon_Icons/carbon_icons/windy--strong.svg</normaloff>:/Carbon_Icons/carbon_icons/windy--strong.svg</iconset>
+ <normaloff>:/Images/Images/steering-wheel.svg</normaloff>:/Images/Images/steering-wheel.svg</iconset>
</property>
<property name="iconSize">
<size>
@@ -142,8 +142,8 @@ QPushButton:pressed {
</property>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QPushButton" name="DB_Steering_Tile">
+ <item row="1" column="1">
+ <widget class="QPushButton" name="DB_Settings_Tile">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -154,11 +154,11 @@ QPushButton:pressed {
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
- <string>Steering Controls</string>
+ <string>Configure</string>
</property>
<property name="icon">
<iconset resource="../assets/res.qrc">
- <normaloff>:/Images/Images/steering-wheel.svg</normaloff>:/Images/Images/steering-wheel.svg</iconset>
+ <normaloff>:/Carbon_Icons/carbon_icons/settings.svg</normaloff>:/Carbon_Icons/carbon_icons/settings.svg</iconset>
</property>
<property name="iconSize">
<size>
@@ -171,8 +171,8 @@ QPushButton:pressed {
</property>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QPushButton" name="DB_Settings_Tile">
+ <item row="0" column="0">
+ <widget class="QPushButton" name="DB_IC_Tile">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -183,11 +183,11 @@ QPushButton:pressed {
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
- <string>Configure</string>
+ <string>Instrument Cluster</string>
</property>
<property name="icon">
<iconset resource="../assets/res.qrc">
- <normaloff>:/Carbon_Icons/carbon_icons/settings.svg</normaloff>:/Carbon_Icons/carbon_icons/settings.svg</iconset>
+ <normaloff>:/Carbon_Icons/carbon_icons/meter.svg</normaloff>:/Carbon_Icons/carbon_icons/meter.svg</iconset>
</property>
<property name="iconSize">
<size>
@@ -195,9 +195,6 @@ QPushButton:pressed {
<height>50</height>
</size>
</property>
- <property name="flat">
- <bool>false</bool>
- </property>
</widget>
</item>
</layout>
diff --git a/ui/Settings_Window.ui b/ui/Settings_Window.ui
index ff73614..477fa40 100644
--- a/ui/Settings_Window.ui
+++ b/ui/Settings_Window.ui
@@ -71,8 +71,21 @@ QCheckBox:indicator:disabled {
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
- <item row="1" column="3" rowspan="4">
- <spacer name="horizontalSpacer">
+ <item row="0" column="0" colspan="4">
+ <spacer name="verticalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" rowspan="5">
+ <spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -84,6 +97,215 @@ QCheckBox:indicator:disabled {
</property>
</spacer>
</item>
+ <item row="3" column="1" colspan="2">
+ <widget class="QFrame" name="frame_general_settings">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="1" column="5" colspan="2" alignment="Qt::AlignLeft">
+ <widget class="QLabel" name="connectionLogo">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/connection-signal--off.svg</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="4">
+ <widget class="QLabel" name="IPAddr">
+ <property name="text">
+ <string>IP Address *</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="7" alignment="Qt::AlignHCenter">
+ <widget class="QCheckBox" name="place_holder_toggle_2">
+ <property name="toolTip">
+ <string>Default: WS</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="0" colspan="3">
+ <widget class="QLabel" name="label_11">
+ <property name="toolTip">
+ <string>Default: WS</string>
+ </property>
+ <property name="text">
+ <string>Protocol</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="10" alignment="Qt::AlignLeft">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>grpc</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" colspan="4">
+ <widget class="QLabel" name="status">
+ <property name="text">
+ <string>Status</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="7">
+ <widget class="QLabel" name="connectionStatus">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Disconnected</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="1" rowspan="2">
+ <widget class="QFrame" name="PageIcons">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ </layout>
+ </widget>
+ </item>
+ <item row="3" column="5">
+ <widget class="QLabel" name="label_9">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/security-services.svg</pixmap>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="4" rowspan="4">
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="3" column="0" colspan="4">
+ <widget class="QLabel" name="label">
+ <property name="toolTip">
+ <string>Default: Secure</string>
+ </property>
+ <property name="text">
+ <string>Secure Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="2" rowspan="2">
+ <widget class="QFrame" name="PageLabels">
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ </layout>
+ </widget>
+ </item>
+ <item row="4" column="5" alignment="Qt::AlignRight">
+ <widget class="QLabel" name="label_12">
+ <property name="text">
+ <string>ws</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="5" colspan="7">
+ <widget class="QLineEdit" name="IPAddrInput">
+ <property name="placeholderText">
+ <string>Default: localhost</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="6" colspan="3" alignment="Qt::AlignHCenter">
+ <widget class="QCheckBox" name="place_holder_toggle_1">
+ <property name="toolTip">
+ <string>Default: Secure</string>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="checked">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" colspan="11">
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Maximum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
<item row="1" column="1" colspan="2">
<widget class="QFrame" name="frame_2">
<property name="sizePolicy">
@@ -133,32 +355,10 @@ QCheckBox:indicator:disabled {
</property>
</widget>
</item>
- <item>
- <widget class="QPushButton" name="refreshBtn">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="font">
- <font>
- <weight>50</weight>
- <bold>false</bold>
- </font>
- </property>
- <property name="text">
- <string>Refresh Status</string>
- </property>
- <property name="iconSize">
- <size>
- <width>30</width>
- <height>30</height>
- </size>
- </property>
- </widget>
- </item>
</layout>
</widget>
</item>
- <item row="4" column="1" colspan="2">
+ <item row="5" column="1" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -174,8 +374,8 @@ QCheckBox:indicator:disabled {
</property>
</spacer>
</item>
- <item row="1" column="0" rowspan="4">
- <spacer name="horizontalSpacer_2">
+ <item row="1" column="3" rowspan="5">
+ <spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -187,143 +387,57 @@ QCheckBox:indicator:disabled {
</property>
</spacer>
</item>
- <item row="3" column="1" colspan="2">
- <widget class="QFrame" name="frame_3">
+ <item row="4" column="1" colspan="2">
+ <widget class="QFrame" name="frame_page_settings">
+ <property name="minimumSize">
+ <size>
+ <width>300</width>
+ <height>300</height>
+ </size>
+ </property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
- <layout class="QGridLayout" name="gridLayout_2">
- <item row="4" column="6" colspan="2">
- <widget class="QCheckBox" name="place_holder_toggle_1">
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="7" column="4">
+ <widget class="QPushButton" name="pushButton_3">
<property name="text">
<string/>
</property>
- <property name="checked">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1" colspan="8">
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Maximum</enum>
+ <property name="icon">
+ <iconset resource="../assets/res.qrc">
+ <normaloff>:/Carbon_Icons/carbon_icons/view.svg</normaloff>:/Carbon_Icons/carbon_icons/view.svg</iconset>
</property>
- <property name="sizeHint" stdset="0">
+ <property name="iconSize">
<size>
- <width>20</width>
- <height>40</height>
+ <width>30</width>
+ <height>30</height>
</size>
</property>
- </spacer>
- </item>
- <item row="1" column="7" colspan="4">
- <widget class="QLabel" name="connectionStatus">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text">
- <string>Disconnected</string>
- </property>
- </widget>
- </item>
- <item row="8" column="2" rowspan="3">
- <widget class="QFrame" name="PageLabels">
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Instrument Cluster</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>HVAC</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Steering Controls</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="2" column="0" colspan="4">
- <widget class="QLabel" name="IPAddr">
- <property name="text">
- <string>IP Address *</string>
- </property>
</widget>
</item>
- <item row="10" column="9">
- <widget class="QCheckBox" name="place_holder_toggle_2">
+ <item row="5" column="4">
+ <widget class="QPushButton" name="pushButton">
<property name="text">
<string/>
</property>
- </widget>
- </item>
- <item row="8" column="0">
- <widget class="QLabel" name="label_6">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Ignored">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <property name="icon">
+ <iconset resource="../assets/res.qrc">
+ <normaloff>:/Carbon_Icons/carbon_icons/view.svg</normaloff>:/Carbon_Icons/carbon_icons/view.svg</iconset>
</property>
- <property name="maximumSize">
+ <property name="iconSize">
<size>
- <width>25</width>
- <height>25</height>
+ <width>30</width>
+ <height>30</height>
</size>
</property>
- <property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/meter.svg</pixmap>
- </property>
- <property name="scaledContents">
- <bool>true</bool>
- </property>
</widget>
</item>
- <item row="10" column="6" colspan="2" alignment="Qt::AlignLeft">
- <widget class="QPushButton" name="pushButton_3">
+ <item row="6" column="4">
+ <widget class="QPushButton" name="pushButton_2">
<property name="text">
<string/>
</property>
@@ -339,15 +453,15 @@ QCheckBox:indicator:disabled {
</property>
</widget>
</item>
- <item row="3" column="0" colspan="4">
- <widget class="QLabel" name="tokenPath">
+ <item row="7" column="1" colspan="3">
+ <widget class="QLabel" name="label_5">
<property name="text">
- <string>JWT token Path *</string>
+ <string>Steering Controls</string>
</property>
</widget>
</item>
- <item row="10" column="0">
- <widget class="QLabel" name="label_8">
+ <item row="6" column="0">
+ <widget class="QLabel" name="label_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -364,109 +478,61 @@ QCheckBox:indicator:disabled {
<string/>
</property>
<property name="pixmap">
- <pixmap resource="../assets/res.qrc">:/Images/Images/steering-wheel.svg</pixmap>
+ <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/windy--strong.svg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
- <item row="5" column="0" colspan="3">
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>CA</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0" colspan="4">
- <widget class="QLabel" name="label">
+ <item row="0" column="0" colspan="5" alignment="Qt::AlignHCenter">
+ <widget class="QLabel" name="label_2">
<property name="text">
- <string>Insecure Mode</string>
+ <string>Page Settings</string>
</property>
</widget>
</item>
- <item row="4" column="5">
- <widget class="QLabel" name="label_9">
+ <item row="6" column="1" colspan="3">
+ <widget class="QLabel" name="label_4">
<property name="text">
- <string/>
- </property>
- <property name="pixmap">
- <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/security-services.svg</pixmap>
+ <string>HVAC</string>
</property>
</widget>
</item>
- <item row="6" column="1" colspan="7">
- <spacer name="verticalSpacer_4">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
+ <item row="5" column="0">
+ <widget class="QLabel" name="label_6">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
</property>
- <property name="sizeHint" stdset="0">
+ <property name="maximumSize">
<size>
- <width>20</width>
- <height>40</height>
+ <width>25</width>
+ <height>25</height>
</size>
</property>
- </spacer>
- </item>
- <item row="5" column="9" colspan="2">
- <widget class="QToolButton" name="toolButton">
<property name="text">
- <string>...</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0" colspan="11">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Page Settings</string>
+ <string/>
</property>
- </widget>
- </item>
- <item row="8" column="1" rowspan="3">
- <widget class="QFrame" name="PageIcons">
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
+ <property name="pixmap">
+ <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/meter.svg</pixmap>
</property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
+ <property name="scaledContents">
+ <bool>true</bool>
</property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <property name="spacing">
- <number>0</number>
- </property>
- <property name="leftMargin">
- <number>0</number>
- </property>
- <property name="topMargin">
- <number>0</number>
- </property>
- <property name="rightMargin">
- <number>0</number>
- </property>
- <property name="bottomMargin">
- <number>0</number>
- </property>
- </layout>
</widget>
</item>
- <item row="1" column="4" rowspan="4">
- <spacer name="horizontalSpacer_3">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
+ <item row="5" column="1" colspan="3">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Instrument Cluster</string>
</property>
- </spacer>
+ </widget>
</item>
- <item row="9" column="0">
- <widget class="QLabel" name="label_7">
+ <item row="7" column="0">
+ <widget class="QLabel" name="label_8">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@@ -483,101 +549,47 @@ QCheckBox:indicator:disabled {
<string/>
</property>
<property name="pixmap">
- <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/windy--strong.svg</pixmap>
+ <pixmap resource="../assets/res.qrc">:/Images/Images/steering-wheel.svg</pixmap>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
</widget>
</item>
- <item row="10" column="8">
+ <item row="8" column="4" alignment="Qt::AlignLeft">
<widget class="QLabel" name="label_10">
<property name="text">
<string>CAN</string>
</property>
</widget>
</item>
- <item row="2" column="5" colspan="6">
- <widget class="QLineEdit" name="IPAddrInput">
- <property name="placeholderText">
- <string>Default: localhost</string>
- </property>
- </widget>
- </item>
- <item row="9" column="6" colspan="2" alignment="Qt::AlignLeft">
- <widget class="QPushButton" name="pushButton_2">
+ <item row="8" column="3" alignment="Qt::AlignHCenter">
+ <widget class="QCheckBox" name="place_holder_toggle_3">
<property name="text">
<string/>
</property>
- <property name="icon">
- <iconset resource="../assets/res.qrc">
- <normaloff>:/Carbon_Icons/carbon_icons/view.svg</normaloff>:/Carbon_Icons/carbon_icons/view.svg</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>30</width>
- <height>30</height>
- </size>
- </property>
</widget>
</item>
- <item row="1" column="5" colspan="2">
- <widget class="QLabel" name="connectionLogo">
+ <item row="8" column="2" alignment="Qt::AlignRight|Qt::AlignVCenter">
+ <widget class="QLabel" name="label_14">
<property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="3" column="5" colspan="6">
- <widget class="QLineEdit" name="tokenPathInput">
- <property name="placeholderText">
- <string>/Path/To/Token</string>
+ <string>Kuksa</string>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="4">
- <widget class="QLabel" name="status">
- <property name="text">
- <string>Status</string>
- </property>
- </widget>
- </item>
- <item row="5" column="5" colspan="4">
- <widget class="QLineEdit" name="lineEdit"/>
- </item>
- <item row="8" column="6" colspan="2" alignment="Qt::AlignLeft">
- <widget class="QPushButton" name="pushButton">
+ <item row="8" column="1" alignment="Qt::AlignHCenter|Qt::AlignVCenter">
+ <widget class="QLabel" name="label_15">
<property name="text">
<string/>
</property>
- <property name="icon">
- <iconset resource="../assets/res.qrc">
- <normaloff>:/Carbon_Icons/carbon_icons/view.svg</normaloff>:/Carbon_Icons/carbon_icons/view.svg</iconset>
- </property>
- <property name="iconSize">
- <size>
- <width>30</width>
- <height>30</height>
- </size>
+ <property name="pixmap">
+ <pixmap resource="../assets/res.qrc">:/Carbon_Icons/carbon_icons/x-axis.svg</pixmap>
</property>
</widget>
</item>
</layout>
</widget>
</item>
- <item row="0" column="0" colspan="4">
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
</layout>
</widget>
</widget>