@autocodingsystems/gateway-client
v1.5.1
Published
Library and commandline utility to control the acs gateway - device drivers for the most common industrial production line devices
Downloads
34
Maintainers
Readme
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 [email protected]
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.