Fix bugs, grammar, text, and refactor into class

atse 2023-06-30 11:27:31 +08:00
parent 9e3d63c377
commit 8c9d0ffc94
4 changed files with 453 additions and 397 deletions

View File

@ -9,15 +9,51 @@ class Client:
def __init__(self): def __init__(self):
self._reader = None self._reader = None
self._writer = None self._writer = None
self._connecting_task = None
self._command_lock = asyncio.Lock() self._command_lock = asyncio.Lock()
async def connect(self, host='192.168.1.26', port=23, timeout=None): async def connect(self, host='192.168.1.26', port=23, timeout=None):
self._reader, self._writer = await asyncio.open_connection(host, port) """Connect to the TEC with host and port, throws TimeoutError if
unable to connect. Returns True if not cancelled with disconnect.
Example::
client = aioclient.Client()
connected = await client.connect()
if connected:
return
"""
self._connecting_task = asyncio.create_task(asyncio.open_connection(host, port))
try:
self._reader, self._writer = await self._connecting_task
except asyncio.CancelledError:
return False
finally:
self._connecting_task = None
await self._check_zero_limits() await self._check_zero_limits()
return True
def is_connecting(self):
"""Returns True if client is connecting"""
return self._connecting_task is not None
def is_connected(self):
"""Returns True if client is connected"""
return self._writer is not None
async def disconnect(self): async def disconnect(self):
"""Disconnect the client if connected, cancel connection if connecting"""
if self._connecting_task is not None:
self._connecting_task.cancel()
if self._writer is None:
return
# Reader needn't be closed
self._writer.close() self._writer.close()
await self._writer.wait_closed() await self._writer.wait_closed()
self._reader = None
self._writer = None
async def _check_zero_limits(self): async def _check_zero_limits(self):
pwm_report = await self.get_pwm() pwm_report = await self.get_pwm()
@ -145,11 +181,11 @@ class Client:
"""Set configuration parameters """Set configuration parameters
Examples:: Examples::
tec.set_param("pwm", 0, "max_v", 2.0) await tec.set_param("pwm", 0, "max_v", 2.0)
tec.set_param("pid", 1, "output_max", 2.5) await tec.set_param("pid", 1, "output_max", 2.5)
tec.set_param("s-h", 0, "t0", 20.0) await tec.set_param("s-h", 0, "t0", 20.0)
tec.set_param("center", 0, "vref") await tec.set_param("center", 0, "vref")
tec.set_param("postfilter", 1, 21) await tec.set_param("postfilter", 1, 21)
See the firmware's README.md for a full list. See the firmware's README.md for a full list.
""" """

View File

