OCSEPICS
Class OCSAction

java.lang.Object
  extended by java.util.TimerTask
      extended by OCSEPICS.EPICSAction
          extended by OCSEPICS.OCSAction
All Implemented Interfaces:
FourMSControllerInterfaces.SubActionOperations, java.lang.Runnable, CAEventListener

 class OCSAction
extends EPICSAction
implements CAEventListener

This class will be used to perform a specific action upon a mechanism in the ISISP/WYFFOS/INTEGRAL EPICS system. The INTEGRAL/ISISP/WYFFOS EPICS system is controlled slightly differently to those which use CAD/CAR so there is a need to specialise in order to control these mechanisms. The class is data driven from source data that originates in the OCS database.

It will interrogate the ICS database in order to establish the names of the PVs which it will need to use in order to execute OCS related actions upon the IOC. The protocol used in initiating actions upon the ISISP mechanisms is outlined in the document wht-isis-9. ISISP does not have CAD/CAR/SIR support, there are a series of PVs associated with a given subaction which must be manipulated and monitored in ordered to successfully execute an operation on the IOC. It should be noted that the documentation is not strictly correct and to acheive a full understanding of the protocol the user should read through the source code also.

The class employs a state machine in order to maintain the state of the underlying hardware which it is controlling. Due to the nature of the implmentation of the underlying controlling software which not orthogonal, this is at times a little chaotic.

The state machine has the following states associated with it :

State Transition Method Description
UNINITIALISED OCSAction(JICSCore.MessageHandler, java.sql.Connection, java.lang.String, java.lang.String, java.lang.String, java.util.Hashtable, JICSCore.OCSCORBAHelper, int, FourMS.FourMSParameterConverter, OCSEPICS.EPICSMechanism) Initial state of the action until it is initialised.
INACTIVE actionInactive(java.lang.String) Action is inactive, action is not controlling it's associated mechanism in anyway
COMMAND_PROCESSING commandProcessing(java.lang.String, ing.status.StatusItemValue) CORBA request has been received from external client and IOC has been instructed to perform the action and it is currently analyzing the command request to ensure that it is a valid demand i.e. demand argument is in the correct type and range.
COMMAND_ACCEPTED commandAccepted(java.lang.String, ing.status.StatusItemValue) IOC has verified that the command request which was received through an external CORBA client and that it will attempt to execute the command.
ACTIVE actionActive(java.lang.String, ing.status.StatusItemValue) The IOC is performing the request command. A mechanism in the IOC may or may not be moving at this point. An example action might be a move, stop or datum.
TIMED_OUT actionTimedOut() The IOC has taken longer than the timeout period which is associated with this action to complete.
COMPLETED actionCompleted(java.lang.String, ing.status.StatusItemValue, boolean) The IOC has completed the requested action and the CORBA client will be informed of it's completion. The action may or may not have completed successfully (for example in the case of a mechanism error).

Version:
$Id: OCSAction.java,v 1.6 2007/03/02 10:31:02 cb Exp $
Author:
Craige Bevil

Field Summary
private  OCSEPICSConsts.OCSActionStatesType ActionState
          This is the current state that the action has reached in the state machine.
private  java.lang.String CommStat
          This is the last value for the COMMSTAT PV which indicates whether or not the last command was accepted OK or not.
private  java.lang.String CommStr
          This is the last value for the COMMSTR PV which indicates whether or not the last command to be attempted was accepted without problems or not.
private  java.lang.String CommStrOkValue
          This is the value which indicates that the commstr does not contain an error.
private  java.lang.String ErrStr
          This is the current ERRSTR which is associated with the mechanism.
private  java.util.Hashtable<OCSEPICSConsts.PVTypes,ProcessVariable> IOCProcessVariables
          This hashtable contains a reference to all of the process variables which will be needed in order to perform actions on the mechanisms on the IOC.
private  EPICSMechanism Mechanism
          The EPICS mechanism.
private  int MechStat
          This is the current MECHSTAT which is associated with the mechanism which is the basis for the action.
