Add pyproject.toml
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,3 +2,5 @@ target/
|
||||
result
|
||||
*.pyc
|
||||
*.jdebug*
|
||||
env
|
||||
pykirdy.egg-info/
|
||||
1
pykirdy/MANIFEST.in
Normal file
1
pykirdy/MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
include pykirdy/ui/view/MainWindow.ui
|
||||
@@ -1,5 +1,5 @@
|
||||
from pprint import pp
|
||||
from driver.kirdy import Kirdy, FilterConfig
|
||||
from pykirdy.kirdy import Kirdy, FilterConfig
|
||||
import signal
|
||||
import time
|
||||
import asyncio
|
||||
|
||||
108
pykirdy/autotune_example.py
Normal file
108
pykirdy/autotune_example.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from pykirdy.aioclient import Kirdy, FilterConfig
|
||||
from pykirdy.autotune import PIDAutotune
|
||||
import asyncio
|
||||
import signal
|
||||
import json
|
||||
from sipyco.asyncio_tools import SignalHandler
|
||||
|
||||
async def main():
|
||||
"""
|
||||
PID AutoTune Tools for Kirdy
|
||||
The obtained temperature works best at the target temperature specified.
|
||||
Before running PID AutoTune, please
|
||||
1. Secure the laser diode onto the LD adapter and copper heat sink
|
||||
2. Make sure Kirdy has warmed up and reached thermal equilibrium state
|
||||
|
||||
In case of PID Autotune Failure, you can
|
||||
1. Run the PID Autotune again
|
||||
2. Or increase the lookback period
|
||||
3. Or increase the sampling rate
|
||||
"""
|
||||
|
||||
# Target temperature of the autotune routine, celsius
|
||||
target_temperature = 20
|
||||
# Value by which output will be increased/decreased from zero, amps
|
||||
output_step = 1
|
||||
# Reference period for local minima/maxima, seconds
|
||||
lookback = 2.0
|
||||
# Determines by how much the input value must
|
||||
# overshoot/undershoot the setpoint, celsius
|
||||
noiseband = 2.0
|
||||
|
||||
kirdy = Kirdy()
|
||||
kirdy.start_session(host='192.168.1.134', port=1550)
|
||||
|
||||
await kirdy.wait_until_connected()
|
||||
|
||||
while not(kirdy.connected()):
|
||||
pass
|
||||
|
||||
await kirdy.laser.set_power_on(False)
|
||||
await kirdy.laser.set_i(0)
|
||||
|
||||
await kirdy.thermostat.set_power_on(False)
|
||||
await kirdy.thermostat.set_constant_current_control_mode()
|
||||
await kirdy.thermostat.set_tec_i_out(0)
|
||||
await kirdy.thermostat.clear_alarm()
|
||||
|
||||
|
||||
signal_handler = SignalHandler()
|
||||
signal_handler.setup()
|
||||
async def sig_handling():
|
||||
await signal_handler.wait_terminate()
|
||||
tuner.setFailed()
|
||||
asyncio.create_task(sig_handling())
|
||||
|
||||
# Configure the Thermistor Parameters
|
||||
await kirdy.thermostat.set_sh_beta(3950)
|
||||
await kirdy.thermostat.set_sh_r0(10.0 * 1000)
|
||||
await kirdy.thermostat.set_sh_t0(25)
|
||||
|
||||
# Set a large enough temperature range so that it won't trigger overtemperature protection
|
||||
await kirdy.thermostat.set_temp_mon_upper_limit(target_temperature + 20)
|
||||
await kirdy.thermostat.set_temp_mon_lower_limit(target_temperature - 20)
|
||||
|
||||
await kirdy.thermostat.set_tec_max_cooling_i(output_step)
|
||||
await kirdy.thermostat.set_tec_max_heating_i(output_step)
|
||||
|
||||
# The Polling Rate of Temperature Adc is equal to the PID Update Interval
|
||||
await kirdy.thermostat.config_temp_adc_filter(FilterConfig.Sinc5Sinc1With50hz60HzRejection.f16sps)
|
||||
settings = await kirdy.device.get_settings_summary()
|
||||
sampling_rate = settings["thermostat"]["temp_adc_settings"]["rate"]
|
||||
|
||||
print("Settings: {0}".format(settings))
|
||||
|
||||
tuner = PIDAutotune(target_temperature, output_step,
|
||||
lookback, noiseband, 1/sampling_rate)
|
||||
|
||||
await kirdy.thermostat.set_power_on(True)
|
||||
|
||||
while True:
|
||||
status_report = await kirdy.device.get_status_report()
|
||||
|
||||
temperature = status_report["thermostat"]["temperature"]
|
||||
ts = status_report['ts']
|
||||
print("Ts: {0} Current Temperature: {1} degree".format(ts, temperature))
|
||||
|
||||
if (tuner.run(temperature, ts / 1000.0)):
|
||||
print(tuner._state)
|
||||
break
|
||||
|
||||
tuner_out = tuner.output()
|
||||
await kirdy.thermostat.set_tec_i_out(float(tuner_out))
|
||||
|
||||
await kirdy.thermostat.set_tec_i_out(0)
|
||||
await kirdy.thermostat.set_power_on(False)
|
||||
|
||||
# if tuner.state() == PIDAutotuneState.STATE_SUCCEEDED:
|
||||
# pid_params = tuner.get_pid_parameters(tuning_rule="tyreus-luyben")
|
||||
# await kirdy.thermostat.set_pid_kp(pid_params.Kp)
|
||||
# await kirdy.thermostat.set_pid_ki(pid_params.Ki)
|
||||
# await kirdy.thermostat.set_pid_kd(pid_params.Kd)
|
||||
# await kirdy.thermostat.set_pid_output_max(1.0)
|
||||
# await kirdy.thermostat.set_pid_output_min(1.0)
|
||||
|
||||
await kirdy.end_session()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
0
pykirdy/pykirdy/__init__.py
Normal file
0
pykirdy/pykirdy/__init__.py
Normal file
@@ -3,12 +3,9 @@ import logging
|
||||
from collections import deque, namedtuple
|
||||
from enum import Enum
|
||||
import socket
|
||||
import json
|
||||
import time
|
||||
import signal
|
||||
from driver.kirdy import Kirdy, FilterConfig
|
||||
from pykirdy.aioclient import Kirdy, FilterConfig
|
||||
import asyncio
|
||||
from sipyco.asyncio_tools import SignalHandler
|
||||
|
||||
# Based on hirshmann pid-autotune libiary
|
||||
# See https://github.com/hirschmann/pid-autotune
|
||||
@@ -251,108 +248,3 @@ class PIDAutotune:
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
async def main():
|
||||
"""
|
||||
PID AutoTune Tools for Kirdy
|
||||
The obtained temperature works best at the target temperature specified.
|
||||
Before running PID AutoTune, please
|
||||
1. Secure the laser diode onto the LD adapter and copper heat sink
|
||||
2. Make sure Kirdy has warmed up and reached thermal equilibrium state
|
||||
|
||||
In case of PID Autotune Failure, you can
|
||||
1. Run the PID Autotune again
|
||||
2. Or increase the lookback period
|
||||
3. Or increase the sampling rate
|
||||
"""
|
||||
|
||||
# Target temperature of the autotune routine, celsius
|
||||
target_temperature = 20
|
||||
# Value by which output will be increased/decreased from zero, amps
|
||||
output_step = 1
|
||||
# Reference period for local minima/maxima, seconds
|
||||
lookback = 2.0
|
||||
# Determines by how much the input value must
|
||||
# overshoot/undershoot the setpoint, celsius
|
||||
noiseband = 2.0
|
||||
|
||||
kirdy = Kirdy()
|
||||
kirdy.start_session(host='192.168.1.126', port=1337)
|
||||
|
||||
await kirdy.wait_until_connected()
|
||||
|
||||
while not(kirdy.connected()):
|
||||
pass
|
||||
|
||||
await kirdy.laser.set_power_on(False)
|
||||
await kirdy.laser.set_i(0)
|
||||
|
||||
await kirdy.thermostat.set_power_on(False)
|
||||
await kirdy.thermostat.set_constant_current_control_mode()
|
||||
await kirdy.thermostat.set_tec_i_out(0)
|
||||
await kirdy.thermostat.clear_alarm()
|
||||
|
||||
|
||||
signal_handler = SignalHandler()
|
||||
signal_handler.setup()
|
||||
async def sig_handling():
|
||||
await signal_handler.wait_terminate()
|
||||
tuner.setFailed()
|
||||
asyncio.create_task(sig_handling())
|
||||
|
||||
await kirdy.device.set_active_report_mode(False)
|
||||
|
||||
# Configure the Thermistor Parameters
|
||||
await kirdy.thermostat.set_sh_beta(3950)
|
||||
await kirdy.thermostat.set_sh_r0(10.0 * 1000)
|
||||
await kirdy.thermostat.set_sh_t0(25)
|
||||
|
||||
# Set a large enough temperature range so that it won't trigger overtemperature protection
|
||||
await kirdy.thermostat.set_temp_mon_upper_limit(target_temperature + 20)
|
||||
await kirdy.thermostat.set_temp_mon_lower_limit(target_temperature - 20)
|
||||
|
||||
await kirdy.thermostat.set_tec_max_cooling_i(output_step)
|
||||
await kirdy.thermostat.set_tec_max_heating_i(output_step)
|
||||
|
||||
# The Polling Rate of Temperature Adc is equal to the PID Update Interval
|
||||
await kirdy.thermostat.config_temp_adc_filter(FilterConfig.Sinc5Sinc1With50hz60HzRejection.f16sps)
|
||||
settings = await kirdy.device.get_settings_summary()
|
||||
sampling_rate = settings["thermostat"]["temp_adc_settings"]["rate"]
|
||||
|
||||
print("Settings: {0}".format(settings))
|
||||
|
||||
tuner = PIDAutotune(target_temperature, output_step,
|
||||
lookback, noiseband, 1/sampling_rate)
|
||||
|
||||
await kirdy.thermostat.set_power_on(True)
|
||||
|
||||
while True:
|
||||
status_report = await kirdy.device.get_status_report()
|
||||
|
||||
temperature = status_report["thermostat"]["temperature"]
|
||||
ts = status_report['ts']
|
||||
print("Ts: {0} Current Temperature: {1} degree".format(ts, temperature))
|
||||
|
||||
if (tuner.run(temperature, ts / 1000.0)):
|
||||
print(tuner._state)
|
||||
break
|
||||
|
||||
tuner_out = tuner.output()
|
||||
await kirdy.thermostat.set_tec_i_out(float(tuner_out))
|
||||
|
||||
await kirdy.thermostat.set_tec_i_out(0)
|
||||
await kirdy.thermostat.set_power_on(False)
|
||||
|
||||
if tuner.state() == PIDAutotuneState.STATE_SUCCEEDED:
|
||||
pid_params = tuner.get_pid_parameters(tuning_rule="tyreus-luyben")
|
||||
await kirdy.thermostat.set_pid_kp(pid_params.Kp)
|
||||
await kirdy.thermostat.set_pid_ki(pid_params.Ki)
|
||||
await kirdy.thermostat.set_pid_kd(pid_params.Kd)
|
||||
await kirdy.thermostat.set_pid_output_max(1.0)
|
||||
await kirdy.thermostat.set_pid_output_min(1.0)
|
||||
|
||||
await kirdy.end_session()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -18,7 +18,7 @@ import os
|
||||
import argparse
|
||||
import logging
|
||||
import asyncio
|
||||
from driver.kirdy import FilterConfig, Kirdy as Kirdy_Driver
|
||||
from pykirdy.aioclient import FilterConfig, Kirdy as Kirdy_Driver
|
||||
import qasync
|
||||
from qasync import asyncClose, asyncSlot
|
||||
from collections import deque
|
||||
@@ -28,8 +28,7 @@ from typing import Any, Optional, List
|
||||
from dateutil import tz
|
||||
import math
|
||||
import socket
|
||||
from pid_autotune import PIDAutotune, PIDAutotuneState
|
||||
import importlib.resources
|
||||
from pykirdy.autotune import PIDAutotune, PIDAutotuneState
|
||||
|
||||
FLOAT_REGEX = re.compile(r'(?P<number>[+-]?((((\d+(\.\d*)?)|(\d*\.\d+))([eE][+-]?\d+)?)|((?i:nan)|(inf))))\s*((?P<siPrefix>[u' + SI_PREFIXES + r']?)(?P<suffix>[\w°℃].*))?$')
|
||||
|
||||
@@ -392,8 +391,7 @@ registerParameterType('mutex', MutexParameter)
|
||||
class UpdateNetSettingsForm(QtWidgets.QDialog):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
ui_file_path = importlib.resources.files("ui").joinpath("update_network_settings_form.ui")
|
||||
uic.loadUi(ui_file_path, self)
|
||||
uic.loadUi(os.path.join(os.path.dirname(__file__), "ui/update_network_settings_form.ui"), self)
|
||||
|
||||
def get_net_settings(self):
|
||||
try:
|
||||
@@ -414,14 +412,12 @@ class UpdateNetSettingsForm(QtWidgets.QDialog):
|
||||
class CfgPdMonForm(QtWidgets.QDialog):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
ui_file_path = importlib.resources.files("ui").joinpath("config_pd_mon_form.ui")
|
||||
uic.loadUi(ui_file_path, self)
|
||||
uic.loadUi(os.path.join(os.path.dirname(__file__), "ui/config_pd_mon_form.ui"), self)
|
||||
|
||||
class ConnSettingsForm(QtWidgets.QDialog):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
ui_file_path = importlib.resources.files("ui").joinpath("conn_settings_form.ui")
|
||||
uic.loadUi(ui_file_path, self)
|
||||
uic.loadUi(os.path.join(os.path.dirname(__file__), "ui/conn_settings_form.ui"), self)
|
||||
|
||||
def get_net_settings(self):
|
||||
try:
|
||||
@@ -438,8 +434,7 @@ class ConnSettingsForm(QtWidgets.QDialog):
|
||||
class ConfigAdcFilterForm(QtWidgets.QDialog):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
ui_file_path = importlib.resources.files("ui").joinpath("config_adc_filter_form.ui")
|
||||
uic.loadUi(ui_file_path, self)
|
||||
uic.loadUi(os.path.join(os.path.dirname(__file__), "ui/config_adc_filter_form.ui"), self)
|
||||
self.filter_type_cbox.addItems(['Sinc5Sinc1With50hz60HzRejection', 'Sinc5Sinc1', 'Sinc3', 'Sinc3WithFineODR'])
|
||||
self.fine_filter_sampling_rate_spinbox.setVisible(False)
|
||||
self.fine_filter_sampling_rate_spinbox.setMinimum(FilterConfig.Sinc3WithFineODR.lower_limit)
|
||||
@@ -564,8 +559,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
super(MainWindow, self).__init__()
|
||||
self.kirdy = Kirdy_Driver()
|
||||
|
||||
ui_file_path = importlib.resources.files("ui").joinpath("kirdy_qt.ui")
|
||||
uic.loadUi(ui_file_path, self)
|
||||
uic.loadUi(os.path.join(os.path.dirname(__file__), "ui/mainwindow.ui"), self)
|
||||
|
||||
self.info_box = QtWidgets.QMessageBox()
|
||||
self.info_box.setIcon(QtWidgets.QMessageBox.Icon.Information)
|
||||
@@ -724,7 +724,7 @@
|
||||
<customwidget>
|
||||
<class>QtWaitingSpinner</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>waitingspinnerwidget</header>
|
||||
<header>pykirdy.ui.waitingspinnerwidget</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
21
pykirdy/pyproject.toml
Normal file
21
pykirdy/pyproject.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[build-system]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pykirdy"
|
||||
version = "0.0"
|
||||
authors = [{name = "M-Labs"}]
|
||||
description = "Python utilities for the Sinara 1550 Kirdy"
|
||||
urls.Repository = "https://git.m-labs.hk/M-Labs/kirdy"
|
||||
license = {text = "GPLv3"}
|
||||
dependencies = [
|
||||
"numpy >= 1.26.4",
|
||||
"pyqtgraph >= 0.13.7",
|
||||
"pyqt6 >= 6.8.0",
|
||||
"qasync >= 0.27.1",
|
||||
"pglive >= 0.7.2",
|
||||
]
|
||||
|
||||
[project.gui-scripts]
|
||||
kirdy_qt = "pykirdy.kirdy_qt:main"
|
||||
Reference in New Issue
Block a user