gondola_core/tof/commands.rs
1// This file is part of gaps-online-software and published
2// under the GPLv3 license
3
4use crate::prelude::*;
5
6#[derive(Debug, Copy, Clone, PartialEq, FromRepr, AsRefStr, EnumIter)]
7#[cfg_attr(feature = "pybindings", pyclass(eq, eq_int))]
8#[repr(u8)]
9pub enum TofCommandCode {
10 Unknown = 0u8,
11 /// en empty command just to check if stuff is online
12 Ping = 1u8,
13 /// command code for getting the monitoring data from the component
14 Moni = 2u8,
15 /// Kill myself
16 Kill = 4u8, // Shi!
17 /// Reload a default (to be defined) config file
18 ResetConfigWDefault = 5u8,
19 /// Make the current editable config the active config
20 SubmitConfig = 6u8,
21 /// command code to configure the data publisher thread
22 SetDataPublisherConfig = 20u8,
23 /// command code for "Set LTB Thresholds"
24 SetLTBThresholds = 21u8,
25 /// command code for "Configure MTB"
26 SetMTConfig = 22u8,
27 /// command code for chaning general run parameters
28 SetTofRunConfig = 23u8,
29 /// command code for changing RB parameters
30 SetTofRBConfig = 24u8,
31 /// command code for AnalysisEngineConfig
32 SetAnalysisEngineConfig = 27u8,
33 /// command code for "Set preamp bias"
34 SetPreampBias = 28u8,
35 /// Change the settings of the event builder
36 SetTOFEventBuilderConfig = 29u8,
37 /// command code for "Stop Data taking"
38 DataRunStop = 30u8,
39 /// command code for "Start Data taking"
40 DataRunStart = 31u8,
41 /// command code for "Start validation run"
42 StartValidationRun = 32u8,
43 /// command code for "Get all waveforms"
44 GetFullWaveforms = 41u8,
45 /// command code for "Send the whole event cache over the wire"
46 UnspoolEventCache = 44u8,
47 /// command code for "Run full calibration"
48 RBCalibration = 53u8,
49 /// command code for restarting systemd
50 RestartLiftofRBClients = 60u8,
51 /// command code for putting liftof-cc in listening mode
52 Listen = 70u8,
53 /// command code for putting liftof-cc in staging mode
54 Staging = 71u8,
55 /// lock the cmd dispatcher
56 Lock = 80u8,
57 /// unlock the cmd dispatcher
58 Unlock = 81u8,
59 /// Enable sending of TOF packets
60 SendTofEvents = 90u8,
61 /// Diesable sending of TofEventPacket
62 NoSendTofEvents = 91u8,
63 /// Enable sending of RBWaveform packets
64 SendRBWaveforms = 92u8,
65 /// Disable sending of RBWaveform packets
66 NoSendRBWaveforms = 93u8,
67 /// Enable RB Channel Masks
68 SetRBChannelMask = 99u8,
69 /// Shutdown RB - send shutdown now to RB
70 ShutdownRB = 100u8,
71 /// Change the config file for the next run
72 ChangeNextRunConfig = 101u8,
73 /// Shutdown RAT - send shutdown command to 2RBs in the same RAT
74 ShutdownRAT = 102u8,
75 /// Shutdown a pair of RATs (as always two of them are hooked up to the
76 /// same PDU channel)
77 ShutdownRATPair = 103u8,
78 /// Shutdown the TOF CPU
79 ShutdownCPU = 104u8,
80 /// Upload a new config file
81 UploadConfig = 105u8,
82}
83
84expand_and_test_enum!(TofCommandCode, test_tofcommandcode_repr);
85
86/// A general command class with an arbitrary payload
87///
88/// Since the commands should in general be small
89/// the maixmal payload size is limited to 256 bytes
90///
91/// All commands will get broadcasted and the
92/// receiver has to figure out if they have
93/// to rect to that command
94#[derive(Debug, Clone, PartialEq)]
95#[cfg_attr(feature="pybindings", pyclass)]
96pub struct TofCommand {
97 pub command_code : TofCommandCode,
98 pub payload : Vec<u8>,
99}
100
101impl TofCommand {
102 // BFSW command header 144, 235, 86, 248, 70, 41, 7, 15,
103 pub fn new() -> Self {
104 Self {
105 command_code : TofCommandCode::Unknown,
106 payload : Vec::<u8>::new(),
107 }
108 }
109
110 //pub fn from_config(cfg_file : String) -> Self {
111 // let mut cmd = TofCommand::new();
112 // cmd.command_code = TofCommandCode::UploadConfig:
113
114 //}
115
116 /// In case the command is supposed to change the next run configuration
117 /// we can create it with this function
118 ///
119 /// # Arguments
120 ///
121 /// * key_value : a list of keys and a single value (last item of the
122 /// list
123 pub fn forge_changerunconfig(key_value : &Vec<String>) -> Self {
124 let mut cmd = TofCommand::new();
125 cmd.command_code = TofCommandCode::ChangeNextRunConfig;
126 if key_value.len() == 0 {
127 error!("Empty command!");
128 return cmd;
129 }
130 let mut payload_string = String::from("");
131 for k in 0..key_value.len() - 1 {
132 payload_string += &format!("{}::", key_value[k]);
133 }
134 payload_string += key_value.last().unwrap();
135 let mut payload = Vec::<u8>::new();
136 payload.extend_from_slice(payload_string.as_bytes());
137 cmd.payload = payload;
138 cmd
139 }
140
141 /// After the command has been unpackt, reconstruct the
142 /// key/value string
143 pub fn extract_changerunconfig(&self) -> Option<Vec<String>> {
144 if self.command_code != TofCommandCode::ChangeNextRunConfig {
145 error!("Unable to extract configuration file changes from {}", self);
146 return None;
147 }
148 let mut liftof_config = Vec::<String>::new();
149 match String::from_utf8(self.payload.clone()) {
150 Err(err) => {
151 error!("Unable to extract the String payload! {err}");
152 }
153 Ok(concat_string) => {
154 let foo = concat_string.split("::").collect::<Vec<&str>>().into_iter();
155 for k in foo {
156 liftof_config.push(String::from(k));
157 }
158 }
159 }
160 Some(liftof_config)
161 }
162}
163
164impl TofPackable for TofCommand {
165 const TOF_PACKET_TYPE : TofPacketType = TofPacketType::TofCommandV2;
166}
167
168impl Serialization for TofCommand {
169
170 const HEAD : u16 = 0xAAAA;
171 const TAIL : u16 = 0x5555;
172
173 fn from_bytestream(stream : &Vec<u8>,
174 pos : &mut usize)
175 -> Result<Self, SerializationError>{
176 let mut command = TofCommand::new();
177 if parse_u16(stream, pos) != Self::HEAD {
178 error!("The given position {} does not point to a valid header signature of {}", pos, Self::HEAD);
179 return Err(SerializationError::HeadInvalid {});
180 }
181 command.command_code = TofCommandCode::from(parse_u8(stream, pos));
182 let payload_size = parse_u8(stream, pos);
183 let payload = stream[*pos..*pos + payload_size as usize].to_vec();
184 command.payload = payload;
185 *pos += payload_size as usize;
186 let tail = parse_u16(stream, pos);
187 if tail != Self::TAIL {
188 error!("After parsing the event, we found an invalid tail signature {}", tail);
189 return Err(SerializationError::TailInvalid);
190 }
191 Ok(command)
192 }
193
194 fn to_bytestream(&self) -> Vec<u8> {
195 let mut stream = Vec::<u8>::with_capacity(9);
196 stream.extend_from_slice(&Self::HEAD.to_le_bytes());
197 stream.push(self.command_code as u8);
198 stream.push(self.payload.len() as u8);
199 stream.extend_from_slice(self.payload.as_slice());
200 stream.extend_from_slice(&Self::TAIL.to_le_bytes());
201 stream
202 }
203}
204
205impl Default for TofCommand {
206 fn default() -> Self {
207 Self::new()
208 }
209}
210
211#[cfg(feature = "random")]
212impl FromRandom for TofCommand {
213 fn from_random() -> Self {
214 let mut rng = rand::rng();
215 let command_code = TofCommandCode::from_random();
216 let payload_size = rng.random::<u8>();
217 let mut payload = Vec::<u8>::with_capacity(payload_size as usize);
218 for _ in 0..payload_size {
219 payload.push(rng.random::<u8>());
220 }
221 Self {
222 command_code : command_code,
223 payload : payload
224 }
225 }
226}
227
228impl fmt::Display for TofCommand {
229 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
230 //let cc = RBCommand::command_code_to_string(self.command_code);
231 let mut repr = String::from("<TofCommand");
232 repr += &(format!("\n cmd code : {}", self.command_code));
233 match self.command_code {
234 TofCommandCode::ShutdownRB
235 | TofCommandCode::ShutdownRAT
236 | TofCommandCode::ShutdownRATPair => {
237 repr += &(format!("\n Sending shutdown command to RBs {:?}>", self.payload));
238 }
239 _ => {
240 repr += ">";
241 }
242 }
243 write!(f, "{}", repr)
244 }
245}
246
247#[cfg(feature="pybindings")]
248#[pymethods]
249impl TofCommand {
250
251 #[getter]
252 fn get_command_code(&mut self) -> TofCommandCode {
253 self.command_code
254 }
255
256 #[setter]
257 fn set_command_code(&mut self, command_code : TofCommandCode) {
258 self.command_code = command_code;
259 }
260
261 /// Pack myself nicely in a TofPacket and
262 /// serialize myself
263 ///
264 /// Can be used to interface with BFSW/GSE
265 /// systems
266 fn wrap_n_pack(&self) -> Vec<u8> {
267 self.pack().to_bytestream()
268 }
269
270 /// An explicit getter for the
271 /// command code, to interface
272 /// with BFSW/GSE systems
273 fn get_cc_u8(&self) -> u8 {
274 self.command_code as u8
275 }
276
277 #[pyo3(name="to_bytestream")]
278 fn to_bytestream_py(&self) -> Vec<u8> {
279 self.to_bytestream()
280 }
281}
282
283#[cfg(feature="pybindings")]
284pythonize_packable!(TofCommand);
285
286/// A hardwired map of RB -> RAT
287#[cfg_attr(feature="pybindings", pyfunction)]
288pub fn get_rbratmap_hardcoded() -> HashMap<u8,u8> {
289 warn!("Using hardcoded rbratmap!");
290 let mapping = HashMap::<u8,u8>::from(
291 [(1, 10),
292 (2, 15),
293 (3, 1),
294 (4, 15),
295 (5, 20),
296 (6, 19),
297 (7, 17),
298 (8, 9),
299 (9, 13),
300 (11,10),
301 (13, 4),
302 (14, 2),
303 (15, 1),
304 (16, 8),
305 (17,17),
306 (18,13),
307 (19, 7),
308 (20, 7),
309 (21, 5),
310 (22,11),
311 (23, 5),
312 (24, 6),
313 (25, 8),
314 (26,11),
315 (27, 6),
316 (28,20),
317 (29, 3),
318 (30, 9),
319 (31, 3),
320 (32, 2),
321 (33,18),
322 (34,18),
323 (35, 4),
324 (36,19),
325 (39,12),
326 (40,12),
327 (41,14),
328 (42,14),
329 (44,16),
330 (46,16)]);
331 mapping
332}
333
334/// A hardwired map of RAT -> (RB1, RB2)
335#[cfg_attr(feature="pybindings", pyfunction)]
336pub fn get_ratrbmap_hardcoded() -> HashMap<u8,(u8,u8)> {
337 warn!("Using hardcoded ratrb map!");
338 let mapping = HashMap::<u8,(u8,u8)>::from(
339 [(1, (3,15)),
340 (2, (32,14)),
341 (3, (31,29)),
342 (4, (35,13)),
343 (5, (23,21)),
344 (6, (27,24)),
345 (7, (20,19)),
346 (8, (16,25)),
347 (9, (8,30)),
348 (10,(1,11)),
349 (11,(26,22)),
350 (12,(39,40)),
351 (13,(9,18)),
352 (14,(41,42)),
353 (15,(2,4)),
354 (16,(46,44)),
355 (17,(7,17)),
356 (18,(33,34)),
357 (19,(36,6)),
358 (20,(28,5))]);
359 mapping
360}
361
362/// A hardwired map of PDU #id PDUCHANNEL #id to (RAT,RAT)
363///
364/// Can be used to synchronize powering down proces for
365/// RATs
366#[cfg_attr(feature="pybindings", pyfunction)]
367pub fn get_ratpdumap_hardcoded() -> HashMap<u8,HashMap::<u8, (u8,u8)>> {
368 warn!("Using hardcoded rat-pdu map!");
369 let mut mapping = HashMap::<u8,HashMap::<u8,(u8,u8)>>::new();
370 let mut ch_map = HashMap::<u8, (u8,u8)>::from([(3, (15,16)), (7, (8,9))]);
371 mapping.insert(0u8, ch_map.clone());
372 ch_map = HashMap::<u8, (u8, u8)>::from([(2, (2,17)), (3, (4,5)), (5, (13,14))]);
373 mapping.insert(1u8, ch_map.clone());
374 ch_map = HashMap::<u8, (u8, u8)>::from([(3, (12,20)), (4, (10,11)), (5, (8,9))]);
375 mapping.insert(2u8, ch_map.clone());
376 ch_map = HashMap::<u8, (u8, u8)>::from([(2, (6,7)), (3, (1,3))]);
377 mapping.insert(3u8, ch_map.clone());
378 mapping
379}
380
381/// Send the 'sudo shutdown now' command to a single RB
382///
383/// # Arguements:
384/// * rb : The RB id of the RB to be shutdown
385/// (NOT RAT)
386#[cfg_attr(feature="pybindings", pyfunction)]
387pub fn shutdown_rb(rb : u8) -> Option<TofCommand> {
388 let code = TofCommandCode::ShutdownRB;
389 let mut cmd = TofCommand::new();
390 cmd.command_code = code;
391 cmd.payload = vec![rb];
392 Some(cmd)
393}
394
395/// Send the 'sudo shutdown now' command to all RBs in a RAT
396///
397/// # Arguments:
398/// * rat : The RAT id for the rat the RBs to be
399/// shutdown live in
400#[cfg_attr(feature="pybindings", pyfunction)]
401pub fn shutdown_rat(rat : u8) -> Option<TofCommand> {
402 let code = TofCommandCode::ShutdownRAT;
403 let mut cmd = TofCommand::new();
404 cmd.command_code = code;
405 cmd.payload = Vec::<u8>::new();
406 let ratmap = get_ratrbmap_hardcoded();
407 match ratmap.get(&rat) {
408 None => {
409 error!("Don't know RBs in RAT {}", rat);
410 return None
411 }
412 Some(pair) => {
413 cmd.payload.push(pair.0);
414 cmd.payload.push(pair.1);
415 }
416 }
417 Some(cmd)
418}
419
420/// Send the 'sudo shutdown now' command to all RBs in a RAT
421///
422/// This will prepare the shutdown command for the RBs in the
423/// RATs which are connected to a specific pdu channel
424///
425/// # Arguments:
426/// * pdu : PDU ID (0-3)
427/// * pduchannel : PDU Channel (0-7)
428#[cfg_attr(feature="pybindings", pyfunction)]
429pub fn shutdown_ratpair(pdu : u8, pduchannel : u8) -> Option<TofCommand> {
430 let code = TofCommandCode::ShutdownRATPair;
431 let mut cmd = TofCommand::new();
432 cmd.command_code = code;
433 cmd.payload = Vec::<u8>::new();
434 let ratmap = get_ratrbmap_hardcoded();
435 let ratpdumap = get_ratpdumap_hardcoded();
436 match ratpdumap.get(&pdu) {
437 None => {
438 error!("Don't know that there is a RAT connected to PDU {}!", pdu);
439 return None;
440 }
441 Some(select_pdu) => {
442 match select_pdu.get(&pduchannel) {
443 None => {
444 error!("Don't know that there is a RAT connected to PDU {}, channel {}!", pdu, pduchannel);
445 return None;
446 }
447 Some(rats) => {
448 match ratmap.get(&rats.0) {
449 Some(rbs) => {
450 cmd.payload.push(rbs.0);
451 cmd.payload.push(rbs.1);
452 }
453 None => {
454 error!("RAT mapping incorrect!");
455 return None;
456 }
457 }
458 match ratmap.get(&rats.1) {
459 Some(rbs) => {
460 cmd.payload.push(rbs.0);
461 cmd.payload.push(rbs.1);
462 },
463 None => {
464 error!("RAT mapping incorrect!");
465 return None;
466 }
467 }
468 }
469 }
470 }
471 }
472 Some(cmd)
473}
474
475/// Send the 'sudo shutdown now' command to
476/// ALL RBs
477#[cfg_attr(feature="pybindings", pyfunction)]
478pub fn shutdown_all_rbs() -> Option<TofCommand> {
479 Some(TofCommand {
480 command_code : TofCommandCode::ShutdownRB,
481 payload : Vec::<u8>::new()
482 })
483}
484
485/// Send the 'sudo shutdown now command to
486/// the TOF main computer ("TOFCPU")
487#[cfg_attr(feature="pybindings", pyfunction)]
488pub fn shutdown_tofcpu() -> Option<TofCommand> {
489 Some(TofCommand {
490 command_code : TofCommandCode::ShutdownCPU,
491 payload : Vec::<u8>::new()
492 })
493}
494
495/// Restart the liftof-rb clients on the given boards
496///
497/// # Arguments
498/// * rbs: restart the client on the given rb ids,
499/// if empty, restart on all of them
500#[cfg_attr(feature="pybindings", pyfunction)]
501pub fn restart_liftofrb(rbs : Vec<u8>) -> Option<TofCommand> {
502 // We don't use & for Vec here, since we need to give it to payload
503 // so there would be a .clone() anyway and so python can understand
504 // the function argument
505 Some(TofCommand {
506 command_code : TofCommandCode::RestartLiftofRBClients,
507 payload : rbs
508 })
509}
510
511/// Trigger the start of a new data run with
512/// the next active config
513#[cfg_attr(feature="pybindings", pyfunction)]
514pub fn start_run() -> Option<TofCommand> {
515 Some(TofCommand {
516 command_code : TofCommandCode::DataRunStart,
517 payload : Vec::<u8>::new(),
518 })
519}
520
521/// Stop the current active run and idle
522#[cfg_attr(feature="pybindings", pyfunction)]
523pub fn stop_run() -> Option<TofCommand> {
524 Some(TofCommand {
525 command_code : TofCommandCode::DataRunStop,
526 payload : Vec::<u8>::new(),
527 })
528}
529
530/// Run a calibration of all RBs
531///
532/// # Arguments:
533/// * pre_run_calibration : Run the RBCalibration routine before
534/// every run start
535/// * send_packetes : Send the RBCalibration packets
536/// * save_events : Save the events to the RBCalibration
537/// packets
538#[cfg_attr(feature="pybindings", pyfunction)]
539pub fn calibrate_rbs(pre_run_calibration : bool, send_packets : bool, save_events : bool) -> Option<TofCommand> {
540 let payload = vec![pre_run_calibration as u8, send_packets as u8, save_events as u8];
541 Some(TofCommand {
542 command_code : TofCommandCode::RBCalibration,
543 payload : payload,
544 })
545}
546
547/// Change the MTBSettings in the config file with relevant trigger settings
548#[cfg_attr(feature="pybindings", pyfunction)]
549pub fn change_triggerconfig(cfg : &TriggerConfig) -> Option<TofCommand> {
550 let payload = cfg.to_bytestream();
551 Some(TofCommand {
552 command_code : TofCommandCode::SetMTConfig,
553 payload : payload,
554 })
555}
556
557/// Change the EventBuilderSettings in the config file
558#[cfg_attr(feature="pybindings", pyfunction)]
559pub fn change_tofeventbuilderconfig(cfg : &TOFEventBuilderConfig) -> Option<TofCommand> {
560 let payload = cfg.to_bytestream();
561 Some(TofCommand {
562 command_code : TofCommandCode::SetTOFEventBuilderConfig,
563 payload : payload,
564 })
565}
566
567/// Change the data publisher config part of the config file
568#[cfg_attr(feature="pybindings", pyfunction)]
569pub fn change_datapublisherconfig(cfg : &DataPublisherConfig) -> Option<TofCommand> {
570 let payload = cfg.to_bytestream();
571 Some(TofCommand {
572 command_code : TofCommandCode::SetDataPublisherConfig,
573 payload : payload,
574 })
575}
576
577/// Change the data publisher config part of the config file
578#[cfg_attr(feature="pybindings", pyfunction)]
579pub fn change_tofrunconfig(cfg : &TofRunConfig) -> Option<TofCommand> {
580 let payload = cfg.to_bytestream();
581 Some(TofCommand {
582 command_code : TofCommandCode::SetTofRunConfig,
583 payload : payload,
584 })
585}
586
587#[cfg_attr(feature="pybindings", pyfunction)]
588pub fn change_tofrbconfig(cfg : &TofRBConfig) -> Option<TofCommand> {
589 let payload = cfg.to_bytestream();
590 Some(TofCommand {
591 command_code : TofCommandCode::SetTofRBConfig,
592 payload : payload,
593 })
594}
595
596///// Send the 'sudo shutdown now' command to a single RB
597/////
598///// # Arguements:
599///// * rb : The RB id of the RB to be shutdown
600///// (NOT RAT)
601//#[pyfunction]
602//#[pyo3(name="shutdown_rb")]
603//pub fn py_shutdown_rb(rb : u8) -> PyResult<TofCommand> {
604// let cmd = shutdown_rb(rb).unwrap();
605// Ok(TofCommand {
606// command : cmd
607// })
608//}
609//
610//
611///// Send the 'sudo shutdown now' command to
612///// ALL RBs
613//#[pyfunction]
614//#[pyo3(name="shutdown_all_rbs")]
615//pub fn py_shutdown_all_rbs() -> PyResult<TofCommand> {
616// let cmd = shutdown_all_rbs().unwrap();
617// let pycmd = TofCommand {
618// command : cmd
619// };
620// return Ok(pycmd);
621//}
622//
623///// Send the 'sudo shutdown now' command to all RBs in a RAT
624/////
625///// # Arguments:
626///// * rat : The RAT id for the rat the RBs to be
627///// shutdown live in
628//#[pyfunction]
629//#[pyo3(name="shutdown_rat")]
630//pub fn py_shutdown_rat(rat : u8) -> PyResult<TofCommand> {
631// match shutdown_rat(rat) {
632// None => {
633// return Err(PyValueError::new_err(format!("There might not be a RAT{}!", rat)));
634// }
635// Some(cmd) => {
636// let pycmd = TofCommand {
637// command : cmd
638// };
639// return Ok(pycmd);
640// }
641// }
642//}
643//
644///// Send the 'sudo shutdown now' command to all RBs
645///// in the 2 RATs connected to a certain PDU channel
646/////
647///// This will prepare the shutdown command for the RBs in the
648///// RATs which are connected to a specific pdu channel
649/////
650///// # Arguments:
651///// * pdu : PDU ID (0-3)
652///// * pduchannel : PDU Channel (0-7)
653//#[pyfunction]
654//#[pyo3(name="shutdown_ratpair")]
655//pub fn py_shutdown_ratpair(pdu : u8, pduchannel : u8) -> PyResult<TofCommand> {
656// match shutdown_ratpair(pdu, pduchannel) {
657// None => {
658// return Err(PyValueError::new_err(format!("There might be an issue with the pdu mapping. Can nto find RATs at PDU {} channel {}!", pdu, pduchannel)));
659// }
660// Some(cmd) => {
661// let pycmd = TofCommand {
662// command : cmd
663// };
664// return Ok(pycmd);
665// }
666// }
667//}
668//
669///// Send the 'sudo shutdown now command to
670///// the TOF main computer ("TOFCPU")
671//#[pyfunction]
672//#[pyo3(name="shutdown_cpu")]
673//pub fn py_shutdown_tofcpu() -> PyResult<TofCommand> {
674// match shutdown_tofcpu() {
675// None => {
676// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
677// }
678// Some(cmd) => {
679// let pycmd = TofCommand {
680// command : cmd
681// };
682// return Ok(pycmd);
683// }
684// }
685//}
686//
687//
688///// Restart the liftof-rb clients on the given boards
689/////
690///// # Arguments
691///// * rbs: restart the client on the given rb ids,
692///// if empty, restart on all of them
693//#[pyfunction]
694//#[pyo3(name="restart_liftofrb")]
695//pub fn py_restart_liftofrb(rbs : Vec<u8>) -> PyResult<TofCommand> {
696// match restart_liftofrb(&rbs) {
697// None => {
698// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
699// }
700// Some(cmd) => {
701// let pycmd = TofCommand {
702// command : cmd
703// };
704// return Ok(pycmd);
705// }
706// }
707//}
708//
709///// Trigger the start of a new data run with
710///// the next active config
711//#[pyfunction]
712//#[pyo3(name="start_run")]
713//pub fn py_start_run() -> PyResult<TofCommand> {
714// match start_run() {
715// None => {
716// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
717// }
718// Some(cmd) => {
719// let pycmd = TofCommand {
720// command : cmd
721// };
722// return Ok(pycmd);
723// }
724// }
725//}
726//
727///// Stop the current active run and idle
728//#[pyfunction]
729//#[pyo3(name="stop_run")]
730//pub fn py_stop_run() -> PyResult<TofCommand> {
731// match stop_run() {
732// None => {
733// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
734// }
735// Some(cmd) => {
736// let pycmd = TofCommand {
737// command : cmd
738// };
739// return Ok(pycmd);
740// }
741// }
742//}
743//
744///// Run a calibration of all RBs
745/////
746///// # Arguments:
747///// * pre_run_calibration : Run the RBCalibration routine before
748///// every run start
749///// * send_packetes : Send the RBCalibration packets
750///// * save_events : Save the events to the RBCalibration
751///// packets
752//#[pyfunction]
753//#[pyo3(name="rb_calibration")]
754//pub fn py_rb_calibration(pre_run_calibration : bool, send_packets : bool, save_events : bool) -> PyResult<TofCommand> {
755// match rb_calibration(pre_run_calibration,send_packets, save_events) {
756// None => {
757// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
758// }
759// Some(cmd) => {
760// let pycmd = TofCommand {
761// command : cmd
762// };
763// return Ok(pycmd);
764// }
765// }
766//}
767//
768//
769///// Change the MTBSettings in the config file with relevant trigger settings
770//#[pyfunction]
771//#[pyo3(name="change_triggerconfig")]
772//pub fn py_change_triggerconfig(cfg : &PyTriggerConfig) -> PyResult<TofCommand> {
773// match change_triggerconfig(&cfg.config) {
774// None => {
775// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
776// }
777// Some(cmd) => {
778// let pycmd = TofCommand {
779// command : cmd
780// };
781// return Ok(pycmd);
782// }
783// }
784//}
785//
786//
787///// Change the TOFEventBuilderSettings in the config
788//#[pyfunction]
789//#[pyo3(name="change_tofeventbuilderconfig")]
790//pub fn py_change_tofeventbuilderconfig(cfg : &PyTOFEventBuilderConfig) -> PyResult<TofCommand> {
791// match change_tofeventbuilderconfig(&cfg.config) {
792// None => {
793// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
794// }
795// Some(cmd) => {
796// let pycmd = TofCommand {
797// command : cmd
798// };
799// return Ok(pycmd);
800// }
801// }
802//}
803//
804///// Change the data publisher config part of the config file
805//#[pyfunction]
806//#[pyo3(name="change_datapublisherconfig")]
807//pub fn py_change_datapublisherconfig(cfg : &PyDataPublisherConfig) -> PyResult<TofCommand> {
808// match change_datapublisherconfig(&cfg.config) {
809// None => {
810// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
811// }
812// Some(cmd) => {
813// let pycmd = TofCommand {
814// command : cmd
815// };
816// return Ok(pycmd);
817// }
818// }
819//}
820//
821///// Change the run config part of the config file
822//#[pyfunction]
823//#[pyo3(name="change_tofrunconfig")]
824//pub fn py_change_tofrunconfig(cfg : &PyTofRunConfig) -> PyResult<TofCommand> {
825// match change_tofrunconfig(&cfg.config) {
826// None => {
827// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
828// }
829// Some(cmd) => {
830// let pycmd = TofCommand {
831// command : cmd
832// };
833// return Ok(pycmd);
834// }
835// }
836//}
837//
838///// Change the RB config part of the config file
839//#[pyfunction]
840//#[pyo3(name="change_tofrbconfig")]
841//pub fn py_change_tofrbconfig(cfg : &PyTofRBConfig) -> PyResult<TofCommand> {
842// match change_tofrbconfig(&cfg.config) {
843// None => {
844// return Err(PyValueError::new_err(format!("You encounterd a dragon \u{1f409}! We don't know what's going on either.")));
845// }
846// Some(cmd) => {
847// let pycmd = TofCommand {
848// command : cmd
849// };
850// return Ok(pycmd);
851// }
852// }
853//}
854