---
tags:
- connect iot
description: "This documentation details the OIB Driver for integrating IoT applications with factory processes"
---
# 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`. 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`. 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:
```json
{
"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`
```json
{
"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:
```json
{
"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:
```json
{
"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:
```json
["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:
```json
{
"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:
```js
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 {
// 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,
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:
```json
["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:
```json
[
{
"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:
```json
{
"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:
```json
{
[
{
"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:
```json
{
"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:
```json
["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:
```json
["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`
```json
{
"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`
```json
{
"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`
```json
{
"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:
```json
{
"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:
```xml
```
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](oib/oib_boardgatekeeper.md) |
| Eventing | ... | [Information](oib/oib_eventing.md) |
| FeederInterlocking | ... | [Information](oib/oib_feederinterlocking.md) |
| LineControl | ... | [Information](oib/oib_linecontrol.md) |
| LineControlInterceptor | ... | [Information](oib/oib_linecontrolinterceptor.md) |
| Maintenance | ... | [Information](oib/oib_maintenance.md) |
| OperatorAssist | ... | [Information](oib/oib_operatorassist.md) |
| Optimizer | ... | [Information](oib/oib_optimizer.md) |
| PackagingUnit | ... | [Information](oib/oib_packagingunit.md) |
| PrinterControl | ... | [Information](oib/oib_printercontrol.md) |
| ProcessData | ... | [Information](oib/oib_processdata.md) |
| SetupCenter | ... | [Information](oib/oib_setupcenter.md) |
| Traceability | ... | [Information](oib/oib_traceability.md) |