private  OCSEPICSConsts.OCSActionStatesType NextEventTriggeredState
          This is the next expected state that the state machine should move to should the expected transition take place.
private  OCSEPICSConsts.PrematureClStatStates PrematureCLStatState
          Whether we have a received a clstat transition between ACTIVE and DONE before command processing has been completed by the IOC.
 
Fields inherited from class OCSEPICS.EPICSAction
ActionRelatedPVs, ClstatPV, CommPV, CommStatPV, CommStrPV, CORBAHelper, CurrentPositionPV, DemandPV, ErrStrPV, ExpectedNumberOfSubactionArguments, InstrumentName, IOCAction, iocActionState, LastSubactionCompletionState, MechName, MechStatPV, ParameterConvertor, SecondsBeforeTimeout, SubActionInitiatorCB, SubactionName, SubactionState, SubactionTimeout, SubActionTimer, SyslogMessageHandler, TimeoutPV
 
Fields inherited from interface OCSEPICS.CAEventListener
UnitOfInterest
 
Constructor Summary
OCSAction(MessageHandler SyslogMessageHandler, java.sql.Connection DBConnection, java.lang.String SubactionName, java.lang.String MechName, java.lang.String InstrumentName, java.util.Hashtable<java.lang.String,ProcessVariable> ActionRelatedPVs, OCSCORBAHelper CORBAHelper, int SubactionTimeout, FourMS.FourMSParameterConverter ParameterConvertor, EPICSMechanism Mechanism)
          The constructor for the class.
 
Method Summary
private  boolean actionActive(java.lang.String PVName, ing.status.StatusItemValue StatusItem)
          This is the part of the state machine for the OCS actions and performs the actions required once the EPICS action is active in the IOC.
private  boolean actionCompleted(java.lang.String PVName, ing.status.StatusItemValue StatusItem, boolean ForceState)
          This is the part of the state machine for the OCS actions and performs the actions required when the action in the IOC completes successfully.
private  boolean actionInactive(java.lang.String ReasonForTransition)
          This method forms part of the action state machine and will be called when the action is in state inactive.
protected  boolean actionTimedOut()
          This is the part of the state machine for the OCS actions and performs the actions required should the command that we issued to the IOC timeout in it's execution.
 boolean cancelAction()
          Cancels an existing subaction if it is running but raises an exception otherwise.
 void channelAccessEvent(java.lang.String PVName, ing.status.StatusItemValue StatusItem)
          Obligation of the CAEventListener interface.
private  boolean commandAccepted(java.lang.String PVName, ing.status.StatusItemValue StatusItem)
          This is the part of the state machine for the OCSAction and performs the actions required when we are expecting to go to state COMMAND_ACCEPTED from state COMMAND_PROCESSING.
private  boolean commandProcessing(java.lang.String PVName, ing.status.StatusItemValue StatusValue)
          This method will be called as part of the event driven transition of the action state machine.
 void finalize()
           
private  void initiateEPICSCommand()
          This is the part of the state machine for the OCS actions and performs the action required when the command has been issued to IOC and we are waiting for it to accept the command.
private  void initiateEPICSCommand(java.lang.String demandValue)
          This is the part of the state machine for the OCS actions.
 void observerUnableToListen(java.lang.String PVName, java.lang.String reason)
          Obligation of the CAEventListener interface.This method is called when the observer is unable to listen a PV any longer
 void resetStateMachine(java.lang.String Reason)
          Resets the state machine which models the OCS action.
 void setCommStrOkValue(java.lang.String CommStrOkValue)
          Used to set the value of the COMMSTR PV which is used to indicate that the command was requested was validated successfully.
 boolean startAction(java.lang.String[] SubActionArgs, FourMSControllerInterfaces.SubActionCompletionListener SubActionInitiatorCB)
          This is the obligation of the SubActionOperations IDL interface which will be used by an external CORBA client to invoke this subaction.
 
Methods inherited from class OCSEPICS.EPICSAction
run
 
Methods inherited from class java.util.TimerTask
cancel, scheduledExecutionTime
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

Mechanism

private EPICSMechanism Mechanism
The EPICS mechanism.


PrematureCLStatState

