Before reading this section, familiarize yourself with the following concepts:
- Status-dependent methods
- Asynchronous methods
- Interface IACComponentTaskExec
- Physical model from the user's point of view .
PAProcessFunction is an abstract class. You need to derive them in order to use them. PAProcessFunction is programmed in such a way that it mainly consists of virtual methods and properties that can be overwritten if necessary in order to change the standard behavior. However, some of them have to be overwritten. Which these are is explained below using the example code.
Statusmethoden
For every ACStateEnum value that the ACState property can take, there is a corresponding status method :
public virtual void SMStarting()
public virtual void SMRunning()
public virtual void SMCompleted()
public virtual void SMResetting()
public virtual void SMPausing()
public virtual void SMPaused()
public virtual void SMResuming()
public virtual void SMHolding()
public virtual void SMHeld()
public virtual void SMRestarting()
public virtual void SMAborting()
public virtual void SMAborted()
public virtual void SMStopping()
public virtual void SMStopped()
These virtual methods are called either when the status changes or cyclically at one-second intervals. The cyclic call is activated by calling the "PABase . SubscribeToProjectWorkCycle ()" method and deactivated by the" PABase . UnSubscribeToProjectWorkCycle () method". PAProcessFunction uses these methods if an error has occurred so that a cyclical check is made to see whether the error status has been corrected in the meantime. UnSubscribeToProjectWorkCycle () is then called so that the processor is not unnecessarily loaded when there is nothing to do . If you want to monitor such error states in your derivation at cyclical intervals, then use these two methods as well. The cyclic calls are made by the PABase class in the DoWork () method . It reads the ACState variable and looks in the method list, whether there is a method with the same name. If the method is found, then this is called. In the method list only the methods are listed that start withACMethodState attribute class and the IsPeriodic property is set to true . This is the case with the methods listed above. Example:
[ACMethodState("en{'Starting'}de{'Startend'}", 20, true)]
public virtual void SMStarting()
Transitions-Methoden
Changes of state occur through so-called "transitions" , which are either executed automatically in the background or through UI interaction in which the user calls one of the transition methods:
public virtual void Pause()
public virtual void Resume()
public virtual void Hold()
public virtual void Restart()
public virtual void Abort()
public virtual void Stopp()
public virtual void Reset()
[ACMethodAsync("Process", "en{'Start'}de{'Start'}", (short)MISort.Start, false)]
public virtual ACMethodEventArgs Start(ACMethod acMethod)
The start method differs from the other transition methods in that it is an asynchronous method for starting the process function at all.
The call of transition methods is secured by the corresponding IsEnabled method so that invalid state transitions do not take place. Which state transitions are permitted is defined using state transition tables. The state transition table for ACState is in the abstract base class gip.core.autocomponent. PAFuncStateConvBase implemented.
State transition table PAFuncStateConvBase
Two static methods are defined in PAFuncStateConvBase with which the standard state transition table can be queried:
public static ACStateEnum GetDefaultNextACState(ACStateEnum acState, string transitionMethod = "")
public static bool IsEnabledTransitionDefault(ACStateEnum acState, string transitionMethod, PAProcessFunction paProcessFunction)
GetDefaultNextACState () returns the next subsequent state, depending on the current state transferred in the "acState" parameter. The second optional parameter specifies which transition or transition method is called. The names of the transition methods are declared in the constants of the static class ACStateConst:
ACStateConst.TMStart, ACStateConst.TMRun, ACStateConst.TMPause, ACStateConst.TMResume, ACStateConst.TMHold, ACStateConst.TMRestart, ACStateConst.TMAbort, ACStateConst.TMStopp, ACStateConst.TMReset
If the parameter "transitionMethod" is left blank, returns the standard successor state. Otherwise the next state that will occur when the corresponding transition method is called.
The "IsEnabledTransistionDefault ()" method returns which transition method may be called in a certain state.
Individual state transition table
If you want to program a different state machine or you have connected an external system (e.g. via a PLC or OPC connection) that uses other variables with which another state machine is implemented and this must be transferred to the iPlus state machine, then route Deselect the PAFuncStateConvBase class and add your class as a child component of the PAProcessFunction. The following methods must be implemented in your " converter class" :
public abstract ACStateEnum GetNextACState(PAProcessFunction sender, string transitionMethod = "");
public abstract bool IsEnabledTransition(PAProcessFunction sender, string transitionMethod);
public abstract MsgWithDetails SendACMethod(PAProcessFunction sender, ACMethod acMethod);
public abstract PAProcessFunction.CompleteResult ReceiveACMethodResult(PAProcessFunction sender, ACMethod acMethod, out MsgWithDetails msg);
A process function calls the instance method "GetNextACState ()" implemented by you instead of the static method "GetDefaultNextACState" and the instance method" IsEnabledTransition ()" instead of the static method " IsEnabledTransistionDefault ()".
In the SMStarting state, the basic implementation calls the " SendACMethod ()" method so that the parameters are sent to the external system. In the SMCompleted state, however, "ReceiveACMethodResult ()" is called to query the result from the external system. You must also program these two methods in your converter class .
Converter classes usually have further network-compatible destination properties declared, which in turn are linked to source properties of communication driver classes by property binding. These properties basically reflect the "state machine of their own standard". Program your converter class event- oriented so that you react to change events of these properties and transfer them to the ACState state machine and set the CurrentACState property of the parent process function (ParentACComponent) directly.
Example
The following program code was taken from the sample project, which you can download from the start page, in order to be able to understand the steps how to implement your own process function:
- Derive from PAProcessFunction. The ACClassInfo attribute class must be constructed as follows:
- Use Global.ACKinds .TPAProcessFunction to tell iPlus that it is a process function.
- "Global.ACStorableTypes .Required" must be used because, for example, the ACState property can be persisted and the state must be restored when the service is restarted.
- Reference the associated workflow class that is compatible with this process function. In this example it is "PWOrder .PWClassName" which you will get to know as an example in the following chapter (PWNodeProcessMethod) .
- Declare the parameter and return list of the virtual method (ACMethod) that is transferred when the start method is called asynchronously. Finally, generate an instance of ACMethodWrapper to announce the virtual method to the iPlus runtime by calling "RegisterVirtualMethod ()".
- Declare an Execute helper for the static calls by passing the static Execute handler as a delegate to the RegisterExecuteHandler () method.
- Override the start method and publish it using the ACMethodAsync attribute class .
- From this moment on, a process function is fully programmed and can be used in the iPlus development environment. However, the actual program code for what the function should actually do is still missing. This is why the SMRunning method has been overwritten in this code example and, for demonstration purposes, it waits for three cyclic calls because it was first activated with "SubscribeToProjectWorkCycle" and then the cyclic processing is deactivated with "UnSubscribeToProjectWorkCycle".
- In this step the actual functionality is programmed. In this example, the actual purpose is to write "order data" to a file that has been transferred by the asynchronous caller (workflow class) in the "Content" parameter. Because writing a file could take a long time, this writing process is transferred to the DelegateQueue of the root ACComponent ( application manager ). This means that the calling thread (cyclic processing) is not blocked and other functions are then used immediately.
- In the last step, you bring the state machine into the "SMCompleted" state. When the auxiliary property ACStateConverter not "zero" is , then you have added a separate converter class in the application tree as a child instance. In this case, your converter class decides what the next state will be - this could possibly also be a state other than "SMCompleted". When the auxiliary property ACStateConverter "zero" is the default implementation is used and SMCompleted returned.
Finally, an important note : Always override the "SMIdle ()" method to reset your private field values. In the SMIdle state, a function must always be brought to the basic state - as it was originally created in the heap when it was generated !