Skip to content

Connect IoT - OIB Driver#

The ASM OIB is a integration platform for integrate the applications required to operate the required process steps.

ASM OIB is a single configuration point for these applications.

The purpose of the ASM OIB is to map the different deployment and configuration scenarios into a configuration which can be accessed from the higher level software applications in a transparent manner.

ASM OIB provides therefore some functionality to describe the logical factory structure. In this factory structure a dynamic registration of application services can be performed. This enables the higher level software to access functionality and information even in a dynamic environment.

Another purpose is a provide services via interfaces which are bundled by functionality cluster. These interface version should be stable for several versions of the applications. This enables a more stable overall system, even if single applications are replaced.

Data Types#

These are the supported specific data types:

Name Description
String String Value
Bool Boolean Value
Int Integer value
Double Double value
DateTime Date and Time Value
Object Structured value

Protocol Parameters#

The protocol supports the following parameters:

Name Type Possible Values Default Value Description
appName String "Connect IoT" Connect IoT endpoint identifier on the OIB side. To be shown on the ASM Studio in each subscription controlled by this instance.
sdkVersion Enum OIB_60
OIB_62
OIB_63
OIB_64
OIB_65
OIB_66
OIB_65 Base version of the SDK to use. Some features will not work on earlier versions
logUnhandledEvents Boolean false Log all received events, even if they are not being handled by controller
logSdkLogs Enum None
Debug
Information
Warning
Error
Information Enable logging the internal logs from the OIB SDK using the application logging infrastructure. Note, the logs will have the same verbosity as the original ones
enableOibTraceData Boolean false Should the driver log all OIB trace data as debug log
dumpMessagesReceived Boolean false Should the driver dump debug log of received messages
dumpMessagesReceivedPath String "${tmp}" Path where to dump debug log of received messages (use token ${tmp} for user temporary directory
localInterface String "" Hostname (or IP) where the OIB callbacks will be looking for. Leave it empty to use the LocalNetworkName
localNetworkName String "" Network Name (Part of, case sensitive) to use to fetch IP information. Leave it empty to use the registered hostname.
lineNameResolver String ".*\\(.*)" Regular expression used to extract the line name from the line full path
stationNameResolver String ".*\\(.*)" Regular expression used to extract the station name from the station full path
linesToHandle String "" List of lines to handle using this driver (comma separated). Will affect the behavior of the enable<OIBServiceName>. Leave empty for all. If line matches both the linesToHandle and the linesToIgnore filter, then the line is ignored.
linesToIgnore String "" List of lines to ignore using this driver (comma separated). Will affect the behavior of the enable<OIBServiceName>. Leave empty for none.
siteToHandle String "" Specific site to be handled by this instance. This is mandatory if used in an OIB Core with multiple sites configured. If only one site is present, this setting can be left empty
connectMode Enum Standard
PerLine
Standard Determine the way the connection to the lines should be performed.
Standard - Connection is a success when all interfaces/services are available
PerLine - Each line has their own connection lifecycle and flow
defaultCommandTimeout Integer 60000 Default timeout to use on driver commands (ms)
callbackBasePort Integer 4000 Base port number used on callbacks. When service callback port is configured as 0 (use a free port). Each OIB service will use this base port added with some offset
coreHeartbeatInterval Integer 60000 Interval wait time between heartbeat frames sent to oib core (milliseconds)
configurationManagerAddress String "localhost" Hostname (or IP) where the ConfigurationManager is listening
configurationManagerPort Integer 1406 Port where the ConfigurationManager is listening
configurationManagerCallbackPort Integer 0 Port where the OIB Configuration Manager will send back information. Use 0 to use a free port starting at callbackBasePort
extensions Object[] [] List of extensions to load. Starting from 9.0 version, the OIB driver was split in multiple extensions and allow usage of custom ones as well.
accessToken String Optional Access token to access OIB features
useDockingStations Boolean false Enable support for Docking Stations features
dockingStationsToHandle String "" List of Docking Stations to handle using this driver (comma separated)
dockingStationsToIgnore String "" List of Docking Stations to ignore using this driver (comma separated)
dockingStationEndpointFilterToHandle String "" Regular Expression used to match SetupCenter Endpoints to Handle on the Docking Station discovery process (one per line). If empty, no filter is done (all are handled). If used, then 'Docking Station EndPoint Filter to Ignore' is not used.
dockingStationEndpointFilterToIgnore String "" Regular Expression used to match SetupCenter Endpoints to Ignore on the Docking Station discovery process (one per line). If empty, none is ignored (all are handled).
appConfigOverride String Allows the override of the app configurations. Each line should be a pair of: config=value

Internal Interface#

To allow a clean integration with Connect IoT, internal mappings between the OIB interface and Connect IoT entities was implemented. This section contains the full mapping done.

Factory Layout#

The Factory Layout describes the configurations in Factory Explorer and SIPLACE Desk Pro related with Lines, Stations, Head Types, Station Locations and DockingStations. Notice that Stations can have a stationType of PickAndPlace, Printer and GenericDevice.

Properties#

Property Id Data Type Possible Values Description
OIB.Property.FactoryLayout Object JSON-formatted object with the entire factory layout.

Example of a Factory Layout JSON object:

{
    "lines": [
        {
            "site": "Virtual Site",
            "area": "Virtual Area",
            "friendlyName": "Virtual Production Line",
            "name": "Virtual Line 01",
            "fullPath": "Virtual Lines\\Virtual Line 01",
            "siplaceProOID": 327843842,
            "stations": [
                {
                    "friendlyName": "Virtual DEK Horizon Printer 01",
                    "name": "Virtual DEK Horizon Printer 01",
                    "fullPath": "Virtual DEK Horizon Printer 01",
                    "model": "DEK Horizon iX",
                    "serialNumber": "1116596",
                    "stationType": "Printer",
                    "ipAddress": "10.0.1.99",
                    "conveyorLaneCount": 2,
                    "deviceInLinePosition": 1,
                    "deviceVerticalPositionInLine": 1,
                    "locations": []
                },
                {
                    "friendlyName": "Virtual DEK Horizon Printer 02",
                    "name": "Virtual DEK Horizon Printer 02",
                    "fullPath": "Virtual DEK Horizon Printer 02",
                    "model": "DEK Horizon iX",
                    "serialNumber": "1116604",
                    "stationType": "Printer",
                    "ipAddress": "10.0.1.96",
                    "conveyorLaneCount": 2,
                    "deviceInLinePosition": 2,
                    "deviceVerticalPositionInLine": 1,
                    "locations": []
                },
                {
                    "friendlyName": "Virtual Solder Paste Inspection 01",
                    "name": "Virtual Solder Paste Inspection 01",
                    "fullPath": "Virtual Solder Paste Inspection 01",
                    "model": "AOI_Koh Young Technology",
                    "serialNumber": "AOI0001",
                    "stationType": "GenericDevice",
                    "ipAddress": "10.0.1.97",
                    "conveyorLaneCount": 2,
                    "deviceInLinePosition": 3,
                    "deviceVerticalPositionInLine": 1,
                    "locations": []
                },
                {
                    "friendlyName": "Virtual SX4 01",
                    "name": "Virtual SX4 01",
                    "fullPath": "Virtual Stations\\Virtual SX4 01",
                    "model": "SIPLACE SX4",
                    "serialNumber": "10000000",
                    "stationType": "PickAndPlace",
                    "ipAddress": "10.0.0.6",
                    "conveyorLaneCount": 2,
                    "deviceInLinePosition": 4,
                    "deviceVerticalPositionInLine": 1,
                    "locations": [
                        {
                            "location": "1",
                            "locationType": "FrontRight",
                            "headType": "C&P 20 10xx"
                        },
                        {
                            "location": "4",
                            "locationType": "FrontLeft",
                            "headType": "C&P 20 10xx"
                        },
                        {
                            "location": "2",
                            "locationType": "BackRight",
                            "headType": "C&P 20 10xx"
                        },
                        {
                            "location": "3",
                            "locationType": "BackLeft",
                            "headType": "C&P 20 10xx"
                        }
                    ]
                },
                {
                    "friendlyName": "Virtual Reflow Oven 01",
                    "name": "Virtual Reflow Oven 01",
                    "fullPath": "Virtual Reflow Oven 01",
                    "model": "Oven_Heller Industries",
                    "serialNumber": "RO0001",
                    "stationType": "GenericDevice",
                    "ipAddress": "10.0.1.98",
                    "conveyorLaneCount": 2,
                    "deviceInLinePosition": 5,
                    "deviceVerticalPositionInLine": 1,
                    "locations": []
                }
            ]
        }
    ],
    "heads": [
        "C&P 12 3xxx",
        "C&P 14 P 4xxx",
        "C&P 20 10xx",
        "C&P 20 M 1xxx",
        "C&P 20 M2 4xxx",
        "C&P 20 M3 6xxx",
        "C&P 20 P 4xxx",
        "C&P 20 P2 6xxx",
        "C&P 6 3xxx",
        "CPP 12 2xxx",
        "CPP 12 M 2xxx",
        "P&P Module",
        "PP1",
        "RV 12 7xx",
        "RV 12 9xx",
        "RV 6 8xx",
        "RV 6 8xx9xx",
        "RVC 6 9xx",
        "Twin Head 5xx",
        "Twin Head High Force 5xx",
        "Twin VHF 5xx",
        "Very High Force Head 5xx"
    ],
    "dockingStations": []
}

Events#

OIB.Event.FactoryLayout#

This event will contain the property OIB.Property.FactoryLayoutByEvent with the JSON-formatted object with the entire factory layout.

SiplacePro.Event.JobList#

This event will contain the property SiplacePro.Property.JobList with the JobList JSON-formatted object.

SiplacePro.Event.JobDetails#

This event will contain the property SiplacePro.Property.JobDetails with the JobDetails JSON-formatted object.

SiplacePro.Event.RecipeDetails#

This event will contain the property SiplacePro.Property.RecipeDetails with the RecipeDetails JSON-formatted object.

Commands#

OIB.Command.TriggerFactoryLayout#

This command will trigger the request to get the Factory Layout. The actual data response will be exposed by the OIB.Event.FactoryLayout event that will be triggered with the OIB.Property.FactoryLayoutByEvent property.

This command has no parameters.

Example:

SendRequest connect.iot.driver.oib.executeCommand

{
  "commandId": "OIB.Command.FactoryLayout",
}

Siplace Pro SPI#

The Siplace Pro is a programming system to manage production data for SIPLACE Lines. We use the SPI (SIPLACE Pro Interface), the programming interface (API) for accessing SIPLACE Pro data.

Properties#

Property Id Data Type Possible Values Description
OIB.Property.FeederTypes Object JSON-formatted object with the all the TapeFeederType available in the system.
OIB.Property.NozzleTypes Object JSON-formatted object with the all the NozzleType available in the system.

Example of a FeederTypes JSON object:

{
    "feeders": [
        {
            "oid_long": 172,
            "code": 60,
            "name": "12mm S",
            "fullPath": "TapeFeederType:12mm S"
        },
        {
            "oid_long": 173,
            "code": 61,
            "name": "16mm S",
            "fullPath": "TapeFeederType:16mm S"
        },
        {
            "oid_long": 757,
            "code": 554,
            "name": "Label Presenter E",
            "fullPath": "TapeFeederType:Label Presenter E"
        },
        {
            "oid_long": 812,
            "code": 782,
            "name": "SEMO CRF80 X",
            "fullPath": "TapeFeederType:SEMO CRF80 X"
        },
        {
            "oid_long": 836,
            "code": 284,
            "name": "8mm X AR",
            "fullPath": "TapeFeederType:8mm X AR"
        },
        {
            "oid_long": 864,
            "code": 794,
            "name": "Generic Tape Feeder FFI X",
            "fullPath": "TapeFeederType:Generic Tape Feeder FFI X"
        }
    ]
}

Example of a NozzleTypes JSON object:

{
    "nozzles": [
        {
            "oid_long": 10014790,
            "code": 590,
            "name": "590 PP",
            "fullPath": "NozzleType:590 PP"
        },
        {
            "oid_long": 838,
            "code": 1019,
            "name": "1019 C&P20",
            "fullPath": "NozzleType:1019 C&P20"
        },
        {
            "oid_long": 968,
            "code": 6118,
            "name": "6118 C&P20 P2",
            "fullPath": "NozzleType:6118 C&P20 P2"
        }
    ]
}

Commands#

SiplacePro.Command.GetSetupList#

This command will trigger the request to get a list of SetupFullPaths from a specific line (LineFullPath). The reply will contain the string array of the setups full path on that line. The typical usage scenario of this command is on GetSetupList task from controller-engine-oib-task tasks package.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get SetupList from (e.g.: eg:"Virtual Lines\Virtual Line 01")

Typical Output Example from GetSetupList Task:

["Demo Setups\\Virtual Line ASM ProcessExpert Testboard V10","Demo Setups\\Virtual Line ASM Simple Product Board","Demo Setups\\Virtual Line ASM Simple Product Board @ 19-10-07 07:52:24 [13556]"]

SiplacePro.Command.GetSetupDetails#

This command will trigger the request to get the setup details from a specific SetupFullPath (and LineFullPath). The reply will contain the object with the setup details. The typical usage scenario of this command is on GetSetupDetails task from controller-engine-oib-task tasks package.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get SetupList from (e.g.: eg:"Virtual Lines\Virtual Line 01")
SetupFullPath String Yes The Setup Full Path to get SetupList from (e.g.: eg:"Demo Setups\Virtual Line ASM ProcessExpert Testboard V10")

Typical Output Example from GetSetupDetails Task:

{
    "FullPath": "Demo Setups\\Virtual Line ASM Simple Product Board @ 19-10-07 07:52:24 [13556]",
    "Stations": [
        {
            "FullPath": "Virtual Stations\\Virtual SX4 01",
            "StationTopologyConfiguration": "HighSpeed",
            "PCBCameraFullPath": "PCB Cam X (34)",
            "BarcodeSystemTypeName": "External Forced System With CLI",
            "EndOfCluster": "True",
            "WhisperDownTheMachine": "False",
            "PCBTransport": "Standard",
            "SlowConveyorMode": "False",
            "HeavyBoardConveyorMode": "False",
            "PlacementMode": "Alternating",
            "PlacementModeAreaFront": "Right",
            "PlacementModeAreaRear": "Left",
            "StationLocations": [
                {
                    "Number": 1,
                    "LocationType": "FrontRight",
                    "StaticAttachableHeadTypeID": "Rev20Vhs",
                    "TableInsertType": "CotXInner",
                    "Tables": [
                        {
                            "TableFullPath": "System\\Table5[13562]",
                            "TableTypeID": "Changeover_40X",
                            "TableTypeFullPath": "Change Over Table 40 X",
                            "Feeders": [
                                {
                                    "StartTrack": 0,
                                    "Species": "Tape",
                                    "TrackArea": 40,
                                    "TypeName": "8mm X",
                                    "TypeOIDLong": 292,
                                    "TypeFullPath": "8mm X",
                                    "Reserves": [
                                        {
                                            "Division": 1,
                                            "ComponentFullPath": "Demo Components\\0201R",
                                            "ComponentName": "0201R"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "Number": 4,
                    "LocationType": "FrontLeft",
                    "StaticAttachableHeadTypeID": "Rev20Vhs",
                    "TableInsertType": "CotXInner",
                    "Tables": [
                        {
                            "TableFullPath": "System\\Table6[13563]",
                            "TableTypeID": "Changeover_34X",
                            "TableTypeFullPath": "Change Over Table 34 X",
                            "Feeders": [
                                {
                                    "StartTrack": 0,
                                    "Species": "Tape",
                                    "TrackArea": 7,
                                    "TypeName": "8mm X",
                                    "TypeOIDLong": 292,
                                    "TypeFullPath": "8mm X",
                                    "Reserves": [
                                        {
                                            "Division": 1,
                                            "ComponentFullPath": "Demo Components\\0201R",
                                            "ComponentName": "0201R"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "Number": 2,
                    "LocationType": "BackRight",
                    "StaticAttachableHeadTypeID": "Rev20Vhs",
                    "TableInsertType": "CotXInner",
                    "Tables": [
                        {
                            "TableFullPath": "System\\Table7[13564]",
                            "TableTypeID": "Changeover_34X",
                            "TableTypeFullPath": "Change Over Table 34 X",
                            "Feeders": [
                                {
                                    "StartTrack": 0,
                                    "Species": "Tape",
                                    "TrackArea": 40,
                                    "TypeName": "8mm X",
                                    "TypeOIDLong": 292,
                                    "TypeFullPath": "8mm X",
                                    "Reserves": [
                                        {
                                            "Division": 1,
                                            "ComponentFullPath": "Demo Components\\0201R",
                                            "ComponentName": "0201R"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                },
                {
                    "Number": 3,
                    "LocationType": "BackLeft",
                    "StaticAttachableHeadTypeID": "Rev20Vhs",
                    "TableInsertType": "CotXInner",
                    "Tables": [
                        {
                            "TableFullPath": "System\\Table8[13565]",
                            "TableTypeID": "Changeover_40X",
                            "TableTypeFullPath": "Change Over Table 40 X",
                            "Feeders": [
                                {
                                    "StartTrack": 0,
                                    "Species": "Tape",
                                    "TrackArea": 2,
                                    "TypeName": "2 x 8mm X",
                                    "TypeOIDLong": 461,
                                    "TypeFullPath": "2 x 8mm X",
                                    "Reserves": [
                                        {
                                            "Division": 2,
                                            "ComponentFullPath": "Demo Components\\0201R",
                                            "ComponentName": "0201R"
                                        },
                                        {
                                            "Division": 1,
                                            "ComponentFullPath": "Demo Components\\SOT23",
                                            "ComponentName": "SOT23"
                                        }
                                    ]
                                },
                                {
                                    "StartTrack": 0,
                                    "Species": "Tape",
                                    "TrackArea": 1,
                                    "TypeName": "8mm X",
                                    "TypeOIDLong": 292,
                                    "TypeFullPath": "8mm X",
                                    "Reserves": [
                                        {
                                            "Division": 1,
                                            "ComponentFullPath": "Demo Components\\0201R",
                                            "ComponentName": "0201R"
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

If you want to calculate Pickup Quantity by Feeder Reserve based on RecipeDetailsOutput you could use the code Task where you would link both RecipeDetails and GetSetupDetails outputs as inputs to the code task and the output of the code task will have Pickup Quantity data. The code task has the following inputs/outputs: | Name | Task I/O | Type | Description | | ----------------------- | ----------- | ------ | -------| | recipe | Task Input | Object | GetRecipeDetails task Output | | setup | Task Input | Object | GetSetupDetails task Output | | setupWithPickupQuantity | Task Output | Object | SetupDetail with PickupQuantity |

A sample code task for this type of calculation is: Example code:

import { Framework } from 'framework';

export default class {

    /** Allows accessing external functions */
    private framework: Framework;

    constructor(framework: Framework) {
        this.framework = framework;
    }

    /*
     * Entry point of the class (IMPORTANT: don't change the signature of this method)
     * Should return an object containing the values for each output to emit
     * If necessary, use the parameter "outputs" to emit data while running the code.
     */
    public async main(inputs: any, outputs: any): Promise<any> {
        // Add code here

        const recipeDetails: RecipeDetails = JSON.parse(inputs.recipe);
        const setupDetails: SetupDetails = JSON.parse(inputs.setup);

        if (setupDetails.FullPath !== recipeDetails.SetupFullPath) {
            throw new Error(`Recipe '${recipeDetails.RecipeFullPath}' has a different SetupFullPath '${recipeDetails.SetupFullPath}' than the expected '${setupDetails.FullPath}'.`);
        }

        if (recipeDetails.NeedsReoptimization) {
            throw new Error(`Recipe '${recipeDetails.RecipeFullPath}' needs ReOptimization.`);
        }

        if (!recipeDetails.OptimizationDetails) {
            throw new Error(`Recipe '${recipeDetails.RecipeFullPath}' has invalid OptimizationDetails: '${recipeDetails.OptimizationDetails}'`);
        }

        // Setup PickupQuantity at 0 for each feeder reserve (cleanup possible values at input)
        for (const station of setupDetails.Stations) {
            for (const location of station.StationLocations) {
                for (const table of location.Tables) {
                    for (const feeder of table.Feeders) {
                        for (const reserve of feeder.Reserves) {
                            reserve.PickupQuantity = 0;
                        }
                    }
                }
            }
        }


        // Ok, Cycle for each Placement
        for (const placement of recipeDetails.OptimizationDetails.Placements) {
            if (placement.PickupLinkIndex >= 0 && recipeDetails.OptimizationDetails.Pickups.length > placement.PickupLinkIndex && recipeDetails.OptimizationDetails.Pickups[placement.PickupLinkIndex]) {
                const pickup: OptimizationPickupDetails = placement.PickupLinkIndex && recipeDetails.OptimizationDetails.Pickups[placement.PickupLinkIndex];
                // Try to find the station,
                let stationFound: boolean = false; // Just for log purposes
                for (const station of setupDetails.Stations) {
                    if (station.FullPath === pickup.StationFullPath) {
                        // Ok, it's "this" station.
                        // Try to find the Location
                        let locationFound: boolean = false; // Just for log purposes
                        for (const location of station.StationLocations) {
                            if (pickup.Location === location.LocationType) {
                                // Ok. Found Location. 
                                // Only found one table on each location so far, and can't figure out any link, so assuming it's always like this
                                for (const table of location.Tables) {
                                    // Let's find the feeder.
                                    let feederFound: boolean = false; // Just for log purposes
                                    for (const feeder of table.Feeders) {
                                        // We need to check each Division
                                        // (We have double track feeders, each with it's own division)
                                        // (On Single Track Feeders, division is 1)
                                        for (const reserve of feeder.Reserves) {
                                            // Note: Feeder Division is missing here, because it was already translated / normalized into(Station)Tracks.So this means for example: 
                                            // Station A-Location 1-Track 5-Feeder X- Division #1 > (is equal) Station A-Location 1-(Station)Track 5
                                            // Station A-Location 1-Track 5-Feeder X- Division #2 > (is equal) Station A-Location 1-(Station)Track 6
                                            if ((feeder.TrackArea + (reserve.Division - 1)) === (pickup.Track + pickup.Reserve)) {
                                                // Ok, Here we have the feeder!
                                                // Is it the same Component !?
                                                if (reserve.ComponentFullPath === pickup.ComponentFullPath) {
                                                    // Gotcha!
                                                    // Let's increase the Pickup Quantity
                                                    reserve.PickupQuantity++;
                                                    // this.framework.logger.debug(`Quantity increased to ${reserve.PickupQuantity} on Station '${pickup.StationFullPath}, Location '${pickup.Location}', Feeder '${pickup.Track}', Component '${pickup.ComponentFullPath}'`);
                                                }
                                                else {
                                                    this.framework.logger.warning(`Component '${pickup.ComponentFullPath}' (Station '${pickup.StationFullPath}, Location '${pickup.Location}', Feeder '${pickup.Track}') not found on SetupDetails`);

                                                }
                                                feederFound = true;
                                                break;
                                            }
                                        }
                                    }
                                    if (!feederFound) {
                                        this.framework.logger.warning(`Feeder '${pickup.Track}' (Station '${pickup.StationFullPath}, Location '${pickup.Location}') not found on SetupDetails`);
                                    }
                                }
                                locationFound = true;
                                break;
                            }
                        }
                        if (!locationFound) {
                            this.framework.logger.warning(`Location '${pickup.StationFullPath}' not found on SetupDetails`);
                        }
                        stationFound = true;
                        break;
                    }
                }
                if (!stationFound) {
                    this.framework.logger.warning(`Station '${pickup.StationFullPath}' not found on SetupDetails`);
                }
            } else {
                this.framework.logger.warning(`Could not resolve Pickup '${placement.PickupLinkIndex}' on Placement '${placement.Index}'`);
            }
        }
        return { setupWithPickupQuantity: setupDetails };
    }
}

export interface SetupDetails {
    FullPath: string,
    Stations: StationDetails[];
}
export interface StationDetails {
    FullPath: string,
    StationLocations: StationLocationDetails[],
}
export interface StationLocationDetails {
    LocationType: string,
    Tables: TableDetail[],
}
export interface TableDetail {
    TableFullPath: string,
    Feeders: FeederDetail[],
}
export interface FeederDetail {
    StartTrack: number,
    TrackArea: number,
    Reserves: ReserveDetail[],
}
export interface ReserveDetail {
    Division: number,
    ComponentFullPath: string,
    ComponentName: string,
    PickupQuantity: number
}
export interface RecipeDetails {
    RecipeFullPath: string,
    SetupFullPath: string,
    NeedsReoptimization: boolean
    OptimizationDetails: OptimizationDetails
}
export interface OptimizationDetails {
    ComponentPlacement: Map<string, ComponentPlacementDetails>,
    Placements: OptimizationPlacementDetails[],
    Panels: OptimizationPanelDetails[],
    Pickups: OptimizationPickupDetails[],
}
export interface OptimizationPlacementDetails {
    Index: number,
    PanelIndex: number,
    PickupLinkIndex: number,
    ComponentPlacementRefDesignator: string,
    ComponentPlacementComponentFullPath: string
}
export interface OptimizationPanelDetails {
    Index: number,
    Name: string,
    BoardSideName: string,
}
export interface ComponentPlacementDetails {
    ReferenceDesignator: string,
    ComponentFullPath: string,
    ComponentShapeFullPath: string,
    OffsetX: number,
    OffsetY: number,
    Angle: number,
    Level: number,
    Omit: boolean,
    Exclusive: boolean,
    Glue: boolean
}
export interface OptimizationPickupDetails {
    Index: number,
    ComponentFullPath: string,
    StationFullPath: string,
    Location: string,
    Tower: number,
    Track: number,
    Reserve: number,
    LinkType: string
}

SiplacePro.Command.GetJobList#

This command will trigger the request to get a list of JobFullPaths from a specific line (LineFullPath). The reply will contain the string array of the job full path on that line. This command will also trigger an SiplacePro.Event.JobList event with the object described below. The typical usage scenario of this command is on GetJobList task from controller-engine-oib-task tasks package.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get JobList from (e.g.: eg:"Virtual Lines\Virtual Line 01")

Typical Output Example from GetJobList Task:

["Demo Jobs\\Job ASM ProcessExpert Testboard V10","Demo Jobs\\Job ASM Simple Product Board"]

SiplacePro.Command.GetJobDetails#

This command will request the Job/Setup/Recipe object structure from a specific Line (LineFullPath) and Job (JobFullPath). This command will also trigger an SiplacePro.Event.JobDetails event with the object described below. If JobFullPath is not specified, then, all Jobs from LineFullPath are fetched.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get JobDetails from (e.g.: "Virtual Lines\Virtual Line 01")
JobFullPath String No The Job Full Path to get JobDetails from (e.g.: "Demo Jobs\Job ASM ProcessExpert Testboard V10")

Typical Output Example from GetJobDetails Task:

[
    {
        "JobFullPath": "Demo Jobs\\Job ASM ProcessExpert Testboard V10",
        "JobSetupFullPath": "Demo Setups\\Virtual Line ASM ProcessExpert Testboard V10",
        "Recipes": [
            {
                "RecipeFullPath": "Demo Recipes\\Recipe ASM ProcessExpert Testboard V10",
                "BoardFullPaths": [
                    "Demo Boards\\ASM ProcessExpert Testboard V10"
                ],
                "PrinterSetupFullPath": ""
            }
        ]
    },
    {
        "JobFullPath": "Demo Jobs\\Job ASM Simple Product Board",
        "JobSetupFullPath": "Demo Setups\\Virtual Line ASM Simple Product Board",
        "Recipes": [
            {
                "RecipeFullPath": "Demo Recipes\\Recipe ASM Simple Product Board",
                "BoardFullPaths": [
                    "Demo Boards\\ASM Simple Product Board"
                ],
                "PrinterSetupFullPath": ""
            }
        ]
    }
]

SiplacePro.Command.GetRecipeDetails#

This command will request the Recipe/Panels/ChildPanels/ComponentPlacements object structure from a specific Line (LineFullPath), Job (JobFullPath) and Recipe (RecipeFullPath) This command will also trigger an SiplacePro.Event.RecipeDetails event with the object described below.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get RecipeDetails from (e.g.: "Virtual Lines\Virtual Line 01")
JobFullPath String No The Job Full Path to get RecipeDetails from (e.g.: "Demo Jobs\Job ASM ProcessExpert Testboard V10")
RecipeFullPath String Yes The Recipe Full Path to get RecipeDetails from (e.g.: "Demo Recipes\Recipe ASM ProcessExpert Testboard V10")

Note: If empty JobFullPath, this command will search the recipe by RecipeFullPath without checking parent Job.

Typical Output Example from GetRecipeDetails Task:

{
    "RecipeFullPath": "LINE-3\\MK\\C99910759T00",
    "SetupFullPath": "LINE-3\\MK\\C9996299T00VS9988T00 @ 20-12-07 13:33:07 [1338920]",
    "NeedsReoptimization": false,
    "Boards": [
        {
            "FullPath": "C999-NEW\\C99910759T00",
            "BoardSide": "Top",
            "PlacementLists": [
                {
                    "PlacementListFullPath": "C999-NEW\\C99910759T00",
                    "ClusterName": "444316",
                    "ComponentPlacements": [
                        {
                            "ReferenceDesignator": "R9",
                            "ComponentFullPath": "XXXXXXXX\\0002010076",
                            "ComponentShapeFullPath": "XXXXXXXX\\0002010076",
                            "OffsetX": 29.7252,
                            "OffsetY": 61.4722,
                            "Angle": 3.141592653589793,
                            "Level": 0,
                            "Omit": false,
                            "Exclusive": false,
                            "Glue": false
                        },
                        {
                            "ReferenceDesignator": "C61",
                            "ComponentFullPath": "XXXXXXXX\\0003010141",
                            "ComponentShapeFullPath": "XXXXXXXX\\0003010141",
                            "OffsetX": 13.8938,
                            "OffsetY": 69.6764,
                            "Angle": -1.570796326794897,
                            "Level": 0,
                            "Omit": false,
                            "Exclusive": false,
                            "Glue": false
                        }
                    ]
                },
                {
                    "PlacementListFullPath": "C999-NEW\\C99910759T00",
                    "ClusterName": "444314",
                    "ComponentPlacements": [
                        {
                            "ReferenceDesignator": "R9",
                            "ComponentFullPath": "XXXXXXXX\\0002010076",
                            "ComponentShapeFullPath": "XXXXXXXX\\0002010076",
                            "OffsetX": 29.7252,
                            "OffsetY": 61.4722,
                            "Angle": 3.141592653589793,
                            "Level": 0,
                            "Omit": false,
                            "Exclusive": false,
                            "Glue": false
                        },
                        {
                            "ReferenceDesignator": "C61",
                            "ComponentFullPath": "XXXXXXXX\\0003010141",
                            "ComponentShapeFullPath": "XXXXXXXX\\0003010141",
                            "OffsetX": 13.8938,
                            "OffsetY": 69.6764,
                            "Angle": -1.570796326794897,
                            "Level": 0,
                            "Omit": false,
                            "Exclusive": false,
                            "Glue": false
                        }
                    ]
                }
            ]
        }
    ],
    "PanelLinksDetails": [
        {
            "PanelName": "/C99910759T00/Top_444315_1_1",
            "ClusterName": " 444314",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 1,
            "Columns": 5,
            "Index": 1
        },
        {
            "PanelName": "/C99910759T00/Top_444315_1_2",
            "ClusterName": " 444314",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 1,
            "Columns": 5,
            "Index": 2
        },
        {
            "PanelName": "/C99910759T00/Top_444315_1_3",
            "ClusterName": " 444314",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 1,
            "Columns": 5,
            "Index": 3
        }
    ],
    "OptimizationDetails": {
        "ComponentPlacement": {
            "XXXXXXXX\\0004090034": {
                "ReferenceDesignator": "VP4",
                "ComponentFullPath": "XXXXXXXX\\0004090034",
                "ComponentShapeFullPath": "XXXXXXXX\\0004090034",
                "OffsetX": 38.1,
                "OffsetY": 41.838,
                "Angle": 1.570796326794897,
                "Level": 0,
                "Omit": false,
                "Exclusive": false,
                "Glue": false,
                "AlternativeComponents": [
                    {
                        "ComponentName": "MP-00000750-004"
                    },
                    {
                        "ComponentName": "MP-10000750-017"
                    },
                    {
                        "ComponentName": "MP-10000750-018"
                    }
                ]
            },
            "XXXXXXXX\\0004110003": {
                "ReferenceDesignator": "VP1",
                "ComponentFullPath": "XXXXXXXX\\0004110003",
                "ComponentShapeFullPath": "XXXXXXXX\\WP61300AA",
                "OffsetX": 49.8616,
                "OffsetY": 16.7554,
                "Angle": 1.570796326794897,
                "Level": 0,
                "Omit": false,
                "Exclusive": false,
                "Glue": false
            }
        },
        "Placements": [
            {
                "Index": 0,
                "PanelIndex": 1,
                "PickupLinkIndex": 159,
                "ComponentPlacementRefDesignator": "VP4",
                "ComponentPlacementComponentFullPath": "XXXXXXXX\\0004090034"
            },
            {
                "Index": 1,
                "PanelIndex": 1,
                "PickupLinkIndex": 188,
                "ComponentPlacementRefDesignator": "VP1",
                "ComponentPlacementComponentFullPath": "XXXXXXXX\\0004110003"
            }
        ],
        "Panels": [
            {
                "Index": 0,
                "Name": "/C99910759T00",
                "BoardSideName": null
            },
            {
                "Index": 1,
                "Name": "/C99910759T00/Top_444315_1_1",
                "BoardSideName": ""
            }
        ],
        "Pickups": [
            {
                "Index": 0,
                "ComponentFullPath": "XXXXXXXX\\0002010346",
                "StationFullPath": "LINE3NEW\\X4S",
                "Location": "FrontRight",
                "Tower": 0,
                "Track": 1,
                "Reserve": 0,
                "LinkType": "ComponentPickup"
            },
            {
                "Index": 1,
                "ComponentFullPath": "XXXXXXXX\\0004010045",
                "StationFullPath": "LINE3NEW\\X4S",
                "Location": "FrontRight",
                "Tower": 0,
                "Track": 2,
                "Reserve": 0,
                "LinkType": "ComponentPickup"
            },
            {
                "Index": 2,
                "ComponentFullPath": "XXXXXXXX\\0003010142",
                "StationFullPath": "LINE3NEW\\X4S",
                "Location": "FrontRight",
                "Tower": 0,
                "Track": 3,
                "Reserve": 0,
                "LinkType": "ComponentPickup"
            }
        ]
    },
    "Comments": {
        "TargetCycleTime": "Test Target Cycle Time Comment"
    }
}

SiplacePro.Command.GetOptimizationResult#

This command will trigger the request to get the Optimization Results from a specific recipe (Uses GetNormalizedBoardContent().OptimizationResultDataPerStations). The reply will contain the object with the Optimization Result. Notice, however, that typically the first call to this command might take longer than the command timeout (creating a new connection to SiplacePro, cache values, etc). To overcome this scenario, an event (SiplacePro.Event.OptimizationResult) is always triggered whenever this command is executed, so the recommendation would be to use the event to capture OptimizationResult data (this event contains a single property SiplacePro.Property.OptimizationResult with the optimization result Object identified below ).

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get SetupList from (e.g.: eg:"Virtual Lines\Virtual Line 01")
RecipeFullPath String Yes The Recipe Full Path to get RecipeDetails from (e.g.: "Demo Recipes\Recipe ASM ProcessExpert Testboard V10")

Typical Output Example from SiplacePro.Command.GetOptimizationResult Command:

{
    [
    {
        "RecipeFullPath": "Demo Recipes\\Recipe ASM Simple Product Board",
        "StationFullPath": "Virtual Stations\\Virtual SX4 01",
        "CycleTimeSeconds": 4.755,
        "Placements": 80,
        "HeadCycles": 4,
        "ComponentsPerSecond": 60568,
        "ReducedPlacements": 0,
        "OptimizationResultDataPerModule": [
            {
                "ModuleName": " 1 - Front Right / C&P 20 10xx",
                "Location": 1,
                "HeadTypeId": 8,
                "BuildTimeSeconds": 3.91,
                "CycleTimeSeconds": 2.638,
                "Placements": 20,
                "HeadCycles": 1,
                "ComponentsPerSecond": 27293,
                "ReducedPlacements": 0
            },
            {
                "ModuleName": " 4 - Front Left / C&P 20 10xx",
                "Location": 4,
                "HeadTypeId": 8,
                "BuildTimeSeconds": 3.91,
                "CycleTimeSeconds": 4.334,
                "Placements": 20,
                "HeadCycles": 1,
                "ComponentsPerSecond": 16613,
                "ReducedPlacements": 0
            },
            {
                "ModuleName": " 2 - Back Right / C&P 20 10xx",
                "Location": 2,
                "HeadTypeId": 8,
                "BuildTimeSeconds": 4.503,
                "CycleTimeSeconds": 4.755,
                "Placements": 20,
                "HeadCycles": 1,
                "ComponentsPerSecond": 15142,
                "ReducedPlacements": 0
            },
            {
                "ModuleName": " 3 - Back Left / C&P 20 10xx",
                "Location": 3,
                "HeadTypeId": 8,
                "BuildTimeSeconds": 4.503,
                "CycleTimeSeconds": 3.239,
                "Placements": 20,
                "HeadCycles": 1,
                "ComponentsPerSecond": 22229,
                "ReducedPlacements": 0
            }
        ]
    }
]
}

SiplacePro.Command.GetPanels#

This command will retrieve the Board information from the session and wil extract the information regarding Panel Names, Matrixes and if they are omitted.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get SetupList from (e.g.: eg:"Virtual Lines\Virtual Line 01")
BoardName String Yes The Board Name (e.g.: "Demo Boards\ASM Simple Product Board")

Typical Output Example from SiplacePro.Command.GetPanels Command:

{
    "Top": [
        {
            "PanelName": "Panel_Top_1_3_2",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 2,
            "ColumnNumber": 1
        },
        {
            "PanelName": "Panel_Top_1_3_3",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 2,
            "ColumnNumber": 2
        },
        {
            "PanelName": "Panel_Top_1_1_2",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 0,
            "ColumnNumber": 1
        },
        {
            "PanelName": "Panel_Top_1_4_2",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 3,
            "ColumnNumber": 1
        },
        {
            "PanelName": "Panel_Top_1_2_1",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 1,
            "ColumnNumber": 0
        },
        {
            "PanelName": "Panel_Top_1_3_4",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 2,
            "ColumnNumber": 3
        },
        {
            "PanelName": "Panel_Top_1_1_1",
            "ClusterName": "Cluster 9",
            "Omit": true,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 0,
            "ColumnNumber": 0
        },
        {
            "PanelName": "Panel_Top_1_4_3",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 3,
            "ColumnNumber": 2
        },
        {
            "PanelName": "Panel_Top_1_1_4",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 0,
            "ColumnNumber": 3
        },
        {
            "PanelName": "Panel_Top_1_1_3",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 0,
            "ColumnNumber": 2
        },
        {
            "PanelName": "Panel_Top_1_4_4",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 3,
            "ColumnNumber": 3
        },
        {
            "PanelName": "Panel_Top_1_4_1",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 3,
            "ColumnNumber": 0
        },
        {
            "PanelName": "Panel_Top_1_2_4",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 1,
            "ColumnNumber": 3
        },
        {
            "PanelName": "Panel_Top_1_2_2",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 1,
            "ColumnNumber": 1
        },
        {
            "PanelName": "Panel_Top_1_3_1",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 2,
            "ColumnNumber": 0
        },
        {
            "PanelName": "Panel_Top_1_2_3",
            "ClusterName": "Cluster 9",
            "Omit": false,
            "BoardElementIndex": 0,
            "Rows": 0,
            "Columns": 0,
            "Index": 0,
            "RowNumber": 1,
            "ColumnNumber": 2
        }
    ],
    "Bottom": []
}

This example is a Board 4x4 with one Panel omitted.

SiplacePro.Command.GetRecipesForLine#

This command will trigger the request to get the list of Recipes for a specific line (LineFullPath). The reply will contain the string array of the recipes full path for that line.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get Recipes list from (e.g.: eg:"Virtual Lines\Virtual Line 01")

Typical Output Example:

["Demo Setups\\Recipe - X4 S & SX2","Demo Setups\\Recipe - SX2","Recipe - X4 S"]

SiplacePro.Command.QuerySetupsForLine#

This command will retrieve the Setups for a specific line (LineFullPath). The reply will contain the string array of the Setups full path for that line.

Command Parameter Name Type Mandatory Possible Values Default Value Description
LineFullPath String Yes The Line Full Path to get Setups from (e.g.: eg:"Virtual Lines\Virtual Line 01")

Typical Output Example:

["Demo Setups\\Setup 1","Demo Setups\\Setup 2"]

Driver Extensions#

This protocol driver provides a set of extension that allow the customization to perform actions that are independent of the Driver Definitions associated. This means you can, using customization, get/set node values without needing to describe them.

This is particularly useful when accessing equipment data that is shared/too complex to access using the regular mechanisms. Also useful when needing to access data whose naming convention may vary from device to device. To use these extensions you can either implement your own task or use the supplied Tasks Send Notification to Driver and Subscribe in Driver.

Objects#

The objects are structures that are either passed as parameters or returned as result values.

RegisterHandler#

Name Type Description
type String Id of the event to register a notification. Examples:BoardGateKeeper.Event.BoardRequest, Monitoring.Event.StationEvent

UnregisterHandler#

Name Type Description
type String Id of the event to unregister notifications. Examples:BoardGateKeeper.Event.BoardRequest, Monitoring.Event.StationEvent

ExecuteCommand#

Name Type Description
commandId String Id of the command to execute (send to device). Example:BoardGateKeeper.Command.BoardRequestReply
parameters Json object Parameter names and values.

OibEventOccurrence#

Name Type Description
messageId String Id of the message (may be necessary for return commands)
eventId String Id of the event that occurred
values Json object Event properties names and values.

Methods#

Register Event Notification#

Notifies the protocol driver to raise the occurrences of a specific event when it occurs.

void connect.iot.driver.oib.registerHandler(data: RegisterHandler)

Note : The events will be published to the listeners connect.iot.driver.oib. appended with the name of the event registered. Example: connect.iot.driver.oib.BoardGateKeeper.Event.BoardRequest

Example#

Notify connect.iot.driver.oib.registerHandler

{
  "type": "BoardGateKeeper.Event.BoardRequest"
}

Unregister Event Notification#

Notifies the protocol driver to stop raising the occurrences of a specific event when they occur.

void connect.iot.driver.oib.unregisterHandler(data: UnregisterHandler)

Example#

Notify connect.iot.driver.oib.unregisterHandler

{
  "type": "BoardGateKeeper.Event.BoardRequest"
}

Execute Command#

Executes a custom command.

any connect.iot.driver.oib.executeCommand(data: ExecuteCommand)

Example#

SendRequest connect.iot.driver.oib.executeCommand

{
  "commandId": "BoardGateKeeper.Command.BoardRequestReply",
  "parameters": {
    "Internal.ReplyId": "aaabbbccc",
    "RequestResult": "Confirmed",
    "Reason": "",
    "BoardPath": "",
    "BoardSide": "Undefined",
    "VIHResult": "[ { \"PanelName\": \"Test1\", \"Place\": true, \"Reason\": \"Reason 1\" }, { \"PanelName": \"Test2\", \"Place\": false, \"Reason\": \"Reason 2\" } ]",
    "OverridingBarcode": ""
  }
}

Reply

true

Events#

connect.iot.driver.oib.*#

Events are raised only if registered first. The content of the event is of type OibEventOccurrence, where the values will vary depending on the event that was triggered.

The full name of the event triggered will have appended the full name of the event previously registered.

Example:

{
  "requestId": "aaabbbccc",
  "eventId": "BoardGateKeeper.Event.BoardRequest",
  "values": {
    "BoardGateKeeper.Property.Line.Name": "OIB Training\\Line 1",
    "BoardGateKeeper.Property.Station.Name": "Station 1 - TX1",
    "BoardGateKeeper.Property.Board.Barcode": "1234567890",
    "BoardGateKeeper.Property.Board.BoardTime": 1554302541320,
    "BoardGateKeeper.Property.Position.BcrSide": "Unknown",
    "BoardGateKeeper.Property.Position.Lane": "Left",
    "BoardGateKeeper.Property.Position.Origin": "Front",
    "BoardGateKeeper.Property.Position.SubConveyor": "None"
  }
}

Capture Trace Record#

To capture a trace record on the node service create a node.exe.config (on the folder where the node.exe is being executed) with the following content:

<configuration>
      <system.diagnostics>
             <sources>
                   <source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
                          <listeners>
                                <add name="traceListener" type="System.Diagnostics.XmlWriterTraceListener" initializeData= "c:\temp\Traces.svclog" />
                          </listeners>
                   </source>
             </sources>
      </system.diagnostics>
</configuration>

A trace record file will then be created (c:\temp\Traces.svclog) (can be open with Microsoft Service Trace Viewer) that may be helpful on debugging activities.

Extensions#

Topic Description Documentation
BoardGateKeeper ... Information
Eventing ... Information
FeederInterlocking ... Information
LineControl ... Information
LineControlInterceptor ... Information
Maintenance ... Information
OperatorAssist ... Information
Optimizer ... Information
PackagingUnit ... Information
PrinterControl ... Information
ProcessData ... Information
SetupCenter ... Information
Traceability ... Information