otsdaq  3.11.00
FEVInterface.h
1 #ifndef _ots_FEVInterface_h_
2 #define _ots_FEVInterface_h_
3 
4 #include <functional>
5 
6 #define TRACEMF_USE_VERBATIM 1 // for trace longer path filenames
7 #include "artdaq/DAQdata/Globals.hh"
8 
9 #include "otsdaq/Configurable/Configurable.h"
10 #include "otsdaq/FECore/FESlowControlsWorkLoop.h"
11 #include "otsdaq/FiniteStateMachine/VStateMachine.h"
12 #include "otsdaq/WorkLoopManager/WorkLoop.h"
13 
14 #include "otsdaq/CoreSupervisors/CoreSupervisorBase.h"
15 
16 #include "otsdaq/SupervisorInfo/AllSupervisorInfo.h" //to send errors to Gateway, e.g.
17 
18 #include "otsdaq/FECore/FESlowControlsChannel.h"
19 #include "otsdaq/SOAPUtilities/SOAPMessenger.h" //for xdaq::ApplicationDescriptor communication
20 
21 #include <array>
22 #include <iostream>
23 #include <map>
24 #include <mutex>
25 #include <string>
26 #include <thread>
27 #include <vector>
28 
29 #include "otsdaq/Macros/CoutMacros.h"
30 
31 #define __ARGS__ \
32  [[maybe_unused]] const frontEndMacroStruct_t & feMacroStruct, \
33  [[maybe_unused]] FEVInterface::frontEndMacroConstArgs_t argsIn, \
34  [[maybe_unused]] FEVInterface::frontEndMacroArgs_t argsOut
35 
36 #define __GET_ARG_IN_NO_DEFAULT__(X, Y) getFEMacroConstArgumentValue<Y>(argsIn, X)
37 #define __GET_ARG_IN_DEFAULT__(X, Y, D) getFEMacroConstArgumentValue<Y>(argsIn, X, D)
38 #define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
39 #define __GET_ARG_IN_CHOOSER__(...) \
40  GET_4TH_ARG(__VA_ARGS__, __GET_ARG_IN_DEFAULT__, __GET_ARG_IN_NO_DEFAULT__, )
41 #define __GET_ARG_IN__(...) __GET_ARG_IN_CHOOSER__(__VA_ARGS__)(__VA_ARGS__)
42 #define __GET_ARG_OUT__(X, Y) getFEMacroArgumentValue<Y>(argsOut, X)
43 
44 #define __SET_ARG_IN__(X, Y) FEVInterface::emplaceFEMacroArgumentValue(argsIn, X, Y)
45 #define __SET_ARG_OUT__(X, Y) FEVInterface::setFEMacroArgumentValue(argsOut, X, Y)
46 #define __SET_PCT_DONE__(X) setFEMacroPercentDone(X)
47 
48 // clang-format off
49 #define PLOTLY_PLOT "Plotly_Plot"
72 
73 namespace ots
74 {
75 class FEVInterfacesManager;
76 
86 class FEVInterface : public WorkLoop, public Configurable, public VStateMachine
87 {
88  friend class FEVInterfacesManager;
89 
90  public:
92  const std::string& interfaceUID,
93  const ConfigurationTree& theXDAQContextConfigTree,
94  const std::string& configurationPath);
95 
96  virtual ~FEVInterface(void);
97 
98  virtual void setParentPointers(CoreSupervisorBase* supervisor,
99  FEVInterfacesManager* manager);
100 
101  FEVInterfacesManager* parentInterfaceManager_ = nullptr;
102 
103  const std::string& getInterfaceUID (void) const { return interfaceUID_; }
104  const std::string& getInterfaceType (void) const { return interfaceType_; }
105 
106  virtual void universalRead (char* address, char* returnValue) = 0;
107  virtual void universalWrite (char* address, char* writeValue) = 0;
108  const unsigned int& getUniversalAddressSize (void) { return universalAddressSize_; }
109  const unsigned int& getUniversalDataSize (void) { return universalDataSize_; }
110  virtual void universalBlockRead (char* address, char* returnValue, unsigned int numberOfBytes) { throw std::runtime_error("UNDEFINED BLOCK READ"); /* to make compiler happy, use params */ __COUTV__((void*)address); __COUTV__((void*)returnValue); __COUTV__(numberOfBytes); }
112  virtual void universalBlockWrite (char* address, char* writeValue, unsigned int numberOfBytes) { throw std::runtime_error("UNDEFINED BLOCK WRITE"); /* to make compiler happy, use params */ __COUTV__((void*)address); __COUTV__((void*)writeValue); __COUTV__(numberOfBytes); }
113 
114 
115  void runSequenceOfCommands (const std::string& treeLinkName);
116 
117  static void sendAsyncExceptionToGateway (FEVInterface* fe, const std::string& errMsg, bool isPauseException, bool isStopException);
118 
121  virtual void configure (void)
122  {
123  __COUT__ << "\t Configure" << std::endl;
125  "LinkToConfigureSequence"); /*Run Configure Sequence Commands*/
126  }
127  virtual void start (std::string /*runNumber*/)
128  {
129  __COUT__ << "\t Start" << std::endl;
130  runSequenceOfCommands("LinkToStartSequence"); /*Run Start Sequence Commands*/
131  }
132  virtual void stop (void)
133  {
134  __COUT__ << "\t Stop" << std::endl;
135  runSequenceOfCommands("LinkToStopSequence"); /*Run Stop Sequence Commands*/
136  }
137  virtual void halt (void) { stop(); }
138  virtual void pause (void) { stop(); }
139  virtual void resume (void) { start(""); }
140  virtual bool running (void) { /*while(WorkLoop::continueWorkLoop_){;}*/ return false; }
146  virtual void configureSlowControls (void);
147  void addSlowControlsChannels (ConfigurationTree slowControlsGroupLink, std::map<std::string /* ROC UID*/, FESlowControlsChannel>* mapOfSlowControlsChannels);
148 
149  virtual void resetSlowControlsChannelIterator (void);
151  virtual unsigned int getSlowControlsChannelCount (void);
152  bool slowControlsRunning (void);
153  void startSlowControlsWorkLoop (void) { slowControlsWorkLoop_.startWorkLoop(); }
154  void stopSlowControlsWorkLoop (void) { slowControlsWorkLoop_.stopWorkLoop(); }
155 
156  static const std::string UNKNOWN_TYPE;
157 
158  protected:
160  std::map<std::string, FESlowControlsChannel> mapOfSlowControlsChannels_;
161  std::map<std::string,
162  FESlowControlsChannel>::iterator slowControlsChannelsIterator_;
163  FESlowControlsWorkLoop slowControlsWorkLoop_;
164  std::atomic<bool> slowControlsWorkLoopShouldRun_{true};
170  public:
172  static const std::string DEFAULT; //for default arg values in FE macro definitions
173 
174  using frontEndMacroArg_t = std::pair<const std::string /* arg name */, std::string /* arg return value */>;
175  using frontEndMacroArgs_t = std::vector<frontEndMacroArg_t>&;
176  using frontEndMacroConstArgs_t = const std::vector<frontEndMacroArg_t>&;
177  struct frontEndMacroStruct_t;
178  using frontEndMacroFunction_t = void (ots::FEVInterface::*)(__ARGS__);
180  {
182  const std::string& feMacroName,
183  const frontEndMacroFunction_t& feMacroFunction,
184  const std::vector<std::string>& namesOfInputArgs,
185  const std::vector<std::string>& namesOfOutputArgs,
186  const std::string& requiredUserPermissions = "1" /*Level definition: 0:no-access,1:=user,255:=admin*/,
187  const std::string& allowedCallingFrontEnds = "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/,
188  const std::string& feMacroTooltip = "")
189  : feMacroName_ (feMacroName)
190  , macroFunction_ (feMacroFunction)
191  , namesOfInputArguments_ (namesOfInputArgs)
192  , namesOfOutputArguments_ (namesOfOutputArgs)
193  , requiredUserPermissions_ (requiredUserPermissions)
194  , allowedCallingFrontEnds_ (allowedCallingFrontEnds)
195  , feMacroTooltip_ (feMacroTooltip)
196  {
197  }
198 
199  const std::string feMacroName_;
201  const std::vector<std::string> namesOfInputArguments_, namesOfOutputArguments_;
202  const std::string requiredUserPermissions_;
203  const std::string allowedCallingFrontEnds_;
204  const std::string feMacroTooltip_;
205  }; //end frontEndMacroStruct_t
206  const std::map<std::string, frontEndMacroStruct_t>& getMapOfFEMacroFunctions(void)
207  {
208  return mapOfFEMacroFunctions_;
209  }
213  virtual std::map<std::string, std::string> getFEMacroInputDefaults(
214  const std::string& /*feMacroName*/,
215  const std::map<std::string, std::string>& /*currentInputValues*/) const
216  {
217  return {};
218  }
219  void runSelfFrontEndMacro (
220  const std::string& feMacroName,
221  const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs,
222  std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs);
224  void runSelfFrontEndMacro(
225  const std::string& feMacroName,
226  const std::vector<frontEndMacroArg_t>& inputArgs,
227  std::vector<frontEndMacroArg_t>& outputArgs,
228  const std::function<void(unsigned int)>& onProgress);
229 
236  {
237  macroStruct_t(const std::string& macroString);
238 
239  enum
240  {
241  OP_TYPE_READ,
242  OP_TYPE_WRITE,
243  OP_TYPE_DELAY,
244  };
245 
246  struct readOp_t
247  {
248  uint64_t address_;
249  bool addressIsVar_;
250  std::string addressVarName_;
251  bool dataIsVar_;
252  std::string dataVarName_;
253  }; // end macroStruct_t::writeOp_t declaration
254 
255  struct writeOp_t
256  {
257  uint64_t address_;
258  bool addressIsVar_;
259  std::string addressVarName_;
260  uint64_t data_;
261  bool dataIsVar_;
262  std::string dataVarName_;
263  }; // end macroStruct_t::writeOp_t declaration
264 
265  struct delayOp_t
266  {
267  uint64_t delay_;
268  bool delayIsVar_;
269  std::string delayVarName_;
270  }; // end macroStruct_t::writeOp_t declaration
271 
272  std::string macroName_;
273  std::vector<std::pair<unsigned int /*op type*/,
274  unsigned int /*index in specific type vector*/> >
275  operations_;
276  std::vector<macroStruct_t::readOp_t> readOps_;
277  std::vector<macroStruct_t::writeOp_t> writeOps_;
278  std::vector<macroStruct_t::delayOp_t> delayOps_;
279  std::set<std::string> namesOfInputArguments_, namesOfOutputArguments_;
280  bool lsbf_;
281  }; // end macroStruct_t declaration
282  protected:
284  std::map<std::string /*name*/, uint64_t /*value*/>& variableMap);
285 
286  public:
293  template<class T>
294  void sendToFrontEnd (const std::string& targetInterfaceID, const T& value) const;
295  void runFrontEndMacro (const std::string& targetInterfaceID,const std::string& feMacroName, const std::vector<FEVInterface::frontEndMacroArg_t>& inputArgs, std::vector<FEVInterface::frontEndMacroArg_t>& outputArgs) const;
296 
297  void PauseResumeSlowControls (__ARGS__);
298 
303  template<class T>
304  void receiveFromFrontEnd (const std::string& requester, T& retValue, unsigned int timeoutInSeconds = 1) const;
306  void receiveFromFrontEnd (const std::string& requester, std::string& retValue, unsigned int timeoutInSeconds = 1) const;
309  template<class T>
310  T receiveFromFrontEnd (const std::string& requester = "*", unsigned int timeoutInSeconds = 1) const;
312  std::string receiveFromFrontEnd (const std::string& requester = "*", unsigned int timeoutInSeconds = 1) const;
313 
317  protected:
318  bool workLoopThread (toolbox::task::WorkLoop* workLoop);
319 
320  std::string interfaceUID_, interfaceType_;
321  std::string mfSubject_;
322 
323  unsigned int universalAddressSize_ = 0;
324  unsigned int universalDataSize_ = 0;
325 
326 
329  std::map<std::string, frontEndMacroStruct_t> mapOfFEMacroFunctions_;
331  const std::string& feMacroName,
332  frontEndMacroFunction_t feMacroFunction,
333  const std::vector<std::string>& namesOfInputArgs,
334  const std::vector<std::string>& namesOfOutputArgs,
335  uint8_t requiredUserPermissions = 1 /*Level definition: 0:no-access,1:=user,255:=admin*/,
336  const std::string& allowedCallingFEs = "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/,
337  const std::string& feMacroTooltip = "");
339  const std::string& feMacroName,
340  frontEndMacroFunction_t feMacroFunction,
341  const std::vector<std::string>& namesOfInputArgs,
342  const std::vector<std::string>& namesOfOutputArgs,
343  const std::string& requiredUserPermissions = WebUsers::DEFAULT_USER_GROUP + ":1" /*Level definition: 0:no-access,1:=user,255:=admin*/,
344  const std::string& allowedCallingFEs = "*" /*StringMacros:: wild card set match string (i.e. string-to-set, then wild-card-set match)*/,
345  const std::string& feMacroTooltip = "");
346 
347  public:
348  static const std::string& getFEMacroConstArgument (frontEndMacroConstArgs_t args, const std::string& argName);
349  static std::string& getFEMacroArgument (frontEndMacroArgs_t args, const std::string& argName);
350  protected:
351  template<class T>
352  std::string& setFEMacroArgumentValue (frontEndMacroArgs_t args, const std::string& argName, const T& value) const;
353  public:
354  template<class T>
355  static std::string& emplaceFEMacroArgumentValue (frontEndMacroArgs_t args, const std::string& argName, const T& value);
356 
358  void setFEMacroPercentDone (unsigned int percentDone);
359  int getFEMacroPercentDone (std::thread::id threadID) const;
360  void clearFEMacroPercentDone (std::thread::id threadID);
361 
362  protected:
363  mutable std::mutex feMacroPercentDoneMutex_;
364  std::map<std::thread::id, int> feMacroPercentDoneMap_;
365 
366 }; // end FEVInterface class
367 
368 template<class T>
369 T getFEMacroConstArgumentValue (FEVInterface::frontEndMacroConstArgs_t args, const std::string& argName, const T& defaultValue = T());
370 
372 template<>
373 std::string getFEMacroConstArgumentValue<std::string> (FEVInterface::frontEndMacroConstArgs_t args, const std::string& argName, const std::string& defaultValue);
374 
375 template<class T>
376 T getFEMacroArgumentValue (FEVInterface::frontEndMacroArgs_t args, const std::string& argName);
377 
379 template<>
380 std::string getFEMacroArgumentValue<std::string> (FEVInterface::frontEndMacroArgs_t argsIn, const std::string& argName);
381 
383 #include "otsdaq/FECore/FEVInterface.icc"
384 
385 // clang-format on
386 
387 } // namespace ots
388 
389 #endif
void runMacro(FEVInterface::macroStruct_t &macro, std::map< std::string, uint64_t > &variableMap)
runMacro
virtual void resetSlowControlsChannelIterator(void)
virtual in case channels are handled in multiple maps, for example
void(ots::FEVInterface::*)(const frontEndMacroStruct_t &feMacroStruct, FEVInterface::frontEndMacroConstArgs_t argsIn, FEVInterface::frontEndMacroArgs_t argsOut) frontEndMacroFunction_t
void function (vector-of-inputs, vector-of-outputs)
Definition: FEVInterface.h:178
virtual void configureSlowControls(void)
end State Machine handlers
static void sendAsyncExceptionToGateway(FEVInterface *fe, const std::string &errMsg, bool isPauseException, bool isStopException)
void runSequenceOfCommands(const std::string &treeLinkName)
virtual void configure(void)
Definition: FEVInterface.h:121
std::map< std::string, frontEndMacroStruct_t > mapOfFEMacroFunctions_
Map of FE Macro functions members.
Definition: FEVInterface.h:329
virtual std::map< std::string, std::string > getFEMacroInputDefaults(const std::string &, const std::map< std::string, std::string > &) const
Definition: FEVInterface.h:213
static const std::string & getFEMacroConstArgument(frontEndMacroConstArgs_t args, const std::string &argName)
< for specialized access to FE Macro in/out arguments
bool universalBlockReadImplementationConfirmed
is confirmed by slow controls handling (for example) that universalBlockRead is implemented by the FE...
Definition: FEVInterface.h:111
void addSlowControlsChannels(ConfigurationTree slowControlsGroupLink, std::map< std::string, FESlowControlsChannel > *mapOfSlowControlsChannels)
static const std::string DEFAULT
end Slow Controls
Definition: FEVInterface.h:172
std::string mfSubject_
for GEN_COUT decorations which would be safe in destructors, e.g. mirror interfaceUID_
Definition: FEVInterface.h:321
virtual FESlowControlsChannel * getNextSlowControlsChannel(void)
virtual in case channels are handled in multiple maps, for example
void runFrontEndMacro(const std::string &targetInterfaceID, const std::string &feMacroName, const std::vector< FEVInterface::frontEndMacroArg_t > &inputArgs, std::vector< FEVInterface::frontEndMacroArg_t > &outputArgs) const
virtual void universalRead(char *address, char *returnValue)=0
throw std::runtime_error exception on error/timeout
void setFEMacroPercentDone(unsigned int percentDone)
FE Macro progress reporting (for async macros via FESupervisor)
T receiveFromFrontEnd(const std::string &requester="*", unsigned int timeoutInSeconds=1) const
static std::string & getFEMacroArgument(frontEndMacroArgs_t args, const std::string &argName)
virtual bool running(void)
Definition: FEVInterface.h:140
bool slowControlsRunning(void)
slow controls workloop calls this
virtual unsigned int getSlowControlsChannelCount(void)
virtual in case channels are handled in multiple maps, for example
void receiveFromFrontEnd(const std::string &requester, T &retValue, unsigned int timeoutInSeconds=1) const
bool workLoopThread(toolbox::task::WorkLoop *workLoop)
end FE Communication helpers //////
void sendToFrontEnd(const std::string &targetInterfaceID, const T &value) const
end FE Macros
void registerFEMacroFunction(const std::string &feMacroName, frontEndMacroFunction_t feMacroFunction, const std::vector< std::string > &namesOfInputArgs, const std::vector< std::string > &namesOfOutputArgs, uint8_t requiredUserPermissions=1, const std::string &allowedCallingFEs="*", const std::string &feMacroTooltip="")
std::map< std::string, FESlowControlsChannel > mapOfSlowControlsChannels_
Slow Controls members.
Definition: FEVInterface.h:160
defines used also by OtsConfigurationWizardSupervisor
< members fully define a front-end macro function
Definition: FEVInterface.h:180
const frontEndMacroFunction_t macroFunction_
Note: must be called using this instance.
Definition: FEVInterface.h:200
macroStruct_t(const std::string &macroString)
macroStruct_t constructor
bool lsbf_
least significant byte first
Definition: FEVInterface.h:280