Skip to content

Connect IoT - Fuji Nexim Driver#

As products become more varied, the shift toward variable-mix variable-volume production is accelerating. Changes to bewildering production schedules and frequent machine changes lead to defective products and missed deadlines, and several other difficult problems are arising such as increasing inventories of materials, parts, and products.

Nexim is a production system that integrates the functions of the production cycle (Plan, Do, See) for reliable planning support and changeover support, flexible data management, and maintaining high operation rates and quality.

Data Types#

These are the supported specific data types:

Name Description
Integer Integer number
Numeric Decimal number
String String value
Boolean Boolean value
DateTime Date/Time value
Object JSON formatted value

Table: Fuji Nexim specific data types.

Supported Functionalities#

The FujiNexim tasks package (controller-engine-fujinexim-tasks) has direct support for the following tasks/functionalities:

Task FujiNexim Functionality Description
onFujiNeximRequest, sendFujiNeximReply BOMLIST BOM list notification
onFujiNeximRequest, sendFujiNeximReply MCSTATECHANGE Machine state change notification
onFujiNeximRequest, sendFujiNeximReply PCBCHECKIN Panel checkin notification
onFujiNeximRequest, sendFujiNeximReply PCBCHECKOUT Panel checkout notification
onFujiNeximRequest, sendFujiNeximReply PGCHANGE Program change completion notification
onFujiNeximRequest, sendFujiNeximReply PGCHANGEII Program change completion report II
onFujiNeximRequest, sendFujiNeximReply PRODSTARTED Production start notification
onFujiNeximRequest, sendFujiNeximReply PRODCOMPLETED Production completed notification
executeFujiNeximCommand PARTSSUPPLY Part supply
executeFujiNeximCommand RESTARTEQUIP Fuji equipment control release command
executeFujiNeximCommand STOPEQUIP Fuji equipment control command
executeFujiNeximCommand SETEV Valid event setting notification
executeFujiNeximCommand STARTEV Event notice commencement notification
(integrated on driver) KEEPALIVE Connection check request

The table lists the already pre-configured message format list. The tasks onFujiNeximRequest, sendFujiNeximReply and executeFujiNeximCommand have support to add other messages on the specification.

For example, the SetEv message is a complex one (uses Object at input). An example of one workflow that injects a complex input is:

