diff options
Diffstat (limited to 'Widgets')
-rw-r--r-- | Widgets/Dashboard.py | 13 | ||||
-rw-r--r-- | Widgets/HVACPage.py | 33 | ||||
-rw-r--r-- | Widgets/SteeringCtrlPage.py | 9 | ||||
-rw-r--r-- | Widgets/settings.py | 165 |
4 files changed, 167 insertions, 53 deletions
diff --git a/Widgets/Dashboard.py b/Widgets/Dashboard.py index 1d77e53..e7e17a6 100644 --- a/Widgets/Dashboard.py +++ b/Widgets/Dashboard.py @@ -84,10 +84,15 @@ class Dashboard(Base, Form): - tile: The tile for which the icon needs to be set. - size: The size of the icon. """ - icon = tile.icon() - scaled_pixmap = icon.pixmap(icon.availableSizes()[0]).scaled(size, size, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) - tile.setIcon(QtGui.QIcon(scaled_pixmap)) - tile.setIconSize(QtCore.QSize(size, size)) + try: + icon = tile.icon() + if icon.availableSizes(): + pixmap = icon.pixmap(icon.availableSizes()[0]) + scaled_pixmap = pixmap.scaled(size, size, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) + tile.setIcon(QtGui.QIcon(scaled_pixmap)) + tile.setIconSize(QtCore.QSize(size, size)) + except Exception as e: + print(f"Failed to set icon: {e}") def tile_clicked(self, tile): """ diff --git a/Widgets/HVACPage.py b/Widgets/HVACPage.py index 99ee798..312f82b 100644 --- a/Widgets/HVACPage.py +++ b/Widgets/HVACPage.py @@ -42,7 +42,20 @@ class HVAC_Paths(): self.temperatureList = [str(i) + "°C" for i in range(32, 15, -1)] class HVACWidget(Base, Form): + """ + A widget for controlling HVAC settings. + + Inherits from Base and Form. + """ + def __init__(self, parent=None): + """ + Initializes the HVACWidget. + + Args: + - parent: The parent widget. Defaults to None. + """ + super(self.__class__, self).__init__(parent) self.setupUi(self) @@ -83,23 +96,43 @@ class HVACWidget(Base, Form): self.rightFanSpeed_slider.valueChanged.connect(self.rightFanSpeed_sliderChanged) def leftTempListClicked(self): + """ + Handles the event when an item in the left temperature list is clicked. + Sends the selected temperature value to the feed_kuksa object. + """ + item = self.leftTempList.currentItem() self.leftTempList.scrollToItem(item, 1) self.feed_kuksa.send_values(self.HVAC.leftTemp, item.text()[:-2]) print(item.text()) def rightTempListClicked(self): + """ + Handles the event when an item in the right temperature list is clicked. + Sends the selected temperature value to the feed_kuksa object. + """ + item = self.rightTempList.currentItem() self.rightTempList.scrollToItem(item, 1) self.feed_kuksa.send_values(self.HVAC.rightTemp, item.text()[:-2]) print(item.text()) def leftFanSpeed_sliderChanged(self): + """ + Handles the event when the left fan speed slider is changed. + Sends the selected fan speed value to the feed_kuksa object. + """ + value = self.leftFanSpeed_slider.value() self.feed_kuksa.send_values(self.HVAC.leftFanSpeed, str(value)) print(value) def rightFanSpeed_sliderChanged(self): + """ + Handles the event when the right fan speed slider is changed. + Sends the selected fan speed value to the feed_kuksa object. + """ + value = self.rightFanSpeed_slider.value() self.feed_kuksa.send_values(self.HVAC.rightFanSpeed, str(value)) print(value) diff --git a/Widgets/SteeringCtrlPage.py b/Widgets/SteeringCtrlPage.py index 696c6c9..de3585d 100644 --- a/Widgets/SteeringCtrlPage.py +++ b/Widgets/SteeringCtrlPage.py @@ -18,9 +18,6 @@ import os import sys from PyQt5 import uic from PyQt5.QtWidgets import QApplication, QButtonGroup -from PyQt5.QtCore import QThread - -import time current_dir = os.path.dirname(os.path.abspath(__file__)) @@ -120,6 +117,7 @@ class SteeringCtrlWidget(Base, Form): self.PhoneHangup, self.Voice, self.LaneDeparture, + self.Horn, self.CruiseEnable, self.CruiseSet, self.CruiseResume, @@ -138,13 +136,12 @@ class SteeringCtrlWidget(Base, Form): 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) + 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 17ea7f6..a7820fc 100644 --- a/Widgets/settings.py +++ b/Widgets/settings.py @@ -17,12 +17,13 @@ import os import sys import time from PyQt5 import uic -from PyQt5.QtWidgets import QApplication, QLineEdit, QPushButton, QLabel +from PyQt5.QtWidgets import QApplication, QLineEdit, QPushButton, QLabel, QComboBox, QStyledItemDelegate from qtwidgets import AnimatedToggle from PyQt5.QtWidgets import QWidget from PyQt5.QtCore import QThread from PyQt5 import QtGui import logging +import can current_dir = os.path.dirname(os.path.abspath(__file__)) @@ -31,6 +32,7 @@ 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 import config Form, Base = uic.loadUiType(os.path.join( current_dir, "../ui/Settings_Window.ui")) @@ -39,6 +41,12 @@ Form, Base = uic.loadUiType(os.path.join( Steering_Signal_Type = "Kuksa" +def create_animated_toggle(): + return AnimatedToggle( + checked_color="#4BD7D6", + pulse_checked_color="#00ffff", + ) + class settings(Base, Form): """ A class representing the settings widget of the AGL Demo Control Panel. @@ -60,31 +68,34 @@ class settings(Base, Form): """ super(self.__class__, self).__init__(parent) self.setupUi(self) - - 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.SSL_toggle = create_animated_toggle() + self.Protocol_toggle = create_animated_toggle() + self.CAN_Kuksa_toggle = create_animated_toggle() self.connectionStatus = self.findChild(QLabel, "connectionStatus") self.connectionLogo = self.findChild(QLabel, "connectionLogo") + list_of_configs = config.get_list_configs() + default_config_name = config.get_default_config() + + self.List_Configs_ComboBox = self.findChild(QComboBox, "List_Configs_ComboBox") + self.List_Configs_ComboBox.setItemDelegate(QStyledItemDelegate()) + self.List_Configs_ComboBox.addItems(list_of_configs) + self.List_Configs_ComboBox.setCurrentText(default_config_name) + self.List_Configs_ComboBox.currentTextChanged.connect(lambda: self.set_settings(self.List_Configs_ComboBox.currentText())) + self.IPAddrInput = self.findChild(QLineEdit, "IPAddrInput") + self.PortInput = self.findChild(QLineEdit, "PortInput") + self.TLS_Server_Name = self.findChild(QLineEdit, "TLS_Server_Name") + self.Auth_Token = self.findChild(QLineEdit, "Auth_Token") + self.CA_File = self.findChild(QLineEdit, "CA_File") self.reconnectBtn = self.findChild(QPushButton, "reconnectBtn") self.startClientBtn = self.findChild(QPushButton, "startClientBtn") + self.startClientBtn.setCheckable(True) - self.startClientBtn.clicked.connect(self.set_instance) + self.startClientBtn.clicked.connect(self.start_stop_client) self.reconnectBtn.clicked.connect(self.reconnectClient) self.SSL_toggle.clicked.connect(self.toggleSSL) self.CAN_Kuksa_toggle.clicked.connect(self.toggle_CAN_Kuksa) @@ -102,7 +113,27 @@ class settings(Base, Form): self.place_holder_toggle_2.deleteLater() self.place_holder_toggle_3.deleteLater() - self.refreshStatus() + self.set_settings(default_config_name) + + def start_stop_client(self): + if self.startClientBtn.isChecked(): + # turn button red and change icon to stop from resources + self.set_instance() + if self.client is not None: + self.startClientBtn.setStyleSheet("border: 1px solid red;") + self.startClientBtn.setIcon(QtGui.QIcon(":/Carbon_Icons/carbon_icons/stop.svg")) + self.startClientBtn.setText("Stop Client") + else: + self.startClientBtn.setChecked(False) + else: + # turn button green and change icon to start from resources + if self.client is not None: + self.client.stop() + + self.startClientBtn.setStyleSheet("border: 1px solid green;") + self.startClientBtn.setIcon(QtGui.QIcon(":/Carbon_Icons/carbon_icons/play.svg")) + self.startClientBtn.setText("Start Client") + def toggleSSL(self): """ @@ -117,7 +148,14 @@ class settings(Base, Form): """ global Steering_Signal_Type if (self.CAN_Kuksa_toggle.isChecked()): - Steering_Signal_Type = "CAN" + # check if can0 is available + try: + can_bus = can.interface.Bus(channel='can0', bustype='socketcan_native') + can_bus.shutdown() + Steering_Signal_Type = "CAN" + except: + self.CAN_Kuksa_toggle.setChecked(False) + logging.error("CAN Bus not available") else: Steering_Signal_Type = "Kuksa" @@ -132,13 +170,12 @@ class settings(Base, Form): Sets the instance of the Kuksa client. """ self.kuksa = kuksa_instance.KuksaClientSingleton.instance() - self.client = self.kuksa.get_client() - - self.kuksa_config = self.kuksa.get_config() - - 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') + new_config = self.make_new_config() + if (new_config is None): + logging.error("Invalid configuration") + else: + self.kuksa.reconnect(new_config, self.kuksa_token) + self.client = self.kuksa.get_client() time.sleep(2) @@ -162,7 +199,6 @@ class settings(Base, Form): if (self.client.checkConnection() == True): self.connectionStatus.setText('Connected') 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 @@ -180,23 +216,66 @@ class settings(Base, Form): """ Reconnects the client. """ - try: - 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: - logging.error(e) + if (self.client is not None): + try: + config = self.make_new_config() + self.client.stop() + self.client = self.kuksa.reconnect(config, self.kuksa_token) + self.client.start() + self.refreshStatus() + + self.refreshThread = RefreshThread(self) + self.refreshThread.start() + + except Exception as e: + logging.error(e) + self.set_instance() + + def make_new_config(self): + """ + Makes a new configuration using fields in the settings widget. + """ + + def validate_and_set_style(self, widget, key=None): + text = widget.text() + if text: + if os.path.exists(text): + widget.setStyleSheet("border: 1px solid #4BD7D6 ; /* light blue */") + if key: + self.new_config[key] = text + else: + self.kuksa_token = text + else: + widget.setStyleSheet("border: 1px solid red;") + return None + + new_config = {} + new_config["ip"] = self.IPAddrInput.text() + new_config["port"] = self.PortInput.text() + new_config["protocol"] = self.get_protocol() + new_config["insecure"] = not self.SSL_toggle.isChecked() + new_config["tls_server_name"] = self.TLS_Server_Name.text() if self.Protocol_toggle.isChecked() else None + validate_and_set_style(self, self.CA_File, "cacertificate") + validate_and_set_style(self, self.Auth_Token) + + return new_config + + def set_settings(self, config_name): + """ + Reloads the parameters of settings widget. + """ + new_config = config.select_config(config_name) + self.kuksa_config_name = new_config[0] + self.kuksa_config = new_config[1] + self.kuksa_token = new_config[2] + + self.IPAddrInput.setText(self.kuksa_config["ip"]) + self.PortInput.setText(self.kuksa_config["port"]) + self.SSL_toggle.setChecked(not self.kuksa_config["insecure"]) + self.Protocol_toggle.setChecked(self.kuksa_config["protocol"] == 'grpc') + self.CA_File.setText(self.kuksa_config["cacertificate"]) + self.TLS_Server_Name.setText(self.kuksa_config["tls_server_name"] if self.kuksa_config["tls_server_name"] is not None else "") + self.Auth_Token.setText(self.kuksa_token) class RefreshThread(QThread): def __init__(self, settings): |