forked from M-Labs/thermostat
linuswck
726f1a3657
- Bugs fix: 1. Params Tree user input will not get overwritten by incoming report thermostat_data_model. 2. PID Autotune Sampling Period is now set according to Thermostat sampling interval 3. PID Autotune won't get stuck in Fail State 4. Various types disconnection related Bugs 5. Number of Samples stored in the plot cannot be set 6. Limit the max settable output current to be 2000mA - Improvement: 1. Params Tree settings can be changed with external json 2. Use a Tab system to show a single channel of config instead of two 3. Expose PID Autotune lookback params 4. Icon is changed to Artiq logo - Restructure: 1. Restructure the code to follow Model-View-Delegate Design Pattern
146 lines
6.0 KiB
Python
146 lines
6.0 KiB
Python
from PyQt6 import QtWidgets, QtGui, QtCore
|
|
from PyQt6.QtCore import pyqtSignal, pyqtSlot
|
|
|
|
|
|
class thermostat_ctrl_menu(QtWidgets.QMenu):
|
|
fan_set_act = pyqtSignal(int)
|
|
fan_auto_set_act = pyqtSignal(int)
|
|
|
|
connect_act = pyqtSignal()
|
|
reset_act = pyqtSignal(bool)
|
|
dfu_act = pyqtSignal(bool)
|
|
load_cfg_act = pyqtSignal(int)
|
|
save_cfg_act = pyqtSignal(int)
|
|
net_cfg_act = pyqtSignal(bool)
|
|
|
|
def __init__(self, style):
|
|
super().__init__()
|
|
self._style = style
|
|
self.setTitle("Thermostat settings")
|
|
|
|
self.hw_rev_data = dict()
|
|
|
|
self.fan_group = QtWidgets.QWidget()
|
|
self.fan_group.setEnabled(False)
|
|
self.fan_group.setMinimumSize(QtCore.QSize(40, 0))
|
|
self.fan_layout = QtWidgets.QHBoxLayout(self.fan_group)
|
|
self.fan_layout.setSpacing(9)
|
|
self.fan_lbl = QtWidgets.QLabel(parent=self.fan_group)
|
|
self.fan_lbl.setMinimumSize(QtCore.QSize(40, 0))
|
|
self.fan_lbl.setMaximumSize(QtCore.QSize(40, 16777215))
|
|
self.fan_lbl.setBaseSize(QtCore.QSize(40, 0))
|
|
self.fan_layout.addWidget(self.fan_lbl)
|
|
self.fan_power_slider = QtWidgets.QSlider(parent=self.fan_group)
|
|
self.fan_power_slider.setMinimumSize(QtCore.QSize(200, 0))
|
|
self.fan_power_slider.setMaximumSize(QtCore.QSize(200, 16777215))
|
|
self.fan_power_slider.setBaseSize(QtCore.QSize(200, 0))
|
|
self.fan_power_slider.setRange(1, 100)
|
|
self.fan_power_slider.setOrientation(QtCore.Qt.Orientation.Horizontal)
|
|
self.fan_layout.addWidget(self.fan_power_slider)
|
|
self.fan_auto_box = QtWidgets.QCheckBox(parent=self.fan_group)
|
|
self.fan_auto_box.setMinimumSize(QtCore.QSize(70, 0))
|
|
self.fan_auto_box.setMaximumSize(QtCore.QSize(70, 16777215))
|
|
self.fan_layout.addWidget(self.fan_auto_box)
|
|
self.fan_pwm_warning = QtWidgets.QLabel(parent=self.fan_group)
|
|
self.fan_pwm_warning.setMinimumSize(QtCore.QSize(16, 0))
|
|
self.fan_layout.addWidget(self.fan_pwm_warning)
|
|
|
|
self.fan_power_slider.valueChanged.connect(self.fan_set_act)
|
|
self.fan_auto_box.stateChanged.connect(self.fan_auto_set_act)
|
|
|
|
self.fan_lbl.setToolTip("Adjust the fan")
|
|
self.fan_lbl.setText("Fan:")
|
|
self.fan_auto_box.setText("Auto")
|
|
|
|
fan = QtWidgets.QWidgetAction(self)
|
|
fan.setDefaultWidget(self.fan_group)
|
|
self.addAction(fan)
|
|
self.fan = fan
|
|
|
|
self.actionReset = QtGui.QAction("Reset Thermostat", self)
|
|
self.actionReset.triggered.connect(self.reset_act)
|
|
self.addAction(self.actionReset)
|
|
|
|
self.actionEnter_DFU_Mode = QtGui.QAction("Enter DFU Mode", self)
|
|
self.actionEnter_DFU_Mode.triggered.connect(self.dfu_act)
|
|
self.addAction(self.actionEnter_DFU_Mode)
|
|
|
|
self.actionnet_settings_input_diag = QtGui.QAction("Set IPV4 Settings", self)
|
|
self.actionnet_settings_input_diag.triggered.connect(self.net_cfg_act)
|
|
self.addAction(self.actionnet_settings_input_diag)
|
|
|
|
@pyqtSlot(bool)
|
|
def load(_):
|
|
self.load_cfg_act.emit(0)
|
|
self.load_cfg_act.emit(1)
|
|
loaded = QtWidgets.QMessageBox(self)
|
|
loaded.setWindowTitle("Config loaded")
|
|
loaded.setText("All channel configs have been loaded from flash.")
|
|
loaded.setIcon(QtWidgets.QMessageBox.Icon.Information)
|
|
loaded.show()
|
|
|
|
self.actionLoad_all_configs = QtGui.QAction("Load Config", self)
|
|
self.actionLoad_all_configs.triggered.connect(load)
|
|
self.addAction(self.actionLoad_all_configs)
|
|
|
|
@pyqtSlot(bool)
|
|
def save(_):
|
|
self.save_cfg_act.emit(0)
|
|
self.save_cfg_act.emit(1)
|
|
saved = QtWidgets.QMessageBox(self)
|
|
saved.setWindowTitle("Config saved")
|
|
saved.setText("All channel configs have been saved to flash.")
|
|
saved.setIcon(QtWidgets.QMessageBox.Icon.Information)
|
|
saved.show()
|
|
|
|
self.actionSave_all_configs = QtGui.QAction("Save Config", self)
|
|
self.actionSave_all_configs.triggered.connect(save)
|
|
self.addAction(self.actionSave_all_configs)
|
|
|
|
def about_thermostat():
|
|
QtWidgets.QMessageBox.about(
|
|
self,
|
|
"About Thermostat",
|
|
f"""
|
|
<h1>Sinara 8451 Thermostat v{self.hw_rev_data['rev']['major']}.{self.hw_rev_data['rev']['minor']}</h1>
|
|
|
|
<br>
|
|
|
|
<h2>Settings:</h2>
|
|
Default fan curve:
|
|
a = {self.hw_rev_data['settings']['fan_k_a']},
|
|
b = {self.hw_rev_data['settings']['fan_k_b']},
|
|
c = {self.hw_rev_data['settings']['fan_k_c']}
|
|
<br>
|
|
Fan PWM range:
|
|
{self.hw_rev_data['settings']['min_fan_pwm']} \u2013 {self.hw_rev_data['settings']['max_fan_pwm']}
|
|
<br>
|
|
Fan PWM frequency: {self.hw_rev_data['settings']['fan_pwm_freq_hz']} Hz
|
|
<br>
|
|
Fan available: {self.hw_rev_data['settings']['fan_available']}
|
|
<br>
|
|
Fan PWM recommended: {self.hw_rev_data['settings']['fan_pwm_recommended']}
|
|
""",
|
|
)
|
|
|
|
self.actionAbout_Thermostat = QtGui.QAction("About Thermostat", self)
|
|
self.actionAbout_Thermostat.triggered.connect(about_thermostat)
|
|
self.addAction(self.actionAbout_Thermostat)
|
|
|
|
def set_fan_pwm_warning(self):
|
|
if self.fan_power_slider.value() != 100:
|
|
pixmapi = getattr(QtWidgets.QStyle.StandardPixmap, "SP_MessageBoxWarning")
|
|
icon = self._style.standardIcon(pixmapi)
|
|
self.fan_pwm_warning.setPixmap(icon.pixmap(16, 16))
|
|
self.fan_pwm_warning.setToolTip(
|
|
"Throttling the fan (not recommended on this hardware rev)"
|
|
)
|
|
else:
|
|
self.fan_pwm_warning.setPixmap(QtGui.QPixmap())
|
|
self.fan_pwm_warning.setToolTip("")
|
|
|
|
@pyqtSlot("QVariantMap")
|
|
def hw_rev(self, hw_rev):
|
|
self.hw_rev_data = hw_rev
|
|
self.fan_group.setEnabled(self.hw_rev_data["settings"]["fan_available"])
|