00001 #include "otsdaq-core/FiniteStateMachine/RunControlStateMachine.h"
00002 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00003 #include "otsdaq-core/Macros/CoutHeaderMacros.h"
00004 #include "otsdaq-core/SOAPUtilities/SOAPUtilities.h"
00005 #include "otsdaq-core/SOAPUtilities/SOAPCommand.h"
00006
00007 #include <toolbox/fsm/FailedEvent.h>
00008 #include <xoap/Method.h>
00009 #include <xdaq/NamespaceURI.h>
00010
00011 #include <iostream>
00012
00013 using namespace ots;
00014
00015 const std::string RunControlStateMachine::FAILED_STATE_NAME = "Failed";
00016
00017
00018 RunControlStateMachine::RunControlStateMachine(std::string name)
00019 : stateMachineName_(name)
00020 {
00021 INIT_MF("RunControlStateMachine");
00022
00023 theStateMachine_.addState('I', "Initial", this, &RunControlStateMachine::stateInitial);
00024 theStateMachine_.addState('H', "Halted", this, &RunControlStateMachine::stateHalted);
00025 theStateMachine_.addState('C', "Configured", this, &RunControlStateMachine::stateConfigured);
00026 theStateMachine_.addState('R', "Running", this, &RunControlStateMachine::stateRunning);
00027 theStateMachine_.addState('P', "Paused", this, &RunControlStateMachine::statePaused);
00028 theStateMachine_.addState('X', "Shutdown", this, &RunControlStateMachine::stateShutdown);
00029
00030
00031
00032
00033
00034
00035
00036 theStateMachine_.setStateName('F',RunControlStateMachine::FAILED_STATE_NAME);
00037 theStateMachine_.setFailedStateTransitionAction (this, &RunControlStateMachine::enteringError);
00038 theStateMachine_.setFailedStateTransitionChanged(this, &RunControlStateMachine::inError);
00039
00040
00041 theStateMachine_.addStateTransition('F', 'H', "Halt" , "Halting" , this, &RunControlStateMachine::transitionHalting);
00042
00043
00044
00045 theStateMachine_.addStateTransition('H', 'C', "Configure" , "Configuring" , "ConfigurationAlias", this, &RunControlStateMachine::transitionConfiguring);
00046 theStateMachine_.addStateTransition('H', 'X', "Shutdown" , "Shutting Down", this, &RunControlStateMachine::transitionShuttingDown);
00047 theStateMachine_.addStateTransition('X', 'I', "Startup" , "Starting Up" , this, &RunControlStateMachine::transitionStartingUp);
00048
00049
00050 theStateMachine_.addStateTransition('I', 'H', "Initialize", "Initializing" , this, &RunControlStateMachine::transitionInitializing);
00051 theStateMachine_.addStateTransition('H', 'H', "Halt" , "Halting" , this, &RunControlStateMachine::transitionHalting);
00052 theStateMachine_.addStateTransition('C', 'H', "Halt" , "Halting" , this, &RunControlStateMachine::transitionHalting);
00053 theStateMachine_.addStateTransition('R', 'H', "Abort" , "Aborting" , this, &RunControlStateMachine::transitionHalting);
00054 theStateMachine_.addStateTransition('P', 'H', "Abort" , "Aborting" , this, &RunControlStateMachine::transitionHalting);
00055
00056 theStateMachine_.addStateTransition('R', 'P', "Pause" , "Pausing" , this, &RunControlStateMachine::transitionPausing);
00057 theStateMachine_.addStateTransition('P', 'R', "Resume" , "Resuming" , this, &RunControlStateMachine::transitionResuming);
00058 theStateMachine_.addStateTransition('C', 'R', "Start" , "Starting" , this, &RunControlStateMachine::transitionStarting);
00059 theStateMachine_.addStateTransition('R', 'C', "Stop" , "Stopping" , this, &RunControlStateMachine::transitionStopping);
00060 theStateMachine_.addStateTransition('P', 'C', "Stop" , "Stopping" , this, &RunControlStateMachine::transitionStopping);
00061
00062
00063
00064 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Initialize", XDAQ_NS_URI);
00065 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Configure" , XDAQ_NS_URI);
00066 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Start" , XDAQ_NS_URI);
00067 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Stop" , XDAQ_NS_URI);
00068 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Pause" , XDAQ_NS_URI);
00069 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Resume" , XDAQ_NS_URI);
00070 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Halt" , XDAQ_NS_URI);
00071 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Abort" , XDAQ_NS_URI);
00072 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Shutdown" , XDAQ_NS_URI);
00073 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Startup" , XDAQ_NS_URI);
00074 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Fail" , XDAQ_NS_URI);
00075 xoap::bind(this, &RunControlStateMachine::runControlMessageHandler, "Error" , XDAQ_NS_URI);
00076
00077
00078 reset();
00079 }
00080
00081
00082 RunControlStateMachine::~RunControlStateMachine(void)
00083 {
00084 }
00085
00086
00087 void RunControlStateMachine::reset(void)
00088 {
00089 __COUT__ << "Resetting RunControlStateMachine with name '" << stateMachineName_ << "'..." << __E__;
00090 theStateMachine_.setInitialState('I');
00091 theStateMachine_.reset();
00092 }
00093
00094
00095 xoap::MessageReference RunControlStateMachine::runControlMessageHandler(
00096 xoap::MessageReference message)
00097 throw (xoap::exception::Exception)
00098 {
00099 __COUT__ << "Starting state for " << stateMachineName_ << " is " <<
00100 theStateMachine_.getCurrentStateName() << std::endl;
00101 __COUT__ << SOAPUtilities::translate(message) << std::endl;
00102
00103 theStateMachine_.setErrorMessage("");
00104
00105 std::string command = SOAPUtilities::translate(message).getCommand();
00106
00107 theProgressBar_.reset(command,stateMachineName_);
00108 RunControlStateMachine::theProgressBar_.step();
00109
00110 std::string result = command + "Done";
00111
00112
00113
00114 if(command == "Error" || command == "Fail")
00115 {
00116 __SS__ << command << " was received! Halting immediately." << std::endl;
00117 __COUT_ERR__ << "\n" << ss.str();
00118
00119 try
00120 {
00121 if(theStateMachine_.getCurrentStateName() == "Configured")
00122 theStateMachine_.execTransition("Halt",message);
00123 else if(theStateMachine_.getCurrentStateName() == "Running" ||
00124 theStateMachine_.getCurrentStateName() == "Paused")
00125 theStateMachine_.execTransition("Abort",message);
00126 }
00127 catch(...)
00128 {
00129 __COUT_ERR__ << "Halting failed in reaction to Error... ignoring." << __E__;
00130 }
00131 return SOAPUtilities::makeSOAPMessageReference(result);
00132 }
00133
00134
00135
00136
00137 if(command == "Initialize" &&
00138 theStateMachine_.getCurrentStateName() == "Halted")
00139 {
00140 __COUT__ << "Already Initialized.. ignoring Initialize command." << std::endl;
00141 return SOAPUtilities::makeSOAPMessageReference(result);
00142 }
00143
00144
00145 try
00146 {
00147 theStateMachine_.execTransition(command,message);
00148
00149
00150 if(theStateMachine_.getCurrentStateName() == RunControlStateMachine::FAILED_STATE_NAME)
00151 {
00152 result = command + " " + RunControlStateMachine::FAILED_STATE_NAME + ": " + theStateMachine_.getErrorMessage();
00153 __COUT_ERR__ << "Unexpected Failure state for " << stateMachineName_ << " is " << theStateMachine_.getCurrentStateName() << std::endl;
00154 __COUT_ERR__ << "Error message was as follows: " << theStateMachine_.getErrorMessage() << std::endl;
00155 }
00156 }
00157 catch (toolbox::fsm::exception::Exception& e)
00158 {
00159 result = command + " " + RunControlStateMachine::FAILED_STATE_NAME + ": " + theStateMachine_.getErrorMessage();
00160 __SS__ << "Run Control Message Handling Failed: " << e.what() << std::endl;
00161 __COUT_ERR__ << "\n" << ss.str();
00162 __COUT_ERR__ << "Error message was as follows: " << theStateMachine_.getErrorMessage() << std::endl;
00163 }
00164
00165 RunControlStateMachine::theProgressBar_.step();
00166 theProgressBar_.complete();
00167
00168 __COUT__ << "Ending state for " << stateMachineName_ << " is " << theStateMachine_.getCurrentStateName() << std::endl;
00169 __COUT__ << "result = " << result << std::endl;
00170 return SOAPUtilities::makeSOAPMessageReference(result);
00171 }
00172