@autocodingsystems/gateway-client

1.5.1 • Public • Published

ACS Gateway Client

The AutoCoding Gateway from AutoCoding Systems Ltd permits fully featured drivers for many of the leading equipment vendors in the packaging line environment.

  • Barcode Reading and Machine Vision

    • SICK
    • Datalogic
    • Cognex
  • Industrial Printers

    • Zebra
    • Domino
    • Videojet
    • Markem-Imaje
    • Linx
    • Toshiba
    • Datamax
    • Logopak
    • Intermec
  • Weighing and Metal Detection

    • Loma
    • Ishida
    • KBA-Metronic

For more information on the AutoCoding Gateway, contact info@autocodingsystems.com

Or take a look at the website: https://autocodingsystems.com/solutions/iiot/

Client API Usage

Quickstart: get devices from a local gateway

const Api = require('@autocodingsystems/gateway-client')

const local_gw = new Api('http://localhost:8002')

const run = async () => {
    console.log(await local_gw.raw.getDevices());
}

run();

Description

const Api = require('@autocodingsystems/gateway-client')

This provides a constructor for an Api object. To instantiate the Api, pass in the base Url of the gateway you wish to communicate with as a string:

const local_gw = new Api('http://localhost:8002')

No connections are made until you make a call on the resulting api object, so it's safe to make this object early and hold onto it, or make these api objects lazily just as you need them.

The main part of the return api object are the raw calls that can be made on the gateway under the raw property.

await local_gw.raw.getDevices()

All api calls that contact the gateway are async and return a Promise object that resolves with the data from the gateway.

Raw

getDevices

params

none

returns An array of device objects

{
    Id: <integer> // Internal gateway id for this device, use for subsequent calls
    Name: <string> // Display name for this device
    SupportedDeviceId: <string> // Gateway id of the driver used for this device
    Classes: <array of string> // Capabilities of the device
    HealthStatus: <string> // Overall health of the device
    Active: <bool> // True when the drivers are trying to talk to the device
}

remarks Returns an array of the devices available on the gateway.

getDevice

params

    Id: <integer> // Internal gateway id for this device

returns

A single object representing the configuration of the device

{
    Id: <integer> // Internal gateway id for this device
    Name: <string> // Display name for this device
    SupportedDeviceId: <string> // Gateway id of the driver used for this device
    Classes: <array of string> // Capabilities of this device
    HealthStatus: <string> // Overall health of the device
    Active: <bool> // True when the drivers are trying to talk to the device
    ActivationTime: <string> // Date when this device was activated
    ApplicationNodeId: <int> // Data tag for this device
    SocketClass: <string> // Determines how the driver communicates with the device
    SocketConfiguration: <array of Name Value pairs> configuration for the driver communication with the device
    DeviceConfiguration: <array of Name Value pairs> configuration for the driver
}

remarks

This returns the full details of how a device driver has been configured and whether it's activated and when.

getDeviceStatus

params

    Id: <integer> // Internal gateway id for this device

returns

An array of objects representing the driver properties of the device

{
    Active: <bool> Is in use
    AssignmentTime: <datetime> Timestamp for when last changed
    Description: <string> Text description
    Grouping: <string> Group it belongs to
    HealthStatus: <string> Indication of whether it indicates a problem with the device or not
    HealthStatusMeaning: <string> Describes the problem represented, if any
    Name: <string> The display name
    PropertyType: <Property | Counter>
    Value: <string> Actual value
}

remarks

This gives access to the published state of the driver, representing as much information as the driver has on the device at any point in time.

addDevice

params

    details: <object> // The device details to add to the gateway

{
    DeviceName: <string> // Name to display
    SupportedDeviceId: <string> // Internal Id of the driver to use for this device
    ApplicationNodeId: <integer> // A data tag that can be assigned to the device
    SocketClass: <string> // The name of the communication method used to talk to the device. The values available depend on the value of SupportedDeviceId. Usually 'NE.Connectivity.TcpClient'
    SocketConfigurationSettings: <array of Name Value pairs> // The configuration for the communications with the devic. The exact values available depends on the value of SocketClass
    DriverConfigurationSettings: <array of Name Value pairs> // The configuration of the driver. The exact values available depends on the value of SupportedDeviceId
}

returns

An objects containing the DeviceId of the driver just added

{
    DeviceId: <integer> Internal gateway id for this device
}

remarks

This method lets you add a new device to a gateway. Determining the exact values available can be tricky, but all the information is available from the gateway's Api. The easiest way to configure a device is to use the Gateway's dashboard. However, the information can be put together using the list of available device types (getSupportedDevices) and the detailed information for each device type (getSupportedDevice). The dashboard uses this data to build its UI, so you can do the same if you wish.

You can retrieve the details for an existing device in a format suitable for passing to this call using the command line client. The --backup flag will return JSON that can be sent into this api endpoint to duplicate the device:

npx @autocodingsystems/gateway-client details "http://localhost:8002" "Line_2_SideCoder" --backup

applyDeviceJob

params

    id: <integer> // Internal gateway id for the device
    job: <object> // The javascript object representing the device job

{
    Name: <string> // Display name for the job
    DeviceProfile: <object> // The job profile to apply to the device
    {
        Name: <string> // The device profile to select for the device
        Driver: <string> // The driver this job was created for
        Properties: <array> // The device and job specific data
    },
    VariableSet: <object> // The data to substitue into the job
    {
        Name: <string> // The name of the VariableSet (unused)
        Values: <array of Key Value pairs> // Job specific data
        { 
            Key: <string>
            Value: <string>
        }
    },
    Files: <array of object> // Files to use in the job
    {
        Name: <string> // Name of the file that the job expects to use
        Content: <string> // Contents of the file
        IsBase64: <bool> // True if Content is a base64 string that needs decoding before use
    },
    Metadata: <object> // Optional Details about this job
    {
        DeviceTypeName: <string> // Display name of the type of device this job is for
        DeviceProfileSpecificationVersion: <string> // The exact version of the device profile that this job represents
    }
}

returns

If successful, nothing is returned. You need to query the gateway (or subscribe to events) to get the status of the job.

remarks

It's important to note that the job passed into this call is expected to be a fully parsed Javascript object, not a string.

Even more than when adding a device, a job is a very complex and specialised object. It would not be expected to create a job from scratch every time it's used. The contents of the DeviceProfile section vary widely between different kinds of devices. Instead, it's expected to use the gateway to generate a job using the UI and save the Json file out for later use.

The normal way to re-use jobs is to modify the VariableSet portion before sending it to the device. The VariableSet contains the data that gets used by the rest of the device profile and is in a consistent, specific format that is easy to manipulate regardless of the device type. A VariableSet can contain duplicates of variables - the first instance found is the one used.

removeDeviceJob

params

    id: <integer> // Internal gateway id for this device

returns

If successful, nothing is returned. You need to query the gateway (or subscribe to events) to get the status of the job.

remarks

This allows you to remove a job from a device and return it to a "quiet" state.

getDeviceJobStatus

params

    id: <integer> // Internal gateway id for this device

returns

An object representing the status of the job on the device

{
    Status: <Unknown | Clear | Clearing | Updating | Updated | Fault>
    Message: <string> // Error message, if any
}

remarks

Use this to determine whether a device has a job on it. If a device has been activated but has not yet had a job assigned to it, or been cleared, then status will be Unknown.

deleteDevice

params

    id: <integer> // Internal gateway id for this device

returns

No return if successful

remarks

Delete a device from a gateway. If a driver is active then the driver will stay active even though it's deleted. The driver will not stop and the device will not be removed from the dashboard until the device is deactivated.

setActive

params

    id: <integer> // Internal gateway id for this device,
    active: <bool> // True to start a driver communicating with a device, false to stop it

returns

On success, nothing is returned

remarks

Activating a device loads the appropriate driver, gives the driver the configuration for this device and starts the driver trying to communicate with the device.

Once a device is active, it cannot be modified or deleted. The calls to modify a device will succeed and will work, but their results will not be apparent until the device is deactivated.

Once a device is activated, the gateway will remember this and if the gateway is restarted, will reactivate all devices that were active before it was stopped.

getSupportedDevices

params

    none

returns

An array of objects representing the drivers available for the gateway

{
    Id: <string> // Internal id for the driver
    Name: <string> // Name of the driver
    AlternativeName: <string> // Human readable name
    Classes: <array of string> // Capabilities of this driver
    SupportedSockets: <array of string> // Sockets supported by the driver
}

remarks

This represents the full list of devices available on a gateway

getSupportedDevice

params

    id: <string> // Internal gateway id for the driver

returns

An object representing the full details for this driver

{
    Id: <string> // Internal id for the driver
    Name: <string> // Name of the driver
    AlternativeName: <string> // Human readable name
    Classes: <array of string> // Capabilities of this driver
    DeviceProfiles: <object> // Complex description of the profiles available for this device
    SocketSpecifications: <array of objects> // The methods used to talk to devices
    {
        Name: <string> // Name of the communication method
        Properties: <array of properties> // The details for the socket configuration
        {
            Name: <string> // Property name
            Description: <string> // Description for UIs
            DefaultValue: <string> // The default value for use in UIs
            Type: <String | Boolean | Int64> // The type of the configuration value
            Options: <array of string> // The allowed values of the property
            PropertyType: <SelectFromOptions | UserDefined>
        }
    },
    DeviceProperties: <array of objects> // The configuration of the driver
    {
        Name: <string> // Property name
        Description: <string> // Description for UIs
        DefaultValue: <string> // The default value for use in UIs
        Type: <String | Boolean | Int64> // The type of the configuration value
        Options: <array of string> // The allowed values of the property
        PropertyType: <SelectFromOptions | UserDefined>
    }
}

remarks

The full details of a driver can be used to build UIs for configuring a device

Events

The api can receive events from a given gateway:

local_gw.events([{subscription: '*-*-*', tag: 'everything'}], onconnection, onevent, onerror);

params

subscriptions: <array of subscriptions> // which events to subscribe to
{
    subscription: <string> // Subscription definitions, eg "*-*-*" for everything
    tag: <string> // Data included whenever an event is fired to identify which subscription it's for
}
onconnection: <function> // function to call when connection status changes
    connected: <bool> // Whether we're connected or not
    tags: <array of string> // Array of all tags affected
onevent: <function> // The function to call whenever an event is received from the gateway
    data: <object> // The data representing the event
    {
        gateway: <string> // the url of the gateway raising the event
        deviceId: <integer> // the internal gateway id of the device
        timestamp: <string> // timestamp of the event
        eventClass: <DeviceControl | CodeReader> // The class the event comes from
        event: <string> // The name of the event
        subKey: <string> // The subscription key used to subscribe to this event
        tag: <string> // The tag associated with the subscription
        message: <object> // event specific data
    }
onerror: <function> // fired when there's an error
    data: <object> // Data object describing the error
    {
        type: <string> overall type of error
        error: <object> error specific data
        tags: <array of string> the tags affected by the error
    }

returns

An object representing the subscriptions

{
    stop: <function> // Function to call with no parameters to stop the events stream.
}

remarks

Events are the main way to get information from a device. An event subscription is made up of 3 parts separated by dashes:

  • the device id as an integer
  • the event class
  • the event name

Any part can be replaced with a * character to accept any value, so all events on the gateway can be retried using the subscription string of *-*-*

The complete list of events available:

  • CodeReader
    • BarcodeScanned
    • NoReadsLimitBreached
    • PecBlocked
    • GoodReadsCounterUpdated
    • BadReadsCounterUpdated
    • NoReadsCounterUpdated
  • CheckWeigher
    • BatchUpdate
    • EndOfBatchReport
    • ReportingStatusUpdate
    • StartOfBatchInformation
    • PackWeight
  • MetalDetector
    • ReportingStatusUpdate
    • StartOfBatchInformation
    • BatchUpdate
    • ContaminantUpdate
    • EndOfBatchReport
    • ProductValidationUpdate
  • Coder
    • PrintCountUpdate
  • GenericDataStream
    • PacketReceived
  • DigitalInputs
    • DigitalInputStateChanged DigitalInputCounterValueChanged
  • DigitalOutputs
    • DigitalOutputStateChanged
    • DigitalOutputOverrideStateChanged
  • DeviceControl
    • JobStatusChanged
    • PropertyChanged
    • OverallHealthChanged
  • Reporting
    • ReportingEvent

Miscellany

The api offers some extra methods to help common tasks

collisionmodes

These encapsulate the standard ways of handling name collisions on a gateway. The collisionmodes has the following methods, each with the same api and usage:

  • duplicate
  • rename
  • skip
const desiredName = local_gw.collisionmodes.rename('Desired Name', exisingobjs);
const availableName = local_gw.collisionmodes.rename('Desired Name', exisingobjs);
const desiredNameOrFalsey = local_gw.collisionmodes.skip('Desired Name', exisingobjs);

params

desiredName: <string> // The name we want for a new device on the gateway
existingDevices: <array of devices> // The existing devices on the gateway

returns

The name to use when adding a device to the gateway. This may be different to the desired name and may be falsey.

remarks

The gateway allows multiple devices to have the same name. Each device gets its own internal Id which can be used to disambiguate references to each device - names are generally considered for Display purposes by the gateway itself.

This api allows you to perform soft checking to ensure that names aren't duplicated, if you desire. However no guarantees are made as to concurrency: you may recieve a name that's unique, but another client may add that name before you do - the infrastructure needs to ensure that multiple processes aren't adding devices across all the gateways.

Note that existingDevices is an array of objects, each with a Name string property. This array can come from the getDevices() call. The rename mode will modify the existingDevices array so that multiple calls to this mode will each receive a unique name even if name collisions would have otherwise occurred.

applyDataToJob

Modifies a job object with the given job data.

local_gw.applyDataToJob(job, data);

params

job: <object> // A full object representing a job for a device
data: <array of Key Value pairs> // The data to apply to the job

returns

Nothing, the original job object gets modified.

remarks

This can be done manually without using this api, but it is provided as a convenience.

The given data will override any existing data on the job. The given data is merged with the existing data - any data not overwritten will keep its previous value.

applyDataToJob can be called multiple times with different data sets to apply data from different sources. The data in the later calls will always override the data in the previous calls.

A lot of validation is done on the parameters to ensure that they are being passed correctly. The job is expected to have the following shape, at a minimum:

{
    VariableSet: {
        Name: 'Parameters',
        Values: []
    }
}

The data must take the form of an array of objects with Key and Value properties, as follows:

[
    {
        Key: 'VARIABLE NAME',
        Value: 'The data to use'
    }
]

It is valid to assign an empty array of data to a job, the result is that the job's VariableSet remains unchanged.

waitForJobStatusChange

Wait for a job to change status.

var result = await local_gw.waitForJobStatusChange(4, 'Updating', 60000);

params

    id: <integer> // Internal gateway id for this device
    status: <Unknown | Clearing | Clear | Updating | Updated | Fault> // The status we want to move away from
    timeout: <integer optional> // Maximum length of time to wait in ms

returns

An object representing the status changed to

{
    Status: <Unknown | Clearing | Clear | Updating | Updated | Fault>
    Message: <string> the fault message if any
}

remarks

Used to wait until a job has been applied or cleared. After a call to apply or clear has returned, the device will be in either Clearing or Updating state as appropriate. We then need to wait for this to change before we know if the operation was successful or not.

The status may then become Fault, Clear or Updated, as appropriate. We receive the resulting status and any fault message as a return value.

If the operation timed out, Message will be set to indicate that a timeout occurred.

Commandline Usage

From the commandline:

npx @autocodingsystems/gateway-client <command> [command options ...]

To get the full list of commands available, just run without a command:

npx @autocodingsystems/gateway-client

To get the options available for a command, run the command without any options:

npx @autocodingsystems/gateway-client <command>

Commandline options can sometimes be given by position, these are indicated with an _ in the command's help.

For example, the list command takes a --target parameter. If you omit --target, then the first unnamed parameter gets used as the target.

The following commands are equivalent:

npx @autocodingsystems/gateway-client list --target="http://localhost:8002"
npx @autocodingsystems/gateway-client list --target=http://localhost:8002
npx @autocodingsystems/gateway-client list --target http://localhost:8002
npx @autocodingsystems/gateway-client list http://localhost:8002

Unnamed parameters are assigned in the order that the parameters are listed in the command's help.

Common options

A gateway holds a set of named devices. The commands available operate on these devices by name.

--target

This option is common to all commands and specifies which gateway to talk to. The url should be of the form: http://127.0.0.1:8002

--name

Most commands can affect multiple devices and so the --name parameter can be used to limit which devices are affected. The --name parameter can accept wildcards in any position to perform matching against multiple devices.

--raw

By default, commands return english text describing their results. If further processing is needed on the results, they can instead be returned in JSON format ready to be parsed using this flag.

The format is one line of JSON per operation performed.

Package Sidebar

Install

npm i @autocodingsystems/gateway-client

Weekly Downloads

3

Version

1.5.1

License

ISC

Unpacked Size

86.9 kB

Total Files

50

Last publish

Collaborators

  • autocodingadmin