@ -1,4 +1,4 @@
from PyQt6 import QtWidgets, uic from PyQt6 import QtWidgets, QtGui
from PyQt6.QtCore import pyqtSignal, QObject, QSignalBlocker, pyqtSlot from PyQt6.QtCore import pyqtSignal, QObject, QSignalBlocker, pyqtSlot
from pyqtgraph import PlotWidget from pyqtgraph import PlotWidget
from pyqtgraph.parametertree import Parameter, ParameterTree, ParameterItem, registerParameterType from pyqtgraph.parametertree import Parameter, ParameterTree, ParameterItem, registerParameterType
@ -14,15 +14,6 @@ from qasync import asyncSlot, asyncClose
# pyuic6 -x tec_qt.ui -o ui_tec_qt.py # pyuic6 -x tec_qt.ui -o ui_tec_qt.py
from ui_tec_qt import Ui_MainWindow from ui_tec_qt import Ui_MainWindow
tec_client: Client = None
# ui = None
ui: Ui_MainWindow = None
client_watcher = None
client_watcher_task = None
app: QtWidgets.QApplication = None
def get_argparser(): def get_argparser():
parser = argparse.ArgumentParser(description="ARTIQ master") parser = argparse.ArgumentParser(description="ARTIQ master")
@ -38,130 +29,184 @@ def get_argparser():
class ClientWatcher(QObject): class ClientWatcher(QObject):
fan_update = pyqtSignal(object) fan_update = pyqtSignal(dict)
pwm_update = pyqtSignal(object) pwm_update = pyqtSignal(list)
report_update = pyqtSignal(object) report_update = pyqtSignal(list)
pid_update = pyqtSignal(object) pid_update = pyqtSignal(list)
def __init__(self, parent, update_s): def __init__(self, parent, client, update_s):
self.update_s = update_s self.update_s = update_s
self.running = True self.client = client
self.watch_task = None
super().__init__(parent) super().__init__(parent)
async def run(self): async def run(self):
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
while self.running: while True:
time = loop.time() time = loop.time()
await self.update_params() await self.update_params()
await asyncio.sleep(self.update_s - (loop.time() - time)) await asyncio.sleep(self.update_s - (loop.time() - time))
async def update_params(self): async def update_params(self):
self.fan_update.emit(await tec_client.fan()) self.fan_update.emit(await self.client.fan())
def start_watching(self):
self.watch_task = asyncio.create_task(self.run())
def is_watching(self):
return self.watch_task is not None
@pyqtSlot() @pyqtSlot()
def stop_watching(self): def stop_watching(self):
self.running = False if self.watch_task is not None:
self.watch_task.cancel()
self.watch_task = None
@pyqtSlot() @pyqtSlot(float)
def set_update_s(self): def set_update_s(self, update_s):
self.update_s = ui.report_refresh_spin.value() self.update_s = update_s
def on_connection_changed(result): class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
global client_watcher, client_watcher_task def __init__(self, args):
ui.graph_group.setEnabled(result) super().__init__()
ui.hw_rev_lbl.setEnabled(result)
ui.fan_group.setEnabled(result)
ui.report_group.setEnabled(result)
ui.ip_set_line.setEnabled(not result) self.setupUi(self)
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("")
if client_watcher:
client_watcher.stop_watching()
client_watcher = None
client_watcher_task = None
self._set_up_context_menu()
def hw_rev(hw_rev_d: dict): self.fan_power_slider.valueChanged.connect(self.fan_set)
logging.debug(hw_rev_d) self.fan_auto_box.stateChanged.connect(self.fan_auto_set)
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")
self.fan_pwm_recommended = False
def fan_update(fan_settings): self.tec_client = Client()
logging.debug(fan_settings) self.client_watcher = ClientWatcher(self, self.tec_client, self.report_refresh_spin.value())
if fan_settings is None: self.client_watcher.fan_update.connect(self.fan_update)
return self.report_apply_btn.clicked.connect(
with QSignalBlocker(ui.fan_power_slider): lambda: self.client_watcher.set_update_s(self.report_refresh_spin.value())
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):
ui.fan_auto_box.setChecked(fan_settings["auto_mode"])
if args.connect:
if args.IP:
self.ip_set_line.setText(args.IP)
if args.PORT:
self.port_set_spin.setValue(int(args.PORT))
self.connect_btn.click()
@asyncSlot() def _set_up_context_menu(self):
async def fan_set(_): self.menu = QtWidgets.QMenu()
global tec_client self.menu.setTitle('Thermostat settings')
if tec_client is None or ui.fan_auto_box.isChecked():
return
await tec_client.set_param("fan", ui.fan_power_slider.value())
port = QtWidgets.QWidgetAction(self.menu)
port.setDefaultWidget(self.port_set_spin)
self.menu.addAction(port)
self.menu.port = port
@asyncSlot() fan = QtWidgets.QWidgetAction(self.menu)
async def fan_auto_set(enabled): fan.setDefaultWidget(self.fan_group)
global tec_client self.menu.addAction(fan)
if tec_client is None: self.menu.fan = fan
return
ui.fan_power_slider.setEnabled(not enabled)
if enabled:
await tec_client.set_param("fan", "auto")
else:
await tec_client.set_param("fan", ui.fan_power_slider.value())
self.thermostat_settings.setMenu(self.menu)
@asyncSlot() async def _on_connection_changed(self, result):
async def connect(_): self.graph_group.setEnabled(result)
global tec_client, client_watcher, client_watcher_task self.fan_group.setEnabled(result)
ip, port = ui.ip_set_line.text(), ui.port_set_spin.value() self.report_group.setEnabled(result)
try:
if tec_client: self.ip_set_line.setEnabled(not result)
await tec_client.disconnect() self.port_set_spin.setEnabled(not result)
tec_client = None self.connect_btn.setText("Disconnect" if result else "Connect")
on_connection_changed(False) if result:
self.client_watcher.start_watching()
self._status(await self.tec_client.hw_rev())
self.fan_update(await self.tec_client.fan())
else: else:
ui.status_lbl.setText("Connecting...") self.status_lbl.setText("Disconnected")
tec_client = Client() self.fan_pwm_warning.setPixmap(QtGui.QPixmap())
await tec_client.connect(host=ip, port=port, timeout=30) self.fan_pwm_warning.setToolTip("")
on_connection_changed(True) self.client_watcher.stop_watching()
hw_rev(await tec_client.hw_rev())
# fan_update(await tec_client.fan()) def _set_fan_pwm_warning(self):
if client_watcher is None: if self.fan_power_slider.value() != 100:
client_watcher = ClientWatcher(ui.main_widget, ui.report_refresh_spin.value()) pixmapi = getattr(QtWidgets.QStyle.StandardPixmap, "SP_MessageBoxWarning")
client_watcher.fan_update.connect(fan_update) icon = self.style().standardIcon(pixmapi)
ui.report_apply_btn.clicked.connect( self.fan_pwm_warning.setPixmap(icon.pixmap(16, 16))
lambda: client_watcher.set_update_s(ui.report_refresh_spin.value()) self.fan_pwm_warning.setToolTip("Throttling the fan (not recommended on this hardware rev)")
) else:
app.aboutToQuit.connect(client_watcher.stop_watching) self.fan_pwm_warning.setPixmap(QtGui.QPixmap())
client_watcher_task = asyncio.create_task(client_watcher.run()) self.fan_pwm_warning.setToolTip("")
except Exception as e:
logging.error(f"Failed communicating to the {ip}:{port}: {e}") def _status(self, hw_rev_d: dict):
on_connection_changed(False) logging.debug(hw_rev_d)
self.status_lbl.setText(f"Connected to Thermostat v{hw_rev_d['rev']['major']}.{hw_rev_d['rev']['minor']}")
self.fan_group.setEnabled(hw_rev_d["settings"]["fan_available"])
self.fan_pwm_recommended = hw_rev_d["settings"]["fan_pwm_recommended"]
@pyqtSlot(dict)
def fan_update(self, fan_settings: dict):
logging.debug(fan_settings)
if fan_settings is None:
return
with QSignalBlocker(self.fan_power_slider):
self.fan_power_slider.setValue(fan_settings["fan_pwm"] or 100) # 0 = PWM off = full strength
with QSignalBlocker(self.fan_auto_box):
self.fan_auto_box.setChecked(fan_settings["auto_mode"])
if not self.fan_pwm_recommended:
self._set_fan_pwm_warning()
@asyncSlot(int)
async def fan_set(self, value):
if not self.tec_client.is_connected():
return
if self.fan_auto_box.isChecked():
with QSignalBlocker(self.fan_auto_box):
self.fan_auto_box.setChecked(False)
await self.tec_client.set_param("fan", value)
if not self.fan_pwm_recommended:
self._set_fan_pwm_warning()
@asyncSlot(int)
async def fan_auto_set(self, enabled):
if not self.tec_client.is_connected():
return
if enabled:
await self.tec_client.set_param("fan", "auto")
self.fan_update(await self.tec_client.fan())
else:
await self.tec_client.set_param("fan", self.fan_power_slider.value())
@asyncClose
async def closeEvent(self, event):
self.client_watcher.stop_watching()
await self.tec_client.disconnect()
@asyncSlot()
async def on_connect_btn_clicked(self):
ip, port = self.ip_set_line.text(), self.port_set_spin.value()
try:
if not (self.tec_client.is_connecting() or self.tec_client.is_connected()):
self.status_lbl.setText("Connecting...")
self.connect_btn.setText("Stop")
self.ip_set_line.setEnabled(False)
self.port_set_spin.setEnabled(False)
connected = await self.tec_client.connect(host=ip, port=port, timeout=30)
if not connected:
return
await self._on_connection_changed(True)
else:
await self._on_connection_changed(False)
await self.tec_client.disconnect()
except (OSError, TimeoutError) as e:
logging.error(f"Failed communicating to {ip}:{port}: {e}")
await self._on_connection_changed(False)
await self.tec_client.disconnect()
async def coro_main(): async def coro_main():
global ui, app
args = get_argparser().parse_args() args = get_argparser().parse_args()
if args.logLevel: if args.logLevel:
logging.basicConfig(level=getattr(logging, args.logLevel)) logging.basicConfig(level=getattr(logging, args.logLevel))
@ -171,22 +216,7 @@ async def coro_main():
app = QtWidgets.QApplication.instance() app = QtWidgets.QApplication.instance()
app.aboutToQuit.connect(app_quit_event.set) app.aboutToQuit.connect(app_quit_event.set)
main_window = QtWidgets.QMainWindow() main_window = MainWindow(args)
ui = Ui_MainWindow()
ui.setupUi(main_window)
# ui = uic.loadUi('tec_qt.ui', main_window)
ui.connect_btn.clicked.connect(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() main_window.show()
await app_quit_event.wait() await app_quit_event.wait()

View File

@ -273,7 +273,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>120</width> <width>240</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -294,6 +294,16 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QToolButton" name="thermostat_settings">
<property name="text">
<string notr="true">⚙</string>
</property>
<property name="popupMode">
<enum>QToolButton::InstantPopup</enum>
</property>
</widget>
</item>
<item> <item>
<widget class="Line" name="line_0"> <widget class="Line" name="line_0">
<property name="sizePolicy"> <property name="sizePolicy">
@ -307,6 +317,165 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QWidget" name="fan_group" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<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>
<layout class="QHBoxLayout" name="gan_layout">
<property name="spacing">
<number>9</number>
</property>
<item>
<widget class="QLabel" name="fan_pwm_warning">
<property name="minimumSize">
<size>
<width>16</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="fan_lbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Adjust the fan</string>
</property>
<property name="text">
<string>Fan:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="fan_power_slider">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fan_auto_box">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_1">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item> <item>
<widget class="QWidget" name="report_group" native="true"> <widget class="QWidget" name="report_group" native="true">
<property name="enabled"> <property name="enabled">
@ -341,7 +510,7 @@
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<layout class="QHBoxLayout" name="report_layout" stretch="1,1,1"> <layout class="QHBoxLayout" name="report_layout" stretch="0,1,1,1">
<property name="spacing"> <property name="spacing">
<number>6</number> <number>6</number>
</property> </property>
@ -351,6 +520,16 @@
<property name="leftMargin"> <property name="leftMargin">
<number>0</number> <number>0</number>
</property> </property>
<item>
<widget class="QLabel" name="report_lbl">
<property name="text">
<string>Poll every: </string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item> <item>
<widget class="QDoubleSpinBox" name="report_refresh_spin"> <widget class="QDoubleSpinBox" name="report_refresh_spin">
<property name="sizePolicy"> <property name="sizePolicy">
@ -377,6 +556,9 @@
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
<property name="suffix">
<string> s</string>
</property>
<property name="decimals"> <property name="decimals">
<number>1</number> <number>1</number>
</property> </property>
@ -455,193 +637,6 @@
</layout> </layout>
</widget> </widget>
</item> </item>
<item>
<widget class="Line" name="line_1">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="fan_group" native="true">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<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>
<layout class="QHBoxLayout" name="gan_layout">
<property name="spacing">
<number>9</number>
</property>
<item>
<widget class="QLabel" name="fan_lbl">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Fan:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="fan_power_slider">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>200</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fan_auto_box">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>70</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>70</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string>Auto</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="Line" name="line_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="hw_rev_lbl">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<property name="baseSize">
<size>
<width>150</width>
<height>0</height>
</size>
</property>
<property name="text">
<string>Thermostat vX.Y</string>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>

View File

@ -131,11 +131,16 @@ class Ui_MainWindow(object):
sizePolicy.setVerticalStretch(0) sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.status_lbl.sizePolicy().hasHeightForWidth()) sizePolicy.setHeightForWidth(self.status_lbl.sizePolicy().hasHeightForWidth())
self.status_lbl.setSizePolicy(sizePolicy) self.status_lbl.setSizePolicy(sizePolicy)
self.status_lbl.setMinimumSize(QtCore.QSize(120, 0)) self.status_lbl.setMinimumSize(QtCore.QSize(240, 0))
self.status_lbl.setMaximumSize(QtCore.QSize(120, 16777215)) self.status_lbl.setMaximumSize(QtCore.QSize(120, 16777215))
self.status_lbl.setBaseSize(QtCore.QSize(120, 50)) self.status_lbl.setBaseSize(QtCore.QSize(120, 50))
self.status_lbl.setObjectName("status_lbl") self.status_lbl.setObjectName("status_lbl")
self.settings_layout.addWidget(self.status_lbl) self.settings_layout.addWidget(self.status_lbl)
self.thermostat_settings = QtWidgets.QToolButton(parent=self.bottom_settings_group)
self.thermostat_settings.setText("")
self.thermostat_settings.setPopupMode(QtWidgets.QToolButton.ToolButtonPopupMode.InstantPopup)
self.thermostat_settings.setObjectName("thermostat_settings")
self.settings_layout.addWidget(self.thermostat_settings)
self.line_0 = QtWidgets.QFrame(parent=self.bottom_settings_group) self.line_0 = QtWidgets.QFrame(parent=self.bottom_settings_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -146,6 +151,69 @@ class Ui_MainWindow(object):
self.line_0.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken) self.line_0.setFrameShadow(QtWidgets.QFrame.Shadow.Sunken)
self.line_0.setObjectName("line_0") self.line_0.setObjectName("line_0")
self.settings_layout.addWidget(self.line_0) self.settings_layout.addWidget(self.line_0)
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_pwm_warning = QtWidgets.QLabel(parent=self.fan_group)
self.fan_pwm_warning.setMinimumSize(QtCore.QSize(16, 0))
self.fan_pwm_warning.setText("")
self.fan_pwm_warning.setObjectName("fan_pwm_warning")
self.gan_layout.addWidget(self.fan_pwm_warning)
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.setMinimum(1)
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_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.report_group = QtWidgets.QWidget(parent=self.bottom_settings_group) self.report_group = QtWidgets.QWidget(parent=self.bottom_settings_group)
self.report_group.setEnabled(False) self.report_group.setEnabled(False)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding)
@ -164,6 +232,10 @@ class Ui_MainWindow(object):
self.report_layout.setContentsMargins(0, -1, -1, -1) self.report_layout.setContentsMargins(0, -1, -1, -1)
self.report_layout.setSpacing(6) self.report_layout.setSpacing(6)
self.report_layout.setObjectName("report_layout") self.report_layout.setObjectName("report_layout")
self.report_lbl = QtWidgets.QLabel(parent=self.report_group)
self.report_lbl.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight|QtCore.Qt.AlignmentFlag.AlignTrailing|QtCore.Qt.AlignmentFlag.AlignVCenter)
self.report_lbl.setObjectName("report_lbl")
self.report_layout.addWidget(self.report_lbl)
self.report_refresh_spin = QtWidgets.QDoubleSpinBox(parent=self.report_group) self.report_refresh_spin = QtWidgets.QDoubleSpinBox(parent=self.report_group)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Policy.Fixed, QtWidgets.QSizePolicy.Policy.Expanding)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -201,90 +273,11 @@ class Ui_MainWindow(object):
self.report_apply_btn.setBaseSize(QtCore.QSize(80, 0)) self.report_apply_btn.setBaseSize(QtCore.QSize(80, 0))
self.report_apply_btn.setObjectName("report_apply_btn") self.report_apply_btn.setObjectName("report_apply_btn")
self.report_layout.addWidget(self.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(1, 1)
self.report_layout.setStretch(2, 1) self.report_layout.setStretch(2, 1)
self.report_layout.setStretch(3, 1)
self.horizontalLayout_4.addLayout(self.report_layout) self.horizontalLayout_4.addLayout(self.report_layout)
self.settings_layout.addWidget(self.report_group) 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.horizontalLayout_2.addLayout(self.settings_layout)
self.main_layout.addWidget(self.bottom_settings_group) self.main_layout.addWidget(self.bottom_settings_group)
self.gridLayout_2.addLayout(self.main_layout, 0, 1, 1, 1) self.gridLayout_2.addLayout(self.main_layout, 0, 1, 1, 1)
@ -304,11 +297,13 @@ class Ui_MainWindow(object):
self.ip_set_line.setPlaceholderText(_translate("MainWindow", "IP:port for the Thermostat")) self.ip_set_line.setPlaceholderText(_translate("MainWindow", "IP:port for the Thermostat"))
self.connect_btn.setText(_translate("MainWindow", "Connect")) self.connect_btn.setText(_translate("MainWindow", "Connect"))
self.status_lbl.setText(_translate("MainWindow", "Disconnected")) self.status_lbl.setText(_translate("MainWindow", "Disconnected"))
self.report_box.setText(_translate("MainWindow", "Report")) self.fan_lbl.setToolTip(_translate("MainWindow", "Adjust the fan"))
self.report_apply_btn.setText(_translate("MainWindow", "Apply"))
self.fan_lbl.setText(_translate("MainWindow", "Fan:")) self.fan_lbl.setText(_translate("MainWindow", "Fan:"))
self.fan_auto_box.setText(_translate("MainWindow", "Auto")) self.fan_auto_box.setText(_translate("MainWindow", "Auto"))
self.hw_rev_lbl.setText(_translate("MainWindow", "Thermostat vX.Y")) self.report_lbl.setText(_translate("MainWindow", "Poll every: "))
self.report_refresh_spin.setSuffix(_translate("MainWindow", " s"))
self.report_box.setText(_translate("MainWindow", "Report"))
self.report_apply_btn.setText(_translate("MainWindow", "Apply"))
from pyqtgraph import PlotWidget from pyqtgraph import PlotWidget
from pyqtgraph.parametertree import ParameterTree from pyqtgraph.parametertree import ParameterTree