keithley-tempcontrol 0.16.10__tar.gz → 0.16.11__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (22) hide show
  1. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/PKG-INFO +1 -1
  2. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/pyproject.toml +1 -1
  3. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510.py +27 -18
  4. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_adev.py +8 -7
  5. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_cs.py +38 -33
  6. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_dev.py +9 -7
  7. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/keithley_tempcontrol/cgse_services.py +4 -4
  8. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/keithley_tempcontrol/settings.yaml +2 -0
  9. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/.gitignore +0 -0
  10. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/README.md +0 -0
  11. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/justfile +0 -0
  12. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/noxfile.py +0 -0
  13. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/service_registry.db +0 -0
  14. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/__init__.py +0 -0
  15. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510.yaml +0 -0
  16. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_acs.py +0 -0
  17. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_mon.py +0 -0
  18. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_protocol.py +0 -0
  19. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/egse/tempcontrol/keithley/daq6510_sim.py +0 -0
  20. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/keithley_tempcontrol/__init__.py +0 -0
  21. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/src/keithley_tempcontrol/cgse_explore.py +0 -0
  22. {keithley_tempcontrol-0.16.10 → keithley_tempcontrol-0.16.11}/temperature_readings.log +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: keithley-tempcontrol
3
- Version: 0.16.10
3
+ Version: 0.16.11
4
4
  Summary: Keithley Temperature Control for CGSE
5
5
  Author: IvS KU Leuven
6
6
  Maintainer-email: Rik Huygen <rik.huygen@kuleuven.be>, Sara Regibo <sara.regibo@kuleuven.be>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "keithley-tempcontrol"
3
- version = "0.16.10"
3
+ version = "0.16.11"
4
4
  description = "Keithley Temperature Control for CGSE"
5
5
  authors = [
6
6
  {name = "IvS KU Leuven"}
@@ -1,33 +1,40 @@
1
1
  import logging
2
2
  import re
3
3
  from pathlib import Path
4
- from typing import Dict, Union
4
+ from typing import Dict
5
5
  from typing import List
6
6
  from typing import Tuple
7
7
 
8
+ from egse.connect import get_endpoint
8
9
  from egse.decorators import dynamic_interface
9
10
  from egse.device import DeviceConnectionState
10
11
  from egse.device import DeviceInterface
11
12
  from egse.log import logger
12
- from egse.mixin import DynamicCommandMixin, CommandType
13
+ from egse.mixin import CommandType
14
+ from egse.mixin import DynamicCommandMixin
13
15
  from egse.mixin import add_lf
14
16
  from egse.mixin import dynamic_command
15
17
  from egse.proxy import Proxy
16
18
  from egse.settings import Settings
17
19
  from egse.tempcontrol.keithley.daq6510_dev import DAQ6510
18
- from egse.zmq_ser import connect_address
19
-
20
20
 
21
21
  HERE = Path(__file__).parent
22
22
 
23
- CTRL_SETTINGS = Settings.load("Keithley Control Server")
24
- FW_SETTINGS = Settings.load("Keithley DAQ6510")
25
- DEVICE_SETTINGS = Settings.load(location=HERE, filename="daq6510.yaml")
23
+ cs_settings = Settings.load("Keithley Control Server")
24
+ dev_settings = Settings.load("Keithley DAQ6510")
26
25
 
26
+ PROTOCOL = cs_settings.get("PROTOCOL", "tcp")
27
+ HOSTNAME = cs_settings.get("HOSTNAME", "localhost")
28
+ COMMANDING_PORT = cs_settings.get("COMMANDING_PORT", 0)
29
+ TIMEOUT = cs_settings.get("TIMEOUT")
30
+ SERVICE_TYPE = cs_settings.get("SERVICE_TYPE", "daq6510")
27
31
 
28
32
  DEFAULT_BUFFER_1 = "defbuffer1"
29
33
  DEFAULT_BUFFER_2 = "defbuffer2"
30
34
 
35
+ DEV_HOST = dev_settings.get("HOSTNAME")
36
+ DEV_PORT = dev_settings.get("PORT")
37
+
31
38
 
32
39
  class DAQ6510Interface(DeviceInterface):
33
40
  """
@@ -35,7 +42,7 @@ class DAQ6510Interface(DeviceInterface):
35
42
  """
36
43
 
37
44
  @dynamic_interface
38
- def send_command(self, command: str, response: bool) -> Union[None, str]:
45
+ def send_command(self, command: str, response: bool) -> str | None:
39
46
  """Sends the given SCPI command to the device.
40
47
 
41
48
  The valid commands are described in the DAQ6510 Reference Manual [DAQ6510-901-01 Rev. B / September 2019].
@@ -219,12 +226,12 @@ class DAQ6510Controller(DAQ6510Interface, DynamicCommandMixin):
219
226
  through an Ethernet interface.
220
227
  """
221
228
 
222
- def __init__(self, hostname: str = FW_SETTINGS.HOSTNAME, port: int = FW_SETTINGS.PORT):
229
+ def __init__(self, hostname: str = DEV_HOST, port: int = DEV_PORT):
223
230
  """Opens a TCP/IP socket connection with the Keithley DAQ6510 Hardware.
224
231
 
225
232
  Args:
226
- hostname (str): IP address or fully qualified hostname of the Hexapod hardware controller. The default is
227
- defined in the ``settings.yaml`` configuration file.
233
+ hostname (str): IP address or fully qualified hostname of the DAQ6510 hardware controller.
234
+ The default is defined in the ``settings.yaml`` configuration file.
228
235
  port (int): IP port number to connect to, by default set in the ``settings.yaml`` configuration file.
229
236
 
230
237
  Raises:
@@ -277,7 +284,7 @@ class DAQ6510Controller(DAQ6510Interface, DynamicCommandMixin):
277
284
 
278
285
  return self.daq.is_connected()
279
286
 
280
- def send_command(self, command: str, response: bool) -> Union[None, str]:
287
+ def send_command(self, command: str, response: bool) -> str | None:
281
288
  """Sends an SCPI command to the device.
282
289
 
283
290
  The valid commands are described in the DAQ6510 Reference Manual [DAQ6510-901-01 Rev. B / September 2019].
@@ -292,7 +299,7 @@ class DAQ6510Controller(DAQ6510Interface, DynamicCommandMixin):
292
299
 
293
300
  return self.daq.trans(command) if response else self.daq.write(command)
294
301
 
295
- def read_buffer(self, start: int, end: int, buffer_name: str = DEFAULT_BUFFER_1, elements: List[str] = None):
302
+ def read_buffer(self, start: int, end: int, buffer_name: str = DEFAULT_BUFFER_1, elements: list[str] = None):
296
303
  """Reads specific data elements (measurements) from the given buffer.
297
304
 
298
305
  Elements that can be specified to read out:
@@ -566,10 +573,10 @@ class DAQ6510Proxy(Proxy, DAQ6510Interface):
566
573
 
567
574
  def __init__(
568
575
  self,
569
- protocol: str = CTRL_SETTINGS.PROTOCOL,
570
- hostname: str = CTRL_SETTINGS.HOSTNAME,
571
- port: int = CTRL_SETTINGS.COMMANDING_PORT,
572
- timeout: float = CTRL_SETTINGS.TIMEOUT, # Timeout [s]: > scan count * interval + (one scan duration)
576
+ protocol: str = PROTOCOL,
577
+ hostname: str = HOSTNAME,
578
+ port: int = COMMANDING_PORT,
579
+ timeout: float = TIMEOUT, # Timeout [s]: > scan count * interval + (one scan duration)
573
580
  ):
574
581
  """Initialisation of a DAQ6510Proxy.
575
582
 
@@ -581,7 +588,9 @@ class DAQ6510Proxy(Proxy, DAQ6510Interface):
581
588
  timeout (float): Timeout by which to establish the connection [s]
582
589
  """
583
590
 
584
- super().__init__(connect_address(protocol, hostname, port), timeout=timeout)
591
+ endpoint = get_endpoint(SERVICE_TYPE, protocol, hostname, port)
592
+
593
+ super().__init__(endpoint, timeout=timeout)
585
594
 
586
595
 
587
596
  def create_channel_list(*args) -> str:
@@ -11,17 +11,18 @@ from egse.log import logger
11
11
  from egse.scpi import AsyncSCPIInterface
12
12
  from egse.settings import Settings
13
13
 
14
- settings = Settings.load("Keithley DAQ6510")
14
+ dev_settings = Settings.load("Keithley DAQ6510")
15
15
 
16
- DAQ_DEV_PORT = settings.get("PORT")
17
- DAQ_DEV_NAME = "DAQ6510"
18
- DAQ_DEV_ID_VALIDATION = "DAQ6510"
16
+ DEV_HOST = dev_settings.get("HOSTNAME")
17
+ DEV_PORT = dev_settings.get("PORT")
18
+ DEVICE_NAME = dev_settings.get("DEVICE_NAME", "DAQ6510")
19
+ DEV_ID_VALIDATION = "DAQ6510"
19
20
 
20
21
 
21
22
  class DAQ6510(AsyncSCPIInterface):
22
23
  """Keithley DAQ6510 specific implementation."""
23
24
 
24
- def __init__(self, hostname: str, port: int = DAQ_DEV_PORT, settings: Optional[Dict[str, Any]] = None):
25
+ def __init__(self, hostname: str = DEV_HOST, port: int = DEV_PORT, settings: Optional[Dict[str, Any]] = None):
25
26
  """Initialize a Keithley DAQ6510 interface.
26
27
 
27
28
  Args:
@@ -30,11 +31,11 @@ class DAQ6510(AsyncSCPIInterface):
30
31
  settings: Additional device settings
31
32
  """
32
33
  super().__init__(
33
- device_name=DAQ_DEV_NAME,
34
+ device_name=DEVICE_NAME,
34
35
  hostname=hostname,
35
36
  port=port,
36
37
  settings=settings,
37
- id_validation=DAQ_DEV_ID_VALIDATION, # String that must appear in IDN? response
38
+ id_validation=DEV_ID_VALIDATION, # String that must appear in IDN? response
38
39
  )
39
40
 
40
41
  self._measurement_lock = asyncio.Lock()
@@ -1,23 +1,29 @@
1
- import logging
2
1
  import multiprocessing
3
2
  import sys
4
3
 
5
4
  import rich
6
5
  import typer
7
6
  import zmq
8
- from prometheus_client import start_http_server
9
7
 
8
+ from egse.connect import get_endpoint
10
9
  from egse.control import ControlServer
11
10
  from egse.control import is_control_server_active
12
11
  from egse.log import logger
12
+ from egse.logger import remote_logging
13
+ from egse.registry.client import RegistryClient
13
14
  from egse.settings import Settings
14
15
  from egse.storage import store_housekeeping_information
15
16
  from egse.tempcontrol.keithley.daq6510 import DAQ6510Proxy
16
17
  from egse.tempcontrol.keithley.daq6510_protocol import DAQ6510Protocol
17
18
  from egse.zmq_ser import connect_address
18
19
 
20
+ cs_settings = Settings.load("Keithley Control Server")
19
21
 
20
- CTRL_SETTINGS = Settings.load("Keithley Control Server")
22
+ PROTOCOL = cs_settings.get("PROTOCOL", "tcp")
23
+ HOSTNAME = cs_settings.get("HOSTNAME", "localhost")
24
+ COMMANDING_PORT = cs_settings.get("COMMANDING_PORT", 0)
25
+ STORAGE_MNEMONIC = cs_settings.get("STORAGE_MNEMONIC", "DAQ6510")
26
+ SERVICE_TYPE = cs_settings.get("SERVICE_TYPE", "daq6510")
21
27
 
22
28
 
23
29
  def is_daq6510_cs_active(timeout: float = 0.5) -> bool:
@@ -29,7 +35,14 @@ def is_daq6510_cs_active(timeout: float = 0.5) -> bool:
29
35
  Returns: True if the Control Server is running and replied with the expected answer; False otherwise.
30
36
  """
31
37
 
32
- endpoint = connect_address(CTRL_SETTINGS.PROTOCOL, CTRL_SETTINGS.HOSTNAME, CTRL_SETTINGS.COMMANDING_PORT)
38
+ if COMMANDING_PORT == 0:
39
+ with RegistryClient() as client:
40
+ endpoint = client.get_endpoint(SERVICE_TYPE)
41
+ if endpoint is None:
42
+ logger.debug(f"No endpoint for {SERVICE_TYPE}")
43
+ return False
44
+ else:
45
+ endpoint = connect_address(PROTOCOL, HOSTNAME, COMMANDING_PORT)
33
46
 
34
47
  return is_control_server_active(endpoint, timeout)
35
48
 
@@ -63,13 +76,15 @@ class DAQ6510ControlServer(ControlServer):
63
76
 
64
77
  self.poller.register(self.dev_ctrl_cmd_sock, zmq.POLLIN)
65
78
 
79
+ self.register_service(service_type=cs_settings.SERVICE_TYPE)
80
+
66
81
  def get_communication_protocol(self) -> str:
67
82
  """Returns the communication protocol used by the Control Server.
68
83
 
69
84
  Returns: Communication protocol used by the Control Server, as specified in the settings.
70
85
  """
71
86
 
72
- return CTRL_SETTINGS.PROTOCOL
87
+ return cs_settings.PROTOCOL
73
88
 
74
89
  def get_commanding_port(self) -> int:
75
90
  """Returns the commanding port used by the Control Server.
@@ -77,7 +92,7 @@ class DAQ6510ControlServer(ControlServer):
77
92
  Returns: Commanding port used by the Control Server, as specified in the settings.
78
93
  """
79
94
 
80
- return CTRL_SETTINGS.COMMANDING_PORT
95
+ return cs_settings.COMMANDING_PORT
81
96
 
82
97
  def get_service_port(self):
83
98
  """Returns the service port used by the Control Server.
@@ -85,7 +100,7 @@ class DAQ6510ControlServer(ControlServer):
85
100
  Returns: Service port used by the Control Server, as specified in the settings.
86
101
  """
87
102
 
88
- return CTRL_SETTINGS.SERVICE_PORT
103
+ return cs_settings.SERVICE_PORT
89
104
 
90
105
  def get_monitoring_port(self):
91
106
  """Returns the monitoring port used by the Control Server.
@@ -93,7 +108,7 @@ class DAQ6510ControlServer(ControlServer):
93
108
  Returns: Monitoring port used by the Control Server, as specified in the settings.
94
109
  """
95
110
 
96
- return CTRL_SETTINGS.MONITORING_PORT
111
+ return cs_settings.MONITORING_PORT
97
112
 
98
113
  def get_storage_mnemonic(self):
99
114
  """Returns the storage mnemonics used by the Control Server.
@@ -105,10 +120,7 @@ class DAQ6510ControlServer(ControlServer):
105
120
  settings, "DAQ6510" will be used.
106
121
  """
107
122
 
108
- try:
109
- return CTRL_SETTINGS.STORAGE_MNEMONIC
110
- except AttributeError:
111
- return "DAQ6510"
123
+ return STORAGE_MNEMONIC
112
124
 
113
125
  def is_storage_manager_active(self):
114
126
  from egse.storage import is_storage_manager_active
@@ -142,8 +154,6 @@ class DAQ6510ControlServer(ControlServer):
142
154
  def before_serve(self):
143
155
  """Steps to take before the Control Server is activated."""
144
156
 
145
- start_http_server(CTRL_SETTINGS.METRICS_PORT)
146
-
147
157
 
148
158
  app = typer.Typer(name="daq6510_cs")
149
159
 
@@ -154,18 +164,19 @@ def start():
154
164
 
155
165
  multiprocessing.current_process().name = "daq6510_cs (start)"
156
166
 
157
- try:
158
- control_server = DAQ6510ControlServer()
159
- control_server.serve()
160
- except KeyboardInterrupt:
161
- logger.debug("Shutdown requested...exiting")
162
- except SystemExit as exit_code:
163
- logger.debug("System Exit with code {}.".format(exit_code))
164
- sys.exit(exit_code)
165
- except Exception:
166
- msg = "Cannot start the DAQ6510 Control Server"
167
- logger.exception(msg)
168
- rich.print(f"[red]{msg}.")
167
+ with remote_logging():
168
+ try:
169
+ control_server = DAQ6510ControlServer()
170
+ control_server.serve()
171
+ except KeyboardInterrupt:
172
+ logger.debug("Shutdown requested...exiting")
173
+ except SystemExit as exit_code:
174
+ logger.debug("System Exit with code {}.".format(exit_code))
175
+ sys.exit(exit_code.code)
176
+ except Exception:
177
+ msg = "Cannot start the DAQ6510 Control Server"
178
+ logger.exception(msg)
179
+ rich.print(f"[red]{msg}.")
169
180
 
170
181
  return 0
171
182
 
@@ -199,11 +210,7 @@ def status():
199
210
 
200
211
  multiprocessing.current_process().name = "daq6510_cs (status)"
201
212
 
202
- protocol = CTRL_SETTINGS.PROTOCOL
203
- hostname = CTRL_SETTINGS.HOSTNAME
204
- port = CTRL_SETTINGS.COMMANDING_PORT
205
-
206
- endpoint = connect_address(protocol, hostname, port)
213
+ endpoint = get_endpoint(SERVICE_TYPE, PROTOCOL, HOSTNAME, COMMANDING_PORT)
207
214
 
208
215
  if is_control_server_active(endpoint):
209
216
  rich.print("DAQ6510 CS: [green]active")
@@ -218,6 +225,4 @@ def status():
218
225
 
219
226
 
220
227
  if __name__ == "__main__":
221
- logging.basicConfig(level=logging.DEBUG, format=Settings.LOG_FORMAT_FULL)
222
-
223
228
  sys.exit(app())
@@ -16,9 +16,12 @@ from egse.settings import Settings
16
16
 
17
17
  IDENTIFICATION_QUERY = "*IDN?"
18
18
 
19
- DEVICE_SETTINGS = Settings.load("Keithley DAQ6510")
20
- DEVICE_NAME = "DAQ6510"
21
- READ_TIMEOUT = DEVICE_SETTINGS.TIMEOUT # [s], can be smaller than timeout (for DAQ6510Proxy) (e.g. 1s)
19
+ dev_settings = Settings.load("Keithley DAQ6510")
20
+
21
+ DEVICE_NAME = dev_settings.get("DEVICE_NAME", "DAQ6510")
22
+ DEV_HOST = dev_settings.get("HOSTNAME")
23
+ DEV_PORT = dev_settings.get("PORT")
24
+ READ_TIMEOUT = dev_settings.get("TIMEOUT") # [s], can be smaller than timeout (for DAQ6510Proxy) (e.g. 1s)
22
25
 
23
26
 
24
27
  class DAQ6510Command(ClientServerCommand):
@@ -39,7 +42,7 @@ class DAQ6510Command(ClientServerCommand):
39
42
  class DAQ6510(DeviceInterface, DeviceTransport):
40
43
  """Defines the low-level interface to the Keithley DAQ6510 Controller."""
41
44
 
42
- def __init__(self, hostname: str = None, port: int = None):
45
+ def __init__(self, hostname: str = DEV_HOST, port: int = DEV_PORT):
43
46
  """Initialisation of an Ethernet interface for the DAQ6510.
44
47
 
45
48
  Args:
@@ -50,9 +53,8 @@ class DAQ6510(DeviceInterface, DeviceTransport):
50
53
  super().__init__()
51
54
 
52
55
  self.device_name = DEVICE_NAME
53
-
54
- self.hostname = DEVICE_SETTINGS.HOSTNAME if hostname is None else hostname
55
- self.port = DEVICE_SETTINGS.PORT if port is None else port
56
+ self.hostname = hostname
57
+ self.port = port
56
58
  self._sock = None
57
59
 
58
60
  self._is_connection_open = False
@@ -17,7 +17,7 @@ def start_daq6510():
17
17
  """Start the daq6510 service."""
18
18
  rich.print("Starting service daq6510")
19
19
 
20
- out = redirect_output_to_log(".daq6510_cs.start.log")
20
+ out = redirect_output_to_log("daq6510_cs.start.log")
21
21
 
22
22
  subprocess.Popen(
23
23
  [sys.executable, "-m", "egse.tempcontrol.keithley.daq6510_cs", "start"],
@@ -33,7 +33,7 @@ def stop_daq6510():
33
33
  """Stop the daq6510 service."""
34
34
  rich.print("Terminating service daq6510")
35
35
 
36
- out = redirect_output_to_log(".daq6510_cs.stop.log")
36
+ out = redirect_output_to_log("daq6510_cs.stop.log")
37
37
 
38
38
  subprocess.Popen(
39
39
  [sys.executable, "-m", "egse.tempcontrol.keithley.daq6510_cs", "stop"],
@@ -67,7 +67,7 @@ def start_daq6510_sim():
67
67
  """Start the DAQ6510 Simulator."""
68
68
  rich.print("Starting service DAQ6510 Simulator")
69
69
 
70
- out = redirect_output_to_log(".daq6510_sim.start.log")
70
+ out = redirect_output_to_log("daq6510_sim.start.log")
71
71
 
72
72
  subprocess.Popen(
73
73
  [sys.executable, "-m", "egse.tempcontrol.keithley.daq6510_sim", "start"],
@@ -83,7 +83,7 @@ def stop_daq6510_sim():
83
83
  """Stop the DAQ6510 Simulator."""
84
84
  rich.print("Terminating the DAQ6510 simulator.")
85
85
 
86
- out = redirect_output_to_log(".daq6510_sim.stop.log")
86
+ out = redirect_output_to_log("daq6510_sim.stop.log")
87
87
 
88
88
  subprocess.Popen(
89
89
  [sys.executable, "-m", "egse.tempcontrol.keithley.daq6510_sim", "stop"],
@@ -3,6 +3,8 @@ PACKAGES:
3
3
 
4
4
 
5
5
  Keithley DAQ6510:
6
+
7
+ DEVICE_NAME: DAQ6510
6
8
  HOSTNAME: unknown
7
9
  PORT: 5025
8
10
  MAC_ADDRESS: 08:00:11:24:0C:7A