ariel-tcu 0.17.0__py3-none-any.whl
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.
- ariel_tcu/__init__.py +0 -0
- ariel_tcu/cgse_explore.py +16 -0
- ariel_tcu/cgse_services.py +57 -0
- ariel_tcu/settings.yaml +20 -0
- ariel_tcu-0.17.0.dist-info/METADATA +14 -0
- ariel_tcu-0.17.0.dist-info/RECORD +15 -0
- ariel_tcu-0.17.0.dist-info/WHEEL +4 -0
- ariel_tcu-0.17.0.dist-info/entry_points.txt +14 -0
- egse/ariel/tcu/__init__.py +105 -0
- egse/ariel/tcu/tcu.py +1118 -0
- egse/ariel/tcu/tcu.yaml +43 -0
- egse/ariel/tcu/tcu_cmd_utils.py +1389 -0
- egse/ariel/tcu/tcu_cs.py +246 -0
- egse/ariel/tcu/tcu_devif.py +104 -0
- egse/ariel/tcu/tcu_protocol.py +147 -0
egse/ariel/tcu/tcu_cs.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"""Control Server for the Ariel Telescope Control Unit (TCU)."""
|
|
2
|
+
|
|
3
|
+
import multiprocessing
|
|
4
|
+
import logging
|
|
5
|
+
import sys
|
|
6
|
+
from typing import Annotated
|
|
7
|
+
|
|
8
|
+
import zmq
|
|
9
|
+
import typer
|
|
10
|
+
import rich
|
|
11
|
+
|
|
12
|
+
from egse.ariel.tcu import (
|
|
13
|
+
COMMANDING_PORT,
|
|
14
|
+
HOSTNAME,
|
|
15
|
+
PROTOCOL,
|
|
16
|
+
SERVICE_PORT,
|
|
17
|
+
MONITORING_PORT,
|
|
18
|
+
STORAGE_MNEMONIC,
|
|
19
|
+
PROCESS_NAME,
|
|
20
|
+
SERVICE_TYPE,
|
|
21
|
+
)
|
|
22
|
+
from egse.control import is_control_server_active, ControlServer
|
|
23
|
+
from egse.registry.client import RegistryClient
|
|
24
|
+
from egse.services import ServiceProxy
|
|
25
|
+
from egse.storage import store_housekeeping_information
|
|
26
|
+
from egse.zmq_ser import connect_address, get_port_number
|
|
27
|
+
from egse.ariel.tcu.tcu_protocol import TcuProtocol
|
|
28
|
+
from egse.ariel.tcu.tcu import TcuProxy
|
|
29
|
+
|
|
30
|
+
logger = logging.getLogger("egse.ariel.tcu")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def is_tcu_cs_active(timeout: float = 0.5) -> bool:
|
|
34
|
+
"""Checks whether the Ariel TCU Control Server is running.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
timeout (float): Timeout when waiting for a reply [s].
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
True if the Ariel TCU Control Server is running and replied with the expected answer; False otherwise.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
endpoint = connect_address(PROTOCOL, HOSTNAME, COMMANDING_PORT)
|
|
44
|
+
|
|
45
|
+
return is_control_server_active(endpoint, timeout)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class TcuControlServer(ControlServer):
|
|
49
|
+
def __init__(self, simulator: bool = False):
|
|
50
|
+
super().__init__()
|
|
51
|
+
|
|
52
|
+
multiprocessing.current_process().name = PROCESS_NAME
|
|
53
|
+
|
|
54
|
+
self.logger = logger
|
|
55
|
+
self.service_name = PROCESS_NAME
|
|
56
|
+
self.service_type = SERVICE_TYPE
|
|
57
|
+
|
|
58
|
+
self.device_protocol = TcuProtocol(self, simulator=simulator)
|
|
59
|
+
|
|
60
|
+
self.logger.info(f"Binding ZeroMQ socket to {self.device_protocol.get_bind_address()}")
|
|
61
|
+
|
|
62
|
+
self.device_protocol.bind(self.dev_ctrl_cmd_sock)
|
|
63
|
+
|
|
64
|
+
self.poller.register(self.dev_ctrl_cmd_sock, zmq.POLLIN)
|
|
65
|
+
|
|
66
|
+
self.register_service(SERVICE_TYPE)
|
|
67
|
+
|
|
68
|
+
def get_communication_protocol(self) -> str:
|
|
69
|
+
"""Returns the communication protocol used by the Ariel TCU Control Server.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
Communication protocol used by the Ariel TCU Control Server, as specified in the settings.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
return PROTOCOL
|
|
76
|
+
|
|
77
|
+
def get_commanding_port(self) -> int:
|
|
78
|
+
"""Returns the commanding port used by the Ariel TCU Control Server.
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
Commanding port used by the Ariel TCU Control Server, as specified in the settings.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
return get_port_number(self.dev_ctrl_cmd_sock) or COMMANDING_PORT
|
|
85
|
+
|
|
86
|
+
def get_service_port(self) -> int:
|
|
87
|
+
"""Returns the service port used by the Ariel TCU Control Server.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
Service port used by the Ariel TCU Control Server, as specified in the settings.
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
return get_port_number(self.dev_ctrl_service_sock) or SERVICE_PORT
|
|
94
|
+
|
|
95
|
+
def get_monitoring_port(self) -> int:
|
|
96
|
+
"""Returns the monitoring port used by the Ariel TCU Control Server.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Monitoring port used by the Ariel TCU Control Server, as specified in the settings.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
return get_port_number(self.dev_ctrl_mon_sock) or MONITORING_PORT
|
|
103
|
+
|
|
104
|
+
def get_storage_mnemonic(self) -> str:
|
|
105
|
+
"""Returns the storage mnemonic used by the Ariel TCU Control Server.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Storage mnemonic used by the Ariel TCU Control Server, as specified in the settings.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
return STORAGE_MNEMONIC
|
|
112
|
+
|
|
113
|
+
def is_storage_manager_active(self):
|
|
114
|
+
"""Checks whether the Storage Manager is active."""
|
|
115
|
+
from egse.storage import is_storage_manager_active
|
|
116
|
+
|
|
117
|
+
return is_storage_manager_active()
|
|
118
|
+
|
|
119
|
+
def store_housekeeping_information(self, data):
|
|
120
|
+
"""Sends housekeeping information of the Ariel TCU to the Storage Manager."""
|
|
121
|
+
|
|
122
|
+
origin = self.get_storage_mnemonic()
|
|
123
|
+
store_housekeeping_information(origin, data)
|
|
124
|
+
|
|
125
|
+
def register_to_storage_manager(self):
|
|
126
|
+
from egse.storage import register_to_storage_manager
|
|
127
|
+
from egse.storage.persistence import TYPES
|
|
128
|
+
|
|
129
|
+
register_to_storage_manager(
|
|
130
|
+
origin=self.get_storage_mnemonic(),
|
|
131
|
+
persistence_class=TYPES["CSV"],
|
|
132
|
+
prep={
|
|
133
|
+
"column_names": list(self.device_protocol.get_housekeeping().keys()),
|
|
134
|
+
"mode": "a",
|
|
135
|
+
},
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
def unregister_from_storage_manager(self):
|
|
139
|
+
from egse.storage import unregister_from_storage_manager
|
|
140
|
+
|
|
141
|
+
unregister_from_storage_manager(origin=self.get_storage_mnemonic())
|
|
142
|
+
|
|
143
|
+
# def before_serve(self):
|
|
144
|
+
# start_http_server(CTRL_SETTINGS.METRICS_PORT)
|
|
145
|
+
|
|
146
|
+
def after_serve(self):
|
|
147
|
+
self.deregister_service()
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
app = typer.Typer()
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@app.command()
|
|
154
|
+
def start(
|
|
155
|
+
simulator: Annotated[
|
|
156
|
+
bool, typer.Option("--simulator", "--sim", help="start the Ariel TCU Control Server in simulator mode")
|
|
157
|
+
] = False,
|
|
158
|
+
):
|
|
159
|
+
"""Starts the Ariel TCU Control Server."""
|
|
160
|
+
|
|
161
|
+
try:
|
|
162
|
+
controller = TcuControlServer(simulator)
|
|
163
|
+
controller.serve()
|
|
164
|
+
except KeyboardInterrupt:
|
|
165
|
+
print("Shutdown requested...exiting")
|
|
166
|
+
except SystemExit as exc:
|
|
167
|
+
exit_code = exc.code if hasattr(exc, "code") else 0
|
|
168
|
+
print(f"System Exit with code {exc.code}")
|
|
169
|
+
sys.exit(exit_code)
|
|
170
|
+
except Exception:
|
|
171
|
+
logger.exception("Cannot start the Ariel TCU Control Server")
|
|
172
|
+
# The above line does exactly the same as the traceback, but on the logger
|
|
173
|
+
# import traceback
|
|
174
|
+
# traceback.print_exc(file=sys.stdout)
|
|
175
|
+
|
|
176
|
+
return 0
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
@app.command()
|
|
180
|
+
def stop():
|
|
181
|
+
"""Sends a `quit_server` command to the Ariel TCU Control Server."""
|
|
182
|
+
|
|
183
|
+
with RegistryClient() as reg:
|
|
184
|
+
service = reg.discover_service(SERVICE_TYPE)
|
|
185
|
+
rich.print("service = ", service)
|
|
186
|
+
|
|
187
|
+
if service:
|
|
188
|
+
proxy = ServiceProxy(protocol="tcp", hostname=service["host"], port=service["metadata"]["service_port"])
|
|
189
|
+
proxy.quit_server()
|
|
190
|
+
else:
|
|
191
|
+
# *_, device_type, controller_type = get_hexapod_controller_pars(device_id)
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
with TcuProxy() as tcu_proxy:
|
|
195
|
+
with tcu_proxy.get_service_proxy() as sp:
|
|
196
|
+
sp.quit_server()
|
|
197
|
+
except ConnectionError:
|
|
198
|
+
rich.print("[red]Couldn't connect to 'tcu_cs', process probably not running. ")
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@app.command()
|
|
202
|
+
def status():
|
|
203
|
+
"""Requests the status information from the Ariel TCU Control Server."""
|
|
204
|
+
|
|
205
|
+
with RegistryClient() as reg:
|
|
206
|
+
service = reg.discover_service(SERVICE_TYPE)
|
|
207
|
+
|
|
208
|
+
if service:
|
|
209
|
+
protocol = service.get("protocol", "tcp")
|
|
210
|
+
hostname = service["host"]
|
|
211
|
+
port = service["port"]
|
|
212
|
+
service_port = service["metadata"]["service_port"]
|
|
213
|
+
monitoring_port = service["metadata"]["monitoring_port"]
|
|
214
|
+
endpoint = connect_address(protocol, hostname, port)
|
|
215
|
+
else:
|
|
216
|
+
rich.print(
|
|
217
|
+
f"[red]The Ariel TCU Control Server isn't registered as a service. The Control Server cannot be "
|
|
218
|
+
f"contacted without the required information from the service registry.[/]"
|
|
219
|
+
)
|
|
220
|
+
rich.print("Ariel TCU: [red]not active")
|
|
221
|
+
return
|
|
222
|
+
|
|
223
|
+
if is_control_server_active(endpoint):
|
|
224
|
+
rich.print("Ariel TCU: [green]active")
|
|
225
|
+
|
|
226
|
+
with TcuProxy() as tcu:
|
|
227
|
+
sim = tcu.is_simulator()
|
|
228
|
+
connected = tcu.is_connected()
|
|
229
|
+
ip = tcu.get_ip_address()
|
|
230
|
+
rich.print(f"mode: {'simulator' if sim else 'device'}{'' if connected else ' not'} connected")
|
|
231
|
+
rich.print(f"hostname: {ip}")
|
|
232
|
+
rich.print(f"commanding port: {port}")
|
|
233
|
+
rich.print(f"service port: {service_port}")
|
|
234
|
+
rich.print(f"monitoring port: {monitoring_port}")
|
|
235
|
+
else:
|
|
236
|
+
rich.print("Ariel TCU: [red]not active")
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
if __name__ == "__main__":
|
|
240
|
+
import logging
|
|
241
|
+
|
|
242
|
+
from egse.logger import set_all_logger_levels
|
|
243
|
+
|
|
244
|
+
set_all_logger_levels(logging.DEBUG)
|
|
245
|
+
|
|
246
|
+
sys.exit(app())
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""Device connection interface for the Ariel Telescope Control Unit (TCU)."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
import serial
|
|
7
|
+
|
|
8
|
+
from egse.device import DeviceConnectionInterface, DeviceTransport
|
|
9
|
+
from egse.settings import Settings
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
DEVICE_SETTINGS = Settings.load("Ariel TCU Controller")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class TcuError(Exception):
|
|
16
|
+
"""Generic TCU error for low-level classes."""
|
|
17
|
+
|
|
18
|
+
pass
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TcuDeviceInterface(DeviceConnectionInterface, DeviceTransport):
|
|
22
|
+
"""Defines the low-level interface to the Ariel TCU (Arduino)."""
|
|
23
|
+
|
|
24
|
+
def __init__(self, port: int = None):
|
|
25
|
+
"""Initialisation of a serial interface to the TCU Arduino.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
port (int): Serial port to which to connect to the TCU Arduino.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
super().__init__()
|
|
32
|
+
|
|
33
|
+
# self.hostname = hostname or DEVICE_SETTINGS["HOSTNAME"]
|
|
34
|
+
self.port = port or DEVICE_SETTINGS["COM_PORT"]
|
|
35
|
+
|
|
36
|
+
self.arduino = serial.Serial()
|
|
37
|
+
self.arduino.port = self.port
|
|
38
|
+
self.arduino.baudrate = DEVICE_SETTINGS["BAUD_RATE"]
|
|
39
|
+
self.arduino.bytesize = DEVICE_SETTINGS["NUM_DATA_BITS"]
|
|
40
|
+
self.arduino.parity = DEVICE_SETTINGS["PARITY"]
|
|
41
|
+
self.arduino.stopbits = DEVICE_SETTINGS["NUM_STOP_BITS"]
|
|
42
|
+
|
|
43
|
+
def connect(self) -> None:
|
|
44
|
+
"""Opens the serial port to the TCU Arduino.
|
|
45
|
+
|
|
46
|
+
Raises:
|
|
47
|
+
TcuError: When the serial port could not be opened.
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
if self.is_connected():
|
|
51
|
+
raise TcuError("TCU already connected.")
|
|
52
|
+
# if self.hostname in (None, ""):
|
|
53
|
+
# raise TcuError("TCU hostname is not initialised.")
|
|
54
|
+
if self.port in (None, 0):
|
|
55
|
+
raise TcuError("TCU serial port is not initialised.")
|
|
56
|
+
|
|
57
|
+
try:
|
|
58
|
+
self.arduino.open()
|
|
59
|
+
except Exception as exc:
|
|
60
|
+
raise TcuError(f"Failed to open TCU serial port {self.port}") from exc
|
|
61
|
+
|
|
62
|
+
def disconnect(self) -> None:
|
|
63
|
+
"""Closes the serial port to the TCU Arduino.
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
TcuError: When the serial port could not be closed.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
try:
|
|
70
|
+
self.arduino.close()
|
|
71
|
+
except Exception as exc:
|
|
72
|
+
raise TcuError(f"Failed to close TCU serial port {self.port}") from exc
|
|
73
|
+
|
|
74
|
+
def reconnect(self) -> None:
|
|
75
|
+
"""Re-connects to the Ariel TCU Arduino."""
|
|
76
|
+
|
|
77
|
+
if self.is_connected():
|
|
78
|
+
self.disconnect()
|
|
79
|
+
self.connect()
|
|
80
|
+
|
|
81
|
+
def is_connected(self) -> bool:
|
|
82
|
+
"""Checks whether the serial port to the TCU Arduino is open.
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
True if the serial port to the TCU Arduino is open; False otherwise.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
return self.arduino.is_open
|
|
89
|
+
|
|
90
|
+
def trans(self, command: str) -> bytes:
|
|
91
|
+
"""Sends the given command to the TCU Arduino and returns the response.
|
|
92
|
+
|
|
93
|
+
This is seen as a transaction.
|
|
94
|
+
|
|
95
|
+
Args:
|
|
96
|
+
command: Command string to send to the TCU Arduino.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Response string from the TCU Arduino.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
self.arduino.write(command.encode("utf-8"))
|
|
103
|
+
time.sleep(0.05)
|
|
104
|
+
return self.arduino.readline()
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"""Command protocol for the Ariel Telescope Control Unit (TCU)."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
from egse.ariel.tcu import NUM_TSM_PROBES_PER_FRAME
|
|
7
|
+
from egse.ariel.tcu.tcu import TcuController, TcuSimulator, TcuInterface
|
|
8
|
+
from egse.command import ClientServerCommand
|
|
9
|
+
from egse.control import ControlServer
|
|
10
|
+
from egse.device import DeviceConnectionState
|
|
11
|
+
from egse.protocol import DynamicCommandProtocol
|
|
12
|
+
from egse.settings import Settings
|
|
13
|
+
from egse.system import format_datetime
|
|
14
|
+
from egse.zmq_ser import bind_address
|
|
15
|
+
|
|
16
|
+
_HERE = Path(__file__).parent
|
|
17
|
+
DEVICE_SETTINGS = Settings.load(filename="tcu.yaml", location=_HERE)
|
|
18
|
+
logger = logging.getLogger("egse.ariel.tcu")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TcuCommand(ClientServerCommand):
|
|
22
|
+
"""Command class for the Ariel TCU Control Server."""
|
|
23
|
+
|
|
24
|
+
pass
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class TcuProtocol(DynamicCommandProtocol):
|
|
28
|
+
"""Command protocol for the Ariel TCU Control Server."""
|
|
29
|
+
|
|
30
|
+
def __init__(self, control_server: ControlServer, simulator: bool = False):
|
|
31
|
+
"""Initialisation of an Ariel TCU protocol.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
control_server (ControlServer): Ariel TCU Control Server.
|
|
35
|
+
simulator (bool): Whether to use a simulator as the backend.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
super().__init__(control_server)
|
|
39
|
+
|
|
40
|
+
self.simulator = simulator
|
|
41
|
+
|
|
42
|
+
if self.simulator:
|
|
43
|
+
self.tcu = TcuSimulator()
|
|
44
|
+
else:
|
|
45
|
+
self.tcu = TcuController()
|
|
46
|
+
|
|
47
|
+
try:
|
|
48
|
+
self.tcu.connect()
|
|
49
|
+
except ConnectionError:
|
|
50
|
+
logger.warning("Couldn't establish connection to the Ariel TCU, check the log messages.")
|
|
51
|
+
|
|
52
|
+
# self.metrics = define_metrics("TCU")
|
|
53
|
+
|
|
54
|
+
def get_bind_address(self) -> str:
|
|
55
|
+
"""Returns the bind address for the Ariel TCU Control Server.
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
Bind address for the Ariel TCU Control Server.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
return bind_address(self.control_server.get_communication_protocol(), self.control_server.get_commanding_port())
|
|
62
|
+
|
|
63
|
+
def get_device(self) -> TcuInterface:
|
|
64
|
+
"""Returns the Ariel TCU interface.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Ariel TCU interface.
|
|
68
|
+
"""
|
|
69
|
+
return self.tcu
|
|
70
|
+
|
|
71
|
+
def get_status(self) -> dict:
|
|
72
|
+
"""Returns the status information for the Ariel TCU Control Server.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
Status information for the Ariel TCU Control Server.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
status = super().get_status()
|
|
79
|
+
|
|
80
|
+
if self.state == DeviceConnectionState.DEVICE_NOT_CONNECTED and not self.simulator:
|
|
81
|
+
return status
|
|
82
|
+
|
|
83
|
+
# TODO Add device-specific status information
|
|
84
|
+
|
|
85
|
+
return status
|
|
86
|
+
|
|
87
|
+
def get_housekeeping(self) -> dict:
|
|
88
|
+
"""Returns the housekeeping information for the Ariel TCU Control Server.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
Housekeeping information for the Ariel TCU Control Server.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
result = dict()
|
|
95
|
+
result["timestamp"] = format_datetime()
|
|
96
|
+
|
|
97
|
+
if self.state == DeviceConnectionState.DEVICE_NOT_CONNECTED and not self.simulator:
|
|
98
|
+
return result
|
|
99
|
+
|
|
100
|
+
result["TCU_MODE"] = self.tcu.get_tcu_mode()
|
|
101
|
+
result["TCU_VHK_PSU_VMOTOR"] = self.tcu.vhk_psu_vmotor()
|
|
102
|
+
result["TCU_VHK_PSU_VHI"] = self.tcu.vhk_psu_vhi()
|
|
103
|
+
result["TCU_VHK_PSU_VLOW"] = self.tcu.vhk_psu_vlow()
|
|
104
|
+
result["TCU_VHK_PSU_VMEDP"] = self.tcu.vhk_psu_vmedp()
|
|
105
|
+
result["TCU_VHK_PSU_VMEDN"] = self.tcu.vhk_psu_vmedn()
|
|
106
|
+
result["TCU_IHK_PSU_VMEDN"] = self.tcu.ihk_psu_vmedn()
|
|
107
|
+
result["TCU_IHK_PSU_VMEDP"] = self.tcu.ihk_psu_vmedp()
|
|
108
|
+
result["TCU_IHK_PSU_VLOW"] = self.tcu.ihk_psu_vlow()
|
|
109
|
+
result["TCU_IHK_PSU_VHI"] = self.tcu.ihk_psu_vhi()
|
|
110
|
+
result["TCU_IHK_PSU_VMOTOR"] = self.tcu.ihk_psu_vmotor()
|
|
111
|
+
result["TCU_THK_PSU_FIRST"] = self.tcu.thk_psu_first()
|
|
112
|
+
result["TCU_THK_M2MD_FIRST"] = self.tcu.thk_m2md_first()
|
|
113
|
+
result["TCU_THK_PSU_SECOND"] = self.tcu.thk_psu_second()
|
|
114
|
+
result["TCU_THK_M2MD_SECOND"] = self.tcu.thk_m2md_second()
|
|
115
|
+
result["TCU_THK_CTS_Q1"] = self.tcu.thk_cts_q1()
|
|
116
|
+
result["TCU_THK_CTS_Q2"] = self.tcu.thk_cts_q2()
|
|
117
|
+
result["TCU_THK_CTS_Q3"] = self.tcu.thk_cts_q3()
|
|
118
|
+
result["TCU_THK_CTS_Q4"] = self.tcu.thk_cts_q4()
|
|
119
|
+
result["TCU_THK_CTS_FPGA"] = self.tcu.thk_cts_fpga()
|
|
120
|
+
result["TCU_THK_CTS_ADS1282"] = self.tcu.thk_cts_ads1282()
|
|
121
|
+
result["TCU_VHK_THS_RET"] = self.tcu.vhk_ths_ret()
|
|
122
|
+
result["TCU_HK_ACQ_COUNTER"] = self.tcu.hk_acq_counter()
|
|
123
|
+
|
|
124
|
+
for probe in range(1, NUM_TSM_PROBES_PER_FRAME + 1):
|
|
125
|
+
bias_pos = self.tcu.tsm_adc_value_xx_biasp(probe=probe)
|
|
126
|
+
result[f"TCU_BIAS_POS_PROBE_{probe}"] = bias_pos
|
|
127
|
+
bias_neg = self.tcu.tsm_adc_value_xx_biasn(probe=probe)
|
|
128
|
+
result[f"TCU_BIAS_NEG_PROBE_{probe}"] = bias_neg
|
|
129
|
+
current_pos = self.tcu.tsm_adc_value_xx_currentp(probe=probe)
|
|
130
|
+
result[f"TCU_CURRENT_POS_PROBE_{probe}"] = current_pos
|
|
131
|
+
current_neg = self.tcu.tsm_adc_value_xx_currentn(probe=probe)
|
|
132
|
+
result[f"TCU_CURRENT_NEG_PROBE_{probe}"] = current_neg
|
|
133
|
+
|
|
134
|
+
# alpha = (bias_pos - bias_neg) / (current_pos - current_neg)
|
|
135
|
+
# (c0, c1) ??
|
|
136
|
+
# resistance = alpha / (alpha * c1 + c0)
|
|
137
|
+
|
|
138
|
+
return result
|
|
139
|
+
|
|
140
|
+
def is_device_connected(self) -> bool:
|
|
141
|
+
"""Checks whether the Ariel TCU is connected.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
True if the Ariel TCU is connected; False otherwise.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
return self.tcu.is_connected()
|