{
    "tasks": [
        {
            "id": "task_815",
            "reference": {
                "name": "executeFujiNeximCommand",
                "package": {
                    "name": "@criticalmanufacturing/connect-iot-controller-engine-fujinexim-tasks",
                    "version": "9.0.0"
                }
            },
            "settings": {
                "inputs": [
                    {
                        "name": "machineName",
                        "propertyName": "MachineName",
                        "deviceType": {
                            "$type": "Cmf.Foundation.BusinessObjects.AutomationProtocolDataType, Cmf.Foundation.BusinessObjects",
                            "Name": "String"
                        },
                        "defaultValue": null,
                        "valueType": {
                            "collectionType": null,
                            "friendlyName": "machineName",
                            "type": 4
                        }
                    },
                    {
                        "name": "eventList",
                        "propertyName": "EventList",
                        "deviceType": {
                            "$type": "Cmf.Foundation.BusinessObjects.AutomationProtocolDataType, Cmf.Foundation.BusinessObjects",
                            "Name": "Object"
                        },
                        "defaultValue": null,
                        "valueType": {
                            "collectionType": null,
                            "friendlyName": "eventList",
                            "type": 10
                        }
                    }
                ],
                "outputs": [
                    {
                        "name": "timestamp",
                        "valueType": {
                            "collectionType": null,
                            "friendlyName": "timestamp",
                            "type": 2
                        },
                        "propertyName": "timestamp",
                        "defaultValue": null,
                        "deviceType": null
                    },
                    {
                        "name": "eventRawData",
                        "valueType": {
                            "collectionType": null,
                            "friendlyName": "rawData",
                            "type": null
                        },
                        "propertyName": "eventRawData",
                        "defaultValue": null,
                        "deviceType": null
                    },
                    {
                        "name": "output$machineName",
                        "propertyName": "MachineName",
                        "deviceType": {
                            "$type": "Cmf.Foundation.BusinessObjects.AutomationProtocolDataType, Cmf.Foundation.BusinessObjects",
                            "Name": "String"
                        },
                        "defaultValue": null,
                        "valueType": {
                            "collectionType": null,
                            "friendlyName": "machineName",
                            "type": 4
                        }
                    },
                    {
                        "name": "output$result",
                        "propertyName": "Result",
                        "deviceType": {
                            "$type": "Cmf.Foundation.BusinessObjects.AutomationProtocolDataType, Cmf.Foundation.BusinessObjects",
                            "Name": "Boolean"
                        },
                        "defaultValue": null,
                        "valueType": {
                            "collectionType": null,
                            "friendlyName": "result",
                            "type": 3
                        }
                    }
                ],
                "timeout": 10000,
                "executionMode": 1,
                "executionDestination": 0,
                "message": {
                    "displayName": "SetEv - Valid Event Setting"
                },
                "messageFullName": "SETEV",
                "eventType": "Request",
                "clearInputs": true,
                "___cmf___name": "Execute Fuji Nexim Command"
            },
            "driver": "Handler"
        },
        {
            "id": "task_1305",
            "reference": {
                "name": "timer",
                "package": {
                    "name": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks",
                    "version": "8.2.0-202107125"
                }
            },
            "settings": {
                "_timerType": "Timer",
                "_timerWorkingMode": "UntilDeactivation",
                "_autoActivate": true,
                "interval": 10000,
                "_numberOfOccurrencesAllowed": 30,
                "_cronExpression": "* * * * * *",
                "_timeZone": "Etc/UTC",
                "emitInNewContext": false
            }
        }
    ],
    "converters": [
        {
            "id": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks#anyToConstant",
            "reference": {
                "name": "anyToConstant",
                "package": {
                    "name": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks",
                    "version": "8.2.0-202107125"
                }
            }
        }
    ],
    "links": [
        {
            "id": "c423cc13-7c24-4767-8c9a-4cd152365748",
            "sourceId": "task_1305",
            "targetId": "task_815",
            "inputName": "eventList",
            "outputName": "timestamp",
            "converters": [
                {
                    "id": "@criticalmanufacturing/connect-iot-controller-engine-core-tasks#anyToConstant",
                    "params": {
                        "type": 10,
                        "value": " [ {\"EventName\":\"EventName1\", \"Ack\":\"1\"},  {\"EventName\":\"EventName2\", \"Ack\":\"1\"}]   "
                    }
                }
            ]
        }
    ]
}

This workflow will send the following message:

<STX>SETEV<TAB>483554<TAB>MachineNameExample<TAB>2<CR>EventName1<TAB>1<CR>EventName2<TAB>1<CR><ETX> `

The SetEv message format is the following:

<STX>SETEV<TAB>SeqID<TAB>MachineName<TAB><SetEvent>

where <SetEvent> is

NumList<CR>
EventName<TAB>Ack<CR>
        .
        .
EventName<TAB>Ack<CR><ETX>

The Ack field is set to 0 if the event type is Event, meaning that the driver should not send a reply, or 1 if the event type is Request and a reply must be sent. The event type is defined by the user when creating events. If not specified, it assumes the value Request.

Protocol Parameters#

The protocol supports the following parameters, used to define the communication parameters, as well as the expected behavior of the driver:

Name Type Possible Values Default Value Description
address String "0.0.0.0" Address where the Fuji Interface is listening.
port Integer 0 Port where Fuji Interface is listening.
localAddress String "0.0.0.0" Local address the socket should connect from. Used when multiple network cards are available.
localPort Integer 0 Local port the socket should connect from.
family Enum IPV4, IPV6 IPV4 Version of IP stack, can be either 4 or 6. Default: 4.
keepAliveTime Integer 10000 Time interval to send the KEEPALIVEmessage (ms).
autoConfigure Boolean true Auto configure (SETEV and STARTEV).
machineName String "" Machine names used on Auto configure (comma separated values)
keepAliveTimeout Integer 150000 The Central Server issues a connection check request (KEEPALIVE) to the host computer at regular intervals (default: 120 seconds). KEEPALIVE timeout (ms) - timeout to receive a KEEPALIVE from equipment (default: 150 seconds).
controllerRequestTimeout Integer 10000 Timeout to Requests sent to equipment (ms).
equipmentRequestTimeout Integer 10000 Timeout to Requests sent to controller (ms).

Table: Fuji Nexim specific parameters.

Event Types#

Each Fuji Nexim event has an event type, defined through its extended data, that controls whether the machine waits for a reply when the event occurs:

  • Request - the machine waits for a reply. The driver forwards the event to the controller, and then sends a reply back to the machine.
  • Event - the machine does not wait for a reply. The driver forwards the event to the controller, but does not send a reply back to the machine. This is the "No Reply" behavior.

You set the event type when defining an event, both for the events that come with the driver and for custom events. If you do not set it, the event type defaults to Request, which keeps the previous behavior of the driver.

The event type controls the Ack field that the driver sends in the SETEV message: Request sends 1, and Event sends 0.

Message Framing#

The driver communicates with the Fuji Interface over TCP, so what arrives from the network is a byte stream rather than a sequence of whole messages. A single read can carry half a message, one message, or several at once.

Each Fuji Nexim message is framed as a 4-byte length header, followed by <STX>, the payload, and <ETX>. The driver accumulates the incoming bytes in a buffer and extracts one complete message at a time.

How the buffer is processed#

The buffer is inspected only when an <ETX> arrives. Until then the driver holds what it has and waits for the next chunk, so a message split across several TCP packets is reassembled rather than lost.

When an <ETX> arrives, the driver takes the bytes from the length header up to that <ETX> as one message, removes them from the buffer, and inspects what remains. Several messages received in the same chunk are therefore processed in order, in the same pass.

A length header can contain a byte whose value is the same as <ETX>. The driver accounts for this, so an <ETX> value that falls inside the length header of the next message does not close the current one.

Discarded data#

Data that cannot form a valid message is discarded, and the driver logs a warning naming the reason. The message is not forwarded to the Automation Controller.

Warning Meaning
Found <ETX> without a preceding <STX>. An <ETX> arrived while no message was open. Everything up to and including that <ETX> is dropped.
Found data without an <STX>. Bytes arrived that are not part of a message and no <STX> follows them. They are dropped, and only the bytes that can still be a length header are kept.
Found data before an <STX>. Unexpected bytes precede the length header of the next message. They are dropped, and processing restarts at that message.
Found a new <STX> before the previous batch was closed with an <ETX>. A new message started while the previous one was still open, so the incomplete one is dropped and processing restarts at the new message.

Table: Fuji Nexim framing warnings

Each of these warnings means the equipment, or the network between it and the driver, delivered something the protocol does not allow. An occasional warning during a disconnect or a restart is expected. A warning that repeats under normal operation points at a problem on the Fuji Interface side, and the payloads involved are visible by raising the driver log level to debug.

Length mismatch#

The 4-byte header declares how many bytes the payload holds. When the payload that arrives is a different size, the driver logs a warning that reports both the declared and the received count, and then processes the message anyway.

Note

A length mismatch is a warning, not a rejection. The message still reaches the Automation Controller. Treat a recurring mismatch as a signal that the equipment builds the header incorrectly, and validate the payload in the workflow before relying on it.

Driver Extensions#

Deprecated

The extensibility mechanisms described in this section are deprecated and will be removed in a future version. Define custom properties, events, and commands at runtime with the Custom Driver Definition task (which calls driverProxy.registerCustomDriverDefinitions under the hood) instead.

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, register events that are not present in the Driver Definition.

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.

Objects#

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

RegisterHandler#

Name Type Description
event Event Event to register (full information)

Table: Fuji Nexim specific handler registration.

UnregisterHandler#

Name Type Description
event Event Event to unregister (at least the property name must be supplied)

Table: Fuji Nexim specific handler unregistration.

Methods#

Register Event#

Notifies the protocol driver to raise the occurrences of a specific Fuji Nexim message type when it occurs.

Signature

void connect.iot.driver.fujinexim.registerEvent(data: Event)

Example

Notify connect.iot.driver.fujinexim.registerEvent

{
  "name": "PgChange",
  "deviceId": "PGCHANGE",
  "isEnabled": true,
  "ExtendedData": {
      "eventType": "Request"
  },
  "properties": [
    {
      "name": "time",
      "deviceId": "Time",
      "deviceType": "DateTime",
      "dataType": "DateTime"
    },
    {
      "name": "lineName",
      "deviceId": "LineName",
      "deviceType": "String",
      "dataType": "String"
    },
    {
      "name": "machineName",
      "deviceId": "MachineName",
      "deviceType": "String",
      "dataType": "String"
    },
    {
      "name": "moduleNo",
      "deviceId": "ModuleNo",
      "deviceType": "Integer",
      "dataType": "Integer"
    },
    {
      "name": "laneNo",
      "deviceId": "LaneNo",
      "deviceType": "Integer",
      "dataType": "Integer"
    },
    {
      "name": "programName",
      "deviceId": "ProgramName",
      "deviceType": "String",
      "dataType": "String"
    }
  ]
}

Custom Event Example

{
    "name": "PARTSOUTWARNING", "deviceId": "PARTSOUTWARNING", "isEnabled": true, "extendedData": { "eventType": "Request" },
    "properties":
    [
        { "name": "time", "deviceId": "Time", "dataType": "String", "deviceType": "String", "isReadable": true, "isWritable": true },
        { "name": "lineName", "deviceId": "LineName", "dataType": "String", "deviceType": "String", "isReadable": true, "isWritable": true },
        { "name": "machineName", "deviceId": "MachineName", "dataType": "String", "deviceType": "String", "isReadable": true, "isWritable": true },
        { "name": "moduleNo", "deviceId": "ModuleNo", "dataType": "Integer", "deviceType": "Integer", "isReadable": true, "isWritable": true },
        {
            "name": "partsOutInfo", "deviceId": "PartsOutInfo", "dataType": "Object", "deviceType": "Object", "extendedData":
            {
                "content": [
                    {
                        "name": "Stage",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "Slot",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "PartNo",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "ReelID",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "RemainingQTY",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "RemainingTime",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "RemainingBoard",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    },
                    {
                        "name": "PartsOut",
                        "deviceType": "Integer",
                        "dataType": "Integer",
                        "isArray": false
                    }
                ]
            },
            "isReadable": true, "isWritable": true
        }
    ]
}

Unregister Event#

Notifies the protocol driver to stop raising the occurrences of a specific message when it occurs.

Signature

void connect.iot.driver.fujinexim.unregisterEvent(data: Event)

Example

Notify connect.iot.driver.fujinexim.unregisterEvent

{
  "name": "EventName"
}

Execute Command#

Executes a custom command.

Signature

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

Example

SendRequest connect.iot.driver.fujinexim.executeCommand

{
    "command": {
        "name": "StartEv",
        "deviceId": "STARTEV",
        "extendedData": {
            "executionMode": "SendRequest",
            "destination": "TargetDevice"
        },
        "parameters": [{
            "name": "machineName",
            "deviceId": "MachineName",
            "dataType": "String",
            "deviceType": "String" ,
            "extendedData": {}
        }],
    },
    "parameters": {
        "machineName": "Machine001",
    }
}