SwapStation_Dashboard/ui/widgets.py

175 lines
7.6 KiB
Python

# --- REPLACE the entire content of ui/widgets.py with this ---
from PyQt6.QtWidgets import (
QGroupBox, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QFrame, QPushButton, QFormLayout
)
from PyQt6.QtCore import Qt, pyqtSignal # <-- IMPORT pyqtSignal
from PyQt6.QtGui import QFont
class ChamberWidget(QGroupBox):
# --- ADD SIGNALS HERE ---
open_door_requested = pyqtSignal()
chg_on_requested = pyqtSignal()
chg_off_requested = pyqtSignal()
def __init__(self, title="CHAMBER - X", scale=1.0):
super().__init__(title)
self.setObjectName("ChamberWidget")
self.setFont(QFont("Arial", max(8, int(9 * scale)), QFont.Weight.Bold))
main_layout = QVBoxLayout(self)
main_layout.setSpacing(max(2, int(4 * scale)))
id_layout = QHBoxLayout()
id_layout.addWidget(QLabel("BAT ID: "))
self.id_field = self._create_data_field(scale)
self.id_field.setObjectName("BatIdField") # Set object name for styling
id_layout.addWidget(self.id_field)
main_layout.addLayout(id_layout)
columns_layout = QHBoxLayout()
battery_form_layout = QFormLayout()
battery_form_layout.setVerticalSpacing(max(2, int(4 * scale)))
self.battery_status_label = self._create_status_label("ABSENT", scale)
self.battery_status_label.setProperty("status", "absent")
# --- SET OBJECT NAMES FOR EACH DATA FIELD ---
self.soc_field = self._create_data_field(scale)
self.soc_field.setObjectName("DataField")
self.voltage_field = self._create_data_field(scale)
self.voltage_field.setObjectName("DataField")
self.temp_field = self._create_data_field(scale)
self.temp_field.setObjectName("DataField")
self.battery_fault_field = self._create_data_field(scale)
self.battery_fault_field.setObjectName("DataField")
# --- END OF OBJECT NAMES ---
battery_form_layout.addRow("Status:", self.battery_status_label)
battery_form_layout.addRow("SOC:", self.soc_field)
battery_form_layout.addRow("Voltage:", self.voltage_field)
battery_form_layout.addRow("Temp:", self.temp_field)
battery_form_layout.addRow("Fault:", self.battery_fault_field)
separator_line = QFrame()
separator_line.setFrameShape(QFrame.Shape.VLine)
separator_line.setFrameShadow(QFrame.Shadow.Sunken)
charger_form_layout = QFormLayout()
charger_form_layout.setVerticalSpacing(max(2, int(4 * scale)))
self.charger_status_label = self._create_status_label("OFF", scale)
self.charger_status_label.setProperty("status", "absent")
# --- SET OBJECT NAMES FOR EACH DATA FIELD ---
self.slot_temp_field = self._create_data_field(scale)
self.slot_temp_field.setObjectName("DataField")
self.chg_temp_field = self._create_data_field(scale)
self.chg_temp_field.setObjectName("DataField")
self.door_status_field = self._create_data_field(scale)
self.door_status_field.setObjectName("DoorStatusField")
self.charger_fault_field = self._create_data_field(scale)
self.charger_fault_field.setObjectName("DataField")
# --- END OF OBJECT NAMES ---
charger_form_layout.addRow("Chg Status:", self.charger_status_label)
charger_form_layout.addRow("Chg Temp:", self.chg_temp_field)
charger_form_layout.addRow("Slot Temp:", self.slot_temp_field)
charger_form_layout.addRow("Door Status:", self.door_status_field)
charger_form_layout.addRow("Fault:", self.charger_fault_field)
columns_layout.addLayout(battery_form_layout)
columns_layout.addWidget(separator_line)
columns_layout.addLayout(charger_form_layout)
main_layout.addLayout(columns_layout)
main_layout.addStretch()
button_layout = QHBoxLayout()
self.open_door_btn = QPushButton("OPEN DOOR")
self.chg_on_btn = QPushButton("CHG ON")
self.chg_off_btn = QPushButton("CHG OFF")
self.open_door_btn.setObjectName("ChamberOpenDoorButton")
self.chg_on_btn.setObjectName("ChamberChgOnButton")
self.chg_off_btn.setObjectName("ChamberChgOffButton")
self.open_door_btn.clicked.connect(self.open_door_requested.emit)
self.chg_on_btn.clicked.connect(self.chg_on_requested.emit)
self.chg_off_btn.clicked.connect(self.chg_off_requested.emit)
button_layout.addWidget(self.open_door_btn)
button_layout.addWidget(self.chg_on_btn)
button_layout.addWidget(self.chg_off_btn)
main_layout.addLayout(button_layout)
# ... (the rest of the class is unchanged) ...
def _create_status_label(self, text, scale):
label = QLabel(text)
label.setAlignment(Qt.AlignmentFlag.AlignCenter)
label.setFont(QFont("Arial", max(7, int(8 * scale)), QFont.Weight.Bold))
return label
def _create_data_field(self, scale):
field = QLineEdit("N/A")
field.setReadOnly(True)
field.setFont(QFont("Arial", max(7, int(8 * scale))))
return field
def update_data(self, data):
if data.get("batteryPresent") == 1:
self.battery_status_label.setText("PRESENT")
self.battery_status_label.setProperty("status", "present")
else:
self.battery_status_label.setText("ABSENT")
self.battery_status_label.setProperty("status", "absent")
if data.get("chargerPresent") == 1:
self.charger_status_label.setText("CHARGER ON")
self.charger_status_label.setProperty("status", "present")
else:
self.charger_status_label.setText("CHARGER OFF")
self.charger_status_label.setProperty("status", "absent")
for widget in [self.battery_status_label, self.charger_status_label]:
widget.style().unpolish(widget)
widget.style().polish(widget)
self.id_field.setText(data.get("batteryIdentification", "N/A"))
self.soc_field.setText(f'{data.get("soc", 0)}%')
self.voltage_field.setText(f'{data.get("voltage", 0) / 1000.0:.2f} V')
self.temp_field.setText(f'{data.get("batteryMaxTemp", 0) / 10.0:.1f} °C')
self.battery_fault_field.setText(str(data.get("batteryFaultCode", 0)))
self.slot_temp_field.setText(f'{data.get("slotTemperature", 0) / 10.0:.1f} °C')
self.chg_temp_field.setText(f'{data.get("chargerTemp", 0) / 10.0:.1f} °C')
self.charger_fault_field.setText(str(data.get("chargerFaultCode", 0)))
door_status = "OPEN" if data.get("doorStatus") == 1 else "CLOSED"
self.door_status_field.setText(door_status)
def reset_to_default(self):
"""Resets all fields in this chamber widget to their default state."""
self.battery_status_label.setText("ABSENT")
self.battery_status_label.setProperty("status", "absent")
self.charger_status_label.setText("CHARGER OFF")
self.charger_status_label.setProperty("status", "absent")
# Re-apply the stylesheet for the status labels
for widget in [self.battery_status_label, self.charger_status_label]:
widget.style().unpolish(widget)
widget.style().polish(widget)
self.id_field.setText("N/A")
self.soc_field.setText("N/A")
self.voltage_field.setText("N/A")
self.temp_field.setText("N/A")
self.battery_fault_field.setText("N/A")
self.slot_temp_field.setText("N/A")
self.chg_temp_field.setText("N/A")
self.door_status_field.setText("N/A")
self.charger_fault_field.setText("N/A")