forked from M-Labs/thermostat
Refactor into class
This commit is contained in:
parent
744a472566
commit
663c46525d
146
pytec/tec_qt.py
146
pytec/tec_qt.py
@ -154,6 +154,66 @@ class ClientWatcher(QObject):
|
|||||||
self._update_s = update_s
|
self._update_s = update_s
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelGraphs:
|
||||||
|
"""The maximum number of sample points to store."""
|
||||||
|
DEFAULT_MAX_SAMPLES = 1000
|
||||||
|
|
||||||
|
def __init__(self, t_widget, i_widget):
|
||||||
|
self._t_widget = t_widget
|
||||||
|
self._i_widget = i_widget
|
||||||
|
|
||||||
|
self._t_plot = LiveLinePlot()
|
||||||
|
self._i_plot = LiveLinePlot(name='Feedback')
|
||||||
|
self._iset_plot = LiveLinePlot(name='Setpoint', pen=pg.mkPen('r'))
|
||||||
|
|
||||||
|
self.t_line = self._t_widget.getPlotItem().addLine(label='{value} °C')
|
||||||
|
self.t_line.setVisible(False)
|
||||||
|
|
||||||
|
for graph in t_widget, i_widget:
|
||||||
|
time_axis = LiveAxis('bottom', text="Time since Thermostat reset", **{Axis.TICK_FORMAT: Axis.DURATION})
|
||||||
|
time_axis.showLabel()
|
||||||
|
graph.setAxisItems({'bottom': time_axis})
|
||||||
|
|
||||||
|
graph.add_crosshair(pg.mkPen(color='red', width=1), {'color': 'green'})
|
||||||
|
|
||||||
|
# Enable linking of axes in the graph widget's context menu
|
||||||
|
graph.register(graph.getPlotItem().titleLabel.text) # Slight hack getting the title
|
||||||
|
|
||||||
|
temperature_axis = LiveAxis('left', text="Temperature", units="°C")
|
||||||
|
temperature_axis.showLabel()
|
||||||
|
t_widget.setAxisItems({'left': temperature_axis})
|
||||||
|
|
||||||
|
current_axis = LiveAxis('left', text="Current", units="A")
|
||||||
|
current_axis.showLabel()
|
||||||
|
i_widget.setAxisItems({'left': current_axis})
|
||||||
|
i_widget.addLegend(brush=(50, 50, 200, 150))
|
||||||
|
|
||||||
|
t_widget.addItem(self._t_plot)
|
||||||
|
i_widget.addItem(self._i_plot)
|
||||||
|
i_widget.addItem(self._iset_plot)
|
||||||
|
|
||||||
|
self.t_connector = DataConnector(self._t_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
||||||
|
self.i_connector = DataConnector(self._i_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
||||||
|
self.iset_connector = DataConnector(self._iset_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
||||||
|
|
||||||
|
self.max_samples = self.DEFAULT_MAX_SAMPLES
|
||||||
|
|
||||||
|
def plot_append(self, report):
|
||||||
|
temperature = report['temperature']
|
||||||
|
current = report['tec_i']
|
||||||
|
iset = report['i_set']
|
||||||
|
time = report['time']
|
||||||
|
|
||||||
|
if temperature is not None:
|
||||||
|
self.t_connector.cb_append_data_point(temperature, time)
|
||||||
|
self.i_connector.cb_append_data_point(current, time)
|
||||||
|
self.iset_connector.cb_append_data_point(iset, time)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
for connector in self.t_connector, self.i_connector, self.iset_connector:
|
||||||
|
connector.clear()
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
||||||
|
|
||||||
"""The maximum number of sample points to store."""
|
"""The maximum number of sample points to store."""
|
||||||
@ -221,26 +281,10 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
]
|
]
|
||||||
self._set_param_tree()
|
self._set_param_tree()
|
||||||
|
|
||||||
self.ch0_t_plot = LiveLinePlot()
|
self.channel_graphs = [
|
||||||
self.ch0_i_plot = LiveLinePlot(name='Feedback')
|
ChannelGraphs(getattr(self, f'ch{ch}_t_graph'), getattr(self, f'ch{ch}_i_graph'))
|
||||||
self.ch0_iset_plot = LiveLinePlot(name='Setpoint', pen=pg.mkPen('r'))
|
for ch in range(2)
|
||||||
self.ch1_t_plot = LiveLinePlot()
|
]
|
||||||
self.ch1_i_plot = LiveLinePlot(name='Feedback')
|
|
||||||
self.ch1_iset_plot = LiveLinePlot(name='Setpoint', pen=pg.mkPen('r'))
|
|
||||||
|
|
||||||
self.ch0_t_line = self.ch0_t_graph.getPlotItem().addLine(label='{value} °C')
|
|
||||||
self.ch0_t_line.setVisible(False)
|
|
||||||
self.ch1_t_line = self.ch1_t_graph.getPlotItem().addLine(label='{value} °C')
|
|
||||||
self.ch1_t_line.setVisible(False)
|
|
||||||
|
|
||||||
self._set_up_graphs()
|
|
||||||
|
|
||||||
self.ch0_t_connector = DataConnector(self.ch0_t_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
|
||||||
self.ch0_i_connector = DataConnector(self.ch0_i_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
|
||||||
self.ch0_iset_connector = DataConnector(self.ch0_iset_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
|
||||||
self.ch1_t_connector = DataConnector(self.ch1_t_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
|
||||||
self.ch1_i_connector = DataConnector(self.ch1_i_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
|
||||||
self.ch1_iset_connector = DataConnector(self.ch1_iset_plot, max_points=self.DEFAULT_MAX_SAMPLES)
|
|
||||||
|
|
||||||
self.hw_rev_data = None
|
self.hw_rev_data = None
|
||||||
|
|
||||||
@ -248,7 +292,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.client.connection_error.connect(self.bail)
|
self.client.connection_error.connect(self.bail)
|
||||||
self.client_watcher = ClientWatcher(self, self.client, self.report_refresh_spin.value())
|
self.client_watcher = ClientWatcher(self, self.client, self.report_refresh_spin.value())
|
||||||
self.client_watcher.fan_update.connect(self.fan_update)
|
self.client_watcher.fan_update.connect(self.fan_update)
|
||||||
self.client_watcher.report_update.connect(self.plot)
|
|
||||||
self.client_watcher.report_update.connect(self.update_report)
|
self.client_watcher.report_update.connect(self.update_report)
|
||||||
self.client_watcher.pid_update.connect(self.update_pid)
|
self.client_watcher.pid_update.connect(self.update_pid)
|
||||||
self.client_watcher.pwm_update.connect(self.update_pwm)
|
self.client_watcher.pwm_update.connect(self.update_pwm)
|
||||||
@ -461,45 +504,14 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
@pyqtSlot(int)
|
@pyqtSlot(int)
|
||||||
def set_max_samples(self, samples: int):
|
def set_max_samples(self, samples: int):
|
||||||
self.ch0_t_connector.max_points = samples
|
for channel_graph in self.channel_graphs:
|
||||||
self.ch0_i_connector.max_points = samples
|
channel_graph.t_connector.max_points = samples
|
||||||
self.ch0_iset_connector.max_points = samples
|
channel_graph.i_connector.max_points = samples
|
||||||
self.ch1_t_connector.max_points = samples
|
channel_graph.iset_connector.max_points = samples
|
||||||
self.ch1_i_connector.max_points = samples
|
|
||||||
self.ch1_iset_connector.max_points = samples
|
|
||||||
|
|
||||||
def _set_up_graphs(self):
|
|
||||||
for graph in self.ch0_t_graph, self.ch0_i_graph, self.ch1_t_graph, self.ch1_i_graph:
|
|
||||||
time_axis = LiveAxis('bottom', text="Time since Thermostat reset", **{Axis.TICK_FORMAT: Axis.DURATION})
|
|
||||||
time_axis.showLabel()
|
|
||||||
graph.setAxisItems({'bottom': time_axis})
|
|
||||||
|
|
||||||
graph.add_crosshair(pg.mkPen(color='red', width=1), {'color': 'green'})
|
|
||||||
|
|
||||||
# Enable linking of axes in the graph widget's context menu
|
|
||||||
graph.register(graph.getPlotItem().titleLabel.text) # Slight hack getting the title
|
|
||||||
|
|
||||||
for graph in self.ch0_t_graph, self.ch1_t_graph:
|
|
||||||
temperature_axis = LiveAxis('left', text="Temperature", units="°C")
|
|
||||||
temperature_axis.showLabel()
|
|
||||||
graph.setAxisItems({'left': temperature_axis})
|
|
||||||
|
|
||||||
for graph in self.ch0_i_graph, self.ch1_i_graph:
|
|
||||||
current_axis = LiveAxis('left', text="Current", units="A")
|
|
||||||
current_axis.showLabel()
|
|
||||||
graph.setAxisItems({'left': current_axis})
|
|
||||||
graph.addLegend(brush=(50, 50, 200, 150))
|
|
||||||
|
|
||||||
self.ch0_t_graph.addItem(self.ch0_t_plot)
|
|
||||||
self.ch0_i_graph.addItem(self.ch0_i_plot)
|
|
||||||
self.ch0_i_graph.addItem(self.ch0_iset_plot)
|
|
||||||
self.ch1_t_graph.addItem(self.ch1_t_plot)
|
|
||||||
self.ch1_i_graph.addItem(self.ch1_i_plot)
|
|
||||||
self.ch1_i_graph.addItem(self.ch1_iset_plot)
|
|
||||||
|
|
||||||
def clear_graphs(self):
|
def clear_graphs(self):
|
||||||
for connector in self.ch0_t_connector, self.ch0_i_connector, self.ch0_iset_connector, self.ch1_t_connector, self.ch1_i_connector, self.ch1_iset_connector:
|
for channel_graph in self.channel_graphs:
|
||||||
connector.clear()
|
channel_graph.clear()
|
||||||
|
|
||||||
async def _on_connection_changed(self, result):
|
async def _on_connection_changed(self, result):
|
||||||
self.graph_group.setEnabled(result)
|
self.graph_group.setEnabled(result)
|
||||||
@ -607,19 +619,6 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
await self._on_connection_changed(False)
|
await self._on_connection_changed(False)
|
||||||
await self.client.end_session()
|
await self.client.end_session()
|
||||||
|
|
||||||
@pyqtSlot(list)
|
|
||||||
def plot(self, report):
|
|
||||||
for channel in range(2):
|
|
||||||
temperature = report[channel]['temperature']
|
|
||||||
current = report[channel]['tec_i']
|
|
||||||
iset = report[channel]['i_set']
|
|
||||||
time = report[channel]['time']
|
|
||||||
|
|
||||||
if temperature is not None:
|
|
||||||
getattr(self, f'ch{channel}_t_connector').cb_append_data_point(temperature, time)
|
|
||||||
getattr(self, f'ch{channel}_i_connector').cb_append_data_point(current, time)
|
|
||||||
getattr(self, f'ch{channel}_iset_connector').cb_append_data_point(iset, time)
|
|
||||||
|
|
||||||
@asyncSlot(object, object)
|
@asyncSlot(object, object)
|
||||||
async def send_command(self, param, changes):
|
async def send_command(self, param, changes):
|
||||||
for inner_param, change, data in changes:
|
for inner_param, change, data in changes:
|
||||||
@ -647,15 +646,16 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
|
|||||||
self.params[channel].child("PID Config", "Ki").setValue(settings["parameters"]["ki"])
|
self.params[channel].child("PID Config", "Ki").setValue(settings["parameters"]["ki"])
|
||||||
self.params[channel].child("PID Config", "Kd").setValue(settings["parameters"]["kd"])
|
self.params[channel].child("PID Config", "Kd").setValue(settings["parameters"]["kd"])
|
||||||
self.params[channel].child("Output Config", "Control Method", "Set Temperature").setValue(settings["target"])
|
self.params[channel].child("Output Config", "Control Method", "Set Temperature").setValue(settings["target"])
|
||||||
getattr(self, f'ch{channel}_t_line').setValue(settings["target"])
|
self.channel_graphs[channel].t_line.setValue(settings["target"])
|
||||||
|
|
||||||
@pyqtSlot(list)
|
@pyqtSlot(list)
|
||||||
def update_report(self, report_data):
|
def update_report(self, report_data):
|
||||||
for settings in report_data:
|
for settings in report_data:
|
||||||
channel = settings["channel"]
|
channel = settings["channel"]
|
||||||
|
self.channel_graphs[channel].plot_append(settings)
|
||||||
with QSignalBlocker(self.params[channel]):
|
with QSignalBlocker(self.params[channel]):
|
||||||
self.params[channel].child("Output Config", "Control Method").setValue(settings["pid_engaged"])
|
self.params[channel].child("Output Config", "Control Method").setValue(settings["pid_engaged"])
|
||||||
getattr(self, f'ch{channel}_t_line').setVisible(settings["pid_engaged"])
|
self.channel_graphs[channel].t_line.setVisible(settings["pid_engaged"])
|
||||||
self.params[channel].child("Output Config", "Control Method", "Constant Current").setValue(settings["i_set"])
|
self.params[channel].child("Output Config", "Control Method", "Constant Current").setValue(settings["i_set"])
|
||||||
if settings['temperature'] is not None and settings['tec_i'] is not None:
|
if settings['temperature'] is not None and settings['tec_i'] is not None:
|
||||||
self.params[channel].child("Temperature").setValue(settings['temperature'])
|
self.params[channel].child("Temperature").setValue(settings['temperature'])
|
||||||
|
Loading…
Reference in New Issue
Block a user