forked from M-Labs/kirdy
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
85f81ee8e4 | |||
5b00bd60c7 | |||
4d8e16771e | |||
4d332328c0 | |||
edb8099a26 | |||
49dc8a9b96 | |||
a1b7538295 | |||
8f5a294a53 | |||
87b0e1bf67 | |||
35f66c3516 | |||
dd7e1bbbdd | |||
a3b38fc6b7 |
@ -70,16 +70,10 @@ openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "program target/thumbv
|
||||
```
|
||||
|
||||
## Erasing Flash Settings
|
||||
The flash settings are stored in the last flash sector(ID: 11) of bank 0 of stm32f405. You can erase it with JTAG/SWD adapter or by putting the device in Dfu mode. You may find it useful if you have set network settings incorrectly.
|
||||
The flash settings are stored in the last flash sector(ID: 11) of bank 0 of stm32f405. You can erase it with JTAG/SWD adapter. You may find it useful if you have set network settings incorrectly.
|
||||
|
||||
With JTAG/SWD adapter connected, issue the following command:
|
||||
|
||||
```shell
|
||||
openocd -f interface/stlink.cfg -f target/stm32f4x.cfg -c "flash init; init; halt; flash erase_sector 0 11 last; reset; exit"
|
||||
```
|
||||
|
||||
With STM32 in DFU Mode, connect the USB Type C cable and then issue the following command:
|
||||
|
||||
```
|
||||
dfu-util -a 0 -s 0x080E0000:leave -D erase_flash_settings.bin
|
||||
```
|
||||
|
@ -1,56 +0,0 @@
|
||||
# Thermostat
|
||||
Kirdy incorporates a single channel thermostat circuitry like Sinara-hw [Thermostat](https://github.com/sinara-hw/Thermostat) with improved noise. It can deliver more than 9W of cooling/heating power with better than +-1mK temperature stability.
|
||||
|
||||
## Power Input
|
||||
If you use Kirdy with a PoE (IEEE 802.3af Class 3) PSE, Kirdy may experience power failure due to power limit. If you need more power on Thermostat, you can plug in additional Power supply on the 12V power Jack(Recommend: 12V 2A). Although the TEC Driver has a very high 165 degree thermal shutdown threshold, it is highly recommended to provide active cooling to the TEC Driving Circuitry.
|
||||
|
||||
## Control Mode
|
||||
Like Sinara-hw [Thermostat](https://github.com/sinara-hw/Thermostat), they both share the same control mode and algorithm, namely constant Current Control Mode
|
||||
|
||||
### Constant Current Control Mode
|
||||
You can drive a constant current to the load. The end user to connect an external control loop. If end user wants to use it with an external control loop, it is recommended to retrieve reports via the ActiveReportMode instead of polling status report for better consistency and higher maximum update rate.
|
||||
|
||||
### PID Control Mode
|
||||
Thermostat uses the [PID algorithm](https://hackmd.io/IACbwcOTSt6Adj3_F9bKuw) derived by Quartiq. The included Pid Autotune Algorithm can already achieve the specified +-1mK stability.
|
||||
|
||||
During autotuning, Theremstat drives a user-specified step current into the load to calculate the pid parameters. Improper usage can damage the connected device.
|
||||
|
||||
#### Important Notes
|
||||
1. Configure all the protection mechanisms correctly before running the pid autotune algorithm.
|
||||
2. Supervise the PID autotune process.
|
||||
3. PID Autotune algorithm sometimes can produce unstable PID parameters. Do evaluate the PID performance after autotune is completed
|
||||
4. For best performance, you should do the autotune with Kirdy installed in the environment that it is gonna be used.
|
||||
5. If you are using the GUI, you need to set a high enough polling rate for PID autotune to function correctly.
|
||||
|
||||
#### Usage Guide
|
||||
|
||||
You can run pid autotune via the standalone auto
|
||||
|
||||
1. Target Temperature
|
||||
- Set it to the intended operating temperature for the connected device to operate in. You can still change temperature setpoint afterwards.
|
||||
2. Test Current
|
||||
- Set it to the maximum recommended operating current specified on the TEC/Resistive load.
|
||||
3. Update Rate
|
||||
- This can be set by configuring the filter settings in the Temperature ADC. High Update Rate can yield faster loop response with temperature regulation noise as the trade-off. Higher update rate can be useful if the load is actively cooled.
|
||||
4. Temperature Swing
|
||||
- Lower value can damp the control loop response.
|
||||
5. Lookback Period
|
||||
- Larger value can damp the control loop response. Do note that the larger lookback period also increases the autotune completion time.
|
||||
|
||||
You can give your system a try with the following parameters.
|
||||
1. Target Temperature: (User-Specified)
|
||||
2. Test Current: (User-Specified)
|
||||
3. Update Rate: 16.67Hz (Sinc5Sinc1 Filter with 50Hz and 60Hz Rejection)
|
||||
4. Temperature Swing: 0 Degree
|
||||
5. Lookback Period: 5s
|
||||
|
||||
Once autotune is successful, you can improve its stability by increasing the lookback period.
|
||||
|
||||
#### Troubleshooting
|
||||
If you obtain unstable PID parameters,
|
||||
1. Check if the polling rate is close to the PID update rate. If not, increase the polling rate
|
||||
2. Increase the lookback period and try again.
|
||||
|
||||
If the autotune does not finish running or faikls, you should
|
||||
1. Check if the thermostat has a hard time heating or cooling the connected device to the targe temperature. If yes, you should consider adjust the target temperature accordingly.
|
||||
2. Check if the polling rate is close to the PID update rate. If not, increase the polling rate.
|
Binary file not shown.
@ -62,6 +62,7 @@
|
||||
inherit pname version;
|
||||
hash = "sha256-jqj8X6H1N5mJQ4OrY5ANqRB0YJByqg/bNneEALWmH1A=";
|
||||
};
|
||||
patches = ./patches/0001-Add-option-for-setting-min-range-span-for-y-axis.patch;
|
||||
buildInputs = [ pkgs.python3Packages.poetry-core ];
|
||||
propagatedBuildInputs = with pkgs.python3Packages; [ pyqtgraph numpy ];
|
||||
};
|
||||
|
@ -0,0 +1,61 @@
|
||||
From 59a14e06320fd42d56cd7d953da337c0fe4357fa Mon Sep 17 00:00:00 2001
|
||||
From: linuswck <linuswck@m-labs.hk>
|
||||
Date: Tue, 22 Oct 2024 17:30:36 +0800
|
||||
Subject: [PATCH] Add option for setting min range span for y-axis
|
||||
|
||||
---
|
||||
pglive/sources/live_axis_range.py | 17 ++++++++++++++++-
|
||||
1 file changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/pglive/sources/live_axis_range.py b/pglive/sources/live_axis_range.py
|
||||
index afbd806..9b62ba5 100644
|
||||
--- a/pglive/sources/live_axis_range.py
|
||||
+++ b/pglive/sources/live_axis_range.py
|
||||
@@ -5,7 +5,7 @@ from typing import Optional, List, Tuple, Dict
|
||||
class LiveAxisRange:
|
||||
|
||||
def __init__(self, roll_on_tick: int = 1, offset_left: float = 0., offset_right: float = 0., offset_top: float = 0.,
|
||||
- offset_bottom: float = 0., fixed_range: Optional[List[float]] = None) -> None:
|
||||
+ offset_bottom: float = 0., fixed_range: Optional[List[float]] = None, min_y_range_span: Optional[List[float]] = [None, None]) -> None:
|
||||
self.roll_on_tick = roll_on_tick
|
||||
self.offset_left = offset_left
|
||||
self.offset_right = offset_right
|
||||
@@ -21,6 +21,7 @@ class LiveAxisRange:
|
||||
self.final_x_range = [0., 0.]
|
||||
self.final_y_range = [0., 0.]
|
||||
self.ignored_data_connectors: List[str] = []
|
||||
+ self.min_y_range_span = min_y_range_span
|
||||
|
||||
def get_x_range(self, data_connector, tick: int) -> List[float]:
|
||||
x, _ = data_connector.plot.getData()
|
||||
@@ -116,6 +117,13 @@ class LiveAxisRange:
|
||||
# therefore in that case we must set some range
|
||||
final_range[0] -= 0.4
|
||||
final_range[1] += 0.4
|
||||
+
|
||||
+ if self.min_y_range_span[0] is not None:
|
||||
+ final_range[0] = min(self.min_y_range_span[0], final_range[0])
|
||||
+
|
||||
+ if self.min_y_range_span[1] is not None:
|
||||
+ final_range[1] = max(self.min_y_range_span[1], final_range[1])
|
||||
+
|
||||
if self.final_y_range != final_range:
|
||||
self.final_y_range = final_range
|
||||
return self.final_y_range
|
||||
@@ -139,6 +147,13 @@ class LiveAxisRange:
|
||||
# therefore in that case we must set some range
|
||||
final_range[0] -= 0.4
|
||||
final_range[1] += 0.4
|
||||
+
|
||||
+ if self.min_y_range_span[0] is not None:
|
||||
+ final_range[0] = min(self.min_y_range_span[0], final_range[0])
|
||||
+
|
||||
+ if self.min_y_range_span[1] is not None:
|
||||
+ final_range[1] = max(self.min_y_range_span[1], final_range[1])
|
||||
+
|
||||
if self.final_y_range != final_range:
|
||||
self.final_y_range = final_range
|
||||
return self.final_y_range
|
||||
--
|
||||
2.44.1
|
||||
|
@ -32,7 +32,7 @@ async def device_cfg(kirdy: Kirdy):
|
||||
# Network Settings will be updated on next reboot.
|
||||
await kirdy.device.set_ip_settings(
|
||||
addr="192.168.1.128",
|
||||
port=1337,
|
||||
port=1550,
|
||||
prefix_len=24,
|
||||
gateway="192.168.1.1"
|
||||
)
|
||||
|
@ -181,7 +181,7 @@ class Device:
|
||||
self._send_cmd = send_cmd_handler
|
||||
self._send_raw_cmd = send_raw_cmd_handler
|
||||
|
||||
async def set_ip_settings(self, addr="192.168.1.128", port=1337, prefix_len=24, gateway="192.168.1.1"):
|
||||
async def set_ip_settings(self, addr="192.168.1.128", port=1550, prefix_len=24, gateway="192.168.1.1"):
|
||||
"""
|
||||
Upon command execution, the ip settings are saved into flash and are effective upon next reboot.
|
||||
"""
|
||||
@ -693,7 +693,7 @@ class Kirdy:
|
||||
"""
|
||||
self._err_msg_sig = sig
|
||||
|
||||
def start_session(self, host='192.168.1.128', port=1337):
|
||||
def start_session(self, host='192.168.1.128', port=1550):
|
||||
"""
|
||||
Start Kirdy Connection Session.
|
||||
In case of disconnection, all the queued tasks are cleared and the handler task retries TCP connection indefinitely.
|
||||
@ -879,7 +879,7 @@ class Kirdy:
|
||||
else:
|
||||
self._report_sig.emit(response)
|
||||
else:
|
||||
if self._msg_queue_get_report:
|
||||
if self._msg_queue_get_report and response["msg_type"] == 'Report':
|
||||
self._msg_queue_get_report = False
|
||||
self._int_msg_queue.put_nowait_overwrite(response)
|
||||
except asyncio.exceptions.CancelledError:
|
||||
|
@ -195,14 +195,17 @@ class Graphs:
|
||||
ld_i_set_axis.showLabel()
|
||||
ld_i_set_graph.setAxisItems({'left': ld_i_set_axis})
|
||||
ld_i_set_graph.addItem(self._ld_i_set_plot)
|
||||
self.ld_i_set_connector = DataConnector(self._ld_i_set_plot, max_points=self.max_samples)
|
||||
ld_i_set_graph.y_range_controller = LiveAxisRange(fixed_range=[0.0, 0.4])
|
||||
self.ld_i_set_connector = DataConnector(self._ld_i_set_plot, plot_rate=10.0, update_rate=10.0, max_points=self.max_samples)
|
||||
self.connectors += [self.ld_i_set_connector]
|
||||
|
||||
pd_mon_pwr_axis = LiveAxis('left', text="Power", units="W")
|
||||
pd_mon_pwr_axis.showLabel()
|
||||
|
||||
pd_mon_pwr_graph.y_range_controller = LiveAxisRange(min_y_range_span=[0.0, 100 / 1000 / 1000])
|
||||
pd_mon_pwr_graph.setAxisItems({'left': pd_mon_pwr_axis})
|
||||
pd_mon_pwr_graph.addItem(self._pd_mon_pwr_plot)
|
||||
self.pd_mon_pwr_connector = DataConnector(self._pd_mon_pwr_plot, max_points=self.max_samples)
|
||||
self.pd_mon_pwr_connector = DataConnector(self._pd_mon_pwr_plot, plot_rate=10.0, update_rate=10.0, max_points=self.max_samples)
|
||||
self.connectors += [self.pd_mon_pwr_connector]
|
||||
|
||||
tec_temp_axis = LiveAxis('left', text="Temperature", units="℃")
|
||||
@ -210,19 +213,18 @@ class Graphs:
|
||||
tec_temp_graph.setAxisItems({'left': tec_temp_axis})
|
||||
tec_temp_graph.addItem(self._tec_setpoint_plot)
|
||||
tec_temp_graph.addItem(self._tec_temp_plot)
|
||||
self.tec_setpoint_connector = DataConnector(self._tec_setpoint_plot, max_points=1)
|
||||
self.tec_temp_connector = DataConnector(self._tec_temp_plot, max_points=self.max_samples)
|
||||
self.tec_setpoint_connector = DataConnector(self._tec_setpoint_plot, plot_rate=10.0, update_rate=10.0, max_points=1)
|
||||
self.tec_temp_connector = DataConnector(self._tec_temp_plot, plot_rate=10.0, update_rate=10.0, max_points=self.max_samples)
|
||||
self.connectors += [self.tec_temp_connector, self.tec_setpoint_connector]
|
||||
|
||||
tec_i_axis = LiveAxis('left', text="Current", units="A")
|
||||
tec_i_axis.showLabel()
|
||||
tec_i_graph.setAxisItems({'left': tec_i_axis})
|
||||
tec_i_graph.addLegend(brush=(50, 50, 200, 150))
|
||||
tec_i_graph.y_range_controller = LiveAxisRange(fixed_range=[-1.0, 1.0])
|
||||
tec_i_graph.addItem(self._tec_i_target_plot)
|
||||
tec_i_graph.addItem(self._tec_i_measure_plot)
|
||||
self.tec_i_target_connector = DataConnector(self._tec_i_target_plot, max_points=self.max_samples)
|
||||
self.tec_i_measure_connector = DataConnector(self._tec_i_measure_plot, max_points=self.max_samples)
|
||||
self.tec_i_target_connector = DataConnector(self._tec_i_target_plot, plot_rate=10.0, update_rate=10.0, max_points=self.max_samples)
|
||||
self.tec_i_measure_connector = DataConnector(self._tec_i_measure_plot, plot_rate=10.0, update_rate=10.0, max_points=self.max_samples)
|
||||
self.connectors += [self.tec_i_target_connector, self.tec_i_measure_connector]
|
||||
|
||||
def set_max_samples(self, max_samples):
|
||||
@ -398,19 +400,13 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
"""The maximum number of sample points to store."""
|
||||
DEFAULT_MAX_SAMPLES = 1000
|
||||
DEFAULT_IP_ADDR = '192.168.1.128'
|
||||
DEFAULT_PORT = 1337
|
||||
|
||||
LASER_DIODE_STATUS = [
|
||||
{'name': 'Status', 'title': 'Status: Power Off', 'expanded': True, 'type': 'group', 'children': [
|
||||
{'name': 'Color', 'title': '', 'type': 'color', 'value': 'w', 'readonly': True, "compactHeight": False},
|
||||
]}
|
||||
]
|
||||
DEFAULT_PORT = 1550
|
||||
|
||||
LASER_DIODE_PARAMETERS = [
|
||||
{'name': 'Readings', 'expanded': True, 'type': 'group', 'children': [
|
||||
{'name': 'LD Current Set', 'type': 'float', 'suffix': 'A', 'siPrefix': True, 'readonly': True, "compactHeight": False},
|
||||
{'name': 'PD Current', 'type': 'float', 'suffix': 'A', 'siPrefix': True, 'readonly': True, "compactHeight": False},
|
||||
{'name': 'PD Power', 'type': 'float', 'suffix': 'W', 'siPrefix': True, 'readonly': True, "compactHeight": False},
|
||||
{'name': 'LD Current Set', 'type': 'float', 'unit': 'mA', 'readonly': True, "compactHeight": False},
|
||||
{'name': 'PD Current', 'type': 'float', 'unit': 'uA', 'readonly': True, "compactHeight": False},
|
||||
{'name': 'PD Power', 'type': 'float', 'unit': 'mW', 'readonly': True, "compactHeight": False},
|
||||
{'name': 'LF Mod Termination (50 Ohm)', 'type': 'list', 'limits': ['On', 'Off'], 'readonly': True, "compactHeight": False}
|
||||
]},
|
||||
{'name': 'Output Config', 'expanded': True, 'type': 'group', 'children': [
|
||||
@ -430,16 +426,10 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
]},
|
||||
]
|
||||
|
||||
THERMOSTAT_STATUS = [
|
||||
{'name': 'Status', 'title': 'Status: Power Off', 'expanded': True, 'type': 'group', 'children': [
|
||||
{'name': 'Color', 'title': '', 'type': 'color', 'value': 'w', 'readonly': True, "compactHeight": False},
|
||||
]}
|
||||
]
|
||||
|
||||
THERMOSTAT_PARAMETERS = [
|
||||
{'name': 'Readings', 'expanded': True, 'type': 'group', 'children': [
|
||||
{'name': 'Temperature', 'type': 'float', 'format': '{value:.4f} ℃', 'readonly': True, "compactHeight": False},
|
||||
{'name': 'Current through TEC', 'type': 'float', 'suffix': 'A', 'siPrefix': True, 'decimals': 6, 'readonly': True, "compactHeight": False},
|
||||
{'name': 'Temperature', 'type': 'float', 'unit': '℃', 'format': '{value:.4f}', 'readonly': True, "compactHeight": False},
|
||||
{'name': 'Current through TEC', 'type': 'float', 'unit': 'mA', 'decimals': 6, 'readonly': True, "compactHeight": False},
|
||||
]},
|
||||
{'name': 'Output Config', 'expanded': True, 'type': 'group', 'children': [
|
||||
{'name': 'Control Method', 'type': 'mutex', 'limits': ['Constant Current', 'Temperature PID'],
|
||||
@ -484,14 +474,14 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
{'name': 'Ki', 'type': 'float', 'step': 0.1, 'decimals': 16, 'unit': 'Hz', 'lock': False, 'target': 'thermostat', 'action': 'set_pid_ki', "compactHeight": False},
|
||||
{'name': 'Kd', 'type': 'float', 'step': 0.1, 'decimals': 16, 'unit': 's', 'lock': False, 'target': 'thermostat', 'action': 'set_pid_kd', "compactHeight": False},
|
||||
{'name': "PID Output Clamping", 'expanded': True, 'type': 'group', 'children': [
|
||||
{'name': 'Minimum', 'type': 'float', 'step': 1, 'limits': (-1000, 1000), 'decimals': 6,
|
||||
{'name': 'Minimum', 'type': 'float', 'step': 1, 'limits': (-3000, 3000), 'decimals': 6,
|
||||
'unit': 'mA', 'lock': False, 'target': 'thermostat', 'action': 'set_pid_output_min', "compactHeight": False},
|
||||
{'name': 'Maximum', 'type': 'float', 'step': 1, 'limits': (-1000, 1000), 'decimals': 6,
|
||||
{'name': 'Maximum', 'type': 'float', 'step': 1, 'limits': (-3000, 3000), 'decimals': 6,
|
||||
'unit': 'mA', 'lock': False, 'target': 'thermostat', 'action': 'set_pid_output_max', "compactHeight": False},
|
||||
]},
|
||||
{'name': 'PID Auto Tune', 'expanded': False, 'type': 'group', 'children': [
|
||||
{'name': 'Target Temperature', 'type': 'float', 'value': 20.0, 'step': 0.1, 'unit': '℃', 'format': '{value:.4f}', "compactHeight": False},
|
||||
{'name': 'Test Current', 'type': 'float', 'value': 1000, 'decimals': 6, 'step': 100, 'limits': (-1000, 1000), 'unit': 'mA', "compactHeight": False},
|
||||
{'name': 'Test Current', 'type': 'float', 'value': 1000, 'decimals': 6, 'step': 100, 'limits': (-3000, 3000), 'unit': 'mA', "compactHeight": False},
|
||||
{'name': 'Temperature Swing', 'type': 'float', 'value': 0.0, 'step': 0.0001, 'prefix': '±', 'unit': '℃', 'format': '{value:.4f}', "compactHeight": False},
|
||||
{'name': 'Lookback', 'type': 'float', 'value': 5.0, 'step': 0.1, 'unit': 's', 'format': '{value:.4f}', "compactHeight": False},
|
||||
{'name': 'Run', 'type': 'action', 'tip': 'Run'},
|
||||
@ -559,15 +549,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
else:
|
||||
_traverse(param_tree)
|
||||
|
||||
_add_unit_to_title(self.LASER_DIODE_STATUS)
|
||||
_add_unit_to_title(self.LASER_DIODE_PARAMETERS)
|
||||
_add_unit_to_title(self.THERMOSTAT_STATUS)
|
||||
_add_unit_to_title(self.THERMOSTAT_PARAMETERS)
|
||||
|
||||
self.params = [
|
||||
Parameter.create(name=f"Laser Diode Status", type='group', value=0, children=self.LASER_DIODE_STATUS),
|
||||
Parameter.create(name=f"Laser Diode Parameters", type='group', value=1, children=self.LASER_DIODE_PARAMETERS),
|
||||
Parameter.create(name=f"Thermostat Status", type='group', value=2, children=self.THERMOSTAT_STATUS),
|
||||
Parameter.create(name=f"Thermostat Parameters", type='group', value=3, children=self.THERMOSTAT_PARAMETERS),
|
||||
]
|
||||
self._set_param_tree()
|
||||
@ -659,8 +645,8 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.menu_action_update_net_settings.triggered.connect(show_update_net_settings_form)
|
||||
|
||||
def update_pd_mon_form_readings(self, ld_settings):
|
||||
pwr_unit = self.params[1].child('Photodiode Monitor Config', 'LD Power Limit').opts.get("unit", None)
|
||||
self.params[1].child('Photodiode Monitor Config', 'LD Power Limit').setOpts(limits= (0, siConvert(ld_settings["ld_pwr_limit"]["max"], pwr_unit)))
|
||||
pwr_unit = self.params[0].child('Photodiode Monitor Config', 'LD Power Limit').opts.get("unit", None)
|
||||
self.params[0].child('Photodiode Monitor Config', 'LD Power Limit').setOpts(limits= (0, siConvert(ld_settings["ld_pwr_limit"]["max"], pwr_unit)))
|
||||
self.cfg_pd_mon_form.settable_pwr_range_display_lbl.setText(f" 0 - {siConvert(ld_settings['ld_pwr_limit']['max'], pwr_unit):.4f}")
|
||||
self.cfg_pd_mon_form.cfg_pwr_limit_spinbox.setMaximum(siConvert(ld_settings['ld_pwr_limit']['max'], pwr_unit))
|
||||
|
||||
@ -792,19 +778,19 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.kirdy.task_dispatcher(self.kirdy.laser.set_ld_pwr_limit(settings['laser']['ld_pwr_limit']['max']))
|
||||
self.cfg_pd_mon_form.apply_pwr_limit_max_btn.clicked.connect(apply_ld_pwr_limit_max)
|
||||
|
||||
ld_pwr_limit_unit = self.params[1].child('Photodiode Monitor Config', 'LD Power Limit').opts["unit"]
|
||||
ld_pwr_limit_unit = self.params[0].child('Photodiode Monitor Config', 'LD Power Limit').opts["unit"]
|
||||
ld_pwr_limit_text = self.cfg_pd_mon_form.cfg_pwr_limit_lbl.text()
|
||||
self.cfg_pd_mon_form.cfg_pwr_limit_lbl.setText(ld_pwr_limit_text.replace(":", f" ({ld_pwr_limit_unit}):"))
|
||||
self.cfg_pd_mon_form.cfg_pwr_limit_spinbox.unit = ld_pwr_limit_unit
|
||||
settable_pwr_limit_text = self.cfg_pd_mon_form.settable_pwr_range_lbl.text()
|
||||
self.cfg_pd_mon_form.settable_pwr_range_lbl.setText(settable_pwr_limit_text.replace(":", f" ({ld_pwr_limit_unit}):"))
|
||||
|
||||
pd_responsitivity_unit = self.params[1].child('Photodiode Monitor Config', 'Responsitivity').opts["unit"]
|
||||
pd_responsitivity_unit = self.params[0].child('Photodiode Monitor Config', 'Responsitivity').opts["unit"]
|
||||
pd_responsitivity_text = self.cfg_pd_mon_form.cfg_responsitivity_lbl.text()
|
||||
self.cfg_pd_mon_form.cfg_responsitivity_lbl.setText(pd_responsitivity_text.replace(":", f" ({pd_responsitivity_unit}):"))
|
||||
self.cfg_pd_mon_form.cfg_responsitivity_spinbox.unit = pd_responsitivity_unit
|
||||
|
||||
pd_dark_current_unit = self.params[1].child('Photodiode Monitor Config', 'Dark Current').opts["unit"]
|
||||
pd_dark_current_unit = self.params[0].child('Photodiode Monitor Config', 'Dark Current').opts["unit"]
|
||||
pd_dark_current_text = self.cfg_pd_mon_form.cfg_dark_current_lbl.text()
|
||||
self.cfg_pd_mon_form.cfg_dark_current_lbl.setText(pd_dark_current_text.replace(":", f" ({pd_dark_current_unit}):"))
|
||||
self.cfg_pd_mon_form.cfg_dark_current_spinbox.unit = pd_dark_current_unit
|
||||
@ -817,26 +803,23 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.cfg_adc_filter_form.apply_btn.clicked.connect(apply_adc_filter_settings)
|
||||
|
||||
def _set_param_tree(self):
|
||||
status = self.ld_status
|
||||
status.setHeaderHidden(True)
|
||||
status.setParameters(self.params[0], showTop=False)
|
||||
self.ld_status.setStyleSheet("border: 3px solid #A1A1A1;") # Light Gray
|
||||
self.tec_status.setStyleSheet("border: 3px solid #A1A1A1;") # Light Gray
|
||||
|
||||
tree = self.ld_tree
|
||||
tree.setHeaderHidden(True)
|
||||
tree.setParameters(self.params[0], showTop=False)
|
||||
self.params[0].sigTreeStateChanged.connect(self.send_command)
|
||||
|
||||
tree = self.tec_tree
|
||||
tree.setHeaderHidden(True)
|
||||
tree.setParameters(self.params[1], showTop=False)
|
||||
self.params[1].sigTreeStateChanged.connect(self.send_command)
|
||||
|
||||
status = self.tec_status
|
||||
status.setHeaderHidden(True)
|
||||
status.setParameters(self.params[2], showTop=False)
|
||||
|
||||
tree = self.tec_tree
|
||||
tree.setHeaderHidden(True)
|
||||
tree.setParameters(self.params[3], showTop=False)
|
||||
self.params[3].sigTreeStateChanged.connect(self.send_command)
|
||||
|
||||
self.prev_autotuner_state = None
|
||||
@asyncSlot()
|
||||
async def autotune(param):
|
||||
self.prev_autotuner_state = None
|
||||
match self.autotuner.state():
|
||||
case PIDAutotuneState.STATE_OFF:
|
||||
settings = await self.kirdy.device.get_settings_summary()
|
||||
@ -846,6 +829,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
param.parent().child('Temperature Swing').value(),
|
||||
1.0 / settings['thermostat']['temp_adc_settings']['rate'],
|
||||
param.parent().child('Lookback').value())
|
||||
print(param.parent().child('Lookback').value())
|
||||
self.autotuner.setReady()
|
||||
param.setOpts(title="Stop")
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_constant_current_control_mode())
|
||||
@ -861,20 +845,20 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.background_task_lbl.setText("Ready.")
|
||||
self.loading_spinner.stop()
|
||||
self.loading_spinner.hide()
|
||||
self.params[3].child('PID Config', 'PID Auto Tune', 'Run').sigActivated.connect(autotune)
|
||||
self.params[1].child('PID Config', 'PID Auto Tune', 'Run').sigActivated.connect(autotune)
|
||||
|
||||
@pyqtSlot()
|
||||
def show_pd_mon_cfg_form(param):
|
||||
ld_pwr_limit = self.params[1].child('Photodiode Monitor Config', 'LD Power Limit').value()
|
||||
pd_responsitivity = self.params[1].child('Photodiode Monitor Config', 'Responsitivity').value()
|
||||
pd_dark_current = self.params[1].child('Photodiode Monitor Config', 'Dark Current').value()
|
||||
ld_pwr_limit = self.params[0].child('Photodiode Monitor Config', 'LD Power Limit').value()
|
||||
pd_responsitivity = self.params[0].child('Photodiode Monitor Config', 'Responsitivity').value()
|
||||
pd_dark_current = self.params[0].child('Photodiode Monitor Config', 'Dark Current').value()
|
||||
|
||||
self.cfg_pd_mon_form.cfg_responsitivity_spinbox.setValue(pd_responsitivity)
|
||||
self.cfg_pd_mon_form.cfg_pwr_limit_spinbox.setValue(ld_pwr_limit)
|
||||
self.cfg_pd_mon_form.cfg_dark_current_spinbox.setValue(pd_dark_current)
|
||||
|
||||
self.cfg_pd_mon_form.show()
|
||||
self.params[1].child('Photodiode Monitor Config', 'Configure Photodiode Monitor').sigActivated.connect(show_pd_mon_cfg_form)
|
||||
self.params[0].child('Photodiode Monitor Config', 'Configure Photodiode Monitor').sigActivated.connect(show_pd_mon_cfg_form)
|
||||
|
||||
@asyncSlot()
|
||||
async def show_adc_filter_cfg_form(param):
|
||||
@ -891,7 +875,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.cfg_adc_filter_form.filter_sampling_rate_cbox.setCurrentIndex(self.cfg_adc_filter_form.filter_sampling_rate_cbox.findText(filter_rate))
|
||||
self.cfg_adc_filter_form.show()
|
||||
|
||||
self.params[3].child('Temperature ADC Filter Settings', 'Configure ADC Filter').sigActivated.connect(show_adc_filter_cfg_form)
|
||||
self.params[1].child('Temperature ADC Filter Settings', 'Configure ADC Filter').sigActivated.connect(show_adc_filter_cfg_form)
|
||||
|
||||
@pyqtSlot(str)
|
||||
def cmd_cannot_execute(self, kirdy_msg):
|
||||
@ -899,40 +883,43 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
self.info_box.setWindowTitle("Command fails to execute")
|
||||
self.info_box.show()
|
||||
|
||||
@pyqtSlot(dict)
|
||||
def autotune_tick(self, report):
|
||||
match self.autotuner.state():
|
||||
case PIDAutotuneState.STATE_READY | PIDAutotuneState.STATE_RELAY_STEP_UP | PIDAutotuneState.STATE_RELAY_STEP_DOWN:
|
||||
self.autotuner.run(report['thermostat']['temperature'], report['ts']/1000)
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_tec_i_out(self.autotuner.output()))
|
||||
case PIDAutotuneState.STATE_SUCCEEDED:
|
||||
kp, ki, kd = self.autotuner.get_tec_pid()
|
||||
self.autotuner.setOff()
|
||||
self.params[3].child('PID Config', 'PID Auto Tune', 'Run').setOpts(title="Run")
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_kp(kp))
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_ki(ki))
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_kd(kd))
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_control_mode())
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_temperature_setpoint(self.params[3].child('PID Config', 'PID Auto Tune', 'Target Temperature').value()))
|
||||
self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick)
|
||||
self.background_task_lbl.setText("Ready.")
|
||||
self.loading_spinner.stop()
|
||||
self.loading_spinner.hide()
|
||||
self.info_box.setWindowTitle("PID AutoTune Success")
|
||||
self.info_box.setText("PID Config has been loaded to Thermostat.\nRegulating temperature.")
|
||||
self.info_box.show()
|
||||
|
||||
case PIDAutotuneState.STATE_FAILED:
|
||||
self.autotuner.setOff()
|
||||
self.params[3].child('PID Config', 'PID Auto Tune', 'Run').setOpts(title="Run")
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_tec_i_out(0.0))
|
||||
self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick)
|
||||
self.background_task_lbl.setText("Ready.")
|
||||
self.loading_spinner.stop()
|
||||
self.loading_spinner.hide()
|
||||
self.info_box.setWindowTitle("PID Autotune Failed")
|
||||
self.info_box.setText("PID Autotune is failed.")
|
||||
self.info_box.show()
|
||||
@asyncSlot(dict)
|
||||
async def autotune_tick(self, report):
|
||||
self.autotuner.run(report['thermostat']['temperature'], report['ts']/1000)
|
||||
if self.prev_autotuner_state != self.autotuner.state():
|
||||
match self.autotuner.state():
|
||||
case PIDAutotuneState.STATE_READY | PIDAutotuneState.STATE_RELAY_STEP_UP | PIDAutotuneState.STATE_RELAY_STEP_DOWN:
|
||||
await self.kirdy.thermostat.set_tec_i_out(self.autotuner.output())
|
||||
self.prev_autotuner_state = self.autotuner.state()
|
||||
case PIDAutotuneState.STATE_SUCCEEDED:
|
||||
kp, ki, kd = self.autotuner.get_tec_pid()
|
||||
self.autotuner.setOff()
|
||||
self.params[1].child('PID Config', 'PID Auto Tune', 'Run').setOpts(title="Run")
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_kp(kp))
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_ki(ki))
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_kd(kd))
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_pid_control_mode())
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_temperature_setpoint(self.params[1].child('PID Config', 'PID Auto Tune', 'Target Temperature').value()))
|
||||
self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick)
|
||||
self.background_task_lbl.setText("Ready.")
|
||||
self.loading_spinner.stop()
|
||||
self.loading_spinner.hide()
|
||||
self.info_box.setWindowTitle("PID AutoTune Success")
|
||||
self.info_box.setText("PID Config has been loaded to Thermostat.\nRegulating temperature.")
|
||||
self.info_box.show()
|
||||
self.prev_autotuner_state = None
|
||||
case PIDAutotuneState.STATE_FAILED:
|
||||
self.autotuner.setOff()
|
||||
self.params[1].child('PID Config', 'PID Auto Tune', 'Run').setOpts(title="Run")
|
||||
self.kirdy.task_dispatcher(self.kirdy.thermostat.set_tec_i_out(0.0))
|
||||
self.kirdy_handler.report_update_sig.disconnect(self.autotune_tick)
|
||||
self.background_task_lbl.setText("Ready.")
|
||||
self.loading_spinner.stop()
|
||||
self.loading_spinner.hide()
|
||||
self.info_box.setWindowTitle("PID Autotune Failed")
|
||||
self.info_box.setText("PID Autotune is failed.")
|
||||
self.info_box.show()
|
||||
self.prev_autotuner_state = None
|
||||
|
||||
@pyqtSlot(bool)
|
||||
def _on_connection_changed(self, result):
|
||||
@ -1003,17 +990,17 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
def update_ld_ctrl_panel_settings(self, settings):
|
||||
try:
|
||||
settings = settings['laser']
|
||||
with QSignalBlocker(self.params[1]):
|
||||
self.params[1].child('Output Config', 'LD Current Set').setValuewithLock(settings["ld_drive_current"]['value'])
|
||||
self.params[1].child('Output Config', 'LD Terminals Short').setValuewithLock(settings["ld_terms_short"])
|
||||
self.params[1].child('Output Config', 'Default Power On').setValuewithLock(settings["default_pwr_on"])
|
||||
self.params[1].child('Photodiode Monitor Config', 'LD Power Limit').setValuewithLock(settings["ld_pwr_limit"]["value"])
|
||||
with QSignalBlocker(self.params[0]):
|
||||
self.params[0].child('Output Config', 'LD Current Set').setValuewithLock(settings["ld_drive_current"]['value'])
|
||||
self.params[0].child('Output Config', 'LD Terminals Short').setValuewithLock(settings["ld_terms_short"])
|
||||
self.params[0].child('Output Config', 'Default Power On').setValuewithLock(settings["default_pwr_on"])
|
||||
self.params[0].child('Photodiode Monitor Config', 'LD Power Limit').setValuewithLock(settings["ld_pwr_limit"]["value"])
|
||||
self.update_pd_mon_form_readings(settings)
|
||||
if settings["pd_mon_params"]["responsitivity"] is not None:
|
||||
self.params[1].child('Photodiode Monitor Config', 'Responsitivity').setValuewithLock(settings["pd_mon_params"]["responsitivity"])
|
||||
self.params[0].child('Photodiode Monitor Config', 'Responsitivity').setValuewithLock(settings["pd_mon_params"]["responsitivity"])
|
||||
else:
|
||||
self.params[1].child('Photodiode Monitor Config', 'Responsitivity').setValuewithLock(0)
|
||||
self.params[1].child('Photodiode Monitor Config', 'Dark Current').setValuewithLock(settings["pd_mon_params"]["i_dark"])
|
||||
self.params[0].child('Photodiode Monitor Config', 'Responsitivity').setValuewithLock(0)
|
||||
self.params[0].child('Photodiode Monitor Config', 'Dark Current').setValuewithLock(settings["pd_mon_params"]["i_dark"])
|
||||
except Exception as e:
|
||||
logging.error(f"Params tree cannot be updated. Data:{settings}", exc_info=True)
|
||||
|
||||
@ -1023,20 +1010,24 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
report = report['laser']
|
||||
with QSignalBlocker(self.params[0]):
|
||||
if report['pwr_excursion']:
|
||||
self.params[0].child('Status', 'Color').setValuewithLock('r')
|
||||
self.params[0].child('Status').setOpts(title='Status: OverPower Alarm')
|
||||
self.ld_status.setStyleSheet("border: 3px solid red;")
|
||||
self.ld_status.setText(' Status: OverPower Alarm')
|
||||
else:
|
||||
self.params[0].child('Status', 'Color').setValuewithLock('g' if report['pwr_on'] else 'w')
|
||||
self.params[0].child('Status').setOpts(title='Status: Power On' if report['pwr_on'] else 'Status: Power Off')
|
||||
if report['pwr_on']:
|
||||
self.ld_status.setStyleSheet("border: 3px solid #44E62C;") # Light Green
|
||||
self.ld_status.setText(' Status: Power On')
|
||||
else:
|
||||
self.ld_status.setStyleSheet("border: 3px solid #A1A1A1;") # Light Gray
|
||||
self.ld_status.setText(' Status: Power Off')
|
||||
|
||||
with QSignalBlocker(self.params[1]):
|
||||
self.params[1].child('Readings', 'LD Current Set').setValuewithLock(report["ld_i_set"])
|
||||
self.params[1].child('Readings', 'PD Current').setValuewithLock(report["pd_i"])
|
||||
with QSignalBlocker(self.params[0]):
|
||||
self.params[0].child('Readings', 'LD Current Set').setValuewithLock(report["ld_i_set"])
|
||||
self.params[0].child('Readings', 'PD Current').setValuewithLock(report["pd_i"])
|
||||
if report["pd_pwr"] is not None:
|
||||
self.params[1].child('Readings', 'PD Power').setValuewithLock(report["pd_pwr"])
|
||||
self.params[0].child('Readings', 'PD Power').setValuewithLock(report["pd_pwr"])
|
||||
else:
|
||||
self.params[1].child('Readings', 'PD Power').setValuewithLock(0)
|
||||
self.params[1].child('Readings', 'LF Mod Termination (50 Ohm)').setValuewithLock(report["term_50ohm"])
|
||||
self.params[0].child('Readings', 'PD Power').setValuewithLock(0)
|
||||
self.params[0].child('Readings', 'LF Mod Termination (50 Ohm)').setValuewithLock(report["term_50ohm"])
|
||||
except Exception as e:
|
||||
logging.error(f"Params tree cannot be updated. Data:{report}", exc_info=True)
|
||||
|
||||
@ -1044,29 +1035,29 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
def update_thermostat_ctrl_panel_settings(self, settings):
|
||||
try:
|
||||
settings = settings['thermostat']
|
||||
with QSignalBlocker(self.params[3]):
|
||||
self.params[3].child('Output Config', 'Control Method').setValuewithLock("Temperature PID" if settings["pid_engaged"] else "Constant Current")
|
||||
self.params[3].child('Output Config', 'Control Method', 'Set Current').setValuewithLock(settings["tec_settings"]['i_set']['value'])
|
||||
self.params[3].child('Output Config', 'Control Method', 'Set Temperature').setValuewithLock(float(settings["temperature_setpoint"]))
|
||||
self.params[3].child('Output Config', 'Limits', 'Max Cooling Current').setValuewithLock(settings["tec_settings"]['max_i_pos']['value'])
|
||||
self.params[3].child('Output Config', 'Limits', 'Max Heating Current').setValuewithLock(settings["tec_settings"]['max_i_neg']['value'])
|
||||
self.params[3].child('Output Config', 'Limits', 'Max Voltage Difference').setValuewithLock(settings["tec_settings"]['max_v']['value'])
|
||||
self.params[3].child('Output Config', 'Default Power On').setValuewithLock(settings["default_pwr_on"])
|
||||
with QSignalBlocker(self.params[1]):
|
||||
self.params[1].child('Output Config', 'Control Method').setValuewithLock("Temperature PID" if settings["pid_engaged"] else "Constant Current")
|
||||
self.params[1].child('Output Config', 'Control Method', 'Set Current').setValuewithLock(settings["tec_settings"]['i_set']['value'])
|
||||
self.params[1].child('Output Config', 'Control Method', 'Set Temperature').setValuewithLock(float(settings["temperature_setpoint"]))
|
||||
self.params[1].child('Output Config', 'Limits', 'Max Cooling Current').setValuewithLock(settings["tec_settings"]['max_i_pos']['value'])
|
||||
self.params[1].child('Output Config', 'Limits', 'Max Heating Current').setValuewithLock(settings["tec_settings"]['max_i_neg']['value'])
|
||||
self.params[1].child('Output Config', 'Limits', 'Max Voltage Difference').setValuewithLock(settings["tec_settings"]['max_v']['value'])
|
||||
self.params[1].child('Output Config', 'Default Power On').setValuewithLock(settings["default_pwr_on"])
|
||||
filter_type = settings['temp_adc_settings']['filter_type']
|
||||
filter_rate = settings['temp_adc_settings'][getattr(getattr(FilterConfig, filter_type), "_odr_type")]
|
||||
self.update_adc_filter_form_readings(filter_type, filter_rate)
|
||||
self.params[3].child('Temperature ADC Filter Settings', 'Filter Type').setValue(filter_type)
|
||||
self.params[3].child('Temperature ADC Filter Settings', 'Sampling Rate').setValue(settings['temp_adc_settings']['rate'])
|
||||
self.params[3].child('Temperature Monitor Config', 'Upper Limit').setValuewithLock(settings["temp_mon_settings"]['upper_limit'])
|
||||
self.params[3].child('Temperature Monitor Config', 'Lower Limit').setValuewithLock(settings["temp_mon_settings"]['lower_limit'])
|
||||
self.params[3].child('PID Config', 'Kp').setValuewithLock(settings["pid_params"]['kp'])
|
||||
self.params[3].child('PID Config', 'Ki').setValuewithLock(settings["pid_params"]['ki'])
|
||||
self.params[3].child('PID Config', 'Kd').setValuewithLock(settings["pid_params"]['kd'])
|
||||
self.params[3].child('PID Config', 'PID Output Clamping', 'Minimum').setValuewithLock(settings["pid_params"]['output_min'])
|
||||
self.params[3].child('PID Config', 'PID Output Clamping', 'Maximum').setValuewithLock(settings["pid_params"]['output_max'])
|
||||
self.params[3].child('Thermistor Settings', 'T₀').setValuewithLock(settings["thermistor_params"]['t0'])
|
||||
self.params[3].child('Thermistor Settings', 'R₀').setValuewithLock(settings["thermistor_params"]['r0'])
|
||||
self.params[3].child('Thermistor Settings', 'B').setValuewithLock(settings["thermistor_params"]['b'])
|
||||
self.params[1].child('Temperature ADC Filter Settings', 'Filter Type').setValue(filter_type)
|
||||
self.params[1].child('Temperature ADC Filter Settings', 'Sampling Rate').setValue(settings['temp_adc_settings']['rate'])
|
||||
self.params[1].child('Temperature Monitor Config', 'Upper Limit').setValuewithLock(settings["temp_mon_settings"]['upper_limit'])
|
||||
self.params[1].child('Temperature Monitor Config', 'Lower Limit').setValuewithLock(settings["temp_mon_settings"]['lower_limit'])
|
||||
self.params[1].child('PID Config', 'Kp').setValuewithLock(settings["pid_params"]['kp'])
|
||||
self.params[1].child('PID Config', 'Ki').setValuewithLock(settings["pid_params"]['ki'])
|
||||
self.params[1].child('PID Config', 'Kd').setValuewithLock(settings["pid_params"]['kd'])
|
||||
self.params[1].child('PID Config', 'PID Output Clamping', 'Minimum').setValuewithLock(settings["pid_params"]['output_min'])
|
||||
self.params[1].child('PID Config', 'PID Output Clamping', 'Maximum').setValuewithLock(settings["pid_params"]['output_max'])
|
||||
self.params[1].child('Thermistor Settings', 'T₀').setValuewithLock(settings["thermistor_params"]['t0'])
|
||||
self.params[1].child('Thermistor Settings', 'R₀').setValuewithLock(settings["thermistor_params"]['r0'])
|
||||
self.params[1].child('Thermistor Settings', 'B').setValuewithLock(settings["thermistor_params"]['b'])
|
||||
self.graphs.set_temp_setpoint_line(temp=round(settings["temperature_setpoint"], 4))
|
||||
self.graphs.set_temp_setpoint_line(visible=settings['pid_engaged'])
|
||||
except Exception as e:
|
||||
@ -1075,24 +1066,26 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
@pyqtSlot(dict)
|
||||
def update_thermostat_ctrl_panel_readings(self, report):
|
||||
try:
|
||||
report = report['thermostat']
|
||||
with QSignalBlocker(self.params[2]):
|
||||
if report['temp_mon_status']['over_temp_alarm']:
|
||||
self.params[2].child('Status', 'Color').setValuewithLock('r')
|
||||
self.params[2].child('Status').setOpts(title='Status: OverTemperature Alarm')
|
||||
|
||||
report = report['thermostat']
|
||||
if report['temp_mon_status']['over_temp_alarm']:
|
||||
self.tec_status.setStyleSheet("border: 3px solid red;")
|
||||
self.tec_status.setText(' Status: OverTemperature Alarm')
|
||||
else:
|
||||
if report['pwr_on']:
|
||||
self.tec_status.setStyleSheet("border: 3px solid #44E62C;") # Light Green
|
||||
self.tec_status.setText(' Status: Power On')
|
||||
else:
|
||||
self.params[2].child('Status', 'Color').setValuewithLock('g' if report['pwr_on'] else 'w')
|
||||
self.params[2].child('Status').setOpts(title='Status: Power On' if report['pwr_on'] else 'Status: Power Off')
|
||||
self.tec_status.setStyleSheet("border: 3px solid #A1A1A1;") # Light Gray
|
||||
self.tec_status.setText(' Status: Power Off')
|
||||
|
||||
with QSignalBlocker(self.params[3]):
|
||||
with QSignalBlocker(self.params[1]):
|
||||
if report["temperature"] == None:
|
||||
self.params[3].child('Readings', 'Temperature').setValuewithLock(-273.15)
|
||||
self.params[1].child('Readings', 'Temperature').setValuewithLock(-273.15)
|
||||
else:
|
||||
self.params[3].child('Readings', 'Temperature').setValuewithLock(report["temperature"])
|
||||
self.params[3].child('Readings', 'Current through TEC').setValuewithLock(report["tec_i"])
|
||||
self.params[1].child('Readings', 'Temperature').setValuewithLock(report["temperature"])
|
||||
self.params[1].child('Readings', 'Current through TEC').setValuewithLock(report["tec_i"])
|
||||
rate = 1 / (report['interval']['ms'] / 1e3 + report['interval']['us'] / 1e6)
|
||||
self.params[3].child('Temperature ADC Filter Settings', 'Recorded Sampling Rate').setValue(rate)
|
||||
self.params[1].child('Temperature ADC Filter Settings', 'Recorded Sampling Rate').setValue(rate)
|
||||
self.cfg_adc_filter_form.recorded_sampling_rate_reading_lbl.setText(f"{rate:.2f}")
|
||||
except Exception as e:
|
||||
logging.error(f"Params tree cannot be updated. Data:{report}", exc_info=True)
|
||||
|
@ -258,7 +258,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1337</string>
|
||||
<string>1550</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>5</number>
|
||||
|
@ -78,10 +78,11 @@
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
<bold>true</bold>
|
||||
<underline>false</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Laser Diode</string>
|
||||
<string> Laser Diode </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
@ -92,23 +93,27 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ParameterTree" name="ld_status" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>57</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="ld_status">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Status: Power Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ParameterTree" name="ld_tree" native="true">
|
||||
@ -166,10 +171,11 @@
|
||||
<font>
|
||||
<pointsize>14</pointsize>
|
||||
<bold>true</bold>
|
||||
<underline>false</underline>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Thermostat</string>
|
||||
<string> Thermostat </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>false</bool>
|
||||
@ -180,23 +186,27 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ParameterTree" name="tec_status" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>57</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<widget class="QLabel" name="tec_status">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> Status: Power Off</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ParameterTree" name="tec_tree" native="true">
|
||||
|
@ -3,4 +3,5 @@ ParameterTree:disabled { color: gray }
|
||||
QToolButton:disabled { color: gray }
|
||||
QDoubleSpinBox:disabled { color: gray }
|
||||
QCheckBox:disabled { color: gray }
|
||||
QMenu:disabled { color: gray }
|
||||
QMenu:disabled { color: gray }
|
||||
QLabel:disabled { color: gray }
|
@ -156,6 +156,6 @@ class Ui_Conn_Settings_Form(object):
|
||||
self.dot_2_label.setText(_translate("Conn_Settings_Form", "."))
|
||||
self.addr_in_3.setText(_translate("Conn_Settings_Form", "128"))
|
||||
self.port_no_label.setText(_translate("Conn_Settings_Form", "Port:"))
|
||||
self.port_in.setText(_translate("Conn_Settings_Form", "1337"))
|
||||
self.port_in.setText(_translate("Conn_Settings_Form", "1550"))
|
||||
self.connect_btn.setText(_translate("Conn_Settings_Form", "Connect"))
|
||||
self.cancel_btn.setText(_translate("Conn_Settings_Form", "Cancel"))
|
||||
|
@ -253,7 +253,7 @@ class Ui_Update_Network_Settings_Form(object):
|
||||
self.prefix_len_lbl.setText(_translate("Update_Network_Settings_Form", "Prefix Length:"))
|
||||
self.prefix_len_in.setText(_translate("Update_Network_Settings_Form", "24"))
|
||||
self.port_no_lbl.setText(_translate("Update_Network_Settings_Form", "Port:"))
|
||||
self.port_in.setText(_translate("Update_Network_Settings_Form", "1337"))
|
||||
self.port_in.setText(_translate("Update_Network_Settings_Form", "1550"))
|
||||
self.gateway_lbl.setText(_translate("Update_Network_Settings_Form", "Gateway:"))
|
||||
self.gateway_in_0.setText(_translate("Update_Network_Settings_Form", "192"))
|
||||
self.dot_0_lbl_2.setText(_translate("Update_Network_Settings_Form", "."))
|
||||
|
@ -349,7 +349,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>1337</string>
|
||||
<string>1550</string>
|
||||
</property>
|
||||
<property name="maxLength">
|
||||
<number>5</number>
|
||||
|
@ -30,7 +30,7 @@ impl Default for IpSettings {
|
||||
fn default() -> Self {
|
||||
IpSettings {
|
||||
addr: [192, 168, 1, 128],
|
||||
port: 1337,
|
||||
port: 1550,
|
||||
prefix_len: 24,
|
||||
gateway: [192, 168, 1, 1],
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user