--- alias: user-guide-driver-fujinexim tags: - connect iot description: "This documentation details a driver for communicating with the Fuji Nexim production system, managing data types and functionalities" --- # 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: ```json { "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: ` SETEV483554MachineNameExample2EventName11EventName21` ` The `SetEv` message format is the following: ` SETEVSeqIDMachineName ` where `` is ``` NumList EventNameAck . . EventNameAck ``` 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 ``, the payload, and ``. 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 `` 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 `` arrives, the driver takes the bytes from the length header up to that `` 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 ``. The driver accounts for this, so an `` 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 without a preceding .` | An `` arrived while no message was open. Everything up to and including that `` is dropped. | | `Found data without an .` | Bytes arrived that are not part of a message and no `` follows them. They are dropped, and only the bytes that can still be a length header are kept. | | `Found data before an .` | Unexpected bytes precede the length header of the next message. They are dropped, and processing restarts at that message. | | `Found a new before the previous batch was closed with an .` | 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 {% include-markdown 'includes/pages/iot_driver_extensions_deprecated.md' %} 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** ```ts void connect.iot.driver.fujinexim.registerEvent(data: Event) ``` **Example** Notify `connect.iot.driver.fujinexim.registerEvent` ```json { "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** ```json { "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** ```ts void connect.iot.driver.fujinexim.unregisterEvent(data: Event) ``` **Example** Notify `connect.iot.driver.fujinexim.unregisterEvent` ```json { "name": "EventName" } ``` #### Execute Command Executes a custom command. **Signature** ```ts any connect.iot.driver.fujinexim.executeCommand(data: ExecuteCommand) ``` **Example** SendRequest `connect.iot.driver.fujinexim.executeCommand` ```json { "command": { "name": "StartEv", "deviceId": "STARTEV", "extendedData": { "executionMode": "SendRequest", "destination": "TargetDevice" }, "parameters": [{ "name": "machineName", "deviceId": "MachineName", "dataType": "String", "deviceType": "String" , "extendedData": {} }], }, "parameters": { "machineName": "Machine001", } } ```