DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
tdemodules
scripts
amc_butler.py
Go to the documentation of this file.
1
#!/usr/bin/env python
2
"""
3
Created on: 05/06/2025 11:16
4
5
Author: Shyam Bhuller, Alessandro Thea
6
7
Description: Check the status of an AMC or multiple AMCs to ensure they can be reached.
8
"""
9
10
import
subprocess
11
import
time
12
import
sh
13
import
re
14
import
click
15
from
rich
import
print
16
17
import
tdemodules
18
19
def
ping
(host):
20
return
subprocess.call([
'ping'
,
"-c"
,
'1'
, host]) == 0
21
22
class
Commands
():
23
def
__init__
(self, controllers : dict):
24
self.
controllers
= controllers
25
26
def
stop
(self):
27
for
k, v
in
self.
controllers
.items():
28
print(f
"starting: {k}"
)
29
v.card_stop()
30
return
31
32
def
start
(self):
33
for
k, v
in
self.
controllers
.items():
34
print(f
"starting: {k}"
)
35
v.card_start()
36
return
37
38
def
status
(self):
39
# Constantly get the status of the AMCs to check whether they can be accessed.
40
if
self.
controllers
:
41
print(
"[yellow]Press ctrl-C to exit.[/yellow]"
)
42
ti = 10
43
t = time.time()
44
while
True
:
45
for
k, v
in
self.
controllers
.items():
46
print(f
"Reading status of AMC with IP: {k})"
)
47
v.card_status()
48
print(f
"[cyan]Sleeping {ti}s[/cyan]"
)
49
time.sleep(ti)
50
print(f
"-- {time.time() - t:.2g} s elapsed"
)
51
return
52
53
54
55
56
57
58
@click.command()
59
@click.argument('crate_ip', type=str)
60
@click.option('-a', '--amcs', type=int, multiple=True, default=[i for i in range(10)
])
61
@click.option('-c', 'cmd', type=click.Choice(['arping', 'status', 'start', 'stop'])
, default=
None
)
62
def
main
(crate_ip, amcs, cmd):
63
64
# get list of amcs from the command arguments
65
try
:
66
sh.ping([
"-c"
,
'1'
, crate_ip])
67
print(f
"[green]uTCA crate {crate_ip} is active[/green]"
)
68
except
sh.ErrorReturnCode
as
e:
69
print(f
"[red]Could not ping uTCA Crate at IP: {crate_ip}[/red]"
)
70
exit(1)
71
72
crate_subnet = crate_ip.rsplit(
"."
, 1)[0]
73
nic_ip = crate_subnet+
'.129'
74
75
amc_ips = { i: crate_subnet + f
".{i + 1}"
for
i
in
amcs}
76
77
if
cmd==
'arping'
:
78
79
80
devices = {
81
'crate'
: crate_ip,
82
'nic'
: nic_ip
83
}
84
85
devices.update({f
'AMC {amc}'
: amc_ip
for
amc, amc_ip
in
amc_ips.items()})
86
87
88
89
from
concurrent.futures
import
ThreadPoolExecutor, as_completed
90
import
subprocess
as
sp
91
import
sys
92
93
failures = []
94
MAX_WORKERS=10
95
def
arping(amc_ip):
96
return
sh.arping([
"-c"
,
'1'
, amc_ip])
97
try
:
98
99
with
ThreadPoolExecutor(max_workers=MAX_WORKERS)
as
pool:
100
futures = {pool.submit(arping, amc_ip):(amc, amc_ip)
for
amc, amc_ip
in
devices.items()}
101
for
fut
in
as_completed(futures):
102
amc, amc_ip = futures[fut]
103
try
:
104
rc = fut.result()
105
except
sp.TimeoutExpired:
106
print(f
"[TIMEOUT] {amc}"
, file=sys.stderr)
107
failures.append((amc,
"timeout"
))
108
continue
109
except
sh.ErrorReturnCode
as
e:
110
print(f
"- [red]Could not arping device at IP: {amc_ip}[/red]"
)
111
continue
112
except
Exception
as
ex:
113
print(f
"[EXCEPTION] {amc}: {ex}"
, file=sys.stderr)
114
failures.append((amc,
"exception"
))
115
continue
116
117
match = re.search(
r"Unicast reply from\s+([\d.]+)\s+\[([0-9A-Fa-f:]{17})\]"
, rc)
118
if
match:
119
ipaddr, mac = match.group(1), match.group(2)
120
print(f
"- [green]{amc} ({amc_ip}) responded to arping : mac {mac}[/green]"
)
121
122
123
except
KeyboardInterrupt:
124
print(
"\nInterrupted. Shutting down workers…"
, file=sys.stderr)
125
# ProcessPool will terminate on context exit
126
else
:
127
controllers = { amc_ip:tdemodules.AMCController(amc_ip, 54321 + (i + 1))
for
i,amc_ip
in
amc_ips.items() }
128
print(controllers)
129
cmds =
Commands
(controllers)
130
getattr(cmds, cmd)()
131
132
return
133
134
return
135
136
if
__name__ ==
"__main__"
:
137
138
main
()
amc_butler.Commands
Definition
amc_butler.py:22
amc_butler.Commands.start
start(self)
Definition
amc_butler.py:32
amc_butler.Commands.__init__
__init__(self, dict controllers)
Definition
amc_butler.py:23
amc_butler.Commands.controllers
controllers
Definition
amc_butler.py:24
amc_butler.Commands.stop
stop(self)
Definition
amc_butler.py:26
amc_butler.Commands.status
status(self)
Definition
amc_butler.py:38
amc_butler.ping
ping(host)
Definition
amc_butler.py:19
amc_butler.main
main(crate_ip, amcs, cmd)
Definition
amc_butler.py:62
Generated on
for DUNE-DAQ by
1.17.0