GUI #101
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "atse/thermostat:GUI"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds a GUI for easier control of the Thermostat.
Core functionalities include plotting of temperatures and currents, reporting and adjustment of parameters, and PID autotuning.
@ -0,0 +389,4 @@
self.thermostat_menu = QtWidgets.QMenu()
self.thermostat_menu.setTitle('Thermostat settings')
self.fan_group = QtWidgets.QWidget()
Is there a good reason why these menu widgets are in the code instead of UI files? You may also separate UI into different reusable widgets in most cases
@ -0,0 +104,4 @@
while True:
time = loop.time()
await self.update_params()
await asyncio.sleep(self._update_s - (loop.time() - time))
Well, you could have just skipped wait in update_params and there should not be such drift
In general I think this GUI needs more decoupling data from UI. It can be some state management, or custom data classes as well. I would look into something like https://doc.qt.io/qt-6/qstatemachine.html , or analogs of JS's redux/zustand, but in python.
@ -0,0 +230,4 @@
DEFAULT_MAX_SAMPLES = 1000
"""Thermostat parameters that are particular to a channel"""
THERMOSTAT_PARAMETERS = [[
Also I think it is possible to make this define not only the UI, but also getters/setters from the data state object.
It is not an exactly straight-forward way, but you can inherit the ParameterTree or similar to add the additional fields. The getters/setters may be just functions, that accept state object and the incoming value, alternatively you can add lambda's, but that may need wrapping this list into class or function.
@ -0,0 +504,4 @@
self,
"About Thermostat",
f"""
<h1>Sinara 8451 Thermostat v{self.hw_rev_data['rev']['major']}.{self.hw_rev_data['rev']['minor']}</h1>
This doesn't feel to be hardcoded.
GUIto WIP: GUI@ -0,0 +585,4 @@
@pyqtSlot(int)
def set_max_samples(self, samples: int):
for channel_graph in self.channel_graphs:
channel_graph.t_connector.max_points = samples
The "max_points" feature does not work as I tested on GUI.
Upon inspection on the source code of the library. You cannot change it dynamically with the built-in fns
I tried to re-declare the data queue into the DataConnector class and it works as expected. Not sure if there is better way of doing it.
@ -0,0 +27,4 @@
</property>
<property name="windowIcon">
<iconset>
<normaloff>thermostat-icon-640x640.png</normaloff>thermostat-icon-640x640.png</iconset>
Well, I see two main problems with it (even if it is working):
In this case, I would go with one of our standard ARTIQ icons, or create one from scratch with fewest details possible, targeting sizes 16x16, 32x32, 48x48, 64x64 and 256x256 pixels (it should just look okay being scaled to all sizes, no need to create different versions). For this, SVGs are most suitable, and they can be created in Inkscape (their UX is not good though) or any other software of your choice, and exported as Optimized SVG, but also preserving the original is desired in case of future needs (possibly can be uploaded to private repo).
Actually better it be in separate PR, because the icon creation can take a while, and it is not really necessary to be merged with this PR
In general. When the widgets are in the "Disable State", the widget should be "gray-ed out" as a hint for the user that they cannot interact with them.
You can add the following line with QT Designer into the "styleSheet" properties of various types of widget.
QPushButton:disabled { color: gray }
@ -0,0 +451,4 @@
async def network_settings(_):
ask_network = QtWidgets.QInputDialog(self)
ask_network.setWindowTitle("Network Settings")
ask_network.setLabelText("Set the Thermostat's IPv4 address, netmask and gateway (optional)")
For the network related configuration, there should be a form for the user to fill in instead of entering the configuration as a line of text.
Not really, making smooth transition between dots may be troublesome. Some regex validation though would be nice.
QT supports tab orderings. Will that be enough?
Will Thermostat connections always be configured through an IPv4 address though? Don't we need to support more than that, like for instance hostnames resolved through DNS?
A use-case of this is using SSH local forwarding to remotely control a Thermostat with the GUI; this worked just fine once I adjusted the host and port.
I would go even further and create a separate QSS (Qt Style Sheets) file, so we can lock the appearance of the app, because in different DE configurations (especially Qt based like KDE) it may look different, and sometimes it may be broken. Also @atse already had issues with Adwaita.
Probably locking the style is not "libre software way", but I would say it is better to be usable and do not fit into systems style than be unusable (like barely visible icons or texts) while the appearance matches the system.
68e6de7215
to9806774382
9806774382
tod3dc9f9b37
If PID autotune finishes, there should be a message/diag box to notify the user especially when autotune fails.
When thermostat is autotuning and the connected device is disconnected, then it will end up in this interface.
The control panel is grey-ed out. Clicking the "connect" button does not do anything. You will need to re-run the GUI.
Here is the log. The following error message appears multiple times.
Consider limiting the output current limit according to the specs(+-2A), I tried sourcing 3A into a TEC and Thermostat results in power failure. It requires full power cycle for Ethernet communication to function again.
What about using tabs system instead of fixed panels? At least for settings area, it would make them longer and more convenient to operate one channel. Also in case of 4 channels thermostat tabs are easier to expand...
In this case, I guess current and temp graphs/charts can be merged into one, or as an alternative they can be detachable or removed, resized etc.
I feel this PR is going into a huge mess, since developing a GUI with good UI/UX is rarely an easy task, especially in this case, where there are quite a few nuances that may brake the whole picture. Also I think nobody will truly read it as whole.
I would suggest merging this GUI into some development branch of the main repo, and then iteratively refactor/redesign/add features/fix bugs. I would also suggest starting from specifying the requirements and drawing user/data flow diagrams.
As far as I saw it is not exactly this company policy, but it is a standard practice elsewhere, and I believe it would greatly improve the development process and the GUI itself, as other colleagues would also be able to participate in it.
WIP: GUIto GUId3dc9f9b37
to8753f4a0fc