diff --git a/pytec/pytec/client.py b/pytec/pytec/client.py index 915a9db..3a78b46 100644 --- a/pytec/pytec/client.py +++ b/pytec/pytec/client.py @@ -11,6 +11,10 @@ class Client: self._lines = [""] self._check_zero_limits() + def disconnect(self): + self._socket.shutdown(socket.SHUT_RDWR) + self._socket.close() + def _check_zero_limits(self): pwm_report = self.get_pwm() for pwm_channel in pwm_report: @@ -167,3 +171,11 @@ class Client: def load_config(self): """Load current configuration from EEPROM""" self._command("load") + + def hw_rev(self): + """Get Thermostat hardware revision""" + return self._command("hwrev") + + def fan(self): + """Get Thermostat current fan settings""" + return self._command("fan") diff --git a/pytec/tecQT.py b/pytec/tecQT.py index 4a94439..289ad01 100644 --- a/pytec/tecQT.py +++ b/pytec/tecQT.py @@ -10,7 +10,7 @@ from autotune import PIDAutotune, PIDAutotuneState rec_len = 1000 refresh_period = 20 -TECparams = [ [ +TECparams = [[ {'tag': 'report', 'type': 'parent', 'children': [ {'tag': 'pid_engaged', 'type': 'bool', 'value': False}, ]}, @@ -40,25 +40,30 @@ TECparams = [ [ GUIparams = [[ {'name': 'Disable Output', 'type': 'action', 'tip': 'Disable Output'}, {'name': 'Constant Current', 'type': 'group', 'children': [ - {'name': 'Set Current', 'type': 'float', 'value': 0, 'step': 0.1, 'limits': (-3, 3), 'siPrefix': True, 'suffix': 'A'}, - ]}, - {'name': 'Temperature PID', 'type': 'bool', 'value': False, 'children': [ - {'name': 'Set Temperature', 'type': 'float', 'value': 25, 'step': 0.1, 'limits': (-273, 300), 'siPrefix': True, 'suffix': 'C'}, - ]}, - {'name': 'Output Config', 'expanded': False, 'type': 'group', 'children': [ - {'name': 'Max Current', 'type': 'float', 'value': 0, 'step': 0.1, 'limits': (0, 3), 'siPrefix': True, 'suffix': 'A'}, - {'name': 'Max Voltage', 'type': 'float', 'value': 0, 'step': 0.1, 'limits': (0, 5), 'siPrefix': True, 'suffix': 'V'}, + {'name': 'Set Current', 'type': 'float', 'value': 0, 'step': 0.1, 'limits': (-3, 3), 'siPrefix': True, + 'suffix': 'A'}, ]}, - {'name': 'Thermistor Config', 'expanded': False, 'type': 'group', 'children': [ - {'name': 'T0', 'type': 'float', 'value': 25, 'step': 0.1, 'limits': (-100, 100), 'siPrefix': True, 'suffix': 'C'}, + {'name': 'Temperature PID', 'type': 'bool', 'value': False, 'children': [ + {'name': 'Set Temperature', 'type': 'float', 'value': 25, 'step': 0.1, 'limits': (-273, 300), 'siPrefix': True, + 'suffix': 'C'}, + ]}, + {'name': 'Output Config', 'expanded': False, 'type': 'group', 'children': [ + {'name': 'Max Current', 'type': 'float', 'value': 0, 'step': 0.1, 'limits': (0, 3), 'siPrefix': True, + 'suffix': 'A'}, + {'name': 'Max Voltage', 'type': 'float', 'value': 0, 'step': 0.1, 'limits': (0, 5), 'siPrefix': True, + 'suffix': 'V'}, + ]}, + {'name': 'Thermistor Config', 'expanded': False, 'type': 'group', 'children': [ + {'name': 'T0', 'type': 'float', 'value': 25, 'step': 0.1, 'limits': (-100, 100), 'siPrefix': True, + 'suffix': 'C'}, {'name': 'R0', 'type': 'float', 'value': 10000, 'step': 1, 'siPrefix': True, 'suffix': 'Ohm'}, {'name': 'Beta', 'type': 'float', 'value': 3950, 'step': 1}, ]}, - {'name': 'PID Config', 'expanded': False, 'type': 'group', 'children': [ + {'name': 'PID Config', 'expanded': False, 'type': 'group', 'children': [ {'name': 'kP', 'type': 'float', 'value': 0, 'step': 0.1}, {'name': 'kI', 'type': 'float', 'value': 0, 'step': 0.1}, {'name': 'kD', 'type': 'float', 'value': 0, 'step': 0.1}, - {'name': 'PID Auto Tune', 'expanded': False, 'type': 'group', 'children': [ + {'name': 'PID Auto Tune', 'expanded': False, 'type': 'group', 'children': [ {'name': 'Target Temperature', 'type': 'float', 'value': 20, 'step': 0.1, 'siPrefix': True, 'suffix': 'C'}, {'name': 'Test Current', 'type': 'float', 'value': 1, 'step': 0.1, 'siPrefix': True, 'suffix': 'A'}, {'name': 'Temperature Swing', 'type': 'float', 'value': 1.5, 'step': 0.1, 'siPrefix': True, 'suffix': 'C'}, @@ -71,7 +76,8 @@ GUIparams = [[ autoTuner = [PIDAutotune(20, 1, 1, 1.5, refresh_period / 1000), PIDAutotune(20, 1, 1, 1.5, refresh_period / 1000)] -## If anything changes in the tree, print a message + +# If anything changes in the tree, print a message def change(param, changes, ch): print("tree changes:") for param, change, data in changes: @@ -80,75 +86,79 @@ def change(param, changes, ch): childName = '.'.join(path) else: childName = param.name() - print(' parameter: %s'% childName) - print(' change: %s'% change) - print(' data: %s'% str(data)) + print(' parameter: %s' % childName) + print(' change: %s' % change) + print(' data: %s' % str(data)) print(' ----------') - if (childName == 'Disable Output'): + if childName == 'Disable Output': tec.set_param('pwm', ch, 'i_set', 0) - paramList[ch].child('Constant Current').child('Set Current').setValue(0) - paramList[ch].child('Temperature PID').setValue(False) - autoTuner[ch].setOff() + paramList[ch].child('Constant Current').child('Set Current').setValue(0) + paramList[ch].child('Temperature PID').setValue(False) + autoTuner[ch].setOff() - if (childName == 'Temperature PID'): + if childName == 'Temperature PID': if (data): tec.set_param("pwm", ch, "pid") else: - tec.set_param('pwm', ch, 'i_set', paramList[ch].child('Constant Current').child('Set Current').value()) - - if (childName == 'Constant Current.Set Current'): - tec.set_param('pwm', ch, 'i_set', data) - paramList[ch].child('Temperature PID').setValue(False) + tec.set_param('pwm', ch, 'i_set', paramList[ch].child('Constant Current').child('Set Current').value()) - if (childName == 'Temperature PID.Set Temperature'): + if childName == 'Constant Current.Set Current': + tec.set_param('pwm', ch, 'i_set', data) + paramList[ch].child('Temperature PID').setValue(False) + + if childName == 'Temperature PID.Set Temperature': tec.set_param('pid', ch, 'target', data) - if (childName == 'Output Config.Max Current'): + if childName == 'Output Config.Max Current': tec.set_param('pwm', ch, 'max_i_pos', data) tec.set_param('pwm', ch, 'max_i_neg', data) tec.set_param('pid', ch, 'output_min', -data) tec.set_param('pid', ch, 'output_max', data) - if (childName == 'Output Config.Max Voltage'): + if childName == 'Output Config.Max Voltage': tec.set_param('pwm', ch, 'max_v', data) - if (childName == 'Thermistor Config.T0'): + if childName == 'Thermistor Config.T0': tec.set_param('s-h', ch, 't0', data) - if (childName == 'Thermistor Config.R0'): + if childName == 'Thermistor Config.R0': tec.set_param('s-h', ch, 'r0', data) - if (childName == 'Thermistor Config.Beta'): + if childName == 'Thermistor Config.Beta': tec.set_param('s-h', ch, 'b', data) - if (childName == 'PID Config.kP'): + if childName == 'PID Config.kP': tec.set_param('pid', ch, 'kp', data) - if (childName == 'PID Config.kI'): + if childName == 'PID Config.kI': tec.set_param('pid', ch, 'ki', data) - if (childName == 'PID Config.kD'): + if childName == 'PID Config.kD': tec.set_param('pid', ch, 'kd', data) - if (childName == 'PID Config.PID Auto Tune.Run'): - autoTuner[ch].setParam(paramList[ch].child('PID Config').child('PID Auto Tune').child('Target Temperature').value(), - paramList[ch].child('PID Config').child('PID Auto Tune').child('Test Current').value(), - paramList[ch].child('PID Config').child('PID Auto Tune').child('Temperature Swing').value(), - refresh_period / 1000, - 1) + if childName == 'PID Config.PID Auto Tune.Run': + autoTuner[ch].setParam( + paramList[ch].child('PID Config').child('PID Auto Tune').child('Target Temperature').value(), + paramList[ch].child('PID Config').child('PID Auto Tune').child('Test Current').value(), + paramList[ch].child('PID Config').child('PID Auto Tune').child('Temperature Swing').value(), + refresh_period / 1000, + 1) autoTuner[ch].setReady() - paramList[ch].child('Temperature PID').setValue(False) + paramList[ch].child('Temperature PID').setValue(False) - if (childName == 'Save to flash'): + if childName == 'Save to flash': tec.save_config() - + + def change0(param, changes): change(param, changes, 0) + def change1(param, changes): change(param, changes, 1) + class Curves: def __init__(self, legend: str, key: str, channel: int, color: str, buffer_len: int, period: int): self.curveItem = pg.PlotCurveItem(pen=({'color': color, 'width': 1})) @@ -159,21 +169,22 @@ class Curves: self.time_stamp = np.zeros(buffer_len) self.buffLen = buffer_len self.period = period - + def update(self, tec_data, cnt): if cnt == 0: np.copyto(self.data_buf, np.full(self.buffLen, tec_data[self.channel][self.keyStr])) - else: + else: self.data_buf[:-1] = self.data_buf[1:] self.data_buf[-1] = tec_data[self.channel][self.keyStr] self.time_stamp[:-1] = self.time_stamp[1:] self.time_stamp[-1] = cnt * self.period / 1000 - self.curveItem.setData(x = self.time_stamp, y = self.data_buf) + self.curveItem.setData(x=self.time_stamp, y=self.data_buf) + class Graph: def __init__(self, parent: pg.LayoutWidget, title: str, row: int, col: int, curves: list[Curves]): self.plotItem = pg.PlotWidget(title=title) - self.legendItem = pg.LegendItem(offset=(75, 30), brush=(50,50,200,150)) + self.legendItem = pg.LegendItem(offset=(75, 30), brush=(50, 50, 200, 150)) self.legendItem.setParentItem(self.plotItem.getPlotItem()) parent.addWidget(self.plotItem, row, col) self.curves = curves @@ -184,7 +195,9 @@ class Graph: def update(self, tec_data, cnt): for curve in self.curves: curve.update(tec_data, cnt) - self.plotItem.setRange(xRange=[(cnt - self.curves[0].buffLen) * self.curves[0].period / 1000, cnt * self.curves[0].period / 1000]) + self.plotItem.setRange( + xRange=[(cnt - self.curves[0].buffLen) * self.curves[0].period / 1000, cnt * self.curves[0].period / 1000]) + def TECsync(): global TECparams @@ -209,22 +222,32 @@ def TECsync(): if parents['tag'] == 'PIDtarget': for children in parents['children']: children['value'] = tec.get_pid()[channel]['target'] - -def refreshTreeParam(tempTree:dict, channel:int) -> dict: - tempTree['children']['Constant Current']['children']['Set Current']['value'] = TECparams[channel][1]['children'][3]['value'] + + +def refreshTreeParam(tempTree: dict, channel: int) -> dict: + tempTree['children']['Constant Current']['children']['Set Current']['value'] = TECparams[channel][1]['children'][3][ + 'value'] tempTree['children']['Temperature PID']['value'] = TECparams[channel][0]['children'][0]['value'] - tempTree['children']['Temperature PID']['children']['Set Temperature']['value'] = TECparams[channel][4]['children'][0]['value'] - tempTree['children']['Output Config']['children']['Max Current']['value'] = TECparams[channel][1]['children'][0]['value'] - tempTree['children']['Output Config']['children']['Max Voltage']['value'] = TECparams[channel][1]['children'][2]['value'] - tempTree['children']['Thermistor Config']['children']['T0']['value'] = TECparams[channel][3]['children'][0]['value'] - 273.15 + tempTree['children']['Temperature PID']['children']['Set Temperature']['value'] = \ + TECparams[channel][4]['children'][0]['value'] + tempTree['children']['Output Config']['children']['Max Current']['value'] = TECparams[channel][1]['children'][0][ + 'value'] + tempTree['children']['Output Config']['children']['Max Voltage']['value'] = TECparams[channel][1]['children'][2][ + 'value'] + tempTree['children']['Thermistor Config']['children']['T0']['value'] = TECparams[channel][3]['children'][0][ + 'value'] - 273.15 tempTree['children']['Thermistor Config']['children']['R0']['value'] = TECparams[channel][3]['children'][1]['value'] - tempTree['children']['Thermistor Config']['children']['Beta']['value'] = TECparams[channel][3]['children'][2]['value'] + tempTree['children']['Thermistor Config']['children']['Beta']['value'] = TECparams[channel][3]['children'][2][ + 'value'] tempTree['children']['PID Config']['children']['kP']['value'] = TECparams[channel][2]['children'][0]['value'] tempTree['children']['PID Config']['children']['kI']['value'] = TECparams[channel][2]['children'][1]['value'] tempTree['children']['PID Config']['children']['kD']['value'] = TECparams[channel][2]['children'][2]['value'] return tempTree + cnt = 0 + + def updateData(): global cnt for data in tec.report_mode(): @@ -234,13 +257,13 @@ def updateData(): ch0currentGraph.update(data, cnt) ch1currentGraph.update(data, cnt) - for channel in range (2): + for channel in range(2): if (autoTuner[channel].state() == PIDAutotuneState.STATE_READY or - autoTuner[channel].state() == PIDAutotuneState.STATE_RELAY_STEP_UP or - autoTuner[channel].state() == PIDAutotuneState.STATE_RELAY_STEP_DOWN): + autoTuner[channel].state() == PIDAutotuneState.STATE_RELAY_STEP_UP or + autoTuner[channel].state() == PIDAutotuneState.STATE_RELAY_STEP_DOWN): autoTuner[channel].run(data[channel]['temperature'], data[channel]['time']) tec.set_param('pwm', channel, 'i_set', autoTuner[channel].output()) - elif (autoTuner[channel].state() == PIDAutotuneState.STATE_SUCCEEDED): + elif autoTuner[channel].state() == PIDAutotuneState.STATE_SUCCEEDED: kp, ki, kd = autoTuner[channel].get_tec_pid() autoTuner[channel].setOff() paramList[channel].child('PID Config').child('kP').setValue(kp) @@ -249,14 +272,14 @@ def updateData(): tec.set_param('pid', channel, 'kp', kp) tec.set_param('pid', channel, 'ki', ki) tec.set_param('pid', channel, 'kd', kd) - elif (autoTuner[channel].state() == PIDAutotuneState.STATE_FAILED): + elif autoTuner[channel].state() == PIDAutotuneState.STATE_FAILED: tec.set_param('pwm', channel, 'i_set', 0) autoTuner[channel].setOff() - + if quit: break - cnt += 1 - + cnt += 1 + if __name__ == '__main__': tec = Client(host="192.168.1.26", port=23, timeout=None) @@ -265,7 +288,7 @@ if __name__ == '__main__': pg.setConfigOptions(antialias=True) mw = QtGui.QMainWindow() mw.setWindowTitle('Thermostat Control Panel') - mw.resize(1920,1200) + mw.resize(1920, 1200) cw = QtGui.QWidget() mw.setCentralWidget(cw) l = QtGui.QVBoxLayout() @@ -278,7 +301,7 @@ if __name__ == '__main__': Parameter.create(name='GUIparams', type='group', children=GUIparams[1])] ch0Tree = ParameterTree() - ch0Tree.setParameters(paramList[0], showTop=False) + ch0Tree.setParameters(paramList[0], showTop=False) ch1Tree = ParameterTree() ch1Tree.setParameters(paramList[1], showTop=False) @@ -292,12 +315,16 @@ if __name__ == '__main__': layout.addWidget(ch0Tree, 1, 1, 1, 1) layout.addWidget(ch1Tree, 2, 1, 1, 1) - ch0tempGraph = Graph(layout, 'Channel 0 Temperature', 1, 2, [Curves('Feedback', 'temperature', 0, 'r', rec_len, refresh_period)]) - ch1tempGraph = Graph(layout, 'Channel 1 Temperature', 2, 2, [Curves('Feedback', 'temperature', 1, 'r', rec_len, refresh_period)]) - ch0currentGraph = Graph(layout, 'Channel 0 Current', 1, 3, [Curves('Feedback', 'tec_i', 0, 'r', rec_len, refresh_period), - Curves('Setpoint', 'i_set', 0, 'g', rec_len, refresh_period)]) - ch1currentGraph = Graph(layout, 'Channel 1 Current', 2, 3, [Curves('Feedback', 'tec_i', 1, 'r', rec_len, refresh_period), - Curves('Setpoint', 'i_set', 1, 'g', rec_len, refresh_period)]) + ch0tempGraph = Graph(layout, 'Channel 0 Temperature', 1, 2, + [Curves('Feedback', 'temperature', 0, 'r', rec_len, refresh_period)]) + ch1tempGraph = Graph(layout, 'Channel 1 Temperature', 2, 2, + [Curves('Feedback', 'temperature', 1, 'r', rec_len, refresh_period)]) + ch0currentGraph = Graph(layout, 'Channel 0 Current', 1, 3, + [Curves('Feedback', 'tec_i', 0, 'r', rec_len, refresh_period), + Curves('Setpoint', 'i_set', 0, 'g', rec_len, refresh_period)]) + ch1currentGraph = Graph(layout, 'Channel 1 Current', 2, 3, + [Curves('Feedback', 'tec_i', 1, 'r', rec_len, refresh_period), + Curves('Setpoint', 'i_set', 1, 'g', rec_len, refresh_period)]) t = QtCore.QTimer() t.timeout.connect(updateData) @@ -305,4 +332,4 @@ if __name__ == '__main__': mw.show() - pg.exec() \ No newline at end of file + pg.exec() diff --git a/pytec/tec_qt.py b/pytec/tec_qt.py new file mode 100644 index 0000000..8ee039a --- /dev/null +++ b/pytec/tec_qt.py @@ -0,0 +1,183 @@ +from PyQt6 import QtWidgets, uic +from PyQt6.QtCore import QThread, QThreadPool, pyqtSignal, QRunnable, QObject, QSignalBlocker, pyqtSlot +from pyqtgraph import PlotWidget +from pyqtgraph.parametertree import Parameter, ParameterTree, ParameterItem, registerParameterType +import pyqtgraph as pg +import sys +import argparse +import logging +from pytec.client import Client + +# pyuic6 -x tec_qt.ui -o ui_tec_qt.py +from ui_tec_qt import Ui_MainWindow + +tec_client: Client = None + +# ui = None +ui: Ui_MainWindow = None + +thread_pool = QThreadPool.globalInstance() +connection_watcher = None + + +def get_argparser(): + parser = argparse.ArgumentParser(description="ARTIQ master") + + parser.add_argument("--connect", default=None, action="store_true", + help="Automatically connect to the specified Thermostat in IP:port format") + parser.add_argument('IP', metavar="ip", default=None, nargs='?') + parser.add_argument('PORT', metavar="port", default=None, nargs='?') + parser.add_argument("-l", "--log", dest="logLevel", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], + help="Set the logging level") + + return parser + + +class WatchConnectTask(QThread): + connected = pyqtSignal(bool) + hw_rev = pyqtSignal(dict) + connecting = pyqtSignal() + fan_update = pyqtSignal(object) + + def __init__(self, ip, port, parent): + self.ip = ip + self.port = port + super().__init__(parent) + + def run(self): + global tec_client + try: + if tec_client: + tec_client.disconnect() + tec_client = None + self.connected.emit(False) + else: + self.connecting.emit() + tec_client = Client(host=self.ip, port=self.port, timeout=30) + self.connected.emit(True) + self.hw_rev.emit(tec_client.hw_rev()) + self.fan_update.emit(tec_client.fan()) + except Exception as e: + logging.error(f"Failed communicating to the {self.ip}:{self.port}: {e}") + self.connected.emit(False) + + @pyqtSlot() + def client_disconnected(self): + global tec_client + if tec_client: + tec_client.disconnect() + tec_client = None + self.connected.emit(False) + + +class ClientTask(QRunnable): + def __init__(self, func, *args, **kwargs): + self.func = func + self.args = args + self.kwargs = kwargs + super().__init__() + + def run(self) -> None: + try: + self.func(*self.args, **self.kwargs) + except (TimeoutError, OSError): + logging.warning("Client connection error, disconnecting", exc_info=True) + if connection_watcher: + connection_watcher.client_disconnected() + + +def connected(result): + ui.graph_group.setEnabled(result) + ui.hw_rev_lbl.setEnabled(result) + ui.fan_group.setEnabled(result) + ui.report_group.setEnabled(result) + + ui.ip_set_line.setEnabled(not result) + ui.port_set_spin.setEnabled(not result) + ui.status_lbl.setText("Connected" if result else "Disconnected") + ui.connect_btn.setText("Disconnect" if result else "Connect") + if not result: + ui.hw_rev_lbl.setText("Thermostat vX.Y") + ui.fan_group.setStyleSheet("") + + +def hw_rev(hw_rev_d: dict): + logging.debug(hw_rev_d) + ui.hw_rev_lbl.setText(f"Thermostat v{hw_rev_d['rev']['major']}.{hw_rev_d['rev']['major']}") + ui.fan_group.setEnabled(hw_rev_d["settings"]["fan_available"]) + if hw_rev_d["settings"]["fan_pwm_recommended"]: + ui.fan_group.setStyleSheet("") + ui.fan_group.setToolTip("") + else: + ui.fan_group.setStyleSheet("background-color: yellow") + ui.fan_group.setToolTip("Changing the fan settings of not recommended") + + +def fan_update(fan_settings): + logging.debug(fan_settings) + if fan_settings is None: + return + with QSignalBlocker(ui.fan_power_slider) as _: + ui.fan_power_slider.setValue(fan_settings["fan_pwm"]) + ui.fan_power_slider.setEnabled(not fan_settings["auto_mode"]) + with QSignalBlocker(ui.fan_auto_box) as _: + ui.fan_auto_box.setChecked(fan_settings["auto_mode"]) + + +def fan_set(): + global tec_client + if tec_client is None or ui.fan_auto_box.isChecked(): + return + thread_pool.start(ClientTask(lambda: tec_client.set_param("fan", ui.fan_power_slider.value()))) + + +def fan_auto_set(enabled): + global tec_client + if tec_client is None: + return + ui.fan_power_slider.setEnabled(not enabled) + if enabled: + thread_pool.start(ClientTask(lambda: tec_client.set_param("fan", "auto"))) + else: + thread_pool.start(ClientTask(lambda: tec_client.set_param("fan", ui.fan_power_slider.value()))) + + +def connect(): + global connection_watcher + connection_watcher = WatchConnectTask(ui.ip_set_line.text(), ui.port_set_spin.value(), ui.main_widget) + connection_watcher.connected.connect(connected) + connection_watcher.connecting.connect(lambda: ui.status_lbl.setText("Connecting...")) + connection_watcher.hw_rev.connect(hw_rev) + connection_watcher.fan_update.connect(fan_update) + connection_watcher.start() + + +def main(): + global ui + args = get_argparser().parse_args() + if args.logLevel: + logging.basicConfig(level=getattr(logging, args.logLevel)) + + app = QtWidgets.QApplication(sys.argv) + main_window = QtWidgets.QMainWindow() + #ui = Ui_MainWindow() + #ui.setupUi(main_window) + ui = uic.loadUi('tec_qt.ui', main_window) + + ui.connect_btn.clicked.connect(lambda _checked: connect()) + ui.fan_power_slider.valueChanged.connect(fan_set) + ui.fan_auto_box.stateChanged.connect(fan_auto_set) + + if args.connect: + if args.IP: + ui.ip_set_line.setText(args.IP) + if args.PORT: + ui.port_set_spin.setValue(int(args.PORT)) + ui.connect_btn.click() + + main_window.show() + sys.exit(app.exec()) + + +if __name__ == '__main__': + main() diff --git a/pytec/tec_qt.ui b/pytec/tec_qt.ui new file mode 100644 index 0000000..58f5849 --- /dev/null +++ b/pytec/tec_qt.ui @@ -0,0 +1,671 @@ + + + MainWindow + + + + 0 + 0 + 1280 + 720 + + + + + 1280 + 720 + + + + + 3840 + 2160 + + + + Control TEC + + + + + 1 + 1 + + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + 0 + + + + + false + + + + 1 + 1 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + QLayout::SetDefaultConstraint + + + 3 + + + 3 + + + 3 + + + 3 + + + 2 + + + + + + + + + + + Channel 1 Temperature + + + + + + + Channel 0 Temperature + + + + + + + Channel 0 Current + + + + + + + Channel 1 Current + + + + + + + + + + + 0 + 0 + + + + + 0 + 40 + + + + + 16777215 + 40 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 3 + + + 3 + + + 3 + + + 3 + + + 3 + + + + + + + + 0 + 0 + + + + + 160 + 0 + + + + + 160 + 16777215 + + + + 192.168.1.26 + + + 15 + + + IP:port for the Thermostat + + + true + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 70 + 16777215 + + + + 65535 + + + 23 + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 100 + 0 + + + + Connect + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + 120 + 16777215 + + + + + 120 + 50 + + + + Disconnected + + + + + + + + 0 + 0 + + + + Qt::Vertical + + + + + + + false + + + + 0 + 0 + + + + + 40 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 6 + + + QLayout::SetDefaultConstraint + + + 0 + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 70 + 16777215 + + + + + 70 + 0 + + + + 1 + + + 0.100000000000000 + + + 0.100000000000000 + + + QAbstractSpinBox::AdaptiveDecimalStepType + + + 1.000000000000000 + + + + + + + + 0 + 0 + + + + + 80 + 16777215 + + + + + 80 + 0 + + + + Report + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + + 80 + 0 + + + + Apply + + + + + + + + + + + + + 0 + 0 + + + + Qt::Vertical + + + + + + + false + + + + 40 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + 9 + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 40 + 16777215 + + + + + 40 + 0 + + + + Fan: + + + + + + + + 0 + 0 + + + + + 200 + 0 + + + + + 200 + 16777215 + + + + + 200 + 0 + + + + 100 + + + Qt::Horizontal + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 70 + 16777215 + + + + Auto + + + + + + + + + + + + + 0 + 0 + + + + Qt::Vertical + + + + + + + false + + + + 0 + 0 + + + + + 150 + 0 + + + + + 150 + 16777215 + + + + + 150 + 0 + + + + Thermostat vX.Y + + + + + + + + + + + + + + + + PlotWidget + QWidget +
pyqtgraph
+ 1 +
+ + ParameterTree + QWidget +
pyqtgraph.parametertree
+ 1 +
+
+ + +
diff --git a/pytec/ui_tec_qt.py b/pytec/ui_tec_qt.py new file mode 100644 index 0000000..b26d878 --- /dev/null +++ b/pytec/ui_tec_qt.py @@ -0,0 +1,323 @@ +# Form implementation generated from reading ui file 'tec_qt.ui' +# +# Created by: PyQt6 UI code generator 6.4.2 +# +# WARNING: Any manual changes made to this file will be lost when pyuic6 is +# run again. Do not edit this file unless you know what you are doing. + + +from PyQt6 import QtCore, QtGui, QtWidgets + + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + MainWindow.setObjectName("MainWindow") + MainWindow.resize(1280, 720) + MainWindow.setMinimumSize(QtCore.QSize(1280, 720)) + MainWindow.setMaximumSize(QtCore.QSize(3840, 2160)) + self.main_widget = QtWidgets.QWidget(parent=MainWindow) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(1) + sizePolicy.setHeightForWidth(self.main_widget.sizePolicy().hasHeightForWidth()) + self.main_widget.setSizePolicy(sizePolicy) + self.main_widget.setObjectName("main_widget") + self.gridLayout_2 = QtWidgets.QGridLayout(self.main_widget) + self.gridLayout_2.setContentsMargins(3, 3, 3, 3) + self.gridLayout_2.setSpacing(3) + self.gridLayout_2.setObjectName("gridLayout_2") + self.main_layout = QtWidgets.QVBoxLayout() + self.main_layout.setSpacing(0) + self.main_layout.setObjectName("main_layout") + self.graph_group = QtWidgets.QFrame(parent=self.main_widget) + self.graph_group.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(1) + sizePolicy.setVerticalStretch(1) + sizePolicy.setHeightForWidth(self.graph_group.sizePolicy().hasHeightForWidth()) + self.graph_group.setSizePolicy(sizePolicy) + self.graph_group.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.graph_group.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.graph_group.setObjectName("graph_group") + self.graphs_layout = QtWidgets.QGridLayout(self.graph_group) + self.graphs_layout.setSizeConstraint(QtWidgets.QLayout.SizeConstraint.SetDefaultConstraint) + self.graphs_layout.setContentsMargins(3, 3, 3, 3) + self.graphs_layout.setSpacing(2) + self.graphs_layout.setObjectName("graphs_layout") + self.ch1_tree = ParameterTree(parent=self.graph_group) + self.ch1_tree.setObjectName("ch1_tree") + self.graphs_layout.addWidget(self.ch1_tree, 1, 0, 1, 1) + self.ch0_tree = ParameterTree(parent=self.graph_group) + self.ch0_tree.setObjectName("ch0_tree") + self.graphs_layout.addWidget(self.ch0_tree, 0, 0, 1, 1) + self.ch1_t_graph = PlotWidget(parent=self.graph_group) + self.ch1_t_graph.setObjectName("ch1_t_graph") + self.graphs_layout.addWidget(self.ch1_t_graph, 1, 1, 1, 1) + self.ch0_t_graph = PlotWidget(parent=self.graph_group) + self.ch0_t_graph.setObjectName("ch0_t_graph") + self.graphs_layout.addWidget(self.ch0_t_graph, 0, 1, 1, 1) + self.ch0_i_graph = PlotWidget(parent=self.graph_group) + self.ch0_i_graph.setObjectName("ch0_i_graph") + self.graphs_layout.addWidget(self.ch0_i_graph, 0, 2, 1, 1) + self.ch1_i_graph = PlotWidget(parent=self.graph_group) + self.ch1_i_graph.setObjectName("ch1_i_graph") + self.graphs_layout.addWidget(self.ch1_i_graph, 1, 2, 1, 1) + self.graphs_layout.setColumnMinimumWidth(0, 100) + self.graphs_layout.setColumnMinimumWidth(1, 100) + self.graphs_layout.setColumnMinimumWidth(2, 100) + self.graphs_layout.setRowMinimumHeight(0, 100) + self.graphs_layout.setRowMinimumHeight(1, 100) + self.graphs_layout.setColumnStretch(0, 1) + self.graphs_layout.setColumnStretch(1, 1) + self.graphs_layout.setColumnStretch(2, 1) + self.graphs_layout.setRowStretch(0, 1) + self.graphs_layout.setRowStretch(1, 1) + self.main_layout.addWidget(self.graph_group) + self.bottom_settings_group = QtWidgets.QFrame(parent=self.main_widget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.bottom_settings_group.sizePolicy().hasHeightForWidth()) + self.bottom_settings_group.setSizePolicy(sizePolicy) + self.bottom_settings_group.setMinimumSize(QtCore.QSize(0, 40)) + self.bottom_settings_group.setMaximumSize(QtCore.QSize(16777215, 40)) + self.bottom_settings_group.setFrameShape(QtWidgets.QFrame.Shape.StyledPanel) + self.bottom_settings_group.setFrameShadow(QtWidgets.QFrame.Shadow.Raised) + self.bottom_settings_group.setObjectName("bottom_settings_group") + self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.bottom_settings_group) + self.horizontalLayout_2.setContentsMargins(3, 3, 3, 3) + self.horizontalLayout_2.setSpacing(3) + self.horizontalLayout_2.setObjectName("horizontalLayout_2") + self.settings_layout = QtWidgets.QHBoxLayout() + self.settings_layout.setObjectName("settings_layout") + self.ip_set_line = QtWidgets.QLineEdit(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.ip_set_line.sizePolicy().hasHeightForWidth()) + self.ip_set_line.setSizePolicy(sizePolicy) + self.ip_set_line.setMinimumSize(QtCore.QSize(160, 0)) + self.ip_set_line.setMaximumSize(QtCore.QSize(160, 16777215)) + self.ip_set_line.setMaxLength(15) + self.ip_set_line.setClearButtonEnabled(True) + self.ip_set_line.setObjectName("ip_set_line") + self.settings_layout.addWidget(self.ip_set_line) + self.port_set_spin = QtWidgets.QSpinBox(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Fixed) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.port_set_spin.sizePolicy().hasHeightForWidth()) + self.port_set_spin.setSizePolicy(sizePolicy) + self.port_set_spin.setMinimumSize(QtCore.QSize(70, 0)) + self.port_set_spin.setMaximumSize(QtCore.QSize(70, 16777215)) + self.port_set_spin.setMaximum(65535) + self.port_set_spin.setProperty("value", 23) + self.port_set_spin.setObjectName("port_set_spin") + self.settings_layout.addWidget(self.port_set_spin) + self.connect_btn = QtWidgets.QPushButton(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.connect_btn.sizePolicy().hasHeightForWidth()) + self.connect_btn.setSizePolicy(sizePolicy) + self.connect_btn.setMinimumSize(QtCore.QSize(100, 0)) + self.connect_btn.setMaximumSize(QtCore.QSize(100, 16777215)) + self.connect_btn.setBaseSize(QtCore.QSize(100, 0)) + self.connect_btn.setObjectName("connect_btn") + self.settings_layout.addWidget(self.connect_btn) + self.status_lbl = QtWidgets.QLabel(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.status_lbl.sizePolicy().hasHeightForWidth()) + self.status_lbl.setSizePolicy(sizePolicy) + self.status_lbl.setMinimumSize(QtCore.QSize(120, 0)) + self.status_lbl.setMaximumSize(QtCore.QSize(120, 16777215)) + self.status_lbl.setBaseSize(QtCore.QSize(120, 50)) + self.status_lbl.setObjectName("status_lbl") + self.settings_layout.addWidget(self.status_lbl) + self.line_0 = QtWidgets.QFrame(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.line_0.sizePolicy().hasHeightForWidth()) + self.line_0.setSizePolicy(sizePolicy) + self.line_0.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_0.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_0.setObjectName("line_0") + self.settings_layout.addWidget(self.line_0) + self.report_group = QtWidgets.QWidget(parent=self.bottom_settings_group) + self.report_group.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.report_group.sizePolicy().hasHeightForWidth()) + self.report_group.setSizePolicy(sizePolicy) + self.report_group.setMinimumSize(QtCore.QSize(40, 0)) + self.report_group.setObjectName("report_group") + self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.report_group) + self.horizontalLayout_4.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_4.setSpacing(0) + self.horizontalLayout_4.setObjectName("horizontalLayout_4") + self.report_layout = QtWidgets.QHBoxLayout() + self.report_layout.setSizeConstraint(QtWidgets.QLayout.SizeConstraint.SetDefaultConstraint) + self.report_layout.setContentsMargins(0, -1, -1, -1) + self.report_layout.setSpacing(6) + self.report_layout.setObjectName("report_layout") + self.report_refresh_spin = QtWidgets.QDoubleSpinBox(parent=self.report_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.report_refresh_spin.sizePolicy().hasHeightForWidth()) + self.report_refresh_spin.setSizePolicy(sizePolicy) + self.report_refresh_spin.setMinimumSize(QtCore.QSize(70, 0)) + self.report_refresh_spin.setMaximumSize(QtCore.QSize(70, 16777215)) + self.report_refresh_spin.setBaseSize(QtCore.QSize(70, 0)) + self.report_refresh_spin.setDecimals(1) + self.report_refresh_spin.setMinimum(0.1) + self.report_refresh_spin.setSingleStep(0.1) + self.report_refresh_spin.setStepType(QtWidgets.QAbstractSpinBox.StepType.AdaptiveDecimalStepType) + self.report_refresh_spin.setProperty("value", 1.0) + self.report_refresh_spin.setObjectName("report_refresh_spin") + self.report_layout.addWidget(self.report_refresh_spin) + self.report_box = QtWidgets.QCheckBox(parent=self.report_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.report_box.sizePolicy().hasHeightForWidth()) + self.report_box.setSizePolicy(sizePolicy) + self.report_box.setMaximumSize(QtCore.QSize(80, 16777215)) + self.report_box.setBaseSize(QtCore.QSize(80, 0)) + self.report_box.setObjectName("report_box") + self.report_layout.addWidget(self.report_box) + self.report_apply_btn = QtWidgets.QPushButton(parent=self.report_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.report_apply_btn.sizePolicy().hasHeightForWidth()) + self.report_apply_btn.setSizePolicy(sizePolicy) + self.report_apply_btn.setMinimumSize(QtCore.QSize(80, 0)) + self.report_apply_btn.setMaximumSize(QtCore.QSize(80, 16777215)) + self.report_apply_btn.setBaseSize(QtCore.QSize(80, 0)) + self.report_apply_btn.setObjectName("report_apply_btn") + self.report_layout.addWidget(self.report_apply_btn) + self.report_layout.setStretch(0, 1) + self.report_layout.setStretch(1, 1) + self.report_layout.setStretch(2, 1) + self.horizontalLayout_4.addLayout(self.report_layout) + self.settings_layout.addWidget(self.report_group) + self.line_1 = QtWidgets.QFrame(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.line_1.sizePolicy().hasHeightForWidth()) + self.line_1.setSizePolicy(sizePolicy) + self.line_1.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_1.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_1.setObjectName("line_1") + self.settings_layout.addWidget(self.line_1) + self.fan_group = QtWidgets.QWidget(parent=self.bottom_settings_group) + self.fan_group.setEnabled(False) + self.fan_group.setMinimumSize(QtCore.QSize(40, 0)) + self.fan_group.setObjectName("fan_group") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout(self.fan_group) + self.horizontalLayout_6.setContentsMargins(0, 0, 0, 0) + self.horizontalLayout_6.setSpacing(0) + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.gan_layout = QtWidgets.QHBoxLayout() + self.gan_layout.setSpacing(9) + self.gan_layout.setObjectName("gan_layout") + self.fan_lbl = QtWidgets.QLabel(parent=self.fan_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.fan_lbl.sizePolicy().hasHeightForWidth()) + self.fan_lbl.setSizePolicy(sizePolicy) + 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_lbl.setObjectName("fan_lbl") + self.gan_layout.addWidget(self.fan_lbl) + self.fan_power_slider = QtWidgets.QSlider(parent=self.fan_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.fan_power_slider.sizePolicy().hasHeightForWidth()) + self.fan_power_slider.setSizePolicy(sizePolicy) + 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.setMaximum(100) + self.fan_power_slider.setOrientation(QtCore.Qt.Orientation.Horizontal) + self.fan_power_slider.setObjectName("fan_power_slider") + self.gan_layout.addWidget(self.fan_power_slider) + self.fan_auto_box = QtWidgets.QCheckBox(parent=self.fan_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.fan_auto_box.sizePolicy().hasHeightForWidth()) + self.fan_auto_box.setSizePolicy(sizePolicy) + self.fan_auto_box.setMinimumSize(QtCore.QSize(70, 0)) + self.fan_auto_box.setMaximumSize(QtCore.QSize(70, 16777215)) + self.fan_auto_box.setObjectName("fan_auto_box") + self.gan_layout.addWidget(self.fan_auto_box) + self.horizontalLayout_6.addLayout(self.gan_layout) + self.settings_layout.addWidget(self.fan_group) + self.line_3 = QtWidgets.QFrame(parent=self.bottom_settings_group) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.line_3.sizePolicy().hasHeightForWidth()) + self.line_3.setSizePolicy(sizePolicy) + self.line_3.setFrameShape(QtWidgets.QFrame.Shape.VLine) + self.line_3.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) + self.line_3.setObjectName("line_3") + self.settings_layout.addWidget(self.line_3) + self.hw_rev_lbl = QtWidgets.QLabel(parent=self.bottom_settings_group) + self.hw_rev_lbl.setEnabled(False) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.hw_rev_lbl.sizePolicy().hasHeightForWidth()) + self.hw_rev_lbl.setSizePolicy(sizePolicy) + self.hw_rev_lbl.setMinimumSize(QtCore.QSize(150, 0)) + self.hw_rev_lbl.setMaximumSize(QtCore.QSize(150, 16777215)) + self.hw_rev_lbl.setBaseSize(QtCore.QSize(150, 0)) + self.hw_rev_lbl.setObjectName("hw_rev_lbl") + self.settings_layout.addWidget(self.hw_rev_lbl) + self.horizontalLayout_2.addLayout(self.settings_layout) + self.main_layout.addWidget(self.bottom_settings_group) + self.gridLayout_2.addLayout(self.main_layout, 0, 1, 1, 1) + MainWindow.setCentralWidget(self.main_widget) + + self.retranslateUi(MainWindow) + QtCore.QMetaObject.connectSlotsByName(MainWindow) + + def retranslateUi(self, MainWindow): + _translate = QtCore.QCoreApplication.translate + MainWindow.setWindowTitle(_translate("MainWindow", "Control TEC")) + self.ch1_t_graph.setTitle(_translate("MainWindow", "Channel 1 Temperature")) + self.ch0_t_graph.setTitle(_translate("MainWindow", "Channel 0 Temperature")) + self.ch0_i_graph.setTitle(_translate("MainWindow", "Channel 0 Current")) + self.ch1_i_graph.setTitle(_translate("MainWindow", "Channel 1 Current")) + self.ip_set_line.setText(_translate("MainWindow", "192.168.1.26")) + self.ip_set_line.setPlaceholderText(_translate("MainWindow", "IP:port for the Thermostat")) + self.connect_btn.setText(_translate("MainWindow", "Connect")) + self.status_lbl.setText(_translate("MainWindow", "Disconnected")) + self.report_box.setText(_translate("MainWindow", "Report")) + self.report_apply_btn.setText(_translate("MainWindow", "Apply")) + self.fan_lbl.setText(_translate("MainWindow", "Fan:")) + self.fan_auto_box.setText(_translate("MainWindow", "Auto")) + self.hw_rev_lbl.setText(_translate("MainWindow", "Thermostat vX.Y")) +from pyqtgraph import PlotWidget +from pyqtgraph.parametertree import ParameterTree + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + MainWindow = QtWidgets.QMainWindow() + ui = Ui_MainWindow() + ui.setupUi(MainWindow) + MainWindow.show() + sys.exit(app.exec())