LMES Outbound Collection Logic Explanation
1. Introduction
1.1. Document Purpose
This document aims to elaborate on the internal implementation logic, technical architecture, and business process of the "Outbound Collection" function in the LMES system. It is mainly intended for technical developers, implementation consultants, and senior operation and maintenance personnel to help them deeply understand this functional module for secondary development, system configuration, and troubleshooting.
1.2. Scope of Application
This document applies to the LMES Manufacturing Execution System, especially modules related to production execution and process management.
1.3. Core Concept Definitions
- Outbound: In MES, a business node indicating that a product or carrier has completed all scheduled operations such as processing and inspection at a certain station and is about to leave that station.
- Collection: The action of obtaining data from sources such as equipment (e.g., PLC), sensors, scanners, or operator interfaces during the production process.
- Process Engine: A core technical component used to automate and manage business processes. In this system, it dynamically executes, coordinates, and monitors each step of activity in the outbound process by parsing predefined flowcharts (PFD files).
2. PLC Interaction Sequence Diagram
The following diagram clearly shows the detailed interaction sequence between LMES and PLC in a typical outbound process, including signal triggering, data reading and writing, and the final reset process.
2.1. Core Interaction Principle: Whoever Triggers, Resets
The signal interaction between LMES and PLC strictly follows the "Whoever triggers, resets" principle. This means that if a signal is initiated by one party (e.g., changing from 0 to 1), then after the interaction is completed, the same party should be responsible for restoring it to the initial state (changing from 1 back to 0).
- PLC Trigger:
Outbound_FinishedSignalis set to1by the PLC to start the process, so after receiving the completion signal from LMES, it must also be reset to0by the PLC. - LMES Trigger:
Outbound_CompletedSignalis set to1by LMES to notify the PLC that processing is complete, so after monitoring that the PLC has resetOutbound_FinishedSignal, it must also be reset to0by LMES.
This principle ensures that each interaction is a complete "handshake" process, avoiding confusion in signal states.
3. Core Process Variables Explanation
The table below lists the Logical Variable Identifiers defined in the 10003.xml process template. These identifiers are standard names used internally by the process. They do not directly correspond to PLC addresses but need to be bound to the Variables predefined in the CMS base through the Process Management -> Station Configuration interface. The final PLC addresses are configured in the variables of the CMS base.
| Logical Identifier | Data Type | R/W | Description |
|---|---|---|---|
Outbound_FinishedSignal | int | Read | Trigger signal for PLC to notify LMES of processing completion. Value 1 starts the process. Must be reset to 0 by PLC after processing. |
Outbound_SerialNumberVariable | string | R/W | Used to transmit product serial number. LMES reads or writes back after association query. |
Outbound_MaterialVariable | string | Read | When "Barcode Acquisition Method" is Material Association, LMES reads material code from this variable. |
Outbound_TrayVariable | string | Read | When "Barcode Acquisition Method" is Pallet Association, LMES reads pallet code from this variable. |
Outbound_QualityVariable | string | Read | When "Qualification Judgment Method" includes PLC Judgment, LMES reads the raw processing result given by PLC from this variable. |
Outbound_ResultVariable | string | Write | LMES distributes the final qualification judgment result to PLC (e.g., "1" for OK, "2" for NG). |
Outbound_CompletedSignal | int | Write | Signal for LMES to notify PLC that the outbound process has been completed. |
Outbound_FinishVariable | int | Write | LMES distributes the final result code of this outbound to PLC (see definition below). |
Outbound_Description | string | Write | When an outbound exception occurs or is needed, LMES distributes specific text descriptions to PLC. |
4. Business Logic and Configuration Guide
4.1. Business Processing Sequence
After receiving the Outbound_FinishedSignal=1 signal from the PLC, LMES strictly executes the business logic in the following order internally:
- Outbound Initialization (
OutboundInitializeActivity): Prepare process environment, load product context. - Parameter Collection (
ParameterCollectActivity): Batch read all required process parameters and quality signals from PLC at once. - Qualification Judgment (
...QualificationJudgmentActivity): This is the core decision step.- PLC Judgment: Directly adopt the value of
Outbound_QualityVariable. - Local Judgment: Compare collected parameters with formula specifications.
- Composite Judgment: Execute both judgments above simultaneously, taking the strictest result.
- PLC Judgment: Directly adopt the value of
- Parameter Storage (
ParameterSaveActivity): Store all collected data and judgment results into the database to form a traceability record. - Material Record (
MaterialUsageRecordActivity): Record the materials consumed in this production. - Result Distribution: Write values of result variables like
Outbound_FinishVariableto PLC.
4.2. Related Module Configuration
To correctly configure an outbound process, settings need to be made in the following modules:
- Flow Management (
FlowManagement):- Flow Definition File (
10003_1.pfd): Defines the execution sequence, conditions, and activities of the outbound business logic. This file is the core template of the system, usually maintained by R&D personnel. - Flow Variable Configuration File (
10003.xml): Defines the Logical Variable Identifiers required by the process. This file is also the core template of the system, usually maintained by R&D personnel.
- Flow Definition File (
- Process Management (
ProcessManagement):- Station Configuration: This is the most critical implementation configuration link. Here, you need to bind the Logical Variable Identifiers (such as
Outbound_FinishedSignal) defined in the process template with the Variables already defined in the CMS base. LMES itself does not directly configure PLC addresses but indirectly achieves communication with equipment by referencing these base variables. - Define which Process Parameters the station needs to collect (
ParameterCollectActivitywill read these configurations). - Define which Defect Reasons and corresponding PLC signals the station has (
PLCQualificationJudgmentActivitywill use these configurations).
- Station Configuration: This is the most critical implementation configuration link. Here, you need to bind the Logical Variable Identifiers (such as
- Formula Management (
FormulaManagement):- Define the Process Parameter Standards (such as upper and lower limits) of the product at a certain station, which is the basis for
LocalQualificationJudgmentActivityto perform local judgment.
- Define the Process Parameter Standards (such as upper and lower limits) of the product at a certain station, which is the basis for
- Material Management (
MaterialManagement):- Define the BOM list of the product,
MaterialUsageRecordActivitywill record material consumption based on this list.
- Define the BOM list of the product,
5. Process Details
This chapter will analyze the core logic of outbound collection in detail strictly based on the flowchart.
5.1. Start --> Finished Signal Listening
- Description: After the process starts, it enters the waiting state and continuously listens to the
Outbound_FinishedSignalvariable of the PLC. When the variable value becomes1, the process is activated. - Implementation: Completed by the
VariableMonitorActivityactivity of the framework.
5.2. Barcode Acquisition Method (Conditional Branch)
- Description: The process decides how to obtain the product code based on the
Outbound_ObtainBarcodeTypeconfiguration. - Branch 1 (Method=1): Directly read product code from
Outbound_SerialNumberVariable. - Branch 2 (Method=2): Read material code from
Outbound_MaterialVariable, query product code throughMaterialAssociationActivityassociation, and then distribute product code back to PLC throughVariableWriteActivity. - Branch 3 (Method=3): Read pallet code from
Outbound_TrayVariable, query product code throughTrayAssociationActivityassociation, and then distribute product code back to PLC throughVariableWriteActivity.
5.3. Outbound Initialization
- Description: After obtaining the product identification, unified initialization operations are performed. If an exception occurs at this stage (e.g., product code is empty), the process will jump directly to the "Outbound Result Distribution" step and write an error code. If normal, continue.
- Implementation:
OutboundInitializeActivity(Business Activity).
5.4. Process Parameter Collection & Qualification Judgment
- Description: First, batch read all preset process parameters from PLC through
ParameterCollectActivity. Then, enter different judgment branches according to theQualifiedJudgmentTypeconfiguration. - Branch 1 (Method=1):
PLCQualificationJudgmentActivitydirectly adopts the PLC judgment result. - Branch 2 (Method=2):
LocalQualificationJudgmentActivityperforms comparison judgment internally in MES according to formula specifications. - Branch 3 (Method=3):
CompositeQualificationJudgmentActivitycombines the first two methods for composite judgment.
5.5. Process Parameter Storage
- Description: The judgment results of all branches eventually converge here.
ParameterSaveActivitystores all collected data and judgment results into the database to form a traceability record. After this step is completed, it will trigger (SplitAND) the subsequent "Outbound Result Distribution" and "Material Usage Record" in parallel. - Implementation:
ParameterSaveActivity(Business Activity).
5.6. Material Usage Record
- Description: Executed in parallel with result distribution,
MaterialUsageRecordActivityis responsible for recording the material information consumed in this production. - Implementation:
MaterialUsageRecordActivity(Business Activity).
5.7. Outbound Result Distribution
- Description: Distribute the final result to PLC and notify the SOP system. After this step is completed, it will also trigger (SplitAND) "Finished Signal Reset Listening" and "SOP Outbound Notification" in parallel.
- Implementation: Result distribution is completed by the
VariableWriteActivityactivity of the framework.
5.8. SOP Outbound Notification
- Description: Executed in parallel with signal reset listening,
SopControlActivitynotifies the SOP display terminal of the outbound event. - Implementation:
SopControlActivity(Business Activity).
5.9. Finished Signal Reset Listening & Outbound Completion
- Description: This is the final stage of the process. LMES waits for the PLC to reset
Outbound_FinishedSignalto0throughVariableMonitorActivity, which marks that the PLC has confirmed receipt of the outbound result. - Reset Processing Result: If the qualification judgment method is NOT pure PLC judgment (Method!=1), LMES will actively reset
Outbound_ResultVariableto 0 throughVariableWriteActivity. - Outbound Completion: Finally, LMES resets signal variables such as
Outbound_CompletedSignalto0throughVariableWriteActivity, returning the entire station to standby state, ready to welcome the next product.
5.10. End
- Description: Process ends normally.
- Implementation: Marked by the
EndActivityactivity of the framework.
6. Core Business Activity Implementation Details
This chapter aims to provide internal implementation details of core activities in the outbound process for secondary development or deep configuration personnel. It is worth noting that in all process activities related to station processes, complete configuration information of the current station can be obtained through Flow.DataItems.ApplicationData as ProcessModel.
6.1. OutboundInitializeActivity
- Flow Definition (PFD) Name:
Outbound Initialization - Core Responsibility: Prepare all necessary context data for the outbound process.
- Implementation Details:
- Reset State: Upon entering the activity, it will first clear/reset process variables related to this outbound, such as
OutboundDescriptionValueandOutboundFinishSignal. - Get Product Code: Check if
FlowItemCollection.SerialNumberexists. If empty (e.g., upstream association query failed), it will immediately set an error result (e.g.,NoProductEntry) and terminate the subsequent normal process. - Load Context: If the product code exists, the activity will intelligently load the complete context of the product. It first checks if the current process instance already contains information such as Work Order (
OrderModel), Product Model (ProductModel) (usually passed from the inbound process). If not, it calls theGetProductionAsyncmethod to query the last production record of the product code from the database and uses it to restore key information such as its work order, product model, and inbound time.
- Reset State: Upon entering the activity, it will first clear/reset process variables related to this outbound, such as
- Key Context Variables:
- Read:
SerialNumber,TrayCodeAssociationDescriptionValue,MaterialCodeAssociationDescriptionValue - Write:
OutboundFinishSignal,OutboundDescriptionValue,OrderModel,ProductModel,InboundEntryTime
- Read:
- Secondary Development/Configuration Suggestions: This activity is the foundation of the process and usually does not need modification. But understanding its context loading mechanism (prioritizing current process data, then querying historical records) is crucial for troubleshooting.
6.2. ParameterCollectActivity
- Flow Definition (PFD) Name:
Process Parameter Collection - Core Responsibility: Batch read all variable values related to this outbound from PLC.
- Implementation Details:
- Build Variable List: The activity dynamically builds a list of PLC variable addresses to be read (
varNames). The data source of this list is highly configurable, aggregating all the following points:- Process Parameters defined in station configuration (
ProcessParameters). - Material Parameters defined in station configuration (
MaterialParameters). - Formula Parameters defined in formula (
FormulaParameters), including distribution and monitoring variables. - Some special variables hard-coded in the process, such as
Outbound_QualityVariable.
- Process Parameters defined in station configuration (
- Batch Read: After building the list, it calls the
IFlowVariableService.ReadValueAsyncservice to initiate a one-time batch read request to the data collection module. - Store in Context: Store the returned dictionary containing all variable values (
IReadOnlyDictionary<string, IVariableValue>) as a whole into the process contextFlow.DataItems[FlowItemCollection.ParameterCollectData]for use by subsequent activities.
- Build Variable List: The activity dynamically builds a list of PLC variable addresses to be read (
- Key Context Variables:
- Read:
ApplicationData(GetProcessModel) - Write:
ParameterCollectData
- Read:
- Secondary Development/Configuration Suggestions: This activity is completely configuration-driven. If you need to collect a new PLC point as a Process Parameter, you only need to add the corresponding parameter definition in Process Management, without any code changes.
6.3. ...QualificationJudgmentActivity (Qualification Judgment Series)
PLCQualificationJudgmentActivity(Flow Definition (PFD) Name:PLC Qualification Judgment):- Core Responsibility: Completely rely on the equipment's own judgment result.
- Implementation Details: Logic is the simplest. It directly gets the value of
Outbound_QualityVariablefromParameterCollectData. If the value is1ortrue, it is judged as qualified. If2orfalse, it further calls theGetUnqualifiedReasonsmethod to check the Defect Reason variables in the station configuration to find out specifically which defect signal was triggered.
LocalQualificationJudgmentActivity(Flow Definition (PFD) Name:Local Qualification Judgment):- Core Responsibility: Complete quality judgment inside MES.
- Implementation Details: Logic is the most complex. It will:
- Get the formula version of the current product (
FormulaVersionModel). - Traverse all Process Parameters in the station configuration.
- For each parameter, find its corresponding specification (
lower,upper) in the formula version. - Compare the actual value in
ParameterCollectDatawith the specification. - Any parameter out of tolerance will set the final result to unqualified and record the out-of-tolerance parameter name as the reason.
- Extension Point: This activity calls the implementation of the
ILocalJudgmentStrategyinterface, allowing developers to insert custom, non-standard (e.g., requiring complex calculation) qualification judgment logic through dependency injection.
- Get the formula version of the current product (
CompositeQualificationJudgmentActivity(Flow Definition (PFD) Name:Composite Qualification Judgment):- Core Responsibility: Combine judgment results from PLC and MES.
- Implementation Details: It does not contain independent logic but sequentially calls
PLCJudgmentAsyncandLocalJudgmentAsyncmethods, and then performs an "AND" operation on the two results. Only when both are qualified, the final result is qualified.
- Key Context Variables:
- Read:
ParameterCollectData,OrderModel,ProductModel,FormulaApplyModel - Write:
QualityResultValue,QualityResultReason
- Read:
- Secondary Development/Configuration Suggestions: For complex quality judgment needs, the best practice is to implement the
ILocalJudgmentStrategyinterface instead of directly modifying activity code.
6.4. ParameterSaveActivity
- Flow Definition (PFD) Name:
Process Parameter Storage - Core Responsibility: Assemble and persist the complete traceability record of this outbound.
- Implementation Details:
- Data Aggregation: This is the core of the activity. It collects all necessary information from
Flow.DataItems, including: product code, work order, product model, inbound time, completion time, final qualification judgment result, unqualified reason, operator, and all process parameters and material parameters inParameterCollectData. - Build Model: Assemble aggregated data into a
TraceModelobject. - Handle Special Logic: It checks the interaction result of SOP and judges the data type of this traceability (
TraceDataType), e.g., whether it is inspection data. - Store in Context: Store the built
TraceModelobject back toFlow.DataItems[FlowItemCollection.TraceModel], so that subsequent activities likeMaterialUsageRecordActivitycan obtain complete traceability information.
- Data Aggregation: This is the core of the activity. It collects all necessary information from
- Key Context Variables:
- Read:
ApplicationData,OrderModel,ProductModel,ParameterCollectData,QualityResultValue,QualityResultReason,InboundEntryTime - Write:
TraceModel
- Read:
- Secondary Development/Configuration Suggestions: If you need to add extra custom fields to the traceability record, the most recommended way is to add them to the
TraceModel.ExtraPropertiesdictionary. This can be implemented through a simple custom activity before this activity, or by directly modifying this activity to add.
7. Result Codes and Exception Troubleshooting
7.1. Outbound Result Code Definition (Outbound_FinishVariable)
LMES informs PLC of the final outbound processing result via the Outbound_FinishVariable variable. The meanings and values of these codes are defined by the ExitResultConfig.cs file and can also be viewed and customized in the Process Management -> Process Configuration -> Process Result Value Configuration interface.
| Code | Enum Name | Description |
|---|---|---|
0 | Reset | Reset |
1 | OK | Normal |
6 | NoProductEntry | Product code acquisition exception |
9 | NG | Other exceptions |
10 | MaterialCodeNotBoundProductCode | Material code not bound to product code |
11 | TrayCodeNotBoundProductCode | Pallet code not bound to product code |
7.2. Exception Troubleshooting Guide
When problems occur in the outbound process, priority should be given to using system-provided visual debugging tools, followed by analyzing log files.
-
Use Station Console (Preferred): The LMES system provides a powerful Station Console for each station, which is the Preferred Tool for real-time monitoring and troubleshooting.
- Core Advantages:
- Real-time Log Stream: The console pushes all logs of the current station associated process in real-time, including
flowlog(process logic log),tracelog(traceability data log), andwarnlog(warning/error log), without manual file refresh. - Real-time Variable Monitoring: Can see current values and changes of all PLC variables defined in the process in real-time.
- Process Status Visualization: Can clearly see if the current process is running, stopped, or in an exception state.
- Remote Control: Allows operators or engineers to perform operations like "Reset" on the process directly from the interface for quick recovery.
- Real-time Log Stream: The console pushes all logs of the current station associated process in real-time, including
- Troubleshooting Steps:
- Open the console of the corresponding station.
- Observe the Warning Log window for red error messages.
- Switch to the Process Log window to view detailed steps of process execution, locate the last successfully executed log, and thus judge the problem point.
- Observe the Variable Monitoring area to check if PLC signals change as expected.
- Core Advantages:
-
Analyze Log Files (Offline/Advanced): If the console is inaccessible, or offline deep analysis is needed, it is recommended to use the LMES Log Quick Troubleshooting and Positioning Analysis Tool (LMES Studio). For specific usage, please refer to document
doc/LMES Log Analysis Tool User Manual.md. If this tool cannot be used, you can also view raw log files directly on the server.- Use Process Instance ID: Searching for
【Instance=...】(e.g.,【Instance=721876340764】) in logs can precisely link all relevant logs of a single process execution. This is a more precise tracking method than product code. - Search Product Code: Directly searching for the problematic product serial number can locate relevant processing records but may contain logs of multiple process executions.
- Common Log Keywords:
Exception Reason:: This is the most direct error information, usually clearly pointing out the problem.LogExceptionMessage: Searching this keyword can find exception stack information at the code level.Qualified Signal: Searching activity name "PLC Qualification Judgment" can view whether the raw qualified signal value read from PLC meets expectations.Parameter Range: Searching activity name "Local Qualification Judgment" can see the set range and actual collected value of each parameter, facilitating troubleshooting of which parameter is out of tolerance.Store Parameter:: Searching activity name "Process Parameter Storage" can see the complete traceability model finally stored in the database, confirming data correctness.Unsubscribe: If the process is stuck, check if there areUnsubscribelogs to judge if there is a problem with the variable monitoring part.
- Use Process Instance ID: Searching for
Through the above information, you can efficiently configure, understand, and troubleshoot the outbound process.
8. Advanced Secondary Development
For scenarios requiring deep customization or adding extra logic without modifying existing activity code, the process engine provides two powerful extension methods: IFlowProcessor interceptor and IMethodExecuter custom function.
8.1. IFlowProcessor: Global Process Interceptor
IFlowProcessor is an interface defined under the CMS.Plugin.FlowManagement.Abstractions namespace. Any class implementing this interface, as long as it is correctly registered in the dependency injection container, will be automatically discovered and executed by the process engine. It allows developers to inject custom code at specific lifecycle nodes of Every Activity execution in the process, implementing AOP (Aspect-Oriented Programming).
8.1.1. Core Interception Methods
IFlowProcessor provides three core methods corresponding to three stages of activity execution:
OnEnterAsync(flowProcessor, sender, args): Called before any activity is about to Enter (execute itsEnterAsyncmethod).OnExecuteAsync(flowProcessor, sender, args): Called before any activity is about to Execute (execute itsExecuteAsyncmethod). This is the most commonly used interception point for processing core business logic.OnExitAsync(flowProcessor, sender, args): Called before any activity is about to Exit (execute itsExitAsyncmethod).
8.1.2. How to Use
Through sender as Activity, developers can get the currently executing activity instance, knowing the activity's Type and Name. Through args as ProcessflowEventArgs, the complete process context DataItems can be accessed. Among them, DataItems.ApplicationData stores the complete configuration of the current station, which can be safely cast to ProcessModel type for access: var processModel = (args as ProcessflowEventArgs).DataItems.ApplicationData as ProcessModel;.
This allows developers to implement very flexible logic, such as:
- Modify Process Context: Dynamically add, modify, or delete variables in
DataItemsbefore and after specific activity execution. - Add General Validation: Implement an
IFlowProcessorto judge inOnExecuteAsyncthat if the current activity isParameterSaveActivity, execute a piece of general, cross-process data validation logic before it executes. - Dynamic Logging: Automatically record more detailed diagnostic logs upon entry and exit for specific types of activities.
8.2. IMethodExecuter: Define Custom Process Functions
The second more direct way of secondary development is implementing the IMethodExecuter interface. Unlike IFlowProcessor as a global interceptor, IMethodExecuter allows developers to create Explicitly Callable, named custom "methods" or "functions". These functions are usually triggered by MethodActivity in the process.
8.2.1. IMethodExecuter Interface Analysis
This interface is designed for creating reusable independent business logic blocks. Its core members are as follows:
ExecuterName(Property):stringtype, must provide a Unique Name. This name is the identifier of the method executor, and the process calls it by this name.Execute(ProcessflowEventArgs args)(Method): This is the core method of the executor. When the process calls this executor, this method is triggered.args: Provides access to the process complete contextDataItems, allowing you to read input parameters and write return values.- Return Value:
Task<Dictionary<string, object>>. You can put calculation results into a dictionary and return it. The process engine will automatically update these key-value pairs to the process contextDataItems.
8.2.2. Working Mechanism
- Develop: Developers create one or more classes implementing the
IMethodExecuterinterface. - Register: Register these implementation classes into the dependency injection container.
- Configure: In the process designer interface, implementers can drag a
MethodActivityactivity onto the canvas. In the activity's property configuration, theExecuterNamefield will display all registeredIMethodExecuterimplementations in the form of a Dropdown List. Implementers only need to select the required executor, without manually entering the name. - Execute: When the process runs to that
MethodActivity, the engine finds the correspondingIMethodExecuterinstance based on the name and calls itsExecutemethod. After execution, the returned dictionary will be merged into the process context.
8.2.3. Use Case: Complex Material Traceability Code Parsing
Suppose a key material's QR code contains very complex combination information (e.g., VendorCode-BatchNumber-ProductionDate-LineNumber) and needs to be parsed and written to different PLC variables respectively.
- Create Executor:
public class BarcodeParsingExecuter : IMethodExecuter{public string ExecuterName => "ParseComplexMaterialBarcode";public string ExecuterDescription => "Parse complex material traceability code";public Task<Dictionary<string, object>> Execute(ProcessflowEventArgs args){var context = args.DataItems;var complexBarcode = context["ScannedMaterialBarcode"] as string;var result = new Dictionary<string, object>();if (!string.IsNullOrEmpty(complexBarcode)){var parts = complexBarcode.Split('-');if (parts.Length == 4){result["ParsedVendorCode"] = parts[0];result["ParsedBatchNumber"] = parts[1];result["ParsedProductionDate"] = parts[2];result["ParsedLineNumber"] = parts[3];}}// Returned result is automatically merged into process contextreturn Task.FromResult(result);}}
- Use in Process:
- Add a
MethodActivityafterParameterCollectActivityand set itsExecuterNametoParseComplexMaterialBarcode. - Add a
VariableWriteActivityafter thisMethodActivity, which can directly read variables likeParsedVendorCode,ParsedBatchNumberfrom the process context and write them to corresponding PLC addresses.
- Add a
Through IMethodExecuter, complex logic closely related to specific business can be encapsulated and called by process designers as a "black box", greatly improving process readability and system maintainability.
8.3. Secondary Development Scenario Practice: Collect Extended Field and Store in Traceability Record
This is a very common secondary development requirement: A project needs to collect a custom data outside the standard process (e.g., ambient temperature, equipment running duration, etc.) and store it in the product's traceability record, but without modifying any standard business activity (Activity) code.
Goal: When entering the "Process Parameter Storage" (ParameterSaveActivity) activity, read an extra "Ambient Humidity" variable from PLC and store it in the ExtraProperties of the traceability record.
Scheme: Use IFlowProcessor to intercept when ParameterSaveActivity is about to enter, completing data collection and context injection. Choosing the OnEnterAsync interception point is best practice because it ensures all external data is ready before the activity's core logic executes.
Step 1: Create IFlowProcessor Implementation Class
First, create a new C# class implementing the IFlowProcessor interface.
using CMS.Plugin.FlowManagement.Abstractions;
using CMS.Plugin.MesSuite.Abstractions.Models;
using Microsoft.Extensions.DependencyInjection;
using SYC.Flow.Kernel;
using Volo.Abp.Data;
namespace MyCompany.MyProject.FlowProcessors;
public class ExtraDataCollectionProcessor : IFlowProcessor
{
// Use OnEnterAsync to intercept when activity enters
public async Task OnEnterAsync(FlowProcessor flowProcessor, object sender, EventArgs args)
{
// 1. Judge if current activity is "Process Parameter Storage"
if (sender is ParameterSaveActivity saveActivity)
{
var eventArgs = args as ProcessflowEventArgs;
if (eventArgs == null) return;
var context = eventArgs.DataItems;
var serviceProvider = eventArgs.ServiceProvider;
// 2. Get variable service from service container
var variableService = serviceProvider.GetRequiredService<IFlowVariableService>();
// 3. Read custom PLC variable (assume bound in station configuration)
var humidityVarName = "Custom_Ambient_Humidity"; // Custom logical variable name
var readResult = await variableService.ReadValueAsync(saveActivity, humidityVarName);
var humidityValue = readResult?.Value?.ToString();
// 4. Get or create ExtraProperties dictionary
var extraPropertiesKey = $"{FlowItemCollection.TraceModel}_ExtraProperties";
var extraProperties = context[extraPropertiesKey] as ExtraPropertyDictionary
?? new ExtraPropertyDictionary();
// 5. Add collected humidity value to dictionary
extraProperties["AmbientHumidity"] = humidityValue;
// 6. Write updated dictionary back to process context
context[extraPropertiesKey] = extraProperties;
}
}
}
Step 2: Register Interceptor to Dependency Injection System
To let the process engine discover and use the ExtraDataCollectionProcessor we created, we need to register it into the application's Dependency Injection (DI) container. This is usually done in the ConfigureServices method of the project's module class (e.g., MyProjectModule.cs).
public override void ConfigureServices(ServiceConfigurationContext context)
{
// ... Other service registrations
// Register custom flow processor as singleton
context.Services.AddSingleton<IFlowProcessor, ExtraDataCollectionProcessor>();
}
Step 3: Configure Variable Binding in Station
The last step is to let the system know which real PLC humidity address Custom_Ambient_Humidity corresponds to.
- Enter Process Management -> Process Configuration -> Process Parameters, create a new process parameter, e.g., named "Ambient Humidity".
- Enter Process Management -> Station Configuration, find the station that needs to apply this logic.
- In the station's parameter configuration, bind the newly created "Ambient Humidity" parameter with the logical name
Custom_Ambient_Humidityused in our code. - Finally, bind this logical identifier
Custom_Ambient_Humidityto the Variable in the CMS base pointing to the actual PLC humidity address.
Conclusion
After completing the above three steps, the entire process achieves non-intrusive logic extension. When the outbound process of any station runs to the "Process Parameter Storage" activity:
- Our
ExtraDataCollectionProcessorwill be automatically triggered when this activity Enters. - It reads extra humidity sensor data.
- Cleverly "stuffs" the data into the
ExtraPropertiesof the traceability model about to be saved. - When
ParameterSaveActivityexecutes its core logic later, it doesn't know the existence of this extended property, but it will faithfully save the entireTraceModelincluding our custom data to the database.
This method greatly guarantees the stability of core code while providing high flexibility for secondary development.