private OCSEPICSConsts.PrematureClStatStates PrematureCLStatState
Whether we have a received a clstat transition between ACTIVE and DONE before command processing has been completed by the IOC. If this happens, we have to reset the state machine once command processing has completed.


ErrStr

private java.lang.String ErrStr
This is the current ERRSTR which is associated with the mechanism. It holds a textual description of any problems that may be associated with the mechanism.


MechStat

private int MechStat
This is the current MECHSTAT which is associated with the mechanism which is the basis for the action. This is normally an integer number which indicates any error that may have occured. This will correspond to a code in the message catalogue in the OCS database which contains a textual description of the error.


CommStr

private java.lang.String CommStr
This is the last value for the COMMSTR PV which indicates whether or not the last command to be attempted was accepted without problems or not. If it wasn't it includes the reason why the command was not accepted by the IOC.


CommStat

private java.lang.String CommStat
This is the last value for the COMMSTAT PV which indicates whether or not the last command was accepted OK or not.


CommStrOkValue

private java.lang.String CommStrOkValue
This is the value which indicates that the commstr does not contain an error. This is is set to OK to indicate that the command was validated without any problems.


ActionState

private OCSEPICSConsts.OCSActionStatesType ActionState
This is the current state that the action has reached in the state machine. By default it is in state UNINTIALISED until the state machine is intialised.


NextEventTriggeredState

private OCSEPICSConsts.OCSActionStatesType NextEventTriggeredState
This is the next expected state that the state machine should move to should the expected transition take place. This variable will hold the next expected state. In the case of starting a command off, we expect to move to state COMMAND_PROCESSING for instance but we will only get to that state when we get an event back from the IOC which informs us that command processing is taking place.


IOCProcessVariables

private java.util.Hashtable<OCSEPICSConsts.PVTypes,ProcessVariable> IOCProcessVariables
This hashtable contains a reference to all of the process variables which will be needed in order to perform actions on the mechanisms on the IOC.

Constructor Detail

OCSAction

public OCSAction(MessageHandler SyslogMessageHandler,
                 java.sql.Connection DBConnection,
                 java.lang.String SubactionName,
                 java.lang.String MechName,
                 java.lang.String InstrumentName,
                 java.util.Hashtable<java.lang.String,ProcessVariable> ActionRelatedPVs,
                 OCSCORBAHelper CORBAHelper,
                 int SubactionTimeout,
                 FourMS.FourMSParameterConverter ParameterConvertor,
                 EPICSMechanism Mechanism)
          throws java.lang.Exception
The constructor for the class.

Parameters:
SubactionName - This is the name which is associated with subaction.
SyslogMessageHandler - This will be used for reporting information to the syslog which is running on the whtics.
DBConnection - This is an open JDBC connection to the whtics database.
MechName - This is the name of the mechanism with which this action is associated.
InstrumentName - This is the name of the instrument with which this action is associated.
ActionRelatedPVs - This is a hashtable of PVs within which we can expect to find all of the PVs which this subaction is going to need to use in order to perform it's tasks.
CORBAHelper - This will be used to perform OCS related CORBA activities.
SubactionTimeout - This is the timeout before the subaction is deemed to have failed.
ParameterConvertor - This will be used to convert parameters between logical and engineering units.
Throws:
java.lang.Exception - Should there be an error when initialising the object.
Method Detail

setCommStrOkValue

public void setCommStrOkValue(java.lang.String CommStrOkValue)
Used to set the value of the COMMSTR PV which is used to indicate that the command was requested was validated successfully.


finalize

public void finalize()
              throws java.lang.Throwable
Overrides:
finalize in class EPICSAction
Throws:
java.lang.Throwable

actionInactive

private boolean actionInactive(java.lang.String ReasonForTransition)
This method forms part of the action state machine and will be called when the action is in state inactive. Should we go into this state from any state other than UNINITIALISED, we have to assume that an external CORBA was initially responsible for the transitioning the state machine and in which case, we need to inform the CORBA client that the action is now completed as as part of the state transition. The method will establish if the action that was requested completed successfully or not and the CORBA client will instructed accordingly with respect to the completion state of the action.

Parameters:
ReasonForTransition - This is the reason that we have been requested to move to this state.
Returns:
boolean True if we managed to transition to state INACTIVE without problem.

initiateEPICSCommand

private void initiateEPICSCommand(java.lang.String demandValue)
                           throws StateMachineException
This is the part of the state machine for the OCS actions. This method will be called when an external client of the OCS control system wishes to invoke an action. It initiates an action in the IOC providing that neither it nor ourselves is considered to be active. The OCS state machine must be in state INACTIVE before any action will be taken by this method.

In order to transition to this state there are a number of preconditions which are listed as follows;

Once the preconditions have been met, we can then write to the demand value PV (if required) and if this is successfully performed we can then finally transition to the state COMMAND_PROCESSING.

Parameters:
demandValue - This is the demand value for the move. It can be null if there is no demand value associated with this IOC action.
Throws:
StateMachineException - Should there be any problem transitioning to the state COMMAND_PROCESSING

initiateEPICSCommand

private void initiateEPICSCommand()
                           throws StateMachineException
This is the part of the state machine for the OCS actions and performs the action required when the command has been issued to IOC and we are waiting for it to accept the command. Note that it is not always the case that we have a demand parameter.

Throws:
StateMachineException

commandAccepted

private boolean commandAccepted(java.lang.String PVName,
                                ing.status.StatusItemValue StatusItem)
                         throws StateMachineException
This is the part of the state machine for the OCSAction and performs the actions required when we are expecting to go to state COMMAND_ACCEPTED from state COMMAND_PROCESSING. The method will be called as a result of an event on the COMMSTAT PV which is associated with this OCSAction. If the command is deemed to have been successfully accepted by the IOC then we move to state COMMAND_ACCEPTED and then our next event driven transition will be to state ACTIVE.

Parameters:
StatusItem - This is the details of an event on the commstat PV.
PVName - This is the name of the PV upon which the event occurred.
Returns:
boolean True if we actually transition to the new state
Throws:
StateMachineException - If we have been requested to transition from illegal states.

actionActive

private boolean actionActive(java.lang.String PVName,
                             ing.status.StatusItemValue StatusItem)
                      throws StateMachineException
This is the part of the state machine for the OCS actions and performs the actions required once the EPICS action is active in the IOC. We can only go to state ACTIVE when we are currently in state COMMAND_ACCEPTED and we have an event on the PV CLSTAT associated with this mechanism which indicates that mechanism is now moving.

Parameters:
PVName - This is the name of the PV upon which the event occurred.
StatusItem - This should hold the details of an event on the clstat PV which is associated with this OCS action.
Returns:
boolean True if we actually transition to the new state
Throws:
StateMachineException - This is an exception which is thrown if the state machine finds itself in an illegal state.

commandProcessing

private boolean commandProcessing(java.lang.String PVName,
                                  ing.status.StatusItemValue StatusValue)
                           throws StateMachineException
This method will be called as part of the event driven transition of the action state machine. Only when called when there is an event on commstat PV which is associated with this event will any further processing be performed. Should the PV event indicate that the command is being processed, we then transition to state COMMAND_PROCESSING.

Unfortunately not everything is as it seems. In the wyffos code at least there is the possibility of the clstat PV going to ACTIVE and back to DONE before the commstat PV has been set. This happens in the case of the lamps when they are switched off by the user. We need to deal with this as an exceptional case. Perhaps in time we can change the WYFFOS EPICS code so that this case is handled as other actions are handled.

Parameters:
PVName - This the name of the PV upon which the event occurred.
StatusValue - This holds the data associated with the event
Returns:
boolean True if we actually transition to the new state
Throws:
StateMachineException - When there is some error detacted when we attempt to establish whether or not we should transition the state machine.

actionTimedOut

protected boolean actionTimedOut()
                          throws StateMachineException
This is the part of the state machine for the OCS actions and performs the actions required should the command that we issued to the IOC timeout in it's execution. It can be called when the state machine is in any state and will result in a implicit state change to state INACTIVE.

Specified by:
actionTimedOut in class EPICSAction
Throws:
StateMachineException - Should there be an irregularity detected with state machine.

actionCompleted

private boolean actionCompleted(java.lang.String PVName,
                                ing.status.StatusItemValue StatusItem,
                                boolean ForceState)
                         throws StateMachineException
This is the part of the state machine for the OCS actions and performs the actions required when the action in the IOC completes successfully. This method will be called as a event on a PV when the state machine is in the state ACTIVE and needs to transition to state COMPLETED.

Parameters:
PVName - The name of the PV that the event occurred on.
StatusItem - This is the details of the event .
ForceState - Force a state change without checking for the legality of the transition request. Sometimes there will be a need to force our way into this state if we have two actions for the same mechanism running. This is certainly in teh case of the MOVE and the STOP command which both be active at the same time.
Returns:
boolean True if we actually transition to the new state
Throws:
StateMachineException - If there is a problem performing the state transition.

observerUnableToListen

public void observerUnableToListen(java.lang.String PVName,
                                   java.lang.String reason)
Obligation of the CAEventListener interface.This method is called when the observer is unable to listen a PV any longer

Specified by:
observerUnableToListen in interface CAEventListener
Parameters:
PVName - This is the name of the PV.
reason - This is the reason why the observer cannot listen any longer.

channelAccessEvent

public void channelAccessEvent(java.lang.String PVName,
                               ing.status.StatusItemValue StatusItem)
Obligation of the CAEventListener interface. This method will be called when there is an event on the monitored underlying PVs associated with this EPICS action and will passed a standard status item. It is the responsiblity of this method to provide the PV event driven transitions which move the EPICS action through it's state machine. Aside from the initial invocation of the EPICS action by a CORBA client, the movement through the state machine is driven by channel access events.

The values of other events on PVs which are not directly associated with state transitions are recorded as they will be needed later. For instance, the value of the MECHSTAT, ERRSTR and COMMSTR PVs which are associated with an action will be recorded.

Specified by:
channelAccessEvent in interface CAEventListener
Parameters:
PVName - This is the name of the PV which was responsible for the event
StatusItem - This contains the details of the event. The status item holds the logical value of the event after being converted from engineering units.

startAction

public boolean startAction(java.lang.String[] SubActionArgs,
                           FourMSControllerInterfaces.SubActionCompletionListener SubActionInitiatorCB)
                    throws FourMSControllerInterfaces.SubActionInProgressException,
                           FourMSControllerInterfaces.UnableToStartSubactionException
This is the obligation of the SubActionOperations IDL interface which will be used by an external CORBA client to invoke this subaction. This will be called for instance the WTFFOS or ISISP command line scripts.

Specified by:
startAction in interface FourMSControllerInterfaces.SubActionOperations
Parameters:
SubActionArgs - The arguments which need to be passed into this subaction
SubActionInitiatorCB - A CORBA object which will be called when the subaction completes.
Returns:
boolean True if the subaction can be started, in fact, it never returns false because if there was a problem then we will raise an exception instead.
Throws:
FourMSControllerInterfaces.SubActionInProgressException - When the action is already in progress.
FourMSControllerInterfaces.UnableToStartSubactionException - Unable to start the exception for the reason which is specified

cancelAction

public boolean cancelAction()
                     throws FourMSControllerInterfaces.SubActionNotInProgressException
Cancels an existing subaction if it is running but raises an exception otherwise. It will reset the state machine for the action back to state INACTIVE. The CORBA client which originally invoked the action will be informed that the action has been cancelled.

Specified by:
cancelAction in interface FourMSControllerInterfaces.SubActionOperations
Throws:
FourMSControllerInterfaces.SubActionNotInProgressException - SubActionNotInProgressException

resetStateMachine

public void resetStateMachine(java.lang.String Reason)
Resets the state machine which models the OCS action. This method will be called when there is an unexpected event and the state machine needs to be reset to a knownn state. The state of the machine after being reset will be INACTIVE. The CORBA client which invoked the action will be duly informed that the action has finished.

Parameters:
Reason - The reason why the state machine is being reset.