forked from M-Labs/thermostat
Compare commits
11 Commits
9acff86547
...
93d6df5e92
Author | SHA1 | Date |
---|---|---|
linuswck | 93d6df5e92 | |
atse | 44bea87f03 | |
atse | e6f62e9e19 | |
atse | 271fe449ba | |
atse | 70db0a39eb | |
atse | 26c7382b1e | |
atse | c415d9de8a | |
atse | 7069111e21 | |
atse | 1707728c3c | |
atse | a16d2e9a9e | |
atse | bc4ac43e0b |
|
@ -62,7 +62,7 @@
|
||||||
format = "pyproject";
|
format = "pyproject";
|
||||||
src = pkgs.fetchPypi {
|
src = pkgs.fetchPypi {
|
||||||
inherit pname version;
|
inherit pname version;
|
||||||
sha256 = "sha256-jcdo/R7l3hBEx8MF7M8tOdJNh4A+pxGJ1AJPtHX0mF8=";
|
hash = "sha256-jcdo/R7l3hBEx8MF7M8tOdJNh4A+pxGJ1AJPtHX0mF8=";
|
||||||
};
|
};
|
||||||
buildInputs = [ pkgs.python3Packages.poetry-core ];
|
buildInputs = [ pkgs.python3Packages.poetry-core ];
|
||||||
propagatedBuildInputs = [ pkgs.python3Packages.pyqt6 ];
|
propagatedBuildInputs = [ pkgs.python3Packages.pyqt6 ];
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
format = "pyproject";
|
format = "pyproject";
|
||||||
src = pkgs.fetchPypi {
|
src = pkgs.fetchPypi {
|
||||||
inherit pname version;
|
inherit pname version;
|
||||||
sha256 = "sha256-WBCNhBHHBU4IQdi3ke6F4QH8KWubNZwOAd3jipj/Ks4=";
|
hash = "sha256-WBCNhBHHBU4IQdi3ke6F4QH8KWubNZwOAd3jipj/Ks4=";
|
||||||
};
|
};
|
||||||
propagatedBuildInputs = with pkgs.python3Packages; [ numpy pyqt6 ];
|
propagatedBuildInputs = with pkgs.python3Packages; [ numpy pyqt6 ];
|
||||||
};
|
};
|
||||||
|
@ -85,7 +85,7 @@
|
||||||
format = "pyproject";
|
format = "pyproject";
|
||||||
src = pkgs.fetchPypi {
|
src = pkgs.fetchPypi {
|
||||||
inherit pname version;
|
inherit pname version;
|
||||||
sha256 = "sha256-jqj8X6H1N5mJQ4OrY5ANqRB0YJByqg/bNneEALWmH1A=";
|
hash = "sha256-jqj8X6H1N5mJQ4OrY5ANqRB0YJByqg/bNneEALWmH1A=";
|
||||||
};
|
};
|
||||||
buildInputs = [ pkgs.python3Packages.poetry-core ];
|
buildInputs = [ pkgs.python3Packages.poetry-core ];
|
||||||
propagatedBuildInputs = [ pyqtgraph pkgs.python3Packages.numpy ];
|
propagatedBuildInputs = [ pyqtgraph pkgs.python3Packages.numpy ];
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
graft examples
|
||||||
|
include pytec/gui/resources/artiq.ico
|
||||||
|
include pytec/gui/view/param_tree.json
|
||||||
|
include pytec/gui/view/tec_qt.ui
|
|
@ -15,7 +15,4 @@ tec_qt = "tec_qt:main"
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
packages.find = {}
|
packages.find = {}
|
||||||
py-modules = ["aioexample", "autotune", "example", "plot", "tec_qt", "ui_tec_qt", "waitingspinnerwidget"]
|
py-modules = ["autotune", "plot", "tec_qt"]
|
||||||
|
|
||||||
[tool.setuptools.package-data]
|
|
||||||
"*" = ["*.*"]
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from pytec.aioclient import Client
|
from pytec.aioclient import Client
|
||||||
from PyQt6.QtCore import pyqtSignal, QObject, pyqtSlot
|
from PyQt6.QtCore import pyqtSignal, QObject, pyqtSlot
|
||||||
from qasync import asyncSlot
|
from qasync import asyncSlot
|
||||||
from model.property import Property, PropertyMeta
|
from pytec.gui.model.property import Property, PropertyMeta
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class Thermostat(QObject, metaclass=PropertyMeta):
|
||||||
self.report[i]["interval"] for i in range(len(self.report))
|
self.report[i]["interval"] for i in range(len(self.report))
|
||||||
]
|
]
|
||||||
|
|
||||||
async def disconnect(self):
|
async def end_session(self):
|
||||||
await self._client.end_session()
|
await self._client.end_session()
|
||||||
|
|
||||||
async def set_ipv4(self, ipv4):
|
async def set_ipv4(self, ipv4):
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 131 KiB |
|
@ -1,7 +1,7 @@
|
||||||
from PyQt6 import QtWidgets, QtCore
|
from PyQt6 import QtWidgets, QtCore
|
||||||
|
|
||||||
|
|
||||||
class conn_menu(QtWidgets.QMenu):
|
class ConnMenu(QtWidgets.QMenu):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setTitle("Connection Settings")
|
self.setTitle("Connection Settings")
|
|
@ -42,7 +42,7 @@ class MutexParameter(pTypes.ListParameter):
|
||||||
registerParameterType("mutex", MutexParameter)
|
registerParameterType("mutex", MutexParameter)
|
||||||
|
|
||||||
|
|
||||||
class ctrl_panel(QObject):
|
class CtrlPanel(QObject):
|
||||||
set_zero_limits_warning_sig = pyqtSignal(list)
|
set_zero_limits_warning_sig = pyqtSignal(list)
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
|
@ -2,7 +2,7 @@ from PyQt6 import QtWidgets
|
||||||
from PyQt6.QtCore import pyqtSlot
|
from PyQt6.QtCore import pyqtSlot
|
||||||
|
|
||||||
|
|
||||||
class info_box(QtWidgets.QMessageBox):
|
class InfoBox(QtWidgets.QMessageBox):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setIcon(QtWidgets.QMessageBox.Icon.Information)
|
self.setIcon(QtWidgets.QMessageBox.Icon.Information)
|
|
@ -66,9 +66,10 @@ class _TecGraphs:
|
||||||
|
|
||||||
self._t_line = self._t_widget.getPlotItem().addLine(label="{value} °C")
|
self._t_line = self._t_widget.getPlotItem().addLine(label="{value} °C")
|
||||||
self._t_line.setVisible(False)
|
self._t_line.setVisible(False)
|
||||||
|
# Hack for keeping setpoint line in plot range
|
||||||
self._t_setpoint_plot = (
|
self._t_setpoint_plot = (
|
||||||
LiveLinePlot()
|
LiveLinePlot()
|
||||||
) # Hack for keeping setpoint line in plot range
|
)
|
||||||
|
|
||||||
for graph in t_widget, i_widget:
|
for graph in t_widget, i_widget:
|
||||||
time_axis = LiveAxis(
|
time_axis = LiveAxis(
|
||||||
|
@ -83,8 +84,8 @@ class _TecGraphs:
|
||||||
|
|
||||||
# Enable linking of axes in the graph widget's context menu
|
# Enable linking of axes in the graph widget's context menu
|
||||||
graph.register(
|
graph.register(
|
||||||
graph.getPlotItem().titleLabel.text
|
graph.getPlotItem().titleLabel.text # Slight hack getting the title
|
||||||
) # Slight hack getting the title
|
)
|
||||||
|
|
||||||
temperature_axis = LiveAxis("left", text="Temperature", units="°C")
|
temperature_axis = LiveAxis("left", text="Temperature", units="°C")
|
||||||
temperature_axis.showLabel()
|
temperature_axis.showLabel()
|
|
@ -3,7 +3,7 @@ from PyQt6.QtWidgets import QAbstractButton
|
||||||
from PyQt6.QtCore import pyqtSignal, pyqtSlot
|
from PyQt6.QtCore import pyqtSignal, pyqtSlot
|
||||||
|
|
||||||
|
|
||||||
class net_settings_input_diag(QtWidgets.QInputDialog):
|
class NetSettingsInputDiag(QtWidgets.QInputDialog):
|
||||||
set_ipv4_act = pyqtSignal(str)
|
set_ipv4_act = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, current_ipv4_settings):
|
def __init__(self, current_ipv4_settings):
|
|
@ -1,7 +1,7 @@
|
||||||
from PyQt6 import QtWidgets, QtGui
|
from PyQt6 import QtWidgets, QtGui
|
||||||
|
|
||||||
|
|
||||||
class plot_options_menu(QtWidgets.QMenu):
|
class PlotOptionsMenu(QtWidgets.QMenu):
|
||||||
def __init__(self, max_samples=1000):
|
def __init__(self, max_samples=1000):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.setTitle("Plot Settings")
|
self.setTitle("Plot Settings")
|
|
@ -588,7 +588,7 @@
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>QtWaitingSpinner</class>
|
<class>QtWaitingSpinner</class>
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
<header>view.waitingspinnerwidget</header>
|
<header>pytec.gui.view.waitingspinnerwidget</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
|
@ -2,7 +2,7 @@ from PyQt6 import QtWidgets, QtGui, QtCore
|
||||||
from PyQt6.QtCore import pyqtSignal, pyqtSlot
|
from PyQt6.QtCore import pyqtSignal, pyqtSlot
|
||||||
|
|
||||||
|
|
||||||
class thermostat_ctrl_menu(QtWidgets.QMenu):
|
class ThermostatCtrlMenu(QtWidgets.QMenu):
|
||||||
fan_set_act = pyqtSignal(int)
|
fan_set_act = pyqtSignal(int)
|
||||||
fan_auto_set_act = pyqtSignal(int)
|
fan_auto_set_act = pyqtSignal(int)
|
||||||
|
|
|
@ -2,7 +2,7 @@ from PyQt6.QtCore import pyqtSlot, QObject
|
||||||
from PyQt6 import QtWidgets, QtGui
|
from PyQt6 import QtWidgets, QtGui
|
||||||
|
|
||||||
|
|
||||||
class zero_limits_warning_view(QObject):
|
class ZeroLimitsWarningView(QObject):
|
||||||
def __init__(self, style, limit_warning):
|
def __init__(self, style, limit_warning):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._lbl = limit_warning
|
self._lbl = limit_warning
|
|
@ -14,5 +14,5 @@ setup(
|
||||||
"tec_qt = tec_qt:main",
|
"tec_qt = tec_qt:main",
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
py_modules=['tec_qt', 'ui_tec_qt', 'autotune', 'waitingspinnerwidget'],
|
py_modules=['autotune', 'plot', 'tec_qt'],
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
from view.zero_limits_warning import zero_limits_warning_view
|
from pytec.gui.view.zero_limits_warning import ZeroLimitsWarningView
|
||||||
from view.net_settings_input_diag import net_settings_input_diag
|
from pytec.gui.view.net_settings_input_diag import NetSettingsInputDiag
|
||||||
from view.thermostat_ctrl_menu import thermostat_ctrl_menu
|
from pytec.gui.view.thermostat_ctrl_menu import ThermostatCtrlMenu
|
||||||
from view.conn_menu import conn_menu
|
from pytec.gui.view.conn_menu import ConnMenu
|
||||||
from view.plot_options_menu import plot_options_menu
|
from pytec.gui.view.plot_options_menu import PlotOptionsMenu
|
||||||
from view.live_plot_view import LiveDataPlotter
|
from pytec.gui.view.live_plot_view import LiveDataPlotter
|
||||||
from view.ctrl_panel import ctrl_panel
|
from pytec.gui.view.ctrl_panel import CtrlPanel
|
||||||
from view.info_box import info_box
|
from pytec.gui.view.info_box import InfoBox
|
||||||
from model.pid_autotuner import PIDAutoTuner
|
from pytec.gui.model.pid_autotuner import PIDAutoTuner
|
||||||
from model.thermostat_data_model import WrappedClient, Thermostat
|
from pytec.gui.model.thermostat import WrappedClient, Thermostat
|
||||||
import json
|
import json
|
||||||
from autotune import PIDAutotuneState
|
from autotune import PIDAutotuneState
|
||||||
from qasync import asyncSlot, asyncClose
|
from qasync import asyncSlot, asyncClose
|
||||||
|
@ -23,9 +23,6 @@ from functools import partial
|
||||||
import importlib.resources
|
import importlib.resources
|
||||||
|
|
||||||
|
|
||||||
pg.setConfigOptions(antialias=True)
|
|
||||||
|
|
||||||
|
|
||||||
def get_argparser():
|
def get_argparser():
|
||||||
parser = argparse.ArgumentParser(description="Thermostat Control Panel")
|
parser = argparse.ArgumentParser(description="Thermostat Control Panel")
|
||||||
|
|
||||||
|
@ -47,7 +44,7 @@ def get_argparser():
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-p",
|
"-p",
|
||||||
"--param_tree",
|
"--param_tree",
|
||||||
default=importlib.resources.files("view").joinpath("param_tree.json"),
|
default=importlib.resources.files("pytec.gui.view").joinpath("param_tree.json"),
|
||||||
help="Param Tree Description JSON File",
|
help="Param Tree Description JSON File",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,13 +57,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
super(MainWindow, self).__init__()
|
super(MainWindow, self).__init__()
|
||||||
|
|
||||||
ui_file_path = importlib.resources.files("view").joinpath("tec_qt.ui")
|
ui_file_path = importlib.resources.files("pytec.gui.view").joinpath("tec_qt.ui")
|
||||||
uic.loadUi(ui_file_path, self)
|
uic.loadUi(ui_file_path, self)
|
||||||
|
|
||||||
self.show()
|
|
||||||
|
|
||||||
self.hw_rev_data = None
|
self.hw_rev_data = None
|
||||||
self.info_box = info_box()
|
self.info_box = InfoBox()
|
||||||
|
|
||||||
self.client = WrappedClient(self)
|
self.client = WrappedClient(self)
|
||||||
self.client.connection_error.connect(self.bail)
|
self.client.connection_error.connect(self.bail)
|
||||||
|
@ -94,10 +89,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
]
|
]
|
||||||
self.thermostat.info_box_trigger.connect(self.info_box.display_info_box)
|
self.thermostat.info_box_trigger.connect(self.info_box.display_info_box)
|
||||||
|
|
||||||
self.zero_limits_warning = zero_limits_warning_view(
|
self.zero_limits_warning = ZeroLimitsWarningView(
|
||||||
self.style(), self.limits_warning
|
self.style(), self.limits_warning
|
||||||
)
|
)
|
||||||
self.ctrl_panel_view = ctrl_panel(
|
self.ctrl_panel_view = CtrlPanel(
|
||||||
[self.ch0_tree, self.ch1_tree],
|
[self.ch0_tree, self.ch1_tree],
|
||||||
get_ctrl_panel_config(args),
|
get_ctrl_panel_config(args),
|
||||||
self.send_command,
|
self.send_command,
|
||||||
|
@ -136,17 +131,17 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.thermostat.report_update.connect(self.channel_graphs.update_report)
|
self.thermostat.report_update.connect(self.channel_graphs.update_report)
|
||||||
self.thermostat.pid_update.connect(self.channel_graphs.update_pid)
|
self.thermostat.pid_update.connect(self.channel_graphs.update_pid)
|
||||||
|
|
||||||
self.plot_options_menu = plot_options_menu()
|
self.plot_options_menu = PlotOptionsMenu()
|
||||||
self.plot_options_menu.clear.triggered.connect(self.clear_graphs)
|
self.plot_options_menu.clear.triggered.connect(self.clear_graphs)
|
||||||
self.plot_options_menu.samples_spinbox.valueChanged.connect(
|
self.plot_options_menu.samples_spinbox.valueChanged.connect(
|
||||||
self.channel_graphs.set_max_samples
|
self.channel_graphs.set_max_samples
|
||||||
)
|
)
|
||||||
self.plot_settings.setMenu(self.plot_options_menu)
|
self.plot_settings.setMenu(self.plot_options_menu)
|
||||||
|
|
||||||
self.conn_menu = conn_menu()
|
self.conn_menu = ConnMenu()
|
||||||
self.connect_btn.setMenu(self.conn_menu)
|
self.connect_btn.setMenu(self.conn_menu)
|
||||||
|
|
||||||
self.thermostat_ctrl_menu = thermostat_ctrl_menu(self.style())
|
self.thermostat_ctrl_menu = ThermostatCtrlMenu(self.style())
|
||||||
self.thermostat_ctrl_menu.fan_set_act.connect(self.fan_set_request)
|
self.thermostat_ctrl_menu.fan_set_act.connect(self.fan_set_request)
|
||||||
self.thermostat_ctrl_menu.fan_auto_set_act.connect(self.fan_auto_set_request)
|
self.thermostat_ctrl_menu.fan_auto_set_act.connect(self.fan_auto_set_request)
|
||||||
self.thermostat_ctrl_menu.reset_act.connect(self.reset_request)
|
self.thermostat_ctrl_menu.reset_act.connect(self.reset_request)
|
||||||
|
@ -213,8 +208,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
return
|
return
|
||||||
with QSignalBlocker(self.thermostat_ctrl_menu.fan_power_slider):
|
with QSignalBlocker(self.thermostat_ctrl_menu.fan_power_slider):
|
||||||
self.thermostat_ctrl_menu.fan_power_slider.setValue(
|
self.thermostat_ctrl_menu.fan_power_slider.setValue(
|
||||||
fan_settings["fan_pwm"] or 100
|
fan_settings["fan_pwm"] or 100 # 0 = PWM off = full strength
|
||||||
) # 0 = PWM off = full strength
|
)
|
||||||
with QSignalBlocker(self.thermostat_ctrl_menu.fan_auto_box):
|
with QSignalBlocker(self.thermostat_ctrl_menu.fan_auto_box):
|
||||||
self.thermostat_ctrl_menu.fan_auto_box.setChecked(fan_settings["auto_mode"])
|
self.thermostat_ctrl_menu.fan_auto_box.setChecked(fan_settings["auto_mode"])
|
||||||
if not self.hw_rev_data["settings"]["fan_pwm_recommended"]:
|
if not self.hw_rev_data["settings"]["fan_pwm_recommended"]:
|
||||||
|
@ -399,7 +394,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
@asyncSlot(bool)
|
@asyncSlot(bool)
|
||||||
async def net_settings_request(self, _):
|
async def net_settings_request(self, _):
|
||||||
ipv4 = await self.thermostat.get_ipv4()
|
ipv4 = await self.thermostat.get_ipv4()
|
||||||
self.net_settings_input_diag = net_settings_input_diag(ipv4["addr"])
|
self.net_settings_input_diag = NetSettingsInputDiag(ipv4["addr"])
|
||||||
self.net_settings_input_diag.set_ipv4_act.connect(self.set_net_settings_request)
|
self.net_settings_input_diag.set_ipv4_act.connect(self.set_net_settings_request)
|
||||||
|
|
||||||
@asyncSlot(str)
|
@asyncSlot(str)
|
||||||
|
@ -419,7 +414,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)
|
||||||
app.setWindowIcon(
|
app.setWindowIcon(
|
||||||
QtGui.QIcon(str(importlib.resources.files("resources").joinpath("artiq.ico")))
|
QtGui.QIcon(str(importlib.resources.files("pytec.gui.resources").joinpath("artiq.ico")))
|
||||||
)
|
)
|
||||||
|
|
||||||
main_window = MainWindow(args)
|
main_window = MainWindow(args)
|
||||||
|
|
Loading…
Reference in New Issue