Advanced programming
In this chapter you learn how to program classes for dynamic instantiation (workflows). Before reading any further here, please first familiarize yourself with workflows from the user's point of view.
The following class diagram is an extension of the class diagram for process applications from the previous chapter:
Workflow classes can be categorized according to various aspects:
PWBase is derived from PABase and is the base class of all workflow classes. She takes on the following tasks:
Workflow classes are only instantiated during runtime and loaded into the application tree. So that these workflow instances can also be restored when the iPlus service is restarted, the application tree is saved in the ACClassTask table . You can access the ACClassTask Entity object via the "Content" property , which has already been explained in the section on "Programming an ACComponent".
When the program flow has reached the end of the workflow , the instances (workflow nodes) are unloaded from the application tree and the corresponding ACClassTask entries are deleted.
When a workflow class is instantiated, the ACIdentifier is set in the overwritten method InitACIdentifier (). The ACIdentifier is set with the ACIdentifier of the ACClassWF table entry (ACClassWF entries are created when the workflow is edited with the graphical editor) . Only the ACIdentifier of the root node , which is a derivative of the PWProcessFunction class, also receives a consecutive instance number.
In the following figure, the root node (F) receives the ACIdentifier "MixeryDef (1) ". The second root node that was loaded from the same workflow template receives the ACIdentifier "MixeryDef (2) ". These consecutive instance numbers are displayed in the process control at the bottom right in the "ID" column of the datagrid (3):
PWBase implements the IACComponentPWNode interface :
public interface IACComponentPWNode : IACComponent, IACObjectDesign, IACConfigURL, IACConfigStoreSelection, IACConfigMethodHierarchy
IACComponentPWNode is declared in such a way that the interfaces IACConfigUrl, IACConfigStoreSelection and IACConfigMethodHierarchy must also be implemented so that a workflow class is fully configurable and supports the reading of overwritten configuration memories . To fill the parameter list of a virtual method, PWBase provides the following method:
public virtual bool GetConfigForACMethod(ACMethod paramMethod, bool isForPAF, params Object[] acParameter)
Derivatives that either want the configuration parameters of the workflow class itself or the parameters for a function call to be filled call this method.
Name | description |
---|---|
IACObject Content | Returns the ACClassTask object (Entity Framework) that is used to store the application tree. |
ACClassWF ContentACClassWF | Reference to the definition of the workflow node. (Arises from the graphic editing of the workflow) |
PWProcessFunction RootPW IACComponentPWNode ParentRootWFNode | Reference to the root node of the loaded workflow. If the instance itself is a root node, then the this pointer is returned. |
IACComponentPWGroup GroupPWComponent | Returns the "surrounding" workflow group node to which this node belongs. |
IACWorkflowContext WFContext | Returns an ACProgram instance (ContentTask.ACProgram) so that the configuration data can be read and saved. |
ACProgramLog CurrentProgramLog | Current log of the workflow node. |
IEnumerable<ACProgramLog> PreviousProgramLogs | Past logs of the workflow node. |
ACProgramLog ParentProgramLog | Parent node log. |
ACProgramLog PreviousParentProgramLog | Parent node's past log. |
string ConfigACUrl | ACUrl for accessing the IACConfig entries from an IACConfigProvider. |
string PreValueACUrl | ACUrl of the caller. |
List<ACClassMethod> ACConfigMethodHierarchy | Hierarchy of the sub-workflow calls. |
List<IACConfigStore> MandatoryConfigStores | Configuration memory overwrite sequence. |
When programming your own workflow class, it is sometimes necessary to know how the end user created the workflow. Specifically, this means that you want to explore the "environment" of the outgoing node, which predecessor and successor nodes exist. The following methods are used for this:
public List<TResult> FindPredecessors<TResult>(bool inSameGroup, Func<PWBase, bool> selector, Func<PWBase, bool> deselector = null, int maxRecursionDepth = 0)
where TResult : PWBase
public List<TResult> FindSuccessors<TResult>(bool inSameGroup, Func<PWBase, bool> selector, Func<PWBase, bool> deselector = null, int maxRecursionDepth = 0)
where TResult : PWBase
Use these methods like the search functions of the ACComponent class . In contrast to the search functions of the ACComponent class, which search within the application tree (parent / child), the workflow search functions search via the edges of the workflow. From a technical point of view, you go through the references (ConnectionList) of the event points and select the elements that the transferred selector delegate (search condition) has found. Use the deselector delegate to cancel further searches.
Application example:
PWNodeCheckWeighing checkWeighing = this.FindSuccessors<PWNodeCheckWeighing>(false, c => c is PWNodeCheckWeighing, null, 1).FirstOrDefault();
A PWProcessFunction (workflow process function) represents the root node of a loaded workflow. The ACIdentifier of the instance is supplemented with a consecutive instance number for each new loaded workflow that is dynamically added to the application tree . Please read the previous section "PWBase".
PWProcessFunction implements the IACComponentProcessFunction interface and is therefore comparable to a normal process function because it can be activated by an asynchronous call to the Start () method . In contrast to a function that is statically declared and instantiated in the physical model, the workflow process function is instantiated dynamically by calling the "ACComponent.StartWorkflow ()" method. StartWorkflow () is just a special form of a method call in which the method name corresponds to the workflow name that was assigned during the graphic creation.
Since workflows other sub-workflows can call, they will be charged by Start workflow (); only with the difference that this is done automatically by the workflow class "PWNodeProcessWorkflow". The asynchronous call can be queried via the property . As with normal process functions, the asynchronous call takes place via the ParentACComponent, which implements IACComponentTaskExec . With normal process functions it is the process module, with workflows it is the ApplicationManager class ( root of the application tree), because workflows are always added as child elements of the ApplicationManager and also thepublic ACPointAsyncRMIWrap<ACComponent> CurrentTask
"Methods" or workflows are declared there.
PWProcessFunction is provided with the attribute class ACClassConstructorInfo:
[ACClassConstructorInfo( new object[] {
new object[] {ACProgram.ClassName, Global.ParamOption.Required, typeof(Guid)},
new object[] {ACProgramLog.ClassName, Global.ParamOption.Optional, typeof(Guid)}
} )]
This means that an instantiation or construction of this class urgently requires an ACProgram table entry. In the figurative sense, an ACProgram is comparable to the double-click of a Windows application, in which a program is called (main method) and under which all tasks carried out by the program are logged. The log data are written to the ACProgramLog table. Subprogram calls (subworkflows that are started) are also saved under the same ACProgram. Only when the workflow that was started first has been processed and unloaded from the application tree is an ACProgram no longer written and is only used for later tracking via the ProgramLog Viewer.
The following example shows how an ACProgram is created and a workflow is started (the example comes from the BSOInOrder class from the example project):
In step 6, a second parameter "InOrder" was set with the InOrderID. This is because, instead of the PWProcessFunction, the derived class PWProcFuncOrder from the sample project is to be instantiated, which has declared this additional parameter in its ACClassConstructorInfo declaration. This parameter is necessary so that the class knows which data context it has to work with. When creating the workflow, it must be specified in the "Class to be instantiated of the root node" field that PWProcFuncOrder is to be used as the root class.
Let's now look at how the example class PWProcFuncOrder is programmed:
Name | description |
---|---|
IACContainerTNet<ACMethod> CurrentACMethod | The virtual method (ACMethod) with which this workflow was started. |
ACPointAsyncRMIWrap<ACComponent> CurrentTask | If the workflow was started asynchronously as a sub-workflow, this property is set. Accessing the ValueT property gives you a reference to the workflow node (class PWNodeProcessWorkflow) that started the asynchronous call. |
IACComponentTaskExec ParentTaskExecComp | Reference to the application manager who owns this workflow node as a child instance. |
PWNodeStart PWNodeStart | Start workflow node that this function starts so that workflow processing starts. |
WFDictionary WFDictionary | A dictionary that contains all child instances of this workflow node. The key is ACClassWF. |
IACContainerTNet<uint> ACSubState uint CurrentACSubState | A state property to be able to save further sub-states in addition to the ACState property. |
The PWNodeStart class is always the first workflow node (S) within a node that implements the IACComponentPWGroup interface (these are the PWProcessFunction and PWGroup classes). PWNodeStart implements the interface IPWNodeOut , which specifies the output event point " PWPointOut " of type ACPointEvent . Subsequent nodes within the group must be connected to this event point. The trigger point is triggered when the surrounding group has called the Start () method.
The PWNodeEnd class is always the last workflow node (E) within a node that implements the IACComponentPWGroup interface (these are the PWProcessFunction and PWGroup classes). PWNodeEnd implements the interface IPWNodeIn , which specifies the subscription point "PWPointIn" of type PWPointIn . The program flow within a group must be programmed so that it inevitably ends in "PWPointIn". PWNodeEnd then calls the GroupComplete () method in the associated group, which in turn triggers your initial event point.
The PWBaseInOut class is a combination of PWNodeStart and PWNodeEnd. It can receive events (input point of type PWPointIn) as well as send an output event (starting point of type ACPointEvent). It is therefore the base class for all other workflow classes.
The PWPointIn class is a special variant of a subscription point that is able to subscribe to the corresponding events of the starting points using the workflow edges (table ACClassWFEdge). It also offers properties to be able to query how many events have already been fired and to return the result AND - / OR - or EXUND - linked accordingly . An EXUND link is a special feature in iPlus, which means that only one output event was received and all other output events were not fired and the group of the workflow node to which they belong is not active.
These three classes are derivatives of PWBaseInOut and act as logic gates . You use the properties IsActiveAND, IsActiveOR and IsActiveExAND provided in PWPointIn to switch the logical gate.
PWBaseExecutable extends PWBaseInOut so that a workflow node can be configured. An ACMethod instance is created and the parameters are compiled using the overwritable configuration memory . The final configuration is provided in the CurrentACMethod and ExecutingACMethod properties.
PWBaseExcecutable is also the base class for all workflow nodes that remain in the ACState states for a certain time until their task is completed. Before a workflow node changes to the "Starting" state, it can be stopped by a breakpoint. This class provides some methods for this. It also reads the configuration memory when it starts and sets the breakpoint by itself.
All other classes that are explained in the following sections are derivatives of PWBaseExecutable:
PWGroup is on the one hand a derivative of PWBaseExecutable and on the other hand it implements the "IACComponentPWGroup" interface. Like PWProcessFunction, it is therefore able to have child workflow nodes. It contains a start and end node (PWNodeStart and PWNodeEnd) and should contain at least one node of the type "PWNodeProcessMethod". This is because "PWNodeProcessMethod" classes call functions asynchronously in the physical model . However, you are only allowed to do this if the associated process module has been occupied by the PWGroup instance by setting the "PAProcessModule .Semaphore "connected to the "PWGroup.TrySemaphore " client point . This process module allocation takes place in the "SMStarting" state and is removed again after all child workflow nodes have been processed and the end node triggers. PWGroup is then switched back from the "SMRunning" state to the "SMIdle" basic state.
This method is a cyclic method that is called cyclically as long as it has not transferred the state machine to the SMRunning state and has triggered the start node. Before the algorithm can be explained, you must first get to know the following properties of a PWGroup:
(A) PAProcessModule [] PossibleModuleList:
This list contains process modules that could theoretically be used by this workflow group. It selects all process modules that are a derivative of a class referenced by the property "ContentACClassWF.RefPAACClass". "ContentACClassWF.RefPAACClass" is a reference to a class in theapplication definition projectthat serves as the base class for the process modules in thephysical model(application).
(B) List <PAProcessModule> ProcessModuleList:
ProcessModuleList removes process modules from PossibleModuleList (A) that are not in automatic mode and do not comply with the routing rules. To apply the routing rules, it first reads the overwritable configuration stores(MandatoryConfigStores). Then all process modules are removed that cannot be reached by the previous process modules if the "RoutingCheck" propertyis set.
(C) List <PAProcessModule> AvailableProcessModuleList :
AvailableProcessModuleList removes process modules from ProcessModuleList (B) that are not used by other workflow groups.
(D) PAProcessModule FirstAvailableProcessModule :
Returns the first element from AvailableProcessModuleList (C) .
(E) bool HasHighestPriorityForMapping:
This property returns "true" if this workflow group has the highest priority in order to be allowed to occupy a process module first. For this purpose, all competing workflow group instances with the same "ContentACClassWF.RefPAACClass" are entered in a list, which are sorted according to the start date of their root workflow node (PWProcessFunction) ("ContentACClassWF.RefPAACClass" is a reference to a class in the application definition Project , which serves as the base class for the process modules in the physical model). This priority list can bequeriedusing the property IEnumerable <PWGroup > PriorizedCompetingWFNodes .
(F) bool NeedsAProcessModule :
This property returns "true" if this workflow group has to be connected to a process module (this is the default setting ). The "WithoutPM" configuration property can be used to set that a workflow group should only be used to organize child nodes that are not derivatives of PWNodeProcessMethod.
(G) bool OccupationByScan:
This configuration property specifies that a process module is occupied by a scan event. For this purpose, the corresponding process modules must have a PAFWorkTaskScanBase instance as a subordinate element. The PAFWorkTaskScanBase instance calls the OccupyWithPModuleOnScan () method to put this workflow node into the running state. The standard is FALSE!
SMStarting method algorithm:
bool OnHandleAvailableProcessModule(PAProcessModule processModule)
The SMCompleted state becomes active when the end node (PWNodeEnd) is reached. The status method SMCompleted () calls the method ReleaseAllAccessedModules () to release the occupied process module again. Then it triggers the PWPointOut event and calls the Reset () method to return to the basic state.
"gip.mes.processapplication.PWGroupVB" is a derivative of PWGroup for the MES functionality. It works with the MES tables for production orders, delivery notes and picking orders. These tables contain information about where a product should be transported. PWGroupVB then prevents the use of process modules that cannot lead to the final goal. For this reason, PWGroupVB overwrites ProcessModuleList (B) in order to filter out those process modules that cannot be used. The routing service is used to calculate the possible destinations.
Another feature of PWGroupVB is that it does not occupy a process module at all if there is no material to be processed, so that other workflows do not have to wait unnecessarily. You set this with the configuration property "SkipIfNoComp".
PWBaseNodeProcess extends PWBaseExecutable by a more extensive state machine . It will be the
The SMCompleted status is either set directly in the derivatives or by the callback method
public virtual void TaskCallback(IACPointNetBase sender, ACEventArgs e, IACObject wrapObject).
PWBaseNodeProcess receives this method through the implementation of the IACComponentTaskSubscr interface . IACComponentTaskSubscr is the counterpart to the IACComponentTaskExec interface to provide the necessary subscription point for asynchronous calls .
PWNodeProcessMethod enables functions to be started in the physical model (asynchronously). The parameter list is transferred as a virtual method (ACMethod) . Which virtual method to be used is, in the property " ContentACClassWF. RefPAACClassMethod determined" that the design of the workflow has been set by the workflow editor. The parameters, as well as the configuration properties, are compiled by the overwritable configuration stores ( MandatoryConfigStores ) by using the " PWBase . GetConfigForACMethod() "is called and an empty ACMethod (Template) is passed. This logic is implemented in the overwritten status method SMStarting (). If the function was started successfully, the status SMRunning is changed.
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 workflow class:
This example class is intended for the use of the example function PAFOrder from the previous chapter.
Finally, an important note : Always override the "SMIdle ()" method to reset your private field values. In the SMIdle state, a workflow node must always be brought into the basic state - as it was originally created in the heap during generation!
The following derivations exist in the assembly gip.mes.processapplication:
great | description |
---|---|
PWDosing | Class that is responsible for processing input materials that are assigned to an intermediate product . The intermediate product, in turn, is linked via the material workflow with one or more workflow nodes that are of this PWDosing class. PWDosing is used for fully automatic production. It calls the process function PAFDosing asynchronously in order to delegate the real-time critical tasks to a PLC controller. Consumed quantities are debited by warehouse management (ACFacilityManager). It can work with different data contexts (production and picking orders). |
PWDischarging | Class that is responsible for transporting materials from one point to another. These can either be raw materials, intermediate products or end products . The workflow node can also be linked to an intermediate product in a material workflow . PWDischarging is used for fully automatic production. It calls the process function PAFDischarging asynchronously in order to delegate the real-time critical tasks to a PLC controller. Manufactured, stored or relocated quantities are booked via warehouse management (ACFacilityManager). It can work with different data contexts (production and picking orders or delivery notes). |
PWManualWeighing | Class that is responsible for processing input materials that are assigned to an intermediate product . The intermediate product, in turn, is linked to one or more workflow nodes via the material workflow , which are of this class PWManualWeighing. PWManualWeighing is used to support manual production. It calls the process function PAFManualWeighing asynchronously. Operator guidance is provided by the BSOManualWeighing business object, which is a plug-in for the BSOWorkCenter business object. Consumed quantities are debited by warehouse management (ACFacilityManager). It can work with different data contexts (production and picking orders). |
PWBinSelection | |
PWBinDischarging | |
PWMixing | |
PWCooling | |
PWDrying | |
PWExtruding | |
PWLoad | |
PWUnload | |
PWSampleWeighing | |
PWScanning | |
PWVacuum | |
PWWorkTaskScanBase |
We use cookies to provide you with the best possible experience. They also allow us to analyze user behavior in order to constantly improve the website for you.