2121#include " CommandLineUtilities/Options.h"
2222#include " CommandLineUtilities/Program.h"
2323#include < boost/format.hpp>
24+ #include < boost/property_tree/ptree.hpp>
25+ #include < boost/property_tree/json_parser.hpp>
2426
2527using namespace AliceO2 ::roc::CommandLineUtilities;
2628using namespace AliceO2 ::roc;
27- using namespace AliceO2 ::InfoLogger ;
29+ namespace pt = boost::property_tree ;
2830namespace po = boost::program_options;
2931
3032class ProgramStatus : public Program
@@ -33,19 +35,41 @@ class ProgramStatus : public Program
3335 virtual Description getDescription ()
3436 {
3537 return { " Status" , " Return current RoC configuration status" ,
36- " roc-status --id 42:00.0\n " };
38+ " roc-status --id 42:00.0\n "
39+ " roc-status --id 42:00.0 --json" };
3740 }
3841
3942 virtual void addOptions (boost::program_options::options_description& options)
4043 {
4144 Options::addOptionCardId (options);
42- options.add_options ()(" csv -out" ,
43- po::bool_switch (&mOptions .csvOut ),
44- " Toggle csv -formatted output" );
45+ options.add_options ()(" json -out" ,
46+ po::bool_switch (&mOptions .jsonOut ),
47+ " Toggle json -formatted output" );
4548 }
4649
4750 virtual void run (const boost::program_options::variables_map& map)
4851 {
52+ auto enforcePrecision = [](auto flo) {
53+ std::ostringstream precisionEnforcer;
54+ precisionEnforcer << std::fixed;
55+ precisionEnforcer << std::setprecision (2 );
56+ precisionEnforcer << flo;
57+ return precisionEnforcer.str ();
58+ };
59+
60+ std::ostringstream table;
61+ auto formatHeader = " %-9s %-16s %-10s %-14s %-15s %-10s %-14s %-14s %-8s %-19s\n " ;
62+ auto formatRow = " %-9s %-16s %-10s %-14s %-15s %-10s %-14.2f %-14.2f %-8s %-19.1f\n " ;
63+ auto header = (boost::format (formatHeader) % " Link ID" % " GBT Mode Tx/Rx" % " Loopback" % " GBT MUX" % " Datapath Mode" % " Datapath" % " RX freq(MHz)" % " TX freq(MHz)" % " Status" % " Optical power(uW)" ).str ();
64+ auto lineFat = std::string (header.length (), ' =' ) + ' \n ' ;
65+ auto lineThin = std::string (header.length (), ' -' ) + ' \n ' ;
66+
67+ if (!mOptions .jsonOut ) {
68+ table << lineFat << header << lineThin;
69+ }
70+
71+ // initialize ptree
72+ pt::ptree root;
4973
5074 auto cardId = Options::getOptionCardId (map);
5175 auto params = Parameters::makeParameters (cardId, 2 ); // status available on BAR2
@@ -66,23 +90,9 @@ class ProgramStatus : public Program
6690
6791 Cru::ReportInfo reportInfo = cruBar2->report ();
6892
69- std::ostringstream table;
70- auto formatHeader = " %-9s %-16s %-10s %-14s %-15s %-10s %-14s %-14s %-8s %-19s\n " ;
71- auto formatRow = " %-9s %-16s %-10s %-14s %-15s %-10s %-14.2f %-14.2f %-8s %-19.1f\n " ;
72- auto header = (boost::format (formatHeader) % " Link ID" % " GBT Mode Tx/Rx" % " Loopback" % " GBT MUX" % " Datapath Mode" % " Datapath" % " RX freq(MHz)" % " TX freq(MHz)" % " Status" % " Optical power(uW)" ).str ();
73- auto lineFat = std::string (header.length (), ' =' ) + ' \n ' ;
74- auto lineThin = std::string (header.length (), ' -' ) + ' \n ' ;
75-
76- if (mOptions .csvOut ) {
77- auto csvHeader = " Link ID,GBT Mode,Loopback,GBT Mux,Datapath Mode,Datapath,RX Freq(MHz),TX Freq(MHz),Status,Optical Power(uW)\n " ;
78- std::cout << csvHeader;
79- } else {
80- table << lineFat << header << lineThin;
81- }
93+ std::string clock = (reportInfo.ttcClock == 0 ? " TTC" : " Local" );
8294
83- if (!mOptions .csvOut ) {
84- std::string clock = (reportInfo.ttcClock == 0 ? " TTC" : " Local" );
85- ;
95+ if (!mOptions .jsonOut ) {
8696 std::cout << " ----------------------------" << std::endl;
8797 std::cout << clock << " clock | " ;
8898 if (reportInfo.dynamicOffset ) {
@@ -91,6 +101,13 @@ class ProgramStatus : public Program
91101 std::cout << " Fixed offset" << std::endl;
92102 }
93103 std::cout << " ----------------------------" << std::endl;
104+ } else {
105+ root.put (" clock" , clock);
106+ if (reportInfo.dynamicOffset ) {
107+ root.put (" offset" , " Dynamic" );
108+ } else {
109+ root.put (" offset" , " Fixed" );
110+ }
94111 }
95112
96113 for (const auto & el : reportInfo.linkMap ) {
@@ -133,26 +150,40 @@ class ProgramStatus : public Program
133150
134151 float opticalPower = link.opticalPower ;
135152
136- if (mOptions .csvOut ) {
137- auto csvLine = std::to_string (globalId) + " ," + gbtTxRxMode + " ," + loopback + " ," + gbtMux + " ," + datapathMode + " ," + enabled + " ," +
138- std::to_string (rxFreq) + " ," + std::to_string (txFreq) + " ," + linkStatus + " ," + std::to_string (opticalPower) + " \n " ;
139- std::cout << csvLine;
140- } else {
153+ if (!mOptions .jsonOut ) {
141154 auto format = boost::format (formatRow) % globalId % gbtTxRxMode % loopback % gbtMux % datapathMode % enabled % rxFreq % txFreq % linkStatus % opticalPower;
142155 table << format;
156+ } else {
157+ pt::ptree linkNode;
158+
159+ // add kv pairs for this card
160+ linkNode.put (" gbtMode" , gbtTxRxMode);
161+ linkNode.put (" loopback" , loopback);
162+ linkNode.put (" gbtMux" , gbtMux);
163+ linkNode.put (" datapathMode" , datapathMode);
164+ linkNode.put (" datapath" , enabled);
165+ linkNode.put (" rxFreq" , enforcePrecision (rxFreq));
166+ linkNode.put (" txFreq" , enforcePrecision (txFreq));
167+ linkNode.put (" status" , linkStatus);
168+ linkNode.put (" opticalPower" , enforcePrecision (opticalPower));
169+
170+ // add the link node to the tree
171+ root.add_child (std::to_string (globalId), linkNode);
143172 }
144173 }
145174
146- if (!mOptions .csvOut ) {
175+ if (!mOptions .jsonOut ) {
147176 auto lineFat = std::string (header.length (), ' =' ) + ' \n ' ;
148177 table << lineFat;
149178 std::cout << table.str ();
179+ } else {
180+ pt::write_json (std::cout, root);
150181 }
151182 }
152183
153184 private:
154185 struct OptionsStruct {
155- bool csvOut = false ;
186+ bool jsonOut = false ;
156187 } mOptions ;
157188};
158189
0 commit comments