LitmusEdge 4.0.x API Documentation/Analytics - LE, LEM, LUNS API Docs
Building a pipeline? Read /workflows/build-analytics-pipeline.md first.
Need the catalog of processors with their params and required wire definitions? Read /reference/analytics-processors.md (56 processors on LE 4.0.x, with description and config keys per processor). The reference page is a static snapshot; call
Get All (Supported) Processors Metadataon the target device for exact defaults, enums, and UI hints.THE ONE RULE: an analytics pipeline is always SOURCE -> TRANSFORM(s) -> SINK, wired together. A lone
JSONata/Expression/ KPI processor does nothing on its own (nothing feeds it, nothing consumes it). Minimum pipeline = 3 processors + 2 wires (the wire feeding a sink/publish is alwaysevents).A processor's role is set by its
ConnectDirectionfield inGet All (Supported) Processors Metadata: -outputOnly= SOURCE (e.g.DataHub Subscribe,Generator,Inject,Database Batch Input) -inputOnly= SINK (e.g.DataHub Publish,Database Output,StdOut,FileWriter) -inputOutput= TRANSFORM (everything else:JSONata,Expression, KPI/OEE, anomaly, windows, ...)EXCEPTIONS (a node can run without an input wire two ways): (1)
FeaturescontainsInvoke-> driven on demand viaInvoke Processor. Live set:Inject,Database Batch Input,FileReader,Delay/Rate-Limit,AI Responses. (2) a parameter supplies the data directly -> e.g.AI Visionhasfile_path_for_image("leave empty to use input message as the image"), so it runs standalone when set or wired when empty. Check bothFeaturesand theParameterslabels; do not infer "needs input" fromConnectDirectionalone.Tag data arrives as a flat DeviceHub/DataHub message (fields
value,tagName,deviceID,datatype,timestamp, ... nopayloadwrapper). Full shape: /reference/devicehub-message-format.md. AJSONataschema is object construction over those fields, e.g.{"value": value}.Two ways to build: (a) step by step --
Create New Processorper node, thenConnect Processor InstanceswithConnectionType: "values"or"events"(PLURAL; the API rejects the singular"value"/"event"). NOTE Connect's fields are reversed:Inputs= the upstream producer,Outputs= the downstream consumer. (b) one-shot -- author the whole group as aBackupItemJSON and load it withImport Group(additive: creates/replaces the named group, other groups untouched; placement via eachPositions[].GroupName). Each wire is mirrored on BOTH sides: producerOutputs+= consumer ID AND consumerInputEvents+= producer ID (useInputWaitsfor value-combine inputs);InputsDefinitions {slot: producer}only for named-input nodes likeExpression. Full step tables, the import JSON template, and recipes (subscribe+publish-one-key, OEE, anomaly/SPC) are in /workflows/build-analytics-pipeline.md.
Get All Groups
POST {{edgeUrl}}/analytics/v3
Get All Groups
Returns every analytics group defined on the device. Groups are logical buckets used to scope processors and permissions; default is always present.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetGroups {
GetGroups
}
No arguments.
Response
200 OK -- application/json. data.GetGroups is a plain array of strings (the group names).
{
"data": {
"GetGroups": [
"PredictiveMaintenance",
"OEE - Line 2",
"default",
"SPC"
]
}
}
To get the processors inside a group, call Get Processor Instances with input: <groupName>.
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetGroups {
GetGroups
}
Response
Status: 200 OK
{
"data": {
"GetGroups": [
"PredictiveMaintenance",
"OEE - Line 2",
"OEE - Line 4",
"Preventative Maintenance",
"default",
"OEE - Line 1",
"OEE - Line 3",
"SPC"
]
}
}
Get Processor Instances
POST {{edgeUrl}}/analytics/v3
Get Processor Instances
Returns every processor instance inside one group, with the full configuration needed to render or edit it.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetProcessorInstances($input: String!) {
GetProcessorInstances(input: $input) {
ID
Name
Function
Definitions { Key Value }
ValueInputs
EventInputs
Parameters { Key Value }
Active
Outputs
}
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Group name (e.g. default). |
{ "input": "{{analytics_group_name}}" }
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetProcessorInstances |
[Processor!]! |
All processors in the requested group. |
Processor.ID |
ID |
Processor UUID. Used wherever {{analytics_single_processor_id}} appears. |
Processor.Name |
String |
Display name (often <FunctionName> - [NNNN] for auto-named processors). |
Processor.Function |
String |
Function key (Generator, Database Output, Moving Average, ...). See Get All (Supported) Processors Metadata for the catalog. |
Processor.Definitions |
[KV!]! |
Definition entries (function-specific input bindings). |
Processor.ValueInputs |
[ID!]! |
UUIDs of upstream processors feeding value wires into this one. |
Processor.EventInputs |
[ID!]! |
UUIDs of upstream processors feeding event wires. |
Processor.Parameters |
[KV!]! |
Function-specific tunables (e.g. pollingInterval, window). |
Processor.Active |
Boolean |
true if the processor is currently running. |
Processor.Outputs |
[ID!]! |
UUIDs of downstream processors this one feeds. |
Example response (excerpt)
{
"data": {
"GetProcessorInstances": [
{
"ID": "38687BA1-C2F2-450A-8A9C-9BF10617BADB",
"Name": "DataHub Subscribe - [5513]",
"Function": "DataHub Subscribe",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [
{ "Key": "ignore_failed_data", "Value": "false" },
{ "Key": "ignore_null_value", "Value": "false" }
],
"Active": true,
"Outputs": []
}
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetProcessorInstances($input: String!) {
GetProcessorInstances(input: $input) {
ID
Name
Function
Definitions {
Key
Value
}
ValueInputs
EventInputs
Parameters {
Key
Value
}
Active
Outputs
}
}
Variables
{
"input": "{{analytics_group_name}}"
}
Response
Status: 200 OK
{
"data": {
"GetProcessorInstances": [
{
"ID": "38687BA1-C2F2-450A-8A9C-9BF10617BADB",
"Name": "DataHub Subscribe - [5513]",
"Function": "DataHub Subscribe",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [
{
"Key": "ignore_failed_data",
"Value": "false"
},
{
"Key": "ignore_null_value",
"Value": "false"
},
{
"Key": "topic",
"Value": "scrapHistoryRecord"
}
],
"Active": true,
"Outputs": [
"7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7"
]
},
{
"ID": "CA4DA5E7-5DAD-4131-A95D-1152E92197F6",
"Name": "DataHub Subscribe - [1311]",
"Function": "DataHub Subscribe",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [
{
"Key": "format",
"Value": "json"
},
{
"Key": "topic",
"Value": "P2_EnergyMonitoring"
}
],
"Active": true,
"Outputs": [
"10A5AFCD-D002-4DD0-A7EE-81DBCE813937"
]
},
{
"ID": "10A5AFCD-D002-4DD0-A7EE-81DBCE813937",
"Name": "Database Output - [9039]",
"Function": "Database Output",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [
"CA4DA5E7-5DAD-4131-A95D-1152E92197F6"
],
"Parameters": [
{
"Key": "database",
"Value": "tsdata"
},
{
"Key": "measurement",
"Value": "EnergyMonitoring"
},
{
"Key": "typed",
"Value": "autogen"
}
],
"Active": true,
"Outputs": []
},
{
"ID": "1C589F97-66F4-43A8-BBC3-738C46F11EFD",
"Name": "Flow - [9175]",
"Function": "Database Output",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [
"41BE8686-B8C8-485E-9B40-76F471A63D4D"
],
"Parameters": [
{
"Key": "database",
"Value": "tsdata"
},
{
"Key": "measurement",
"Value": "EnergyMonitoring"
},
{
"Key": "typed",
"Value": "autogen"
}
],
"Active": true,
"Outputs": []
},
{
"ID": "41BE8686-B8C8-485E-9B40-76F471A63D4D",
"Name": "DataHub Subscribe - [644]",
"Function": "DataHub Subscribe",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [
{
"Key": "format",
"Value": "json"
},
{
"Key": "topic",
"Value": "P1_EnergyMonitoring"
}
],
"Active": true,
"Outputs": [
"1C589F97-66F4-43A8-BBC3-738C46F11EFD"
]
},
{
"ID": "E8ED3C80-690C-4549-A509-BBEFE66F039E",
"Name": "DataHub Subscribe - [7390]",
"Function": "DataHub Subscribe",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [
{
"Key": "ignore_failed_data",
"Value": "false"
},
{
"Key": "ignore_null_value",
"Value": "false"
},
{
"Key": "topic",
"Value": "downtimeHistoryRecord"
}
],
"Active": true,
"Outputs": [
"5B4DC834-C069-4340-986A-BC45957D5E07"
]
},
{
"ID": "5B4DC834-C069-4340-986A-BC45957D5E07",
"Name": "Database Output - [5434]",
"Function": "Database Output",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [
"E8ED3C80-690C-4549-A509-BBEFE66F039E"
],
"Parameters": [
{
"Key": "database",
"Value": "tsdata"
},
{
"Key": "measurement",
"Value": "DTR"
},
{
"Key": "typed",
"Value": "autogen"
}
],
"Active": true,
"Outputs": []
},
{
"ID": "7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7",
"Name": "Database Output - [8347]",
"Function": "Database Output",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [
"38687BA1-C2F2-450A-8A9C-9BF10617BADB"
],
"Parameters": [
{
"Key": "database",
"Value": "tsdata"
},
{
"Key": "measurement",
"Value": "SR"
},
{
"Key": "typed",
"Value": "autogen"
}
],
"Active": true,
"Outputs": []
}
]
}
}
Get Group Locking Status
POST {{edgeUrl}}/analytics/v3
Get Group Locking Status
Returns the optimistic-locking state for a group. The LE UI uses this to prevent two operators from concurrently editing the same group's pipeline. A locked group cannot be edited by anyone other than the holder of the lock until the lock expires or is released (Set Group Locking Status with Mode: CHECKIN).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetGroupLockStatus($input: String!) {
GetGroupLockStatus(input: $input) {
GroupName
LockDeadline
LockedBy
LockTime
}
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Group name. |
{ "input": "{{analytics_group_name}}" }
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetGroupLockStatus.GroupName |
String |
Group name, echoed. |
data.GetGroupLockStatus.LockDeadline |
Time |
When the current lock expires. 0001-01-01T00:00:00Z (sentinel) when no lock is held. |
data.GetGroupLockStatus.LockedBy |
String |
API token / user that holds the lock. Empty when no lock is held. |
data.GetGroupLockStatus.LockTime |
Time |
When the lock was acquired. Sentinel 0001-01-01T00:00:00Z when no lock is held. |
{
"data": {
"GetGroupLockStatus": {
"GroupName": "default",
"LockDeadline": "0001-01-01T00:00:00Z",
"LockedBy": "",
"LockTime": "0001-01-01T00:00:00Z"
}
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetGroupLockStatus($input: String!) {
GetGroupLockStatus(input: $input) {
GroupName
LockDeadline
LockedBy
LockTime
}
}
Variables
{
"input": "{{analytics_group_name}}"
}
Response
Status: 200 OK
{
"data": {
"GetGroupLockStatus": {
"GroupName": "default",
"LockDeadline": "0001-01-01T00:00:00Z",
"LockedBy": "",
"LockTime": "0001-01-01T00:00:00Z"
}
}
}
Set Group Locking Status
POST {{edgeUrl}}/analytics/v3
Set Group Locking Status
Acquires (CHECKOUT), releases (CHECKIN), or steals (Force: true) a group's edit lock. Pair with Get Group Locking Status for live UI state.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation SetGroupLockStatus($input: SetGroupTopicsRequest!) {
SetGroupLockStatus(input: $input)
}
Variables (input: SetGroupTopicsRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
GroupName |
String! |
Yes | Group to lock or unlock. |
Mode |
String! |
Yes | CHECKOUT to acquire the lock; CHECKIN to release it. |
Force |
Boolean |
No | Default false. true to acquire the lock even if another user already holds it (the existing holder is preempted). |
{
"input": {
"GroupName": "{{analytics_group_name}}",
"Mode": "CHECKIN",
"Force": false
}
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "SetGroupLockStatus": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation SetGroupLockStatus($input: SetGroupTopicsRequest!) {
SetGroupLockStatus(input: $input)
}
Variables
{
"input": {
"GroupName": "{{analytics_group_name}}",
"Mode": "CHECKIN",
"Force": false
}
}
Response
Status: 200 OK
{
"data": {
"SetGroupLockStatus": null
}
}
Get Processor Positions
POST {{edgeUrl}}/analytics/v3
Get Processor Positions
Returns the UI canvas coordinates of every processor in a group -- the same {Top, Left} values used by the LE UI to render the pipeline diagram. Useful when building a custom UI on top of Analytics, or for exporting/importing a pipeline layout.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetProcessorInstancePositions($input: String!) {
GetProcessorInstancePositions(input: $input) {
Key
Value {
Top
Left
GroupName
}
}
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Group name. |
{ "input": "{{analytics_group_name}}" }
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetProcessorInstancePositions |
[Entry!]! |
One entry per processor in the group. |
data.GetProcessorInstancePositions[].Key |
ID |
Processor UUID. |
data.GetProcessorInstancePositions[].Value.Top / .Left |
Int |
Canvas coordinates in the LE UI's editor. |
data.GetProcessorInstancePositions[].Value.GroupName |
String |
Group name (echoes the request). |
{
"data": {
"GetProcessorInstancePositions": [
{
"Key": "10A5AFCD-D002-4DD0-A7EE-81DBCE813937",
"Value": { "Top": 16, "Left": 0, "GroupName": "default" }
}
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetProcessorInstancePositions($input: String!) {
GetProcessorInstancePositions(input: $input) {
Key
Value {
Top
Left
GroupName
}
}
}
Variables
{
"input": "{{analytics_group_name}}"
}
Response
Status: 200 OK
{
"data": {
"GetProcessorInstancePositions": [
{
"Key": "10A5AFCD-D002-4DD0-A7EE-81DBCE813937",
"Value": {
"Top": 16,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "E8ED3C80-690C-4549-A509-BBEFE66F039E",
"Value": {
"Top": 357,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "5B4DC834-C069-4340-986A-BC45957D5E07",
"Value": {
"Top": 357,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "38687BA1-C2F2-450A-8A9C-9BF10617BADB",
"Value": {
"Top": 241,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "41BE8686-B8C8-485E-9B40-76F471A63D4D",
"Value": {
"Top": 125,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "CA4DA5E7-5DAD-4131-A95D-1152E92197F6",
"Value": {
"Top": 16,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "1C589F97-66F4-43A8-BBC3-738C46F11EFD",
"Value": {
"Top": 125,
"Left": 0,
"GroupName": "default"
}
},
{
"Key": "7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7",
"Value": {
"Top": 241,
"Left": 0,
"GroupName": "default"
}
}
]
}
}
Get Available DB Measurements
GET {{edgeUrl}}/stats/db
Get Available DB Measurements
Returns the time-series databases and their measurements (tables) available on the device. This is not a /analytics/v3 endpoint -- it borrows from DataHub at /stats/db. It is surfaced under Analytics because it's most commonly used when configuring a Database Output or Database Input processor that needs to pick a target measurement.
This endpoint returns the same payload as DataHub > List DBs -- see that page for the full field reference.
Endpoint
GET {{edgeUrl}}/stats/db
Authentication
HTTP Basic Auth. Username is your API token, password is empty. Tokens are managed under System > Access Control > Tokens.
Parameters
None.
Response
200 OK -- application/json. Array of database objects with name, size, and measurements[]. See DataHub > List DBs for the field-by-field reference and example.
Errors
| HTTP status | When it happens |
|---|---|
400 Bad Request |
Missing or malformed query/body parameter. |
401 Unauthorized |
Missing or invalid credentials. |
403 Forbidden |
Token lacks permission for this operation. |
404 Not Found |
Target entity does not exist. |
5xx |
Service is unreachable, restarting, or internally errored. Inspect device logs under System > Support. |
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Response
Status: 200 OK
[
{
"name": "tsdata",
"size": 69788326,
"measurements": [
"Anomaly",
"DTR",
"EnergyMonitoring",
"OEEData",
"P1_L1_Machine1_1_OPC.7C24EDB3-D95C-4097-ADFE-EA7228175ACD",
"P1_L1_Machine2_1_MB.16FC5E6A-345A-4257-A939-9E13F5C416F1",
"P1_L1_Machine3_1_S7.024F0542-540E-4556-8445-13F5158A9E67",
"P1_L2_Machine2_1_MB.0A99BA31-89B9-45B3-822B-3A94CDDAB411",
"P1_L2_Machine3_1_S7.55C2503D-A9A1-4F0E-A538-EA74E98187ED",
"P2_L1_Machine1_1_OPC.F96584F6-DD85-4B7D-9053-53C68C67D290",
"P2_L1_Machine2_1_MB.7BF01228-1B5C-4EFE-9E3C-8E01E2F7F2F6",
"P2_L1_Machine3_1_S7.94D8E47F-9307-47F7-9F8E-B47AE6B90695",
"P2_L2_Machine1_1_OPC.538054E8-2349-4AD0-8C87-830C9A06B118",
"P2_L2_Machine2_1_MB.CEEEF257-0DB8-4F0C-9C0F-B17301B7A673",
"P2_L2_Machine3_1_S7.C27E0DAC-B863-489F-8A19-F526EE6FE2D2",
"SR",
"XMR",
"classification"
]
}
]
Get Parameters
POST {{edgeUrl}}/analytics/v3
Get Parameters
Lists every global parameter known to Analytics. Parameters are read-only at runtime (compare with variables, which are read/write); they are typically set via Variables > Set Parameters during provisioning.
This is the same payload available to processors at runtime when they reference $parameter("<name>") in their configuration.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetParameters {
GetParameters {
DataType
Name
Value
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetParameters |
[Parameter!]! |
All global parameters. |
data.GetParameters[].DataType |
String |
Type: STRING, INT, FLOAT, BOOL, etc. |
data.GetParameters[].Name |
String |
Parameter name. |
data.GetParameters[].Value |
String |
Parameter value (always serialized as string regardless of DataType). |
{
"data": {
"GetParameters": [
{ "DataType": "STRING", "Name": "key", "Value": "valye" }
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetParameters {
GetParameters {
DataType
Name
Value
}
}
Variables
{}
Response
Status: 200 OK
{
"data": {
"GetParameters": [
{
"DataType": "STRING",
"Name": "key",
"Value": "valye"
}
]
}
}
Get Topics in Group
POST {{edgeUrl}}/analytics/v3
Get Topics in Group
Searches the topics published by processors inside a single group, filtered by a substring or pattern. Used by the LE UI to populate autocomplete dropdowns when wiring downstream consumers (e.g. an Integration's MQTT bridge) to analytics outputs.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetGroupTopics($input: GetGroupTopicsRequest!) {
GetGroupTopics(input: $input) {
TotalItems
IsLastPage
Children {
Name
ID
}
}
}
Variables (input: GetGroupTopicsRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
GroupName |
String |
Yes | Group to search inside. |
TagPattern |
String |
Yes | Pattern to match on topic name. |
TagPatternSearchOption |
String |
Yes | Search mode: CONTAINS, STARTSWITH, ENDSWITH, EQUALS. |
Limit |
Int |
Yes | Page size. |
SkipCount |
Int |
Yes | Offset to skip (paging). |
{
"input": {
"GroupName": "{{analytics_group_name}}",
"Limit": 10,
"SkipCount": 0,
"TagPattern": "analytics",
"TagPatternSearchOption": "CONTAINS"
}
}
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetGroupTopics.TotalItems |
Int |
Total matching topics across all pages. |
data.GetGroupTopics.IsLastPage |
Boolean |
true if this is the final page. |
data.GetGroupTopics.Children |
[Topic!]! |
Matching topics in this page. |
data.GetGroupTopics.Children[].Name |
String |
Topic name (e.g. analytics.publish.<id>). |
data.GetGroupTopics.Children[].ID |
ID |
Topic ID. |
{
"data": {
"GetGroupTopics": {
"TotalItems": 1,
"IsLastPage": true,
"Children": [
{ "Name": "analytics.publish.u6PLGF3J1D-C_PQXmJC9Y", "ID": "373ef09a-c290-413d-969c-9db308142c6a" }
]
}
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetGroupTopics($input: GetGroupTopicsRequest!) {
GetGroupTopics(input: $input) {
TotalItems
IsLastPage
Children {
Name
ID
}
}
}
Variables
{
"input": {
"GroupName": "{{analytics_group_name}}",
"Limit": 10,
"SkipCount": 0,
"TagPattern": "analytics",
"TagPatternSearchOption": "CONTAINS"
}
}
Response
Status: 200 OK
{
"data": {
"GetGroupTopics": {
"TotalItems": 1,
"IsLastPage": true,
"Children": [
{
"Name": "analytics.publish.u6PLGF3J1D-C_PQXmJC9Y",
"ID": "373ef09a-c290-413d-969c-9db308142c6a"
}
]
}
}
}
Export Group
POST {{edgeUrl}}/analytics/v3
Export Group
Serializes an entire group -- its processors, wire definitions, canvas positions, AI models, variables, and parameters -- as a single GraphQL response payload. The output is the source-of-truth backup of a pipeline and is the input to Import Group.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query ExportGroup($input: String!) {
ExportGroup(input: $input) {
Processors {
ID
Name
FunctionName
IsActive
Config { settings }
InputEvents
InputWaits
InputsDefinitions
State
Outputs
}
Positions { ID Top Left GroupName }
Version
Git
AIModels { UniqueName Provider URL ModelName }
Variables { UniqueName DataType DBValue IsReadWrite IsPersistent }
Parameters { UniqueName DataType DBValue IsReadWrite IsPersistent }
}
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Group name to export. |
{ "input": "{{analytics_group_name}}" }
Response
200 OK -- application/json. Carries:
Processors-- full processor records with their wiring and settings.Positions-- canvas coordinates.Version/Git-- the Analytics service build that produced the export.AIModels-- AI model references used by the group (URL + ModelName only; API keys are not included).Variables/Parameters-- global state at export time.
To restore on the same or another device, feed the entire ExportGroup payload back through Import Group as the data argument.
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
Security note
The export omits secrets (API keys for AI models, integration credentials) but does include processor settings which may reference variable names or DB names. Review before sharing externally.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query ExportGroup($input: String!) {
ExportGroup(input: $input) {
Processors {
ID
Name
FunctionName
IsActive
Config {
settings
}
InputEvents
InputWaits
InputsDefinitions
State
Outputs
}
Positions {
ID
Top
Left
GroupName
}
Version
Git
AIModels {
UniqueName
Provider
URL
ModelName
}
Variables {
UniqueName
DataType
DBValue
IsReadWrite
IsPersistent
}
Parameters {
UniqueName
DataType
DBValue
IsReadWrite
IsPersistent
}
}
}
Variables
{
"input": "{{analytics_group_name}}"
}
Response
Status: 200 OK
{
"data": {
"ExportGroup": {
"Processors": [
{
"ID": "10A5AFCD-D002-4DD0-A7EE-81DBCE813937",
"Name": "Database Output - [9039]",
"FunctionName": "Database Output",
"IsActive": true,
"Config": {
"settings": {
"database": "tsdata",
"measurement": "EnergyMonitoring",
"typed": "autogen"
}
},
"InputEvents": [
"CA4DA5E7-5DAD-4131-A95D-1152E92197F6"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": []
},
{
"ID": "1C589F97-66F4-43A8-BBC3-738C46F11EFD",
"Name": "Flow - [9175]",
"FunctionName": "Database Output",
"IsActive": true,
"Config": {
"settings": {
"database": "tsdata",
"measurement": "EnergyMonitoring",
"typed": "autogen"
}
},
"InputEvents": [
"41BE8686-B8C8-485E-9B40-76F471A63D4D"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": []
},
{
"ID": "373EF09A-C290-413D-969C-9DB308142C6A",
"Name": "Flow - [5609]",
"FunctionName": "DataHub Publish",
"IsActive": true,
"Config": {
"settings": {
"dynamic_topic": false,
"single_topic": true,
"topic": "analytics.publish.u6PLGF3J1D-C_PQXmJC9Y"
}
},
"InputEvents": [
"735E383E-EF78-485F-84CB-E02F205BE98B"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": []
},
{
"ID": "38687BA1-C2F2-450A-8A9C-9BF10617BADB",
"Name": "DataHub Subscribe - [5513]",
"FunctionName": "DataHub Subscribe",
"IsActive": true,
"Config": {
"settings": {
"ignore_failed_data": false,
"ignore_null_value": false,
"topic": "scrapHistoryRecord"
}
},
"InputEvents": [],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": [
"7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7"
]
},
{
"ID": "41BE8686-B8C8-485E-9B40-76F471A63D4D",
"Name": "DataHub Subscribe - [644]",
"FunctionName": "DataHub Subscribe",
"IsActive": true,
"Config": {
"settings": {
"format": "json",
"topic": "P1_EnergyMonitoring"
}
},
"InputEvents": [],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": [
"1C589F97-66F4-43A8-BBC3-738C46F11EFD"
]
},
{
"ID": "5B4DC834-C069-4340-986A-BC45957D5E07",
"Name": "Database Output - [5434]",
"FunctionName": "Database Output",
"IsActive": true,
"Config": {
"settings": {
"database": "tsdata",
"measurement": "DTR",
"typed": "autogen"
}
},
"InputEvents": [
"E8ED3C80-690C-4549-A509-BBEFE66F039E"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": []
},
{
"ID": "735E383E-EF78-485F-84CB-E02F205BE98B",
"Name": "Flow - [5609]",
"FunctionName": "Change of Value",
"IsActive": true,
"Config": {
"settings": {
"delta_of_tolerance": 0,
"map_field_name": "value",
"pass_through_value": false,
"timerInterval": 0
}
},
"InputEvents": [
"97E2788B-CB2E-44CE-8312-41DD1F388286"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": [
"373EF09A-C290-413D-969C-9DB308142C6A"
]
},
{
"ID": "7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7",
"Name": "Database Output - [8347]",
"FunctionName": "Database Output",
"IsActive": true,
"Config": {
"settings": {
"database": "tsdata",
"measurement": "SR",
"typed": "autogen"
}
},
"InputEvents": [
"38687BA1-C2F2-450A-8A9C-9BF10617BADB"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": []
},
{
"ID": "97E2788B-CB2E-44CE-8312-41DD1F388286",
"Name": "Flow - [5609]",
"FunctionName": "DataHub Subscribe",
"IsActive": true,
"Config": {
"settings": {
"ignore_failed_data": false,
"ignore_null_value": false,
"topic": "${hello}"
}
},
"InputEvents": [],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": [
"735E383E-EF78-485F-84CB-E02F205BE98B"
]
},
{
"ID": "A8E5EA5A-7D0F-46A7-848C-D7FF250FB4C2",
"Name": "JSONata - [7992]",
"FunctionName": "JSONata",
"IsActive": true,
"Config": {
"settings": {
"jsonata_schema": "{\n \"value\": ${key}\n}"
}
},
"InputEvents": [
"B6565676-1A31-488E-8B08-AAB0A2127362"
],
"InputWaits": [],
"InputsDefinitions": {},
"State": {
"jsonata_schema": "{\n \"value\": valye\n}"
},
"Outputs": []
},
{
"ID": "B6565676-1A31-488E-8B08-AAB0A2127362",
"Name": "Inject - [7720]",
"FunctionName": "Inject",
"IsActive": true,
"Config": {
"settings": {
"add_timestamp": true,
"inject_field": "${key}",
"inject_value": "somethiang",
"inject_value_type": "string",
"timer_interval_type": "seconds",
"timer_interval_value": 0,
"timing_mode": "once"
}
},
"InputEvents": [],
"InputWaits": [],
"InputsDefinitions": {},
"State": {
"add_timestamp": true,
"inject_field": "valye",
"inject_value": "somethiang",
"inject_value_type": "string",
"timer_interval_type": "seconds",
"timer_interval_value": 0,
"timing_mode": "once"
},
"Outputs": [
"A8E5EA5A-7D0F-46A7-848C-D7FF250FB4C2"
]
},
{
"ID": "CA4DA5E7-5DAD-4131-A95D-1152E92197F6",
"Name": "DataHub Subscribe - [1311]",
"FunctionName": "DataHub Subscribe",
"IsActive": true,
"Config": {
"settings": {
"format": "json",
"topic": "P2_EnergyMonitoring"
}
},
"InputEvents": [],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": [
"10A5AFCD-D002-4DD0-A7EE-81DBCE813937"
]
},
{
"ID": "E8ED3C80-690C-4549-A509-BBEFE66F039E",
"Name": "DataHub Subscribe - [7390]",
"FunctionName": "DataHub Subscribe",
"IsActive": true,
"Config": {
"settings": {
"ignore_failed_data": false,
"ignore_null_value": false,
"topic": "downtimeHistoryRecord"
}
},
"InputEvents": [],
"InputWaits": [],
"InputsDefinitions": {},
"State": null,
"Outputs": [
"5B4DC834-C069-4340-986A-BC45957D5E07"
]
}
],
"Positions": [
{
"ID": "10A5AFCD-D002-4DD0-A7EE-81DBCE813937",
"Top": 234,
"Left": 0,
"GroupName": "default"
},
{
"ID": "1C589F97-66F4-43A8-BBC3-738C46F11EFD",
"Top": 343,
"Left": 0,
"GroupName": "default"
},
{
"ID": "373EF09A-C290-413D-969C-9DB308142C6A",
"Top": 452,
"Left": 0,
"GroupName": "default"
},
{
"ID": "38687BA1-C2F2-450A-8A9C-9BF10617BADB",
"Top": 125,
"Left": 0,
"GroupName": "default"
},
{
"ID": "41BE8686-B8C8-485E-9B40-76F471A63D4D",
"Top": 343,
"Left": 0,
"GroupName": "default"
},
{
"ID": "5B4DC834-C069-4340-986A-BC45957D5E07",
"Top": 16,
"Left": 0,
"GroupName": "default"
},
{
"ID": "735E383E-EF78-485F-84CB-E02F205BE98B",
"Top": 452,
"Left": 0,
"GroupName": "default"
},
{
"ID": "7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7",
"Top": 125,
"Left": 0,
"GroupName": "default"
},
{
"ID": "97E2788B-CB2E-44CE-8312-41DD1F388286",
"Top": 452,
"Left": 0,
"GroupName": "default"
},
{
"ID": "A8E5EA5A-7D0F-46A7-848C-D7FF250FB4C2",
"Top": 561,
"Left": 0,
"GroupName": "default"
},
{
"ID": "B6565676-1A31-488E-8B08-AAB0A2127362",
"Top": 561,
"Left": 0,
"GroupName": "default"
},
{
"ID": "CA4DA5E7-5DAD-4131-A95D-1152E92197F6",
"Top": 234,
"Left": 0,
"GroupName": "default"
},
{
"ID": "E8ED3C80-690C-4549-A509-BBEFE66F039E",
"Top": 16,
"Left": 0,
"GroupName": "default"
}
],
"Version": "2.0.4",
"Git": "4360afd7f3",
"AIModels": null,
"Variables": null,
"Parameters": null
}
}
}
Get Version
POST {{edgeUrl}}/analytics/v3
Get Version
Returns the deployed version and git revision of the Analytics service. Fast liveness probe and the canonical answer to "what version is in the field" for support tickets.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetVersion {
GetVersion {
Git
Version
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetVersion.Git |
String |
Short git commit hash. |
data.GetVersion.Version |
String |
Semantic version of the Analytics service. |
{ "data": { "GetVersion": { "Git": "4360afd7f3", "Version": "2.0.4" } } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetVersion {
GetVersion {
Git
Version
}
}
Variables
{}
Response
Status: 200 OK
{
"data": {
"GetVersion": {
"Git": "4360afd7f3",
"Version": "2.0.4"
}
}
}
Get All (Supported) Processors Metadata
POST {{edgeUrl}}/analytics/v3
Get All (Supported) Processors Metadata
Returns the complete catalog of processor functions the device supports, with their full input schema. Use this to render a dynamic "Add Processor" form, or to validate a configured processor's parameters before calling Create New Processor / Update Processor.
This is a large response -- each function's metadata includes UI hints, validators, table columns, etc. Cache the result client-side.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetProcessorsMetadata {
GetProcessorsMetadata {
Name
Group
Description
ShortDescription
RequiredDefinitions
ConnectDirection
Features
Properties {
Key
Value {
TabOrder Position LinkedFieldName LinkedValues
Item {
Name Label Default Type EnumItems DisplayLabel
FromNewLine IsValueRequired IsPassword TextType
}
Validators { ValidatorType ValidatorValue }
TableColumns { Name Description DisplayName Default ValueType }
}
}
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetProcessorsMetadata |
[Meta!]! |
One entry per supported processor function. |
Meta.Name |
String |
Function key (e.g. Moving Average). Use as Function in Create New Processor. |
Meta.Group |
String |
Functional grouping (e.g. Statistical, Database, AI). Empty if uncategorized. |
Meta.Description |
String |
Operator-facing description (markdown). Often multi-paragraph. |
Meta.ShortDescription |
String |
One-line summary suitable for a tooltip. |
Meta.RequiredDefinitions |
[String!]! |
Definitions the operator must supply at create time. |
Meta.ConnectDirection |
String |
input, output, inputOutput. Drives which sides of the node accept wires. |
Meta.Features |
[String!]! |
Feature flags the function supports (e.g. event, value, wait). |
Meta.Properties |
[KV!]! |
Full input schema for the function. Each value carries layout, validators, enum items, and table columns. |
{
"data": {
"GetProcessorsMetadata": [
{
"Name": "Moving Average",
"Group": "",
"Description": "# Simple Moving Average...",
"ShortDescription": "",
"ConnectDirection": "inputOutput",
"RequiredDefinitions": []
}
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetProcessorsMetadata {
GetProcessorsMetadata {
Name
Group
Description
ShortDescription
RequiredDefinitions
ConnectDirection
Features
Properties {
Key
Value {
TabOrder
Position
LinkedFieldName
LinkedValues
Item {
Name
Label
Default
Type
EnumItems
DisplayLabel
FromNewLine
IsValueRequired
IsPassword
TextType
}
Validators {
ValidatorType
ValidatorValue
}
TableColumns {
Name
Description
DisplayName
Default
ValueType
EnumItems {
Name
Value
Description
Type
}
}
Rules {
Name
Description
DisplayName
ValueType
EnumItems {
Name
Label
Default
Type
EnumItems
DisplayLabel
FromNewLine
IsValueRequired
IsPassword
TextType
}
}
LinkedFields {
FieldName
FieldValues
Criteria
GroupNumber
}
}
}
}
}
Response
Status: 200 OK
{
"data": {
"GetProcessorsMetadata": [
{
"Name": "Moving Average",
"Group": "",
"Description": "\n# Simple Moving Average \n\n* Simple moving average, also known as Rolling Mean is just an unweighted average of \"n\" values, in the desired window\n\n* The oldest value is then dropped, and a new window with the current value is formed, hence the name \"moving average\"\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "window_size",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Size of window in which values are observed",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Rounding",
"Group": "Functions",
"Description": "\n# Rounding\n\n* Enter the number of digits you would like to round to e.g entering 2, will give results like 10.22. 10.44 (but not 10.556)\n\n * Entering 0 will ignore all floating point values, and just give the integer value\n\n* RoundNearest returns the nearest decimal e.g 10.6 gives 11, 10.1 gives 10\n\n* RoundUp returns the next smallest decimal e.g 10.6 gives 11, 10.1 also gives 11\n\n* RoundDown returns the previous largest decimal e.g 10.6 gives 10, 10.1 also gives 10\n\n* RoundEven returns the nearest integer, rounding ties to even (number of digits entered are irrelevant for this case)\n",
"ShortDescription": "Ratio of uptime and total time",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "digits",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "digits",
"Label": "Round to how many decimals (digits)?",
"Default": "2",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "method",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "method",
"Label": "Round to nearest, Round up, Round down ?",
"Default": "roundUp",
"Type": "string",
"EnumItems": [
"roundNearest",
"roundUp",
"roundDown",
"roundEven"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Signal Decomposition",
"Group": "Functions",
"Description": "\n# Signal Decomposition\n\n* Naive version of signal decomposition\n\n* Additive model: Signal = Trend + Seasonality + Residue\n\n* Multiplicative model: Signal = Trend * Seasonality * Residue\n\n* Trend is calculated by linear regression\n\n* Seasonality is calculated by naive differencing\n",
"ShortDescription": "\nNaive Decompose\n",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "How many values in the Periodic interval",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "model_type",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "model_type",
"Label": "which type of model",
"Default": "additive",
"Type": "string",
"EnumItems": [
"additive",
"multiplicative"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "periodicity",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "periodicity",
"Label": "Periodic interval",
"Default": "5",
"Type": "int",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Change",
"Group": "",
"Description": "\n# Change Processor\n\n* Modifies content of incoming message \n* If ***Change mode*** field is set to **\"set\"**, this processor will assign **Value** to message's **Field**\n\n* If ***Change mode*** field is set to **\"change\"**:\n\t* If **Field** is of type **string** or **JSON** both **Value** and **Replace Value** will be converted to string \nand processor will look for **Value** substrings in **Field** and replace all occurrences of them with **Replace Value** string\n\t* For all other types processor will look for complete match between **Value** and **Field**. If match found **Replace Value** will be set to **Field**\n\n* If ***Change mode*** field is set to **\"delete\"**, this processor will delete **Field** from the payload \n\n* If ***Change mode*** field is set to **\"move\"**, this processor copy contents of '**Field** into **Move to Field** and delete **Field** \n\n* If **Update timestamp** option is set processor will add current timestamp to a message. It will happen after change-processing \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "input_value_type",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_value_type",
"Label": "Type of value1",
"Default": "string",
"Type": "string",
"EnumItems": [
"string",
"uint",
"bool",
"json",
"int",
"float"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "input_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_value",
"Label": "'set' mode: value to set, 'change' mode: value to search ",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "replace_with_value_type",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "replace_with_value_type",
"Label": "Type of value2",
"Default": "string",
"Type": "string",
"EnumItems": [
"string",
"uint",
"bool",
"json",
"int",
"float"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "replace_with_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "replace_with_value",
"Label": "Replace Value for 'change' mode",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "move_to_field",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "move_to_field",
"Label": "Message field to Move data to ",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "update_timestamp",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "update_timestamp",
"Label": "Sets current timestamp to a message",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "mode",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "mode",
"Label": "Type of changes",
"Default": "set",
"Type": "string",
"EnumItems": [
"set",
"change",
"delete",
"move"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "input_field",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_field",
"Label": "Message field to process",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "TensorFlow processor",
"Group": "ML",
"Description": "\n# TensorFlow Processor\n\n* Processor for feeding time-series data to an already created TensorFlow model\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "tags",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "tags",
"Label": "Tags for loading model. If multiple tags, use comma separator",
"Default": "serve",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "input_operation",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_operation",
"Label": "Input tensor used while creating the model. Usually the dictionary of values you feed to the model",
"Default": "input_tensor",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "output_operation",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "output_operation",
"Label": "Output tensor used while creating the model. Usually the output of the model",
"Default": "output_tensor",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Size of values array to process. This is array of values that is modified every new value arrived.",
"Default": "60",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "time_shift_ms",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "time_shift_ms",
"Label": "By how many milliseconds to shift the current timestamp",
"Default": "0",
"Type": "int",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "model_path",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "model_path",
"Label": "Path to model",
"Default": "/var/lib/loopedge-analytics2/models/{MODEL_NAME}",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "number_of_inputs",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "number_of_inputs",
"Label": "Number of inputs",
"Default": "2",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Production Time/ CTR",
"Group": "KPI",
"Description": "\n# Actual Production Time KPI\n\nIf you want to keep track of how much time it takes to complete production, either by:\n\n* counting the time between when you received an order - to when manufacturing is finished, or\n\n* counting the time between the start of manufacturing - to when inspection ends\n\n e.g Currently it takes 5 minutes to produce that metal plate\n\n\n# Cycle Time Ratio KPI\n\nIf you need to monitor what is the production cycle time compared to an ideal production cycle time\n\n* e.g current (production) cycle time is 5 times of your ideal cycle time\n (or) in other words, 'it took you 5 times more time for this production cycle than it actually should/usually does'\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field\n\n### After creating this KPI, you need to add definitions called *manufactureStart* and *manufactureEnd* to the connecting wire, which are event triggers, triggering whenever there is start of manufacturing event and then one more trigger for which represents the end of manufacturing cycle\n",
"ShortDescription": "Production time and Cycle Time Ratio",
"RequiredDefinitions": [
"manufactureStart",
"manufactureEnd"
],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "manufacture_end_from",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "manufacture_end_from",
"Label": "Manufacture End, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "manufacture_end_to",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "manufacture_end_to",
"Label": "Manufacture End, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "ideal_cycle_time",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ideal_cycle_time",
"Label": "Ideal/Standard production cycle time, in seconds",
"Default": "100",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds. If no event, use this timer to keep displaying the output continually. Enter zero to disable",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "manufacture_start_from",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "manufacture_start_from",
"Label": "Manufacture Start, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "manufacture_start_to",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "manufacture_start_to",
"Label": "Manufacture Start, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Normalization",
"Group": "Functions",
"Description": "\n# Normalization Filter\n\n* Initially, a window of value is observed, and the next value is converted between 0 and 1, based on the method of normalization used\n\n* Afterwards, the values follow moving window algorithm and the next value is again placed between 0 and 1 based on the previous window \n",
"ShortDescription": "Normalization",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "mode",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "mode",
"Label": "Which form of Standardization/Normalization",
"Default": "Min-Max",
"Type": "string",
"EnumItems": [
"Min-Max",
"Average-Standard Deviation"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "How many values to observe",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Compliance and Loss",
"Group": "KPI",
"Description": "\n# Compliance and Production Loss KPI\n\n* **Compliance**\n\n * If you do not need to keep a track of ALL the failures happening in a factory (like a machine failure/defective units/failing regulation, etc), but if there is a topic(event trigger) which updates whenever there is such an event, you can just monitor how many units are compliant (pass quality assurance/non-defective units)\n\n* **Production Loss**\n\n * If you need to know how many of the manufactured units were unsuccessful, and hence realize the loss incurred on the desired period.\n\n\t e.g 40 out of the 100 were defective\n\t (or) 40% production is wasted\n\t (or) 60% of your manufactured products are compliant with your standards\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field\n\n### After creating this KPI, you need to add definitions called *manufactureEnd* and *defectiveUnit* to the connecting wire, which are event triggers, triggering when it is the end of manufacturing cycle, and one trigger which represents a defective unit was discovered\n",
"ShortDescription": "Compliance and Production Loss percentage",
"RequiredDefinitions": [
"manufactureEnd",
"defectiveUnit"
],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "manufacture_to",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "manufacture_to",
"Label": "Manufacture End, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "defective_from",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "defective_from",
"Label": "Defective Unit, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "defective_to",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "defective_to",
"Label": "Defective Unit, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds. If your input is unreliable, use this timer to keep displaying the output continually. Enter zero to disable",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "manufacture_from",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "manufacture_from",
"Label": "Manufacture End, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Combination Processor",
"Group": "Functions",
"Description": "\n# Fields Combination Processor\n\n* This Processor can be used to combine fields from different input processors, into a single JSON string\n\n* A definition is needed to be added on the connecting wire after creating this processor\n\n* The fields to combined, will need to be defined as **wire definition**_**fieldName**\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "combination_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "combination_type",
"Label": "Combine selected, or combine all fields?",
"Default": "combine selected fields",
"Type": "string",
"EnumItems": [
"combine selected fields",
"combine all fields"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "what_timestamp_to_take?",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "what_timestamp_to_take?",
"Label": "Take timestamp from which input processor?",
"Default": "fresh timestamp",
"Type": "string",
"EnumItems": [
"first available",
"last available",
"average of inputs",
"fresh timestamp"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "fields_to_combine",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "fields_to_combine",
"Label": "Enter the fields to combine, with comma as the separator",
"Default": "inputA_value, inputB_value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "DataHub Subscribe",
"Group": "",
"Description": "\n# DataHub streaming input processor\n\nGenerate events from specified DataHub topic and attach to output\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "outputOnly",
"Features": [],
"Properties": [
{
"Key": "ignore_null_value",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ignore_null_value",
"Label": "Ignores all null value messages (value is null)",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "topic",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "topic",
"Label": "Topic name for DataHub subscribe",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "ignore_failed_data",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ignore_failed_data",
"Label": "Ignores all unsuccessful messages (success=false)",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "FileWriter",
"Group": "",
"Description": "\n# File Write processor\n\n* Converts input data to specified format, and writes it to a file\n * This can be done by either adding to the end of the file, or replacing the existing content\n * Alternatively, it can also delete the file\n\n* If the **\"Generate Filename From Expression\"** option is enabled, the filename will be evaluated as expression.\n * For example, if you want to get the filename from \"path\" and name\" properties of incoming connection \"AAA\", your expression could be:\n\t**AAA_path + AAA_name + \".txt\"**\n * Please note that static text in expressions should be put into quotes \n\n* Timer interval in seconds acts as a **\"Re-write file on timer\"** option\n * This is useful if you want to keep generating new file names after every few intervals\n\n* If ***\"Output File Type\"*** is set to **value only** processor will save incoming data from **\"value\"\"** payload field as is.\n* If ***\"Output File Type\"*** is set to **CSV** following options will affect output: \n * **CSV Comma** contains CSV-file delimiter (only first character will be used from string entered)\n * **CSV Header** controls whether column names will be included or not \n * **CSV Columns From Payload** controls whether column names will be generated from payload\n * **CSV Custom Columns** contains comma-separated list of columns names (overrides **CSV Columns From Payload**!)\n* If ***\"Output File Type\"*** is set to **Parquet** output file will be rewritten on each incoming payload. \n * If ** Write file Method ** is set to \"append\" then last **Parquet Buffer Capacity** records will be written to file \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOnly",
"Features": [],
"Properties": [
{
"Key": "timer_interval_in_seconds",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timer_interval_in_seconds",
"Label": "Period of time in seconds between generation of a new filename.",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_header",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_header",
"Label": "column names output",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_columns_from_payload",
"Value": {
"TabOrder": 9,
"Position": 9,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_columns_from_payload",
"Label": "get column names from payload",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_custom_columns",
"Value": {
"TabOrder": 10,
"Position": 10,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_custom_columns",
"Label": "output column names",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "parquet_capacity",
"Value": {
"TabOrder": 11,
"Position": 11,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "parquet_capacity",
"Label": "Parquet Buffer Capacity",
"Default": "100",
"Type": "int",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "generate_filename_from_expression",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "generate_filename_from_expression",
"Label": "Generates name of a file to write from filename expression.",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "file_write_method",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "file_write_method",
"Label": "File write method",
"Default": "append",
"Type": "string",
"EnumItems": [
"append",
"overwrite",
"delete"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "output_file_type",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "output_file_type",
"Label": "File type",
"Default": "JSON",
"Type": "string",
"EnumItems": [
"JSON",
"CSV",
"Parquet",
"value only",
"Binary"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "add_new_line",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "add_new_line",
"Label": "Adds newline (\\n) to incoming data",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "create_directories",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "create_directories",
"Label": "Creates directory in filename if it doesnt' exist",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_comma",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_comma",
"Label": "CSV delimiter (one character)",
"Default": ",",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "file_name",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "file_name",
"Label": "Name of a file to write. If not absolute it will be relative to working directory of analytics2 process",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Switch",
"Group": "",
"Description": "\n# Switch Processor\n\n* Sends content of incoming message to an output only when rule checks are met\n\n* Available rules to be checked are: \n * **==** - Equals\n * For strings, **input value** and **checked value** need to be lexicographically equal\n\n * **!=** - Not Equals\n * For strings, **input value** and **checked value** need to be lexicographically different\n\n * **<** - Less than\n * For strings, **input value** needs to be lexicographically before **checked value**\n\n * **<=** - Less than, or equals\n * For strings, **input value** needs to be lexicographically equal to, or before **checked value**\n\n * **>** - Greater than\n * For strings, **input value** needs to be lexicographically after **checked value**\n\n * **>=** - Greater than, or equals\n * For strings, **input value** needs to be lexicographically equal to, or after **checked value**\n\n * **is true** - Only applicable for field having **Bool** data type\n\n * **is false** - Only applicable for field having **Bool** data type\n\n * **is null** - Given field should not be present in the input\n\n * **is not null** - Given field should be present in the input\n\n * **is of type** - Compares the datatype of field with given\n\n * **contains** - Only applicable for field having **String** or **JSON** data type\n\n* For string datatype, the rules for comparison are done via GoLang **strings.compare**\n\n* **Please note that DataHub payload have all numeric values as floats, so this processor will require \"datatype\" field present to perform correct conversions or bool, uint and int data**\n\n* **Field Name**, **Check Value** and **Check Value Type** Represent what field to look for, for the comparison, \nwhat value to check for, and what is the expected type for the mentioned value\n\n* **Output Name** is used to restrict/filter where to publish the output to.\n * If left empty, output will be published to all connected processors \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "rule",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "rule",
"Label": "Which rules to check for",
"Default": "==",
"Type": "string",
"EnumItems": [
"==",
"!=",
"<",
"<=",
">",
">=",
"is true",
"is false",
"is null",
"is not null",
"is of type",
"contains"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Field to process",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "check_value",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "check_value",
"Label": "Value to check for",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "check_value_type",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "check_value_type",
"Label": "Data Type of value being checked",
"Default": "string",
"Type": "string",
"EnumItems": [
"string",
"uint",
"bool",
"json",
"int",
"float"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "output",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "output",
"Label": "Output name for data. Keeping this empty means filtered data will be sent to all outputs",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "AI Vision",
"Group": "Functions",
"Description": "\n# AI Vision Processor\n\n* **File Path** can be provided, or model can expect a base64 image from the input payload\n * File path will always supersede incoming payload\n * Model will take file types *jpg*, *png* and *gif*\t\n\n* **AI Model** must be set to define the unique name identifier for the model being used.\n\n* **System Prompt** parameter allows users to provide a predefined instruction that influences the AI’s behavior and response style.\n * This can be used to enforce a specific tone, persona, or domain expertise in responses.\n\n* **Temperature** parameter (default **1.0**) controls the randomness of responses.\n * Lower values (e.g., **0.2**) make the AI more focused and deterministic.\n * Higher values (e.g., **1.8**) increase creativity but may reduce consistency.\n\n* **Max Completion Tokens** parameter limits the maximum number of tokens the AI can generate in a single response.\n * This ensures output length remains within expected boundaries.\n * If not set, the model’s default value will be used.\n\n* **HTTP Timeout** parameter sets the maximum time (in seconds) the system will wait for a response from the AI.\n * If the AI does not respond within this time, the request will timeout and ignored\n * This prevents excessive delays in cases of high latency.\n",
"ShortDescription": "AI Vision Processor for multiple type of models",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "ai_model",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ai_model",
"Label": "Unique AI Model Name",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "HTTP_timeout",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "HTTP_timeout",
"Label": "HTTP timeout interval in seconds",
"Default": "10",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "file_path_for_image",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "file_path_for_image",
"Label": "File Path for the Image. Leave empty to use input message as the image",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "system_prompt",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "system_prompt",
"Label": "System Prompt used for the AI model",
"Default": "System Prompt used in the AI model\n\n Example: You are a JSON analyser. Analyze the input and act as a CNC expert who gives a response based on it",
"Type": "script",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "temperature",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "temperature",
"Label": "AI model temperature. Float value between 0 and 2",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "max_completion_tokens",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "max_completion_tokens",
"Label": "Maximum completion tokens",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Conversion",
"Group": "Functions",
"Description": "\n# Unit Conversion\n\n* Ready conversions of commonly used Units\n",
"ShortDescription": "conversions of units",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "conversion",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "conversion",
"Label": "What type of conversion",
"Default": "Celsius -> Fahrenheit",
"Type": "string",
"EnumItems": [
"timestamp to local time",
"timestamp to UTC",
"Celsius -> Fahrenheit",
"Fahrenheit -> Celsius",
"degree -> radian",
"radian -> degree",
"degree -> gon",
"gon -> degree",
"radian -> gon",
"gon -> radian"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Base Conversion",
"Group": "Functions",
"Description": "\n# Base Conversion of units\n\n* With this function, you can convert the base from decimal to binary, decimal to HexaDecimal, decimal to OctaDecimal, and the other way round as well \n\n* For conversion of various units to decimal, it is expected that the input is a string\n\n * Your input needs to have a field named **value** if you are converting from binary/octadecimal/hexadecimal to decimal\n\n* e.g if 12 is the input in decimal place, the output of decimal -> hexadecimal would be \"c\"\n\n* e.g if 12 is the input in decimal place, the output of decimal -> binary would be \"1100\"\n",
"ShortDescription": "base conversions",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "conversion",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "conversion",
"Label": "Which type of conversion?",
"Default": "decimal -> binary",
"Type": "string",
"EnumItems": [
"decimal -> binary",
"decimal -> hexaDecimal",
"decimal -> octaDecimal",
"binary -> decimal",
"octaDecimal -> decimal",
"hexaDecimal -> decimal"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Moving Maximum",
"Group": "",
"Description": "\n# Moving Window Maximum\n\n* This KPI shows the maximum value from \"n\" values, in the desired window\n\n* The oldest value is then dropped, and a new window with the current value is formed, hence the name \"moving maximum\"",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Size of window in which values are observed",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Feature Extractor",
"Group": "Functions",
"Description": " \n# Feature Extractor\n\nWith this function, once you enter the window of values you prefer, you can then select which functions would you like to see in our output\n\n* Let's say you picked a window of *N* values\n\n* **Minimum** : Gives you minimum of N values\n\n* **Maximum** : Gives you maximum of N values\n\n* **Average** : Gives you the average(mean) of N values\n\n* **Standard Deviation** : \n\n * standard deviation = squareRoot( (x - average)^2/(N-1) )\n\n* **Variance** : \n\n * variance = (x - average)^2/(N-1)\n\n* **Median** : \n\n * median = N/2 for odd number of window elements, {[N-1] + [N]}/2 for even window elements\n\n* **Kurtosis** : \n\n * kurtosis = [ (N)(N+1) / (N-1)(N-2)(N-3) ] * SIGMA [(x_i - x_avg)/(stdDeviation) ^4]\n\n* **Skewness** :\n\n * skewness = [ (N) / (N-1)(N-2)] * SIGMA [(x_i - x_avg)/(stdDeviation) ^3]\n\n* **Zero crossing rate**: Gives you how many times the signal has crossed zero i.e positive value to negative, OR negative value to positive\n\n* **Root Mean Square** :\n \n * RMS = squareRoot[ SIGMA x^2 / N]\n\n* **Quartiles** : Divides the signal into 4 equal quartiles, based on medians\n\n* **Inter-quartile Range** : Difference between the third quartile and first quartile\n\n* **Mean Absolute Deviation** : \n\n * mean absolute deviation = abs(x - average)/(N)\n\n* **Average absolute variation** : \n\n * avg absolute variation = abs(x - average)/(N)\n\n* The **timer interval** parameter is useful if the connected input tag is currently not polling, but you still want this KPI to publish a value every few seconds, defined by the aforementioned timer\n\n * If you know your input is going to publish at the expected interval, it is better to disable this timer by entering **0** in the field\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "100",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "quartiles",
"Value": {
"TabOrder": 11,
"Position": 11,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "quartiles",
"Label": "quartiles",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "mean_absolute_deviation",
"Value": {
"TabOrder": 13,
"Position": 13,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "mean_absolute_deviation",
"Label": "MAD",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 17,
"Position": 17,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 15,
"Position": 15,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "minimum",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "minimum",
"Label": "Minimum",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "standard_deviation",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "standard_deviation",
"Label": "",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "median",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "median",
"Label": "median",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "zero_crossing_rate",
"Value": {
"TabOrder": 9,
"Position": 9,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "zero_crossing_rate",
"Label": "zcr",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "maximum",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "maximum",
"Label": "Maximum",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "kurtosis",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "kurtosis",
"Label": "kurtosis",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "root_mean_square",
"Value": {
"TabOrder": 10,
"Position": 10,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "root_mean_square",
"Label": "rms",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "average_absolute_variation",
"Value": {
"TabOrder": 14,
"Position": 14,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "average_absolute_variation",
"Label": "AAV",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "average",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "average",
"Label": "Average",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "variance",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "variance",
"Label": "",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "skewness",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "skewness",
"Label": "skewness",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "inter_quartile_range",
"Value": {
"TabOrder": 12,
"Position": 12,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "inter_quartile_range",
"Label": "iqr",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "XMR Chart",
"Group": "Functions",
"Description": "\n# XMR Control Chart\n\n* Once the window is filled with values, a **central line** is calculated which remains constant moving forward\n\n* Other fields that are calculated once window is filled are:\n\n * **Moving ranges** : Difference of successive values\n\n * **Average moving range** : Average of the moving ranges\n\n * **Process Limit Multiplier** is used to calculate the upper and lower process limits\n\n * **Upper and Lower Natural Process limit** : Calculated by taking the product of process limit multiplier and average moving range, and adding/subtracting it to the central line\n\n* In some cases, the central line is adjusted. Here are the cases:\n\n * If current value is outside the process limits, multiple times in a row\n\n * If the multiple values in a row are closer to either limits, than they are to the central line\n\n* The **timer interval** parameter is useful if the connected input tag is currently not polling, but you still want this KPI to publish a value every few seconds, defined by the aforementioned timer\n\n * If you know your input is going to publish at the expected interval, it is better to disable this timer by entering **0** in the field\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "100",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "process_limit_multiplier",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "process_limit_multiplier",
"Label": "Process Limit Multiplier",
"Default": "2.66",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "StdOut",
"Group": "",
"Description": "Just consumer that print to console",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOnly",
"Features": [],
"Properties": []
},
{
"Name": "TensorFlow images processor",
"Group": "ML",
"Description": "\n# TensorFlow Images Processor\n\n* Processor for feeding images to an already created TensorFlow model\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "model_path",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "model_path",
"Label": "Path to model",
"Default": "/var/lib/loopedge-analytics2/models/{MODEL_NAME}",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "tags",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "tags",
"Label": "Tags for loading model. If multiple tags, use comma separator",
"Default": "serve",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "input_operation",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_operation",
"Label": "Input tensor used while creating the model. Usually the dictionary of values you feed to the model",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "output_operation",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "output_operation",
"Label": "Output tensor used while creating the model. Usually the output of the model",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "gray",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "gray",
"Label": "Decode image as gray scale, if this checkmark is true",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "image_format",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "image_format",
"Label": "",
"Default": "png",
"Type": "string",
"EnumItems": [
"png",
"jpg"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "time_shift_ms",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "time_shift_ms",
"Label": "By how many milliseconds to shift the current timestamp",
"Default": "0",
"Type": "int",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Inputs Sum",
"Group": "",
"Description": "\n# Inputs Summation\n\n* This KPI calculates the (cumulative) summation from the given inputs\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Inputs Maximum",
"Group": "",
"Description": "\n# Inputs Maximum\n\n* This KPI calculates the maximum value from the given multiple inputs\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Inputs Average",
"Group": "",
"Description": "\n# Inputs Average\n\n* This KPI calculates the average/mean value from the given multiple inputs\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Maintenance/Failure",
"Group": "KPI",
"Description": "\n# Maintenance and Failure KPIs\n\n*(requirement)* A new topic created such that every time there is a maintenance event or a fault/failure, this topic gets updated\n\n\n1) **Maintenance events per cycle**\n\n * You can see the number of maintenance (planned or unplanned) in a production cycle\n\n e.g In the production cycle of manufacturing a bottle, on average 3 maintenance events are required\n\n2) **Time since last maintenance**\n\n * If you know that the machine needs to be checked periodically, you can see time elapsed between 'maintenance' events\n\n e.g It has been 20 days since the last maintenance event happened\n\n3) **Timestamp of last maintenance**\n\n * Keep track of the previous time when maintenance happened\n\n4) **Number of faults/failures detected in a period**\n\n * You can see the number of failures that have happened in a period\n\n e.g between March 5 and March 16, 12 machine failures happened\n\n5) **Time since last failure**\n\n * If you know that the machine needs to be checked periodically, you can see time elapsed between 'failure' events\n\n e.g It has been 20 days since the last machine failure\n\n6) **Timestamp of last failure**\n\n * Keep track of the previous time when failure happened\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field\n\n### After creating this KPI, you need to add definitions called *maintenance* and *failure* to the connecting wire, which are event triggers, triggering whenever there is event of maintenance or failure\n",
"ShortDescription": "Maintenance and Failure related KPIs",
"RequiredDefinitions": [
"maintenance",
"failure"
],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "unit",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "unit",
"Label": "Display time since last Maintenance/Failure in Seconds, Minutes, Hours, Days or Weeks",
"Default": "seconds",
"Type": "string",
"EnumItems": [
"seconds",
"minutes",
"hours",
"days",
"weeks"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds. If no event, use this timer to keep displaying the output continually. Enter zero to disable",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "maintenance_from",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "maintenance_from",
"Label": "Maintenance, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "maintenance_to",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "maintenance_to",
"Label": "Maintenance, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "failure_from",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "failure_from",
"Label": "Failure, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "failure_to",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "failure_to",
"Label": "Failure, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Change of Value",
"Group": "KPI",
"Description": "\n# Change of value KPI\n\n* Show the entire message payload when the current value is different than the previous value\n\n* A simple use-case of this KPI is: you want to see a message ONLY if there is a significant change from the previous value, otherwise if things are normal, no output is expected\n\n* By entering a **delta**, you can ignore some precision error\n\n* If you enter delta as 0.0, even the smallest change will be detected by this KPI, or you can enter a delta of 0.1 (for example) if you want to allow ignore a change of +/- 0.1 from your previous value\n\n\te.g assume that delta is 0.5 and previous value was 100\n\tNow, if the current value is between 99.5 to 100.5, it will be ignored from this KPI, but any other value would trigger this KPI\n\n* **Map Field Name** asks you what is the field you want to observe for COV. This can be \"value\" or \"asset_online\" etc depending entirely on what is the input message you are sending to this KPI\n\n* The **timer interval** parameter is useful if the connected input tag is currently not polling, but you still want this KPI to publish a value every few seconds, defined by the aforementioned timer\n\n * If you know your input is going to publish at the expected interval, it is better to disable this timer by entering **0** in the field\n\n* **Expected Output:** No output if the current value is the same as the previous value (+ or - *delta*), but outputs the entire input message if there is a change\n",
"ShortDescription": "Change of Value",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "map_field_name",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "map_field_name",
"Label": "What field to observe?",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "delta_of_tolerance",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "delta_of_tolerance",
"Label": "How much delta of values to ignore? (Helps ignore some error of round off)",
"Default": "0.0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Statistical Prediction",
"Group": "Functions",
"Description": "\n# Statistical Prediction by Fourier extrapolation\n\n* To achieve a prediction of value in the future, Fast fourier transform (FFT) is done on the time series signal\n\n* This FFT is then used to de-trend the data, generate sine-cosine waveform out of the signal, and then the signal is restored to it's best capacity\n\n* The **frequency difference** represents the sampling rate of discretization.\n\n * For example, if the window has 10 elements, 1 second frequency difference will generate 10 frequency samples (maximum). 2 seconds will generate 5 samples, and so on\n\n * Usually 1 is good, because it is a time series signal, so you're sampling at every second\n\n* **Harmonics** represent the number of waves to \"add\" to the fundamental wave, to reach the desired signal\n\n * Some signals have a huge number of harmonics, for example square waves have theoretically infinite harmonics\n\n * For the number of harmonics, it is better to start with a lower number and play around with it to see what best fits your needs, rather than just entering a high number \n\n* Due to limitations of working with live data, it is preferable to have a window of data to \"observe\" and then give a \"prediction\" for a future time\n\n* For now, the poling interval of the subscription tag is assumed to be 1 second\n\n* **Expected Output:** Until the window is filled up, no output is expected. Afterwards, the *prediction*, with the timestamp of prediction will be the output\n",
"ShortDescription": "\nPrediction\n",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "display_prediction_on_current_timestamp",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "display_prediction_on_current_timestamp",
"Label": "Check this box if you want to see the answer of the prediction on current timestamp",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "How many values to observe before making each prediction? (assumed with 1 second as poling interval)",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "number_of_predictions",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "number_of_predictions",
"Label": "How many seconds in future to predict? (assumed with 1 second as poling interval)",
"Default": "2",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "frequency_difference",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "frequency_difference",
"Label": "Frequency sampling distance in seconds",
"Default": "1",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "number_of_harmonics",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "number_of_harmonics",
"Label": "Number of harmonics",
"Default": "4",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Database Batch Input",
"Group": "Connect",
"Description": "\n# DB polling processor \n\n* Generate events by periodically polling specified DB measurement\n\n* **Filtering:**\n \n * You could add filtering for queries\n\n * List of fields depends on database and measurement, but for device data, standard filters are: datatype, device_id, is_device_status, register_id, success, tag, topic, value\n\n* **Examples:**\n \n * Filter by tag: \"tag\" = 'tag1'\n \n * Filter by tag and success: \"tag\" = 'tag1' AND \"success\" = 1\n\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "outputOnly",
"Features": [
"Invoke"
],
"Properties": [
{
"Key": "metric_name",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "metric_name",
"Label": "Name of the metric for TimeSeriesDB polling",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "typed",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "typed",
"Label": "Data typed policy",
"Default": "autogen",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "period_secs",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "period_secs",
"Label": "Polling interval in seconds",
"Default": "1",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "filter",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "filter",
"Label": "SQL filter for the WHERE part of the query",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "ignore_failed_data",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ignore_failed_data",
"Label": "Ignores all unsuccessful messages (success=false)",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "ignore_null_value",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ignore_null_value",
"Label": "Ignores all null value messages (value is null)",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "database",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "database",
"Label": "Select database name",
"Default": "tsdata",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Up/DownTime by Value",
"Group": "KPI",
"Description": "\n# UpTime and DownTime by value KPI\n\n* If you would like to compare your current value with a desired value, to count as UpTime or DownTime\n\n* By setting the **condition**, you can define: Downtime if current value is greater(>), less(<), equal(==) or notEqual(!=) than **desired value**\n\n\te.g if current value less than 5 consider it DownTime\n\t(or) if current value not equal to 10.5, consider DownTime\n\t(or) if current value equal 0, consider DownTime, etc\n\n* You can enter a delta too, if you want to forgive some sort of round off error\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "timerInterval",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "device_reset",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "device_reset",
"Label": "Reset everything when device changes?",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "unit",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "unit",
"Label": "Display UpTime/DownTime in Seconds, Minutes, Hours, Days or Weeks",
"Default": "seconds",
"Type": "string",
"EnumItems": [
"seconds",
"minutes",
"hours",
"days",
"weeks"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "condition",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "condition",
"Label": "What sort of comparison to make; Downtime if current value is greater(>), less(<), equal(==) or notEqual(!=) than desired value",
"Default": "less",
"Type": "string",
"EnumItems": [
"less",
"greater",
"equal",
"notEqual"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "desired_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "desired_value",
"Label": "Desired value to check current values with",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "delta_of_tolerance",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "delta_of_tolerance",
"Label": "Allow freedom of desiredValue + or - this delta",
"Default": "0.0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Simple Window",
"Group": "",
"Description": "\n# Simple Moving Window\n\n* Takes input as a single value, outputs a simple moving window following FIFO algorithm\n",
"ShortDescription": "Simple window with no calculation",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "value_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "value_type",
"Label": "What is the type of the incoming value?",
"Default": "float",
"Type": "string",
"EnumItems": [
"float",
"int",
"uint"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "order",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "order",
"Label": "What is the desired order of output window?",
"Default": "Oldest -> Newest",
"Type": "string",
"EnumItems": [
"Oldest -> Newest",
"Newest -> Oldest"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which the values will be observed",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Manufacture Counter",
"Group": "KPI",
"Description": "\n# Total Units manufactured KPI\n\n* If you need a simple count of the total number of units manufactured in a period\n\n\te.g 7,000 glasses manufactured between March 23 and March 26\n\t(or) 500 total units produced this week\n\t(or) 20 products manufactured this month\n\n# Capacity Utilization KPI\n\t\t\nYou can monitor how much output is being produced, compared to an ideal scenario. Kind of like CPU usage, Memory usage, etc\n\t\t\n* e.g The specifications of a machine says it produces 100 stickers per hour, but currently it is only producing 80 stickers per hour. Hence you can see that the machine is operating only at 80% of its actual capacity\n\t\t\n* Possibly even more useful, if the machine is more than 100% utilization, it can be inferred that the machine is likely to overheat and cause breakdown/failure\n\n* *Note* : Capacity Utilization will be updated once manufacture event happens\n\n * Otherwise, it will be updated when the threshold for the hour/day/week is met (decided through the \"unit\" parameter)\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field\n\n### After creating this KPI, you need to add a definition called *manufactureEnd* to the connecting wire, which is an event trigger, triggering whenever there is end of a manufacture cycle\n",
"ShortDescription": "Total units manufactured and capacity utilization",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "ideal_count",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ideal_count",
"Label": "What is the ideal count of manufacture per hour/day/week?",
"Default": "1",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "from_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "from_value",
"Label": "Manufacture End, when value goes from this number",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "to_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "to_value",
"Label": "Manufacture End, when value goes to this number",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds. If no event, use this timer to keep displaying the output continually. Enter zero to disable",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "device_reset",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "device_reset",
"Label": "Reset everything when Device changes?",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "unit",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "unit",
"Label": "What is the unit in which you are entering the ideal Count in? e.g minute, hour, day, week",
"Default": "hour",
"Type": "string",
"EnumItems": [
"hour",
"day",
"week"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "JavaScript processor",
"Group": "Functions",
"Description": "\n# Scripting for data manipulations\n\n* This processor uses JavaScript scripting\n\n* **Simple Use case**: The output you receive from DeviceHub message or from Analytics, might not be helpful, and you want to change the name of a field within that message\n\n * *e.g* Instead of \"value\" you want your data to show \"furnace pressure\"\n\n * *e.g* Instead of having all fields of the message, you only want to have \"success\", \"deviceId\" and \"value\" and skip everything else\n\n * *e.g* You want to add a custom field to the message, based on the \"value\" field, such as: if value = 2, \"error\": \"overheating\"\n\n * *e.g* You only want to change the timestamp to human readable format instead of Unix timestamp, but keep otherwise keep the message as-it-is\n\n * In general, if you want to add, remove or modify *ANY* field in the input, this scripting processor is very useful\n\n* **Single Input:** Every message from the input, is stored as an array called \"values\"\n\n * Using \"for i, message in values{}\" statement, allows to access this input and manipulate it\n\n * Here \"i\" represents what is the *definition* defined in the connection wire, more useful for multi-inputs, to identify and distinguish between each inputs, so for single input, \"i\" can be replaced with \"_\"\n\n * \"message\" contains the entire message in the input, and you can perform your manipulations to this \"message\" parameter\n\n * **Note:** \"i\" and \"message\" can be any custom variable name\n\n* **Multiple Input:** Suppose you have 3 different inputs attached to this scripting processor, with the connecting wires named A, B and C\n\n * \"for i, message in values{}\" will now have 3 inputs\n\n * \"i\" represents from which connection wire is the input coming from\n\n * with if-else statements, every input can be manipulated in isolation, or a common manipulation can be applied to all inputs\n\n * You can choose to output \"result\" only for one input, or all of the inputs\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "script",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "script",
"Label": "Script body",
"Default": "/* \n Single input example: inputProcessors() returns list of IDs of incoming data which placed in values object\n incoming values are checked and changed if matches some condition \n also new string field is generated from all incoming parameters\n */\nvar ids = inputProcessors();\n\nfunction allValuesToString(obj) {\n var res = \"\";\n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n res = res + \" \" + key + \" : \" + obj[key] + \"; \";\n }\n }\n return res;\n} \n\nif (ids.length > 0) {\n if (values && values[ids[0]]) {\n result.allValues = allValuesToString(values[ids[0]]);\n if (values[ids[0]].hasOwnProperty('int_param') && (values[ids[0]].int_param == 777)) {\n result.int_param = 888;\n\t}\n }\n} \n\n/* \n Multiple input example: inputProcessors() returns list of IDs of incoming data which placed in values object\n incoming values are checked and aggregated \n \n\nfunction allValuesToString(obj) {\n var res = \"\";\n \n for (const key in obj) {\n if (obj.hasOwnProperty(key)) {\n res = res + \" \" + key + \" : \" + obj[key] + \"; \";\n }\n }\n return res;\n} \n\nvar ids = inputProcessors();\n\nvar totalSumm = 0;\n\nif (ids.length > 0) { \n result[\"ids\"] = ids;\n for (var i = 0; i < ids.length; i++) { \n var obj = values[ids[i]];\n if (obj && obj.value !== undefined) {\n totalSumm += obj.value; \n }\n }\n result[\"total_summ\"] = totalSumm;\n} \n\n*/",
"Type": "script",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Moving Minimum",
"Group": "",
"Description": "\n# Moving Window Minimum\n\n* This KPI shows the minimum value from \"n\" values, in the desired window\n\n* The oldest value is then dropped, and a new window with the current value is formed, hence the name \"moving minimum\"\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Size of window in which values are observed",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Anomaly Detection",
"Group": "Functions",
"Description": "\n# Standard Deviation Anomaly Detection (Statistical)\n\n* Anomaly detection by 3-Sigma Rule is a conventional heuristic used for an approximately normalized data-set\n\n* A rolling window of values are \"observed\", and their average and standard deviations are calculated\n\n* You can define the number of standard deviations that would be considered \"normal\", hence everything beyond that would be anomalous data\n\n* In case of an anomaly, the standard deviation window is expanded ever so slightly, so that it can adjust if this anomalous data becomes seasonal\n\n * This calculation is done because in live data, it is sometimes not preferable for one large anomaly to drastically change the moving average and moving standard deviations \n\n * With the **control chart mode**, this calculation can be completely bypassed, if all you need to check is whether the value is within upper/lower limit or not\n \n * If **control chart mode** is enabled, there will be no modifications done to the moving window before calculation\n\n* Currently if you have very small deviations (close to 0), it is difficult to distinguish between anomalous data, so it would be better to have a larger window size for those kinds of data\n\n* **Expected Output Fields:** timestamp, current value, moving average, moving standard deviation, upper limit, lower limit, total anomalies, and anomaly field replaces current value, if detected \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "control_chart_mode?",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "control_chart_mode?",
"Label": "Ignore all internal calculations, and just display if the value is within upper and lower limit?",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "deviations",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "deviations",
"Label": "Number of deviations to keep in range",
"Default": "3",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "100",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "topic_reset",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "topic_reset",
"Label": "Reset function on topic change?",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "SPC Charts",
"Group": "Functions",
"Description": " \n# SPC Charts\n\n* First, the **target_mean** (default 100), **window size** (default 50), and **timer interval** need to be set.\n\t* The **timer interval** parameter ensures that even if the connected input tag is not polling, the SPC chart will still publish data at the specified interval.\n * If the input is expected to publish at the expected rate, set the timer interval to **0** to disable the timer.\n\n* The **current mean** and **standard deviation (stdDev)** are calculated based on the input data within the defined window.\n\n* **Upper Specification Limit (USL)** and **Lower Specification Limit (LSL)** are computed based on the **current_mean** and standard deviation.\n\n* The **process capability (Cp)** is calculated as the ratio of the difference between USL and LSL over six times the standard deviation (6σ).\n\n* **CPu** (Upper Capability Index) and **CPl** (Lower Capability Index) are calculated to assess how centered the process is within the specification limits.\n * CPu = (USL - avg) / 3σ, CPl = (avg - LSL) / 3σ\n\n* **Process performance (Cpk)** is calculated by determining the smallest value between CPu and CPl.\n\n* Optionally, if valid data is present, the **Cpm** and **Cpkm** (which use the target mean) will be computed.\n\n* The chart will also output any **Nelson Rule violations** with a **true** flag indicating which rule number has been violated.\n * The rules are as follows\n * Rule1: One point is more than 3 standard deviations away from the mean.\n * Rule2: Nine (or more) points in a row are on the same side of the mean.\n * Rule3: Six (or more) points in a row are continually increasing or decreasing.\n * Rule4: Fourteen (or more) points in a row alternate in direction, increasing then decreasing.\n * Rule5: Two (or three) out of three points in a row are more than 2 standard deviations away from the mean in the same direction.\n * Rule6: Four (or five) out of five points in a row are more than 1 standard deviation away from the mean in the same direction.\n * Rule7: Fifteen points in a row are all within 1 standard deviation of the mean on either side of the mean.\n * Rule8: Eight points in a row exist, but none within 1 standard deviation of the mean, and the points are in both directions from the mean.\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "50",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "target_mean",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "target_mean",
"Label": "Target mean",
"Default": "100",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 15,
"Position": 15,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Expression",
"Group": "Functions",
"Description": "\n# Expression\n\nThis function is for creating a mathematical-like expression with your desired topic. eg. you can enter a formula to convert temperature from Celsius to Fahrenheit, or a custom formula to perform on furnace pressure, etc \n\n* A definition is needed to be added on the connecting wire after creating this KPI. The expression will need to be defined as **wire definition**_**fieldName** *expression*\n\n* For example, (Celsius_value * 9/5) + 32 will be the expression, and then after creating this expression, you just need to add definition for \"Celsius\" to the connected input\n\n* Other examples of how this processor can be used with modifiers such as: **+** (add), **-** (subtract), **/** (divide),* (multiply), ** (raise-to-power), **%** (modulo division)\n\n* Additionally, comparators such as **<** (less than), **>>** (greater than), **<=** (less than equals), **>=** (greater than equals), **==** (exactly equals) can also be used to obtain a true or false result\n * A_value > 10 (implies output will be true if value is greater than 10, otherwise false)\n \n* Regex comparators **=~** and **!~** are used to compare the left side candidate string to the pattern on the right side\n\n* Logical operators can be added to the expression as well, with **&&** (logical AND), **||** (logical OR)\n\n* Ternary operator **?** and **:** are also available for use. For example:\n * A_success ? *true* : *false*\n * In this case, we check if the \"left side\" of the question mark is true or false, if true, output will be true, otherwise false\n * A_value == 10 ? \"equals10\" : \"notEquals10\"\n * In this case we are combining expressions and checking if value is equal to 10 and returning output accordingly\n \n* Finally, there are some useful inbuilt mathematical functions such as:\n * **sin()**, **cos()**, **exp()** (exponential), **log()** (natural logarithm), **sqrt()** (square root), **abs()** (absolute value)\n * A simple example on how to use them would be: *sin(A_value)*, or *sqrt(B_value) + abs(C_value)*, etc\n\n* The **timer interval** parameter is useful if the connected input tag is currently not polling, but you still want this KPI to publish a value every few seconds, defined by the aforementioned timer\n\n * If you know your input is going to publish at the expected interval, it is better to disable this timer by entering **0** in the field\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "timerInterval",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "expression",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "expression",
"Label": "Enter a mathematical expression",
"Default": "(Celsius_value * 9/5) + 32",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "output_field_name",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "output_field_name",
"Label": "Which field name should appear in the output?",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Inject",
"Group": "",
"Description": "\n# Inject Processor\n\n* Generates a new message event based on the provided inputs\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "outputOnly",
"Features": [
"Invoke"
],
"Properties": [
{
"Key": "timer_interval_type",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timer_interval_type",
"Label": "Timer's interval type",
"Default": "seconds",
"Type": "string",
"EnumItems": [
"milliseconds",
"seconds",
"minutes",
"hours",
"days"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timer_interval_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timer_interval_value",
"Label": "Timer's interval value",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "inject_field",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "inject_field",
"Label": "What field to inject into message",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "inject_value_type",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "inject_value_type",
"Label": "Type of injected field's value",
"Default": "string",
"Type": "string",
"EnumItems": [
"string",
"uint",
"bool",
"json",
"int",
"float"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "inject_value",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "inject_value",
"Label": "Injected field's value",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "add_timestamp",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "add_timestamp",
"Label": "Adds a timestamp to message",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timing_mode",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timing_mode",
"Label": "Message injection mode",
"Default": "once",
"Type": "string",
"EnumItems": [
"once",
"interval"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Linear Prediction",
"Group": "Functions",
"Description": "\n# Linear prediction by ordinary least squares model\n\n* Once window values are full, the mean of values is subtracted from each element and squared (Y_i - Mean_Y)\n\n* Same is done for the time series elements (X_i - Mean_X)\n\n* The sum of squares is sum of (X_i - Mean_X)^2 \n\n* The sum of products is sum of (Y_i - Mean_Y) * (X_i - Mean_X)\n\n* The slope is obtained by the formula m = { Sum of products } / { Sum of Squares } \n\n* The intercept is obtained by the formula b = Mean_Y - m * Mean_X\n\n* Finally, prediction is made by extrapolating the number of predictions in the simple formula y = m*X + b\n\n* Residual Error is obtained by modeling for current value, and subtracting the ACTUAL current value\n\n* The **timer interval** parameter is useful if the connected input tag is currently not polling, but you still want this KPI to publish a value every few seconds, defined by the aforementioned timer\n\n * If you know your input is going to publish at the expected interval, it is better to disable this timer by entering **0** in the field\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "How many values to observe before making each prediction?",
"Default": "60",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "number_of_predictions",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "number_of_predictions",
"Label": "How many polling intervals in future to predict?",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "polling_interval",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "polling_interval",
"Label": "What is the polling interval in seconds?",
"Default": "1",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Database Output",
"Group": "",
"Description": "\n# DB publishing processor \n\nPublish all inputs to a specified DB metric\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOnly",
"Features": [],
"Properties": [
{
"Key": "typed",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "typed",
"Label": "Publish typed name",
"Default": "autogen",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "measurement",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "measurement",
"Label": "Name of the measurement to publish",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "database",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "database",
"Label": "If empty - will use default database",
"Default": "tsdata",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "JSONata",
"Group": "",
"Description": "\n# JSONata Processor\n\n* Uses specified JSONata schema to transform incoming payload\n\n* JSONata is a flexible query and transformation language for JSON data\n\n* When using the JSONata processor it is important to define the correct input wires and JSONata expression to match\n\n* Supports both Event and Value wire types \n\n* Using Event wires as Input:\n\n\t* When using the Event wire type, there is no need to specify the wire name when defining the fields in the JSONata expression\n\t\n\t* Defining multiple inputs into a single JSONata process is possible, however each will be considered its own process flow and will generate a new payload\n\t\n\t* Input payload: \n\t\t**{\n\t\t \"datatype\":\"float64\",\n\t\t \"description\":\"\",\n\t\t \"deviceID\":\"75F601CA-0F7A-4C26-90F0-470E2424BAC1\",\n\t\t \"deviceName\":\"Gen\",\n\t\t \"metadata\":{},\n\t\t \"registerId\":\"D5DCF52F-342B-4211-8F4F-B92E4406BC4C\",\n\t\t \"success\":true,\n\t\t \"tagName\":\"tag1\",\n\t\t \"timestamp\":1739558895577,\n\t\t \"value\":0.38164469548275337\n\t\t}**\n\n\t* JSONata expression: \n\n\t\t* In this example I simply need to define the field name from the input in the expression: \n\t\t**{\n\t\t\t\"metric\": $substring(tagName,3),\n\t\t\t\"value\": value,\n\t\t\t\"date\": $fromMillis(timestamp, '[M01]/[D01]/[Y0001] [h#1]:[m01][P]')\n\t\t}**\n\n\t* Output payload: **{\"date\":\"02/14/2025 6:51pm\",\"metric\":\"1\",\"value\":0.38164469548275337}**\n* Using Value wires as Input:\n\n\t* When using the Value wire type, it is important for every input field used there needs to be a prefix wire name\n\n\t* The JSONata processor will not produce a payload until all input payloads are present. So the payload from input 1 will be stored in memory until input 2 produces a payload\n\n\t* Input payload 1:\t(wirename = Input_1)\n\t\t**{\n\t\t \"datatype\":\"float64\",\n\t\t \"description\":\"current metric\",\n\t\t \"deviceID\":\"75F601CA-0F7A-4C26-90F0-470E2424BAC1\",\n\t\t \"deviceName\":\"Gen\",\n\t\t \"metadata\":{},\n\t\t \"registerId\":\"D5DCF52F-342B-4211-8F4F-B92E4406BC4C\",\n\t\t \"success\":true,\n\t\t \"tagName\":\"tag1\",\n\t\t \"timestamp\":1739558895577,\n\t\t \"value\":0.38164469548275337\n\t\t}**\n\t* Input payload 2: (wirename = Input_2)\n\t\t**{\n\t\t \"datatype\":\"float64\",\n\t\t \"description\":\"temp metric\",\n\t\t \"deviceID\":\"75F601CA-0F7A-4C26-90F0-470E2424BAC1\",\n\t\t \"deviceName\":\"Gen\",\n\t\t \"metadata\":{},\n\t\t \"registerId\":\"D5DCF52F-342B-4211-8F4F-B92E4406BC4C\",\n\t\t \"success\":true,\n\t\t \"tagName\":\"tag2\",\n\t\t \"timestamp\":1739558895577,\n\t\t \"value\":-1.8813568907902232\n\t\t}** \n\t* JSONata expression: \n\n\t\t**{\n\t\t\t\"metric_1\": Input_1.tagName\n\t\t\t\"metric_2\": Input_2.tagName\n\t\t\t\"value_1\": Input_1.value,\n\t\t\t\"value_2\": Input_2.value,\n\t\t\t\"date\": $fromMillis(timestamp, '[M01]/[D01]/[Y0001] [h#1]:[m01][P]')\n\t\t}** \n\n\t\t* NOTE: It is required to define fields as **wirename.fieldname**\n\t* Output payload: \n\t\t**{\n\t\t\t\"metric_1\": tag1,\n\t\t\t\"metric_2\": tag2,\n\t\t\t\"value_1\": 0.38164469548275337,\n\t\t\t\"value_2\": -1.8813568907902232,\n\t\t\t\"date\":\"02/14/2025 6:51pm\"\n\t\t}** \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "jsonata_schema",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "jsonata_schema",
"Label": "JSONata schema",
"Default": "",
"Type": "script",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Asset Online Percentage",
"Group": "KPI",
"Description": "\n# Asset Online Percentage KPI\t\n\n* The input tag connected to this KPI will be online for some time, and offline for other\n\n * This is indicated by the *success* field in the incoming message from the tag\n\n* This KPI is a simple ratio of -> the time the tag has been online vs how long it has been running\n\n* Inference can be something like \n\n* If the machine is ON for 10 hours, how many hours is it successfully online (running)?\n\n\te.g 'Today, your machine is only being online for 80% of the time'\n (or) 'Last week your machine was online for 60% of the time'\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field\n\n* **Expected Output Fields:** \"asset_online\" in percentage, and the current timestamp\n",
"ShortDescription": "Ratio of uptime and total time",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "end_hour",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "end_hour",
"Label": "End hour when asset online percentage is calculated",
"Default": "24",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "device_reset",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "device_reset",
"Label": "Reset everything when Device changes?",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "start_hour",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "start_hour",
"Label": "Start hour when asset online percentage is calculated",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "ARIMA Filter",
"Group": "Functions",
"Description": "\n#ARIMA Filter\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "number_of_models",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "number_of_models",
"Label": "Take the average prediction from how many models?",
"Default": "5",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "100",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "seasonality_size",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "seasonality_size",
"Label": "Seasonality size",
"Default": "7",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Gaussian Filter",
"Group": "Functions",
"Description": " \n# Simple Gaussian Digital Filter\n\n* First, the mean, standard deviation and variance of a window of values is calculated\n\n* Coefficient is calculated by the formula 1/ {squareRoot(2 * PI) * deviations}\n\n* Exponential Part is calculated by the formula exp{ -(1/2) * (current - mean)^2 / (dev)^2 }\n\n* Multiplying those values gives the Gaussian Function, and then filtered value is obtained\n\n* The **timer interval** parameter is useful if the connected input tag is currently not polling, but you still want this KPI to publish a value every few seconds, defined by the aforementioned timer\n\n * If you know your input is going to publish at the expected interval, it is better to disable this timer by entering **0** in the field\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "30",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "number_of_deviations",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "number_of_deviations",
"Label": "How many deviations to use for the calculation?",
"Default": "1",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Statistical Functions",
"Group": "Functions",
"Description": " \n# Statistical Functions and tests\n\nFew Statistical functions and normality tests for a window of values\n\n* **Jarque-Bera test** : \n\n * This is simple goodness-of-fit test to check if the sample data has similar skewness and kurtosis to a normal distribution\n \n * The further the JB tet value is from zero, the stronger the fact that the data does not belong to the normal distribution\n \n * Skewness and kurtosis are calculated from the window of data and then JB value is calculated\n \n * JB = (n/6) (skewness^2 + (1/4)(kurtosis-3)^2)\n \n * P-value is calculated by subtracting cumulative distribution function at the JB value for the ChiSquared distribution with 1\n\n* **Cramer-Von-Mises test** :\n\n * This is goodness-of-fit test which uses the summed squared differences between the sample of data, and the expected cumulative distribution function\n\n * First, a window of data is collected, then mean and standard deviation is calculated\n\n * Data is then sorted, and Z-scores are calculated by standardizing the data \n \n * cramerVonMises = (1/12n) + SIGMA { ((2i-1)/(2n) - phiZ)^2 }\n\n * P-value is calculated, based on the value of cramerVonMises\n \n* **Anderson-Darling test** :\n \n * This is a statistical test to check whether a given sample of data is from an empirical distribution function or not\n \n * In this case, we are using a normal distribution - meaning, we use this test to see how far the data departs from an ideal normal distribution\n \n * Compared to other tests, Anderson-Darling test gives more weight to the tails of the distribution\n \n * First, a window of data is collected, then mean and standard deviation is calculated\n \n * Data is then sorted, and Z-scores are calculated by standardizing the data\n \n * A^2 = -n - (1/n)* SIGMA{ (2i-1)ln(phiZ[i]) + (2(n-i)+1)ln(phZ[i]) } formula is applied, where phiZ is the cumulative distribution function for the Z-scores \n \n * P-value is calculated, based on the value of A^2\n\n* **D'Agostino Pearson test** :\n\n * With a combination of skewness and kurtosis test, D'Agostino Pearson test checks whether the shape of the window of values matches a normal distributions\n\n* **Kolmogorov-Smirnov test** :\n\n * Lilliefors test is use to check the hypothesis of normality for the Kolmogorov-Smirnov test \n\n * First, a window of data is collected, then mean and standard deviation is calculated\n\n * D+ and D- are calculated by taking maximum discrepancy between the empirical distribution function and the cumulative distribution function\n\n * K statistic is just max(D+,D-)*Sqrt(n)\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "cramer_von_mises",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "cramer_von_mises",
"Label": "Cramer-Von-Mises test for normality",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "d_agostino_pearson",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "d_agostino_pearson",
"Label": "D'Agostino Pearson test for normality",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "kolmogorov_smirnov",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "kolmogorov_smirnov",
"Label": "Kolmogorov-Smirnov test for normality",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "window_size",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "window_size",
"Label": "Window in which to calculate. Window represents number of seconds",
"Default": "100",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "jarque_bera",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "jarque_bera",
"Label": "Jarque-Bera test for normality",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "anderson_darling",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "anderson_darling",
"Label": "Anderson-Darling test for normality",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "ImagePreview",
"Group": "",
"Description": "\n# Image processor\n\n* Shows image preview\n * **property** specifies name of payload's field which contain image data\n * **name** specifies label of the image\n * **width** specifies width of the image, height will be calculated automatically maintaining aspect ratio\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOnly",
"Features": [],
"Properties": [
{
"Key": "image_name",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "image_name",
"Label": "Name of an image",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "image_property_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "image_property_name",
"Label": "Name of the field with image data",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": true,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "image_width_name",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "image_width_name",
"Label": "Width of an image",
"Default": "500",
"Type": "int",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "AI",
"Group": "Functions",
"Description": "\n# AI Processor\n\n* **AI Model** must be set to define the unique name identifier for the model being used.\n\n* **System Prompt** parameter allows users to provide a predefined instruction that influences the AI’s behavior and response style.\n * This can be used to enforce a specific tone, persona, or domain expertise in responses.\n\n* **Temperature** parameter (default **1.0**) controls the randomness of responses.\n * Lower values (e.g., **0.2**) make the AI more focused and deterministic.\n * Higher values (e.g., **1.8**) increase creativity but may reduce consistency.\n\n* **Max Completion Tokens** parameter limits the maximum number of tokens the AI can generate in a single response.\n * This ensures output length remains within expected boundaries.\n * If not set, the model’s default value will be used.\n\n* **Force Response Format to JSON?** parameter determines whether the AI should strictly return responses in JSON format.\n * If **enabled**, all responses will be structured as valid JSON\n * Important: when using JSON mode, you must also instruct the model to produce JSON yourself via a system or user message\n * If **disabled**, responses will follow the model's default output style\n\n* **HTTP Timeout** parameter sets the maximum time (in seconds) the system will wait for a response from the AI.\n * If the AI does not respond within this time, the request will timeout and ignored\n * This prevents excessive delays in cases of high latency.\n",
"ShortDescription": "AI Processor for multiple type of models",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "force_response_format_to_JSON?",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "force_response_format_to_JSON?",
"Label": "Important: when using JSON mode, you must also instruct the model to produce JSON yourself via a system or user message",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "ai_model",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "ai_model",
"Label": "Unique AI Model Name",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "HTTP_timeout",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "HTTP_timeout",
"Label": "HTTP timeout interval in seconds",
"Default": "10",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "system_prompt",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "system_prompt",
"Label": "System Prompt used for the AI model",
"Default": "System Prompt used in the AI model\n\n Example: You are a JSON analyser. Analyze the input and act as a CNC expert who gives a response based on it",
"Type": "script",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "temperature",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "temperature",
"Label": "AI model temperature. Float value between 0 and 2",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "max_completion_tokens",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "max_completion_tokens",
"Label": "Maximum completion tokens",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Inputs Minimum",
"Group": "",
"Description": "\n# Inputs Minimum\n\n* This KPI calculates the minimum value from the given inputs\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "processing_type",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "processing_type",
"Label": "Data type of the value being processed",
"Default": "",
"Type": "string",
"EnumItems": [
"float",
"signed",
"unsigned"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field_name",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field_name",
"Label": "Usually left unchanged. Use it if incoming is message type, and/or non-default \"value\" field name",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Online and Offline",
"Group": "KPI",
"Description": "\n# Online and Offline KPI\n\n* If you do not care for how long the sensor has been ON for, but care for how long was it functional, Online/Offline is a raw number to have more detailed knowledge of the time\n\n e.g this week, the sensor was functional for 150 hours, offline for 18 hours\n (or) Offline time was 5 minutes out of a total of 60 minutes\n\n* If you enable the \"resetOnStatus\" parameter, this KPI will only show how long the device has been ON, or how long it has been OFF, and will reset every time the status changes from ON or OFF\n\n* The **timer interval** parameter is useful if the connected input tag is offline, but you still want this KPI to \"look\" for a value every few seconds, defined by the aforementioned timer\n\n * If you know your tag is going to reliably publish at the expected interval, it is better to disable this timer by entering **0** in the field\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "timerInterval",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds in which to push values. Zero disables this timer",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "device_reset",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "device_reset",
"Label": "Reset everything when device changes?",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "reset_on_status_change",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "reset_on_status_change",
"Label": "Reset online and offline parameters on change in success? e.g reset online time to 0 when tag offline and vice-versa",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "unit",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "unit",
"Label": "Display Online/Offline in Seconds, Minutes, Hours, Days or Weeks",
"Default": "seconds",
"Type": "string",
"EnumItems": [
"seconds",
"minutes",
"hours",
"days",
"weeks"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Rise and Fall",
"Group": "Functions",
"Description": "\n# Rise and Fall\n\n* **Rise** : Once you enter a lower threshold and an upper threshold, this function will show you the timestamp at which the current value starts to rise from the lower threshold\n\n* **Fall** : Once you enter a lower threshold and an upper threshold, this function will show you the timestamp at which the current value starts to fall from the upper threshold\n\n* Also provides rise time and fall time in seconds\n",
"ShortDescription": "Ratio of uptime and total time",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "tolerance",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "tolerance",
"Label": "Any changes under this tolerance will be ignored",
"Default": "0",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "kpi",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "kpi",
"Label": "Rise or Fall, or both?",
"Default": "rise",
"Type": "string",
"EnumItems": [
"rise",
"fall",
"riseAndFall"
],
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "upper",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "upper",
"Label": "Upper Threshold",
"Default": "80",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "lower",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "lower",
"Label": "Lower Threshold",
"Default": "30",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "DataHub Publish",
"Group": "",
"Description": "\n# DataHub streaming output processor \n\n* Supports Event wire types.\n\n* Single Topic Option:\n\n\t* By default this option is enabled\n\n\t* If disabled, the DataHub Publish processor will publish the data to **Topic defined in processor.ProcessorUUID**\n\n* Static Topic publishing:\n\n\t* Simply define your static topic in the Topic field\n\n\t* All payload that flow into the DataHub Publish processor will be published to the static defined topic\n\n* Dynamic Topic publishing:\n\n\t* Users have the option to define a dynamic topic expression to define the topic the incoming data will be published to.\n\n\t* Dynamic Topic option should be enabled\n\n\t* Dynamic Topic Expression\n\n\t\t* An expression will consist of static strings (wrapped in “”), dynamic fields from input and plus sign (+)\n\n\t\t\t* Plus sign is used to concatenate the static and dynamic fields together\n\n\t\t* When defining the dynamic part of the expression, defining the wire name is required with an underscore between the wirename and input field name \n\t\t\t\n\t\t\t**wirename_fieldname** i.e:**AA_tagName**\n\n\t* Example:\n\t\t\n\t\t* I have a payload that is being generated in Analytics, where deviceName, tagName, Plant and Area are dynamic fields that change based on logic defined in my Analytics flow \n\t\t\t**{\n\t\t\t \"datatype\":\"float64\",\n\t\t\t \"deviceName\":\"Gen\", // dynamic field\n\t\t\t \"success\":true,\n\t\t\t \"tagName\":\"tag2\", // dynamic field\n\t\t\t \"timestamp\":1739558895577, \n\t\t\t \"value\":-1.8813568907902232, /dynamic value\n\t\t\t \"Plant\": \"P1\", // dynamic field\n\t\t\t \"Area\": \"A1\" // dynamic field\n\t\t\t \"Topic\": \"LE_topic.P1.A1.Gen.tag2\"\n\t\t\t}**\n\t\n\t\t* If I want to publish this dynamic data to the following topic structure: **LE_03.<Plant>.<Area>.<deviceName>.<tagName>** I simply need to define the following:\n\t\n\t\t\t* Define an Event wire with a name i.e **AA**\n\t\n\t\t\t* In the DataHub Publish Topic field: **“LE_03.” + AA_Plant + “.” + AA_Area + “.” + AA_deviceName + “.” + AA_tagName**\n\t\n\t\t\t\t* **“LE_03”**: static part of my topic structure\n\t\n\t\t\t\t* **AA_Plant, AA_Area, AA_deviceName, AA_tagName**: are all key names present in my input payload\n\t\n\t\t\t\t* **“.”**: is also static and is used to adhere to Litmus Edge dot notation topic structure and allow for wildcarding\n\t\n\t\t\t* Alternatively, a user can also create the entire topic structure for Analytics flow and just pass a single <wirename>_<fieldname> as the Dynamic Topic expression. In this case using Tengo, Javascript or other logic processors in Analytics. I can create my topic and add it as part of my payload\n\t\n\t\t\t\t* Since my input payload has my entire dynamic topic structure, in the DataHub Publish. Simply just define AA_Topic for your dynamic publishing\n\t\t\t\t\n\t\t\t\t**\"Topic\": \"LE_topic.P1.A1.Gen.tag2\"**\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOnly",
"Features": [],
"Properties": [
{
"Key": "topic",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "topic",
"Label": "Topic name for DataHub publish",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "single_topic",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "single_topic",
"Label": "If true just use output topic. If false add `x.${processorID}` to topic",
"Default": "true",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "dynamic_topic",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "dynamic_topic",
"Label": "If true treats topic string as an expression and evaluates it before publish",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Generator",
"Group": "",
"Description": "Simple generator for testing, use t as the variable",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "outputOnly",
"Features": [],
"Properties": [
{
"Key": "strength",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "strength",
"Label": "Strength of simulated wave approximation - max is 10",
"Default": "10",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "periodicity",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "periodicity",
"Label": "Periodicity of signal in seconds",
"Default": "30",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "amplitude_multiplier",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "amplitude_multiplier",
"Label": "Amplitude multiplier",
"Default": "1",
"Type": "float",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "generatorType",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "generatorType",
"Label": "User defined signal generation or pre-defined generation",
"Default": "User Defined",
"Type": "string",
"EnumItems": [
"User Defined",
"Triangle Wave",
"Square Wave",
"Semi Circle Wave",
"Sawtooth Wave",
"Reverse Sawtooth Wave",
"Anomalies by dips only",
"Anomalies by spikes only",
"Anomalies by spikes and dips",
"Anomalies with gaps in data",
"Anomalies with non-changing data"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timerInterval",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timerInterval",
"Label": "Timer in milliseconds. If no event, use this timer to keep displaying the output continually. Enter zero to disable",
"Default": "1000",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "formula",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "formula",
"Label": "Supported math functions: sin, cos, tan, power, sqrt, log, exp, abs",
"Default": "sin(t)",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Tengo script processor",
"Group": "Functions",
"Description": "\n# Scripting for data manipulations\n\n* This processor uses Tengo scripting, with its rules similar to GoLang\n\n* **Simple Use case**: The output you receive from DeviceHub message or from Analytics, might not be helpful, and you want to change the name of a field within that message\n\n * *e.g* Instead of \"value\" you want your data to show \"furnace pressure\"\n\n * *e.g* Instead of having all fields of the message, you only want to have \"success\", \"deviceId\" and \"value\" and skip everything else\n\n * *e.g* You want to add a custom field to the message, based on the \"value\" field, such as: if value = 2, \"error\": \"overheating\"\n\n * *e.g* You only want to change the timestamp to human readable format instead of Unix timestamp, but keep otherwise keep the message as-it-is\n\n * In general, if you want to add, remove or modify *ANY* field in the input, this scripting processor is very useful\n\n* **Single Input:** Every message from the input, is stored as an array called \"values\"\n\n * Using \"for i, message in values{}\" statement, allows to access this input and manipulate it\n\n * Here \"i\" represents what is the *definition* defined in the connection wire, more useful for multi-inputs, to identify and distinguish between each inputs, so for single input, \"i\" can be replaced with \"_\"\n\n * \"message\" contains the entire message in the input, and you can perform your manipulations to this \"message\" parameter\n\n * **Note:** \"i\" and \"message\" can be any custom variable name\n\n* **Multiple Input:** Suppose you have 3 different inputs attached to this scripting processor, with the connecting wires named A, B and C\n\n * \"for i, message in values{}\" will now have 3 inputs\n\n * \"i\" represents from which connection wire is the input coming from\n\n * with if-else statements, every input can be manipulated in isolation, or a common manipulation can be applied to all inputs\n\n * You can choose to output \"result\" only for one input, or all of the inputs\n\n* **Miscellaneous information:** \n\n * [Available Standard Library](https://github.com/d5/tengo/blob/master/docs/stdlib.md)\n\n * [Syntax details Github:](https://github.com/d5/tengo) or [Official site](https://tengolang.com)\n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "timeout",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timeout",
"Label": "timeout in ms",
"Default": "1000",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "script",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "script",
"Label": "Script body",
"Default": "// Single input example\n\nresult := 0\n\nfor _, message in values{\n \n message[\"customField\"] = float(message[\"value\"]) * 100\n \n result = {\n \"timestamp\": message[\"timestamp\"],\n \"value100\": message[\"customField\"],\n \"success\": message[\"success\"]\n }\n}\n\n/*\n\n// Multiple inputs example\n\nresult:= 0\n\nfor i, message in values{\n \n if i == \"A\"{\n message[\"customField\"] = float(message[\"value\"]) * 10\n }\n if i == \"B\"{\n message[\"customField\"] = float(message[\"value\"]) * 100\n }\n if i == \"C\"{\n message[\"customField\"] = float(message[\"value\"]) * 0.01\n }\n \n result = {\n \"timestamp\" : values[i][\"timestamp\"],\n \"value\" : values[i][\"value\"],\n \"customized_value\": message[\"customField\"], \n \"input_source: \": i,\n \"success\": message[\"success\"]\n }\n}\n*/\n",
"Type": "script",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "Join Processor",
"Group": "",
"Description": "\n# Join processor by Fields\n\n* Output mode\n \n * Two options available here are *map* and *array* form\n\n * **Map** option is better if standard JSON format is needed (eg. for DataBase output)\n\n * **Array** option is better if all values are needed in an array format\n\n* Map Field Prefix\n\n * This field can remain empty, but you can add a prefix if you want, in front of the output fields when they are combined\n\n* Array Sort Order\n\n * In array mode, you can chose to arrange field values in either Ascending and Descending order\n\n* Input Source\n\n * What to show as the input source? Device Name, or the connecting wire definition name?\n\n * If Device Name is chosen, it is *required* to have \"deviceName\" and \"tagName\" field in the input\n",
"ShortDescription": "Join values in array",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [],
"Properties": [
{
"Key": "input_source",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_source",
"Label": "What to show as the input source?",
"Default": "wire connection name",
"Type": "string",
"EnumItems": [
"device name",
"wire connection name"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "pass_through_value",
"Value": {
"TabOrder": 9,
"Position": 9,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "pass_through_value",
"Label": "By enabling this flag input will be joined with output of processor",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": true,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "map_field_prefix",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "map_field_prefix",
"Label": "Any prefix for the map field?",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "array_sort_order",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "array_sort_order",
"Label": "Sort array in ascending order or descending?",
"Default": "asc",
"Type": "string",
"EnumItems": [
"asc",
"desc"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "output_mode",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "output_mode",
"Label": "Output format",
"Default": "",
"Type": "string",
"EnumItems": [
"map",
"array"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "array_sort_by",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "array_sort_by",
"Label": "",
"Default": "time",
"Type": "string",
"EnumItems": [
"tag",
"definition",
"id",
"time"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timestampOrder",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timestampOrder",
"Label": "Take timestamp in which order?",
"Default": "last",
"Type": "string",
"EnumItems": [
"last",
"first",
"avg"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "field",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "field",
"Label": "Which field to join?",
"Default": "value",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "attach_devices",
"Value": {
"TabOrder": null,
"Position": null,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "attach_devices",
"Label": "Aggregate devices in output?",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
},
{
"Name": "FileReader",
"Group": "",
"Description": "\n# File Reading Processor\n\n* Reads a file and passes it as a string in the **\"value\"** field of the output payload\n\n* If the ***File Name*** field is empty, this processor will attempt to get filename from incoming payload field **\"filename\"**\n * Otherwise, the filename entered here field will be honored\n\n* If the **\"Generate Filename From Expression\"** option is enabled, the filename will be evaluated as expression.\n * For example, if you want to get the filename from \"path\" and name\" properties of incoming connection \"AAA\", your expression could be:\n\t**AAA_path + AAA_name + \".txt\"**\n * Please note that static text in expressions should be put into quotes \n\n* Time interval, in seconds, allows a file to be re-read even if the file is unmodified\n * Typically, an input message triggers a file read, if the file is unmodified since the last read\n * The specified time interval resets the “unmodified” status, so that the file can be read at the next input trigger\n * Any change of the processor’s setting also resets the \"unmodified\" status\n * Setting **0** means that the “unmodified” status is never reset, and the file is only read if modified\n\n* **\"File Size Limit\"**: If the file/s is bigger than the specified amount of megabytes, reading action on that file/s will be skipped\n * ***Caution!*** If this limit is set to **0**, files of all sizes will be read, but it can potentially lead to overuse of CPU, memory and storage space\n\n* If ***\"Input File Type\"*** is set to **value only** processor will set incoming data to **\"value\"\"** payload field.\n* If ***\"Input File Type\"*** is set to **CSV** following options will affect input: \n * **CSV Comma** contains CSV-file delimiter (only first character will be used from string entered)\n * **CSV Columns Mode** controls how processor will determine data column names. \n\t* If this option is set to \"indexed\" mode processor will assume CSV file doesnt have header and will generate payload field names as \"FieldXXX\" \n\t* If this option is set to \"from header\" mode processor will get payload field names from CSV file header\n * If this option is set to \"custom\" mode processor will get payload field names **CSV Custom Columns** string \n* **\"Data Output Mode\"**: specifies whether data from file would be sent in one message on record-by-record.\n\t* *** Please note: ** **a message per record** data output mode is not supported for binary or JSON files \n",
"ShortDescription": "",
"RequiredDefinitions": [],
"ConnectDirection": "inputOutput",
"Features": [
"Invoke"
],
"Properties": [
{
"Key": "file_name",
"Value": {
"TabOrder": 0,
"Position": 0,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "file_name",
"Label": "Name of a file to read. If not absolute it will be relative to working directory of analytics2 process",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "generate_filename_from_expression",
"Value": {
"TabOrder": 1,
"Position": 1,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "generate_filename_from_expression",
"Label": "Generates name of a file to write from filename expression.",
"Default": "false",
"Type": "bool",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "file_size_limit_in_mb",
"Value": {
"TabOrder": 3,
"Position": 3,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "file_size_limit_in_mb",
"Label": "Files which size (in megabytes) is greater than this value will not be read. 0 - no limitations",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "timer_interval_in_seconds",
"Value": {
"TabOrder": 4,
"Position": 4,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "timer_interval_in_seconds",
"Label": "Period of time in seconds between generation of a new filename.",
"Default": "0",
"Type": "uint",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "data_output_mode",
"Value": {
"TabOrder": 5,
"Position": 5,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "data_output_mode",
"Label": "Data output mode",
"Default": "a single message",
"Type": "string",
"EnumItems": [
"a single message",
"a message per record"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_columns_mode",
"Value": {
"TabOrder": 7,
"Position": 7,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_columns_mode",
"Label": "column names output",
"Default": "from header",
"Type": "string",
"EnumItems": [
"generated as 'columnXX'",
"from header",
"custom (header exist)",
"custom (no header)"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_custom_columns",
"Value": {
"TabOrder": 8,
"Position": 8,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_custom_columns",
"Label": "input column names",
"Default": "",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "input_file_type",
"Value": {
"TabOrder": 2,
"Position": 2,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "input_file_type",
"Label": "File type",
"Default": "JSON",
"Type": "string",
"EnumItems": [
"JSON",
"CSV",
"value only",
"Parquet",
"Binary"
],
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
},
{
"Key": "csv_comma",
"Value": {
"TabOrder": 6,
"Position": 6,
"LinkedFieldName": null,
"LinkedValues": null,
"Item": {
"Name": "csv_comma",
"Label": "CSV delimiter (one character)",
"Default": ",",
"Type": "string",
"EnumItems": null,
"DisplayLabel": true,
"FromNewLine": false,
"IsValueRequired": false,
"IsPassword": false,
"TextType": ""
},
"Validators": null,
"TableColumns": null,
"Rules": null,
"LinkedFields": null
}
}
]
}
]
}
}
Get Processor Last Error
POST {{edgeUrl}}/analytics/v3
Get Processor Last Error
Returns the most recent error reported by a specific processor instance. Use this to surface failures inline in a UI (e.g. show a red dot on the node with a tooltip carrying Error).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetProcessorInstanceLastError($input: String!) {
GetProcessorInstanceLastError(input: $input) {
Timestamp
Error
}
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Processor UUID. |
{ "input": "{{analytics_single_processor_id}}" }
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetProcessorInstanceLastError.Timestamp |
Time |
ISO 8601 timestamp of the most recent error (or last status update). |
data.GetProcessorInstanceLastError.Error |
String |
Error message. Empty string if the processor is healthy. |
{
"data": {
"GetProcessorInstanceLastError": {
"Timestamp": "2025-09-11T20:07:37Z",
"Error": ""
}
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetProcessorInstanceLastError ($input: String!) {
GetProcessorInstanceLastError(input: $input) {
Timestamp
Error
}
}
Variables
{
"input": "{{analytics_single_processor_id}}"
}
Response
Status: 200 OK
{
"data": {
"GetProcessorInstanceLastError": {
"Timestamp": "2025-09-11T20:07:37Z",
"Error": ""
}
}
}
Get Processor Last Value
POST {{edgeUrl}}/analytics/v3
Get Processor Last Value
Returns the most recent output value of a processor instance. Useful as a poll-based alternative to Subscribe to Processor Output when you only need a snapshot.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetProcessorInstanceLastValue($input: String!) {
GetProcessorInstanceLastValue(input: $input) {
Timestamp
Value
}
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Processor UUID. |
{ "input": "{{analytics_single_processor_id}}" }
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetProcessorInstanceLastValue.Timestamp |
Time |
When the value was emitted. |
data.GetProcessorInstanceLastValue.Value |
JSON |
The output payload itself. Shape depends on the processor's function. |
{
"data": {
"GetProcessorInstanceLastValue": {
"Timestamp": "2025-09-11T20:10:23Z",
"Value": {
"success": true,
"timestamp": 1757621422846,
"value": 0.8135667470259184
}
}
}
}
A null Value means the processor has not emitted yet since the Analytics service started.
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetProcessorInstanceLastValue($input: String!) {
GetProcessorInstanceLastValue(input: $input) {
Timestamp
Value
}
}
Variables
{
"input": "{{analytics_single_processor_id}}"
}
Response
Status: 200 OK
{
"data": {
"GetProcessorInstanceLastValue": {
"Timestamp": "2025-09-11T20:10:23Z",
"Value": {
"success": true,
"timestamp": 1757621422846,
"value": 0.8135667470259184
}
}
}
}
Delete Processors
POST {{edgeUrl}}/analytics/v3
Delete Processors
Deletes one or more processor instances. The mutation is bulk by design -- pass any number of UUIDs in the array. Processors are removed along with their wires (the wires they were on are simply detached on the surviving sides).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation DeleteProcessorInstances($input: [String!]) {
DeleteProcessorInstances(input: $input)
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
[String!] |
Yes | UUIDs of processors to delete. |
{
"input": [
"{{analytics_single_processor_id}}",
"{{analytics_single_processor_id_another}}"
]
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "DeleteProcessorInstances": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation DeleteProcessorInstances($input: [String!]) {
DeleteProcessorInstances(input: $input)
}
Variables
{
"input": [
"{{analytics_single_processor_id}}",
"{{analytics_single_processor_id_another}}"
]
}
Response
Status: 200 OK
{
"data": {
"DeleteProcessorInstances": null
}
}
Get All Topics
POST {{edgeUrl}}/analytics/v3
Get All Topics
Returns every topic the device knows about: device tag aliases, analytics outputs, integration bridges, etc. Use this for cross-group topic discovery (e.g. selecting an upstream DeviceHub topic to subscribe a processor to).
For the group-scoped, paginated, pattern-filtered variant, see Get Topics in Group.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetTopics {
GetTopics {
Topic
Format
Direction
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetTopics |
[Topic!]! |
All topics on the device. |
data.GetTopics[].Topic |
String |
Topic name (e.g. devicehub.alias.P1_L1_Machine3_1_S7.CycleTime_Base). |
data.GetTopics[].Format |
String |
Payload format (json, binary, ...). |
data.GetTopics[].Direction |
String |
input (the device subscribes), output (the device publishes), or both. |
{
"data": {
"GetTopics": [
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.CycleTime_Base",
"Format": "json",
"Direction": "output"
}
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetTopics {
GetTopics {
Topic
Format
Direction
}
}
Response
Status: 200 OK
{
"data": {
"GetTopics": [
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine3_1_S7.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine2_1_MB.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L1_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "analytics.publish.u6PLGF3J1D-C_PQXmJC9Y",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L1_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine2_1_MB.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine1_1_OPC.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "${hello}",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L1_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine1_1_OPC.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine1_1_OPC.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine1_1_OPC.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine3_1_S7.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L3_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine3_1_S7.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine2_1_MB.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine2_1_MB.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L2_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine3_1_S7.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine2_1_MB.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.FaultCode_Min_Value",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine2_1_MB.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L3_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine1_1_OPC.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine2_1_MB.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L2_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine2_1_MB.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L2_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine1_1_OPC.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine1_1_OPC.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "P1_EnergyMonitoring",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.Speed",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine2_1_MB.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine1_1_OPC.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine3_1_S7.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L3_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "downtimeHistoryRecord",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L3_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine3_1_S7.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine2_1_MB.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine3_1_S7.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L1_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine1_1_OPC.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine2_1_MB.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L2_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine3_1_S7.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine1_1_OPC.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine2_1_MB.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.CycleTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L1_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L1_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.Speed",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine1_1_OPC.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine2_1_MB.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine2_1_MB.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L2_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine1_1_OPC.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L3_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine2_1_MB.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "scrapHistoryRecord",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L3_Machine2_1_MB.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine3_1_S7.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine1_1_OPC.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine2_1_MB.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine1_1_OPC.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine3_1_S7.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine2_1_MB.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.Objects_Tags_PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "P2_EnergyMonitoring",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine3_1_S7.PartSize_TestResult",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine2_1_MB.PartMade",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine1_1_OPC.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L2_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L1_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine2_1_MB.BadPart",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P2_L2_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine1_1_OPC.isRunning",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L2_Machine2_1_MB.TaktTime_Base",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.P1_L1_Machine1_1_OPC.isRunning1",
"Format": "json",
"Direction": "output"
},
{
"Topic": "devicehub.alias.L4_Machine3_1_S7.isRunning",
"Format": "json",
"Direction": "output"
}
]
}
}
Subscribe to Processor Output
POST {{edgeUrl}}/analytics/v3
Subscribe to Processor Output (subscription)
Streams the live output of a single processor as it emits. This is a GraphQL subscription -- a plain POST returns at most one event. For continuous streaming, use a WebSocket transport (graphql-ws / subscriptions-transport-ws) or Server-Sent Events.
Transport
WebSocket: wss://{{edgeHost}}/analytics/v3.
The Postman item is shown as POST for documentation purposes; switch to a Postman WebSocket request when streaming.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Subscription body
subscription SubscribeToProcessorInstanceOutput($input: String!) {
SubscribeToProcessorInstanceOutput(input: $input)
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Processor UUID to subscribe to. |
{ "input": "{{analytics_single_processor_id}}" }
Event shape
Each event is a JSON document (the processor's emitted payload) wrapped in the standard GraphQL data envelope. The payload may be a serialized string (as in the example) or an object, depending on the processor's output format.
{
"data": {
"SubscribeToProcessorInstanceOutput": "{\"success\":true,\"timestamp\":1757621792847,\"value\":-0.7678533456077484}"
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
Subscription notes
- Reconnect with backoff on transport close. There is no replay buffer.
- One subscription per processor -- to watch many, open multiple.
- Backpressure-sensitive: for high-rate processors, prefer poll-based
Get Processor Last Valueif you don't need every emission.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
subscription SubscribeToProcessorInstanceOutput($input: String!) {
SubscribeToProcessorInstanceOutput(input: $input)
}
Variables
{
"input": "{{analytics_single_processor_id}}"
}
Response
Status: 200 OK
{
"data": {
"SubscribeToProcessorInstanceOutput": "{\"success\":true,\"timestamp\":1757621792847,\"value\":-0.7678533456077484}"
}
}
Create New Processor
POST {{edgeUrl}}/analytics/v3
Create New Processor
Creates a new processor instance. The Function argument selects which processor kind to instantiate; the Parameters array carries the function-specific configuration. Discover what each function accepts via Get All (Supported) Processors Metadata.
For wiring, use Connect Processor Instances after creation (or pre-fill ValueInputs / EventInputs here).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation CreateProcessorInstance($input: CreateProcessorInstanceRequest!) {
CreateProcessorInstance(input: $input) {
ID
Name
Function
Definitions { Key Value }
ValueInputs
EventInputs
Parameters { Key Value }
Active
Outputs
}
}
Variables (input: CreateProcessorInstanceRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
Function |
String! |
Yes | Function key from Get All (Supported) Processors Metadata (e.g. Generator, Moving Average). |
Name |
String! |
Yes | Display name. Must be unique within the group. |
Active |
Boolean! |
Yes | true to start running immediately; false to create-but-not-run. |
Outputs |
[ID!]! |
Yes | UUIDs of processors this one will feed. Usually [] at create time and populated via wire endpoints. |
ValueInputs |
[ID!]! |
Yes | UUIDs of upstream processors feeding value wires. |
EventInputs |
[ID!]! |
Yes | UUIDs of upstream processors feeding event wires. |
Definitions |
[KeyValueInput!]! |
Yes | Per-input definitions (function-specific binding metadata). |
Parameters |
[KeyValueInput!]! |
Yes | Function-specific tunables. |
Variables (example)
{
"input": {
"Active": true,
"Function": "Generator",
"Name": "API - created Processor",
"Outputs": [],
"ValueInputs": [],
"EventInputs": [],
"Definitions": [],
"Parameters": [
{ "Key": "strength", "Value": "10" },
{ "Key": "amplitude_multiplier","Value": "1" },
{ "Key": "generatorType", "Value": "User Defined" }
]
}
}
Response
200 OK -- application/json. Returns the new processor, including its server-assigned ID. Save this as {{analytics_single_processor_id}} for follow-up calls.
{
"data": {
"CreateProcessorInstance": {
"ID": "DA2A2F9D-EE20-415D-AF7F-C30E6FDE0F83",
"Name": "API - created Processor",
"Function": "Generator",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [ ... ],
"Active": true,
"Outputs": []
}
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation CreateProcessorInstance($input: CreateProcessorInstanceRequest!) {
CreateProcessorInstance(input: $input) {
ID
Name
Function
Definitions {
Key
Value
}
ValueInputs
EventInputs
Parameters {
Key
Value
}
Active
Outputs
}
}
Variables
{
"input": {
"Active": true,
"Function": "Generator",
"Name": "API - created Processor",
"Outputs": [],
"ValueInputs": [],
"EventInputs": [],
"Definitions": [],
"Parameters": [
{
"Key": "strength",
"Value": "10"
},
{
"Key": "periodicity",
"Value": "30"
},
{
"Key": "amplitude_multiplier",
"Value": "1"
},
{
"Key": "generatorType",
"Value": "User Defined"
},
{
"Key": "timerInterval",
"Value": "1000"
},
{
"Key": "formula",
"Value": "sin(t)"
}
],
"GroupName": "default"
}
}
Response
Status: 200 OK
{
"data": {
"CreateProcessorInstance": {
"ID": "DA2A2F9D-EE20-415D-AF7F-C30E6FDE0F83",
"Name": "API - created Processor",
"Function": "Generator",
"Definitions": [],
"ValueInputs": [],
"EventInputs": [],
"Parameters": [
{
"Key": "amplitude_multiplier",
"Value": "1"
},
{
"Key": "generatorType",
"Value": "User Defined"
},
{
"Key": "timerInterval",
"Value": "1000"
},
{
"Key": "formula",
"Value": "sin(t)"
},
{
"Key": "strength",
"Value": "10"
},
{
"Key": "periodicity",
"Value": "30"
}
],
"Active": true,
"Outputs": []
}
}
}
Import Group
POST {{edgeUrl}}/analytics/v3
Import Group
Restores a group from an Export Group payload. The mutation accepts the target groupName (new or existing) and the serialized payload as a JSON string in data.
Importing into an existing group replaces its contents -- snapshot first via Export Group if you may want to roll back.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation ImportGroup($groupName: String!, $data: String!) {
ImportGroup(groupName: $groupName, data: $data)
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
groupName |
String! |
Yes | Target group. Created if it does not exist; replaced if it does. |
data |
String! |
Yes | The ExportGroup payload, JSON-encoded as a string (escaped quotes). |
{
"groupName": "{{analytics_group_name}}",
"data": "{\"__typename\":\"BackupItem\",\"Processors\":[ ... ]}"
}
The data string must be the full BackupItem envelope as returned by ExportGroup. Build it programmatically by stringifying the export response before sending.
Response
200 OK -- application/json. No data returned on success.
{ "data": { "ImportGroup": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation ImportGroup($groupName: String!, $data: String!) {
ImportGroup(groupName: $groupName, data: $data)
}
Variables
{
"groupName": "{{analytics_group_name}}",
"data": "{\"__typename\":\"BackupItem\",\"Processors\":[{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"10A5AFCD-D002-4DD0-A7EE-81DBCE813937\",\"Name\":\"Database Output - [9039]\",\"FunctionName\":\"Database Output\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"database\":\"tsdata\",\"measurement\":\"EnergyMonitoring\",\"typed\":\"autogen\"}},\"InputEvents\":[\"CA4DA5E7-5DAD-4131-A95D-1152E92197F6\"],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"13295498-20FE-465D-9E12-1491E53FB23F\",\"Name\":\"Flow - [5701]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"1494F758-8CB6-460D-BC0F-ABFB8C6B9ACD\",\"Name\":\"Flow - [9566]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"175D1678-DDC4-4141-890A-2AEAC9C3530A\",\"Name\":\"Flow - [2917]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"1C589F97-66F4-43A8-BBC3-738C46F11EFD\",\"Name\":\"Flow - [9175]\",\"FunctionName\":\"Database Output\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"database\":\"tsdata\",\"measurement\":\"EnergyMonitoring\",\"typed\":\"autogen\"}},\"InputEvents\":[\"41BE8686-B8C8-485E-9B40-76F471A63D4D\"],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"1CF6F23B-1539-49E5-9987-1B9282FC7440\",\"Name\":\"Generator - [1096]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"1F971773-3A9F-492B-BEC9-B6BDB18CE187\",\"Name\":\"Flow - [8290]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"30EED68F-B353-473A-9859-223BA214D4E7\",\"Name\":\"Flow - [361]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"373EF09A-C290-413D-969C-9DB308142C6A\",\"Name\":\"Flow - [5609]\",\"FunctionName\":\"DataHub Publish\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"dynamic_topic\":false,\"single_topic\":true,\"topic\":\"analytics.publish.u6PLGF3J1D-C_PQXmJC9Y\"}},\"InputEvents\":[\"735E383E-EF78-485F-84CB-E02F205BE98B\"],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"38687BA1-C2F2-450A-8A9C-9BF10617BADB\",\"Name\":\"DataHub Subscribe - [5513]\",\"FunctionName\":\"DataHub Subscribe\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"ignore_failed_data\":false,\"ignore_null_value\":false,\"topic\":\"scrapHistoryRecord\"}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"38DD824D-5270-49E1-A45D-45C2EDF14D1D\",\"Name\":\"Flow - [8159]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"41BE8686-B8C8-485E-9B40-76F471A63D4D\",\"Name\":\"DataHub Subscribe - [644]\",\"FunctionName\":\"DataHub Subscribe\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"format\":\"json\",\"topic\":\"P1_EnergyMonitoring\"}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"1C589F97-66F4-43A8-BBC3-738C46F11EFD\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"421CB60D-91BA-4EB7-BD66-AA92AF498602\",\"Name\":\"Flow - [5225]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"4507AA2F-B3A2-40CE-B2F3-8540476C60A6\",\"Name\":\"Flow - [6256]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"4B120A78-C3D5-4FBC-B6CC-FD1FAC05F0A7\",\"Name\":\"Flow - [9777]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"5B4DC834-C069-4340-986A-BC45957D5E07\",\"Name\":\"Database Output - [5434]\",\"FunctionName\":\"Database Output\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"database\":\"tsdata\",\"measurement\":\"DTR\",\"typed\":\"autogen\"}},\"InputEvents\":[\"E8ED3C80-690C-4549-A509-BBEFE66F039E\"],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"658E3F0A-6762-4DC2-8820-4CAA2C4C853B\",\"Name\":\"Flow - [9603]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"66D7C5E1-0DBB-4F15-9DB0-7ED63E4960EE\",\"Name\":\"Flow - [8629]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"735E383E-EF78-485F-84CB-E02F205BE98B\",\"Name\":\"Flow - [5609]\",\"FunctionName\":\"Change of Value\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"delta_of_tolerance\":0,\"map_field_name\":\"value\",\"pass_through_value\":false,\"timerInterval\":0}},\"InputEvents\":[\"97E2788B-CB2E-44CE-8312-41DD1F388286\"],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"373EF09A-C290-413D-969C-9DB308142C6A\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7\",\"Name\":\"Database Output - [8347]\",\"FunctionName\":\"Database Output\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"database\":\"tsdata\",\"measurement\":\"SR\",\"typed\":\"autogen\"}},\"InputEvents\":[\"38687BA1-C2F2-450A-8A9C-9BF10617BADB\"],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"97E2788B-CB2E-44CE-8312-41DD1F388286\",\"Name\":\"Flow - [5609]\",\"FunctionName\":\"DataHub Subscribe\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"ignore_failed_data\":false,\"ignore_null_value\":false,\"topic\":\"${hello}\"}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"735E383E-EF78-485F-84CB-E02F205BE98B\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"B5902202-288B-46A8-A678-680CB38AECAD\",\"Name\":\"Flow - [4167]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\",\"Name\":\"Flow - [2801]\",\"FunctionName\":\"TensorFlow processor\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"input_operation\":\"serve_keras_tensor\",\"model_path\":\"/var/lib/loopedge-analytics2/models/shortSavedModel\",\"number_of_inputs\":19,\"output_operation\":\"StatefulPartitionedCall\",\"pass_through_value\":false,\"tags\":\"serve\",\"time_shift_ms\":0,\"window_size\":10}},\"InputEvents\":[],\"InputWaits\":[\"1CF6F23B-1539-49E5-9987-1B9282FC7440\",\"175D1678-DDC4-4141-890A-2AEAC9C3530A\",\"CB227823-3D17-47A7-A3FE-F7D885509BF7\",\"658E3F0A-6762-4DC2-8820-4CAA2C4C853B\",\"1F971773-3A9F-492B-BEC9-B6BDB18CE187\",\"30EED68F-B353-473A-9859-223BA214D4E7\",\"66D7C5E1-0DBB-4F15-9DB0-7ED63E4960EE\",\"BE9F4653-FC54-4568-AED3-4FFD26D7340E\",\"13295498-20FE-465D-9E12-1491E53FB23F\",\"4B120A78-C3D5-4FBC-B6CC-FD1FAC05F0A7\",\"4507AA2F-B3A2-40CE-B2F3-8540476C60A6\",\"BE958B8C-21FC-4317-8B79-22038AB09BB1\",\"B5902202-288B-46A8-A678-680CB38AECAD\",\"F0099E0C-8A33-4FBA-BA19-A6B328161E47\",\"38DD824D-5270-49E1-A45D-45C2EDF14D1D\",\"1494F758-8CB6-460D-BC0F-ABFB8C6B9ACD\",\"421CB60D-91BA-4EB7-BD66-AA92AF498602\",\"E39F4B2F-7395-46A0-B61A-5919F2DB3A1B\",\"E8FD1472-697F-4BDB-AC7C-D73DC5EF49BE\"],\"InputsDefinitions\":{\"0\":\"1CF6F23B-1539-49E5-9987-1B9282FC7440\",\"1\":\"175D1678-DDC4-4141-890A-2AEAC9C3530A\",\"2\":\"CB227823-3D17-47A7-A3FE-F7D885509BF7\",\"3\":\"658E3F0A-6762-4DC2-8820-4CAA2C4C853B\",\"4\":\"1F971773-3A9F-492B-BEC9-B6BDB18CE187\",\"5\":\"30EED68F-B353-473A-9859-223BA214D4E7\",\"6\":\"66D7C5E1-0DBB-4F15-9DB0-7ED63E4960EE\",\"7\":\"13295498-20FE-465D-9E12-1491E53FB23F\",\"8\":\"BE9F4653-FC54-4568-AED3-4FFD26D7340E\",\"9\":\"4B120A78-C3D5-4FBC-B6CC-FD1FAC05F0A7\",\"10\":\"4507AA2F-B3A2-40CE-B2F3-8540476C60A6\",\"11\":\"BE958B8C-21FC-4317-8B79-22038AB09BB1\",\"12\":\"B5902202-288B-46A8-A678-680CB38AECAD\",\"13\":\"F0099E0C-8A33-4FBA-BA19-A6B328161E47\",\"14\":\"38DD824D-5270-49E1-A45D-45C2EDF14D1D\",\"15\":\"1494F758-8CB6-460D-BC0F-ABFB8C6B9ACD\",\"16\":\"421CB60D-91BA-4EB7-BD66-AA92AF498602\",\"17\":\"E39F4B2F-7395-46A0-B61A-5919F2DB3A1B\",\"18\":\"E8FD1472-697F-4BDB-AC7C-D73DC5EF49BE\"},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"BE958B8C-21FC-4317-8B79-22038AB09BB1\",\"Name\":\"Flow - [2309]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"BE9F4653-FC54-4568-AED3-4FFD26D7340E\",\"Name\":\"Flow - [1445]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"CA4DA5E7-5DAD-4131-A95D-1152E92197F6\",\"Name\":\"DataHub Subscribe - [1311]\",\"FunctionName\":\"DataHub Subscribe\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"format\":\"json\",\"topic\":\"P2_EnergyMonitoring\"}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"10A5AFCD-D002-4DD0-A7EE-81DBCE813937\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"CB227823-3D17-47A7-A3FE-F7D885509BF7\",\"Name\":\"Flow - [9035]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"DA2A2F9D-EE20-415D-AF7F-C30E6FDE0F83\",\"Name\":\"API - created Processor\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"E39F4B2F-7395-46A0-B61A-5919F2DB3A1B\",\"Name\":\"Flow - [6474]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"E8ED3C80-690C-4549-A509-BBEFE66F039E\",\"Name\":\"DataHub Subscribe - [7390]\",\"FunctionName\":\"DataHub Subscribe\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"ignore_failed_data\":false,\"ignore_null_value\":false,\"topic\":\"downtimeHistoryRecord\"}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"5B4DC834-C069-4340-986A-BC45957D5E07\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"E8FD1472-697F-4BDB-AC7C-D73DC5EF49BE\",\"Name\":\"Flow - [3557]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]},{\"__typename\":\"BackupProcessorDBRecord\",\"ID\":\"F0099E0C-8A33-4FBA-BA19-A6B328161E47\",\"Name\":\"Flow - [9312]\",\"FunctionName\":\"Generator\",\"IsActive\":true,\"Config\":{\"__typename\":\"BackupProcessorConfig\",\"settings\":{\"amplitude_multiplier\":1,\"formula\":\"sin(t)\",\"generatorType\":\"User Defined\",\"periodicity\":30,\"strength\":10,\"timerInterval\":1000}},\"InputEvents\":[],\"InputWaits\":[],\"InputsDefinitions\":{},\"State\":null,\"Outputs\":[\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\"]}],\"Positions\":[{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"10A5AFCD-D002-4DD0-A7EE-81DBCE813937\",\"Top\":16,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"13295498-20FE-465D-9E12-1491E53FB23F\",\"Top\":1489,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"1494F758-8CB6-460D-BC0F-ABFB8C6B9ACD\",\"Top\":2417,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"175D1678-DDC4-4141-890A-2AEAC9C3530A\",\"Top\":793,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"1C589F97-66F4-43A8-BBC3-738C46F11EFD\",\"Top\":125,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"1CF6F23B-1539-49E5-9987-1B9282FC7440\",\"Top\":677,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"1F971773-3A9F-492B-BEC9-B6BDB18CE187\",\"Top\":1141,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"30EED68F-B353-473A-9859-223BA214D4E7\",\"Top\":1257,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"373EF09A-C290-413D-969C-9DB308142C6A\",\"Top\":452,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"38687BA1-C2F2-450A-8A9C-9BF10617BADB\",\"Top\":241,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"38DD824D-5270-49E1-A45D-45C2EDF14D1D\",\"Top\":2301,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"41BE8686-B8C8-485E-9B40-76F471A63D4D\",\"Top\":125,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"421CB60D-91BA-4EB7-BD66-AA92AF498602\",\"Top\":2533,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"4507AA2F-B3A2-40CE-B2F3-8540476C60A6\",\"Top\":1837,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"4B120A78-C3D5-4FBC-B6CC-FD1FAC05F0A7\",\"Top\":1721,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"5B4DC834-C069-4340-986A-BC45957D5E07\",\"Top\":357,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"658E3F0A-6762-4DC2-8820-4CAA2C4C853B\",\"Top\":1025,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"66D7C5E1-0DBB-4F15-9DB0-7ED63E4960EE\",\"Top\":1373,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"735E383E-EF78-485F-84CB-E02F205BE98B\",\"Top\":452,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"7CCC34AE-6C58-4DB0-9F77-DAFDB793A3B7\",\"Top\":241,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"97E2788B-CB2E-44CE-8312-41DD1F388286\",\"Top\":452,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"B5902202-288B-46A8-A678-680CB38AECAD\",\"Top\":2069,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"BDA9466A-6A0B-4646-B9E4-63FA4C5CEB2C\",\"Top\":2177,\"Left\":697,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"BE958B8C-21FC-4317-8B79-22038AB09BB1\",\"Top\":1953,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"BE9F4653-FC54-4568-AED3-4FFD26D7340E\",\"Top\":1605,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"CA4DA5E7-5DAD-4131-A95D-1152E92197F6\",\"Top\":16,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"CB227823-3D17-47A7-A3FE-F7D885509BF7\",\"Top\":909,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"DA2A2F9D-EE20-415D-AF7F-C30E6FDE0F83\",\"Top\":0,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"E39F4B2F-7395-46A0-B61A-5919F2DB3A1B\",\"Top\":2649,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"E8ED3C80-690C-4549-A509-BBEFE66F039E\",\"Top\":357,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"E8FD1472-697F-4BDB-AC7C-D73DC5EF49BE\",\"Top\":2765,\"Left\":0,\"GroupName\":\"default\"},{\"__typename\":\"BackupProcessorPosition\",\"ID\":\"F0099E0C-8A33-4FBA-BA19-A6B328161E47\",\"Top\":2185,\"Left\":0,\"GroupName\":\"default\"}],\"Version\":\"2.0.4\",\"Git\":\"4360afd7f3\",\"AIModels\":null,\"Variables\":null,\"Parameters\":null}"
}
Response
Status: 200 OK
{
"data": {
"ImportGroup": null
}
}
Invoke Processor
POST {{edgeUrl}}/analytics/v3
Invoke Processor
Manually triggers a processor's user-action handler with a payload. Useful for processors that expose a "call me" action (e.g. an AI prompt processor, a manual override gate). Most processors are reactive and don't need this.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation InvokeProcessorInstance($input: UserActionPayloadInput!) {
InvokeProcessorInstance(input: $input)
}
Variables (input: UserActionPayloadInput!)
| Field | Type | Required | Description |
|---|---|---|---|
Id |
ID! |
Yes | UUID of the processor. |
Data |
JSON |
Yes | Payload to pass to the user-action handler. Shape is function-specific. |
{
"input": {
"Id": "{{analytics_single_processor_id}}",
"Data": {}
}
}
Response
200 OK -- application/json. No data returned on success (the processor's response is published to its output topic; subscribe via Subscribe to Processor Output to observe).
{ "data": { "InvokeProcessorInstance": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation InvokeProcessorInstance($input: UserActionPayloadInput!) {
InvokeProcessorInstance(input: $input)
}
Variables
{
"input": {
"Id": "{{analytics_single_processor_id}}",
"Data": {}
}
}
Response
Status: 200 OK
{
"data": {
"InvokeProcessorInstance": null
}
}
Update Processor
POST {{edgeUrl}}/analytics/v3
Update Processor
Updates a processor's parameters. Pass the full new Parameters array; omitted keys are reset to function defaults. To change wiring, use Connect Processor Instances / Disconnect Processors. To change the processor's Function, delete and recreate it.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation UpdateProcessorInstance($input: UpdateProcessorInstanceRequest!) {
UpdateProcessorInstance(input: $input)
}
Variables (input: UpdateProcessorInstanceRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
Id |
ID! |
Yes | UUID of the processor to update. |
Parameters |
[KeyValueInput!]! |
Yes | Full new parameter set. |
{
"input": {
"Id": "{{analytics_single_processor_id}}",
"Parameters": [
{ "Key": "inject_field", "Value": "value" },
{ "Key": "inject_value_type", "Value": "string" },
{ "Key": "inject_value", "Value": "hello" }
]
}
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "UpdateProcessorInstance": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation UpdateProcessorInstance($input: UpdateProcessorInstanceRequest!) {
UpdateProcessorInstance(input: $input)
}
Variables
{
"input": {
"Id": "{{analytics_single_processor_id}}",
"Parameters": [
{
"Key": "inject_field",
"Value": "value"
},
{
"Key": "inject_value_type",
"Value": "string"
},
{
"Key": "inject_value",
"Value": "hello"
},
{
"Key": "add_timestamp",
"Value": "true"
},
{
"Key": "timing_mode",
"Value": "once"
},
{
"Key": "timer_interval_type",
"Value": "seconds"
},
{
"Key": "timer_interval_value",
"Value": "0"
}
]
}
}
Response
Status: 200 OK
{
"data": {
"UpdateProcessorInstance": null
}
}
Reset Processor
POST {{edgeUrl}}/analytics/v3
Reset Processor
Resets a processor instance to its initial state. Internal buffers, windows, accumulators, and any function-specific transient state are discarded. Use to clear a Moving Average's window, drop a Generator's phase, restart an Aggregator's counter, etc.
The processor remains active -- it resumes emitting on the next input.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation ResetProcessorInstance($input: String!) {
ResetProcessorInstance(input: $input)
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Processor UUID to reset. |
{ "input": "{{analytics_single_processor_id}}" }
Response
200 OK -- application/json. No data returned on success.
{ "data": { "ResetProcessorInstance": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation ResetProcessorInstance($input: String!) {
ResetProcessorInstance(input: $input)
}
Variables
{
"input": "{{analytics_single_processor_id}}"
}
Response
Status: 200 OK
{
"data": {
"ResetProcessorInstance": null
}
}
Set Processor Wire Definition
POST {{edgeUrl}}/analytics/v3
Set Processor Wire Definition
Sets the definition payload for a wire between two processors. A wire definition is a function-specific JSON blob attached to an input to describe how the upstream output should be consumed (e.g. which field to extract, which alias to apply).
Use this after Connect Processor Instances to refine the wire's behavior, or when re-binding an existing wire to a different definition.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation DefineProcessorInstanceInput($input: DefineInputRequest!) {
DefineProcessorInstanceInput(input: $input)
}
Variables (input: DefineInputRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
Id |
ID! |
Yes | Downstream processor UUID (the one receiving the wire). |
InputId |
ID! |
Yes | Upstream processor UUID (the one producing the value). |
Definition |
String! |
Yes | Function-specific wire definition payload. Format depends on the downstream processor's function. |
{
"input": {
"Id": "{{analytics_single_processor_id}}",
"InputId": "{{analytics_single_processor_id_another}}",
"Definition": "{{analytics_wire_definition}}"
}
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "DefineProcessorInstanceInput": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation DefineProcessorInstanceInput($input: DefineInputRequest!) {
DefineProcessorInstanceInput(input: $input)
}
Variables
{
"input": {
"Id": "{{analytics_single_processor_id}}",
"InputId": "{{analytics_single_processor_id_another}}",
"Definition": "{{analytics_wire_definition}}"
}
}
Response
Status: 200 OK
{
"data": {
"DefineProcessorInstanceInput": null
}
}
Disconnect Processors
POST {{edgeUrl}}/analytics/v3
Disconnect Processors
Removes one or more wires between processors. Specify the wire endpoints and the ConnectionType. NOTE the fields are reversed from their names: Inputs = the upstream producer(s), Outputs = the downstream consumer(s). ConnectionType is plural -- values or events (the API rejects singular value/event).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation DisconnectProcessorInstances($input: ConnectionRequest!) {
DisconnectProcessorInstances(input: $input)
}
Variables (input: ConnectionRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
Inputs |
[ID!]! |
Yes | UUIDs of the UPSTREAM producers (where data comes FROM). Reversed from the name. |
Outputs |
[ID!]! |
Yes | UUIDs of the DOWNSTREAM consumers (where data goes TO). Reversed from the name. |
ConnectionType |
String! |
Yes | values or events (plural) -- the kind of wire to remove. |
The mutation removes the cartesian-product set of wires (Outputs x Inputs of type ConnectionType).
{
"input": {
"Inputs": ["{{analytics_single_processor_id}}"],
"Outputs": ["{{analytics_single_processor_id_another}}"],
"ConnectionType": "{{analytics_connection_type}}"
}
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "DisconnectProcessorInstances": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation DisconnectProcessorInstances($input: ConnectionRequest!) {
DisconnectProcessorInstances(input: $input)
}
Variables
{
"input": {
"Inputs": ["{{analytics_single_processor_id}}"],
"Outputs": ["{{analytics_single_processor_id_another}}"],
"ConnectionType": "{{analytics_connection_type}}"
}
}
Response
Status: 200 OK
{
"data": {
"DisconnectProcessorInstances": null
}
}
Connect Processor Instances
POST {{edgeUrl}}/analytics/v3
Connect Processor Instances
Creates wires between processors. Same input shape as Disconnect Processors. The mutation creates the cartesian-product set of wires from Outputs (producers) to Inputs (consumers) of the specified ConnectionType.
After connecting, you can attach a definition payload to the wire via Set Processor Wire Definition.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation ConnectionRequest($input: ConnectionRequest!) {
ConnectProcessorInstances(input: $input)
}
The GraphQL operation name (ConnectionRequest) and the field name (ConnectProcessorInstances) differ -- the operation name is local to the query document; the field name is what the server resolves.
Variables (input: ConnectionRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
Inputs |
[ID!]! |
Yes | UUIDs of the UPSTREAM producers (where data comes FROM). Reversed from the name. |
Outputs |
[ID!]! |
Yes | UUIDs of the DOWNSTREAM consumers (where data goes TO). Reversed from the name. |
ConnectionType |
String! |
Yes | values or events (plural). A wire feeding a sink/publish must be events. |
{
"input": {
"Inputs": ["{{analytics_single_processor_id}}"],
"Outputs": ["{{analytics_single_processor_id_another}}"],
"ConnectionType": "{{analytics_connection_type}}"
}
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "ConnectProcessorInstances": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation ConnectionRequest($input: ConnectionRequest!) {
ConnectProcessorInstances(input: $input)
}
Variables
{
"input": {
"Inputs": ["{{analytics_single_processor_id}}"],
"Outputs": ["{{analytics_single_processor_id_another}}"],
"ConnectionType": "{{analytics_connection_type}}"
}
}
Response
Status: 200 OK
{
"data": {
"ConnectProcessorInstances": null
}
}
Get All AI Providers
POST {{edgeUrl}}/analytics/v3
Get All AI Providers
Lists the AI providers Analytics is built to integrate with. Use this to render a provider picker; the name field is the value to pass to Add AI Model / Update AI Model / Verify AI Model API Key as provider.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetAIProviders {
GetAIProviders {
name
}
}
No arguments.
Response
200 OK -- application/json. Array of provider objects.
| Field | Type | Description |
|---|---|---|
data.GetAIProviders[].name |
String |
Provider key (e.g. OpenAI API, Anthropic API, Ollama API). |
{
"data": {
"GetAIProviders": [
{ "name": "Grok API" },
{ "name": "Google Gemini API" },
{ "name": "Nvidia API" },
{ "name": "OpenAI API" },
{ "name": "Cloudflare AI Gateway" },
{ "name": "Anthropic API" },
{ "name": "Ollama API" }
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetAIProviders {
GetAIProviders {
name
}
}
Response
Status: 200 OK
{
"data": {
"GetAIProviders": [
{
"name": "Grok API"
},
{
"name": "Google Gemini API"
},
{
"name": "Nvidia API"
},
{
"name": "OpenAI API"
},
{
"name": "Cloudflare AI Gateway"
},
{
"name": "Anthropic API"
},
{
"name": "Ollama API"
}
]
}
}
List AI Models
POST {{edgeUrl}}/analytics/v3
List AI Models
Lists every configured AI model on the device. An AI model is a {provider, modelName, URL, uniqueName} tuple plus a stored API key (not returned here for security).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query ListAIModels {
ListAIModels {
modelName
provider
uniqueName
url
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.ListAIModels |
[Model!]! |
All configured AI models. |
data.ListAIModels[].modelName |
String |
Provider-specific model identifier (e.g. claude-3-7-sonnet-20250219, gpt-4o). |
data.ListAIModels[].provider |
String |
Provider name from Get All AI Providers. |
data.ListAIModels[].uniqueName |
String |
Operator-chosen alias used as the key in Update AI Model / Delete AI Model. |
data.ListAIModels[].url |
String |
Provider API base URL (e.g. https://api.anthropic.com/v1). |
{
"data": {
"ListAIModels": [
{
"modelName": "claude-3-7-sonnet-20250219",
"provider": "Anthropic API",
"uniqueName": "Claude Anthropic",
"url": "https://api.anthropic.com/v1"
}
]
}
}
API keys are never returned by this endpoint. To rotate a key, call Update AI Model with the new key.
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query ListAIModels {
ListAIModels {
modelName
provider
uniqueName
url
}
}
Variables
{}
Response
Status: 200 OK
{
"data": {
"ListAIModels": [
{
"modelName": "claude-3-7-sonnet-20250219",
"provider": "Anthropic API",
"uniqueName": "Claude Anthropic",
"url": "https://api.anthropic.com/v1"
}
]
}
}
Verify AI Model API Key
POST {{edgeUrl}}/analytics/v3
Verify AI Model API Key
Validates an API key + provider/URL combination without persisting it. Use this before Add AI Model to fail fast on bad credentials, or to test a new key before rotating.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation verifyAIModel($input: AIModelVerifyRequest!) {
verifyAIModel(input: $input)
}
Variables (input: AIModelVerifyRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
provider |
String! |
Yes | Provider name from Get All AI Providers. |
url |
String! |
Yes | Provider API base URL. |
key |
String! |
Yes | API key / token to verify. |
cfApiKey |
String |
No | Extra Cloudflare API key for Cloudflare AI Gateway. Empty string for other providers. |
{
"input": {
"provider": "{{AI_Model_Provider_Name}}",
"url": "{{AI_Model_URL}}",
"key": "{{AI_Model_API_Key}}",
"cfApiKey": ""
}
}
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.verifyAIModel |
String |
"Verification successful" on success; an error string otherwise. |
{ "data": { "verifyAIModel": "Verification successful" } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation verifyAIModel($input: AIModelVerifyRequest!) {
verifyAIModel(input: $input)
}
Variables
{
"input": {
"provider": "{{AI_Model_Provider_Name}}",
"url": "{{AI_Model_URL}}",
"key": "{{AI_Model_API_Key}}",
"cfApiKey": ""
}
}
Response
Status: 200 OK
{
"data": {
"verifyAIModel": "Verification successful"
}
}
Add AI Model
POST {{edgeUrl}}/analytics/v3
Add AI Model
Registers an AI model on the device. After this call, processors that support AI inference can reference the model by its uniqueName.
Run Verify AI Model API Key first to validate the credentials -- the add mutation itself does not re-verify.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation addAIModel($input: AIModelRequest!) {
addAIModel(input: $input)
}
Variables (input: AIModelRequest!)
| Field | Type | Required | Description |
|---|---|---|---|
provider |
String! |
Yes | Provider name from Get All AI Providers. |
uniqueName |
String! |
Yes | Operator-chosen alias. Must be unique on this device. |
url |
String! |
Yes | Provider API base URL. |
apiKey |
String! |
Yes | API key / token. Stored encrypted on the device. |
modelName |
String! |
Yes | Provider-specific model identifier. |
cfApiKey |
String |
No | Extra Cloudflare API key for Cloudflare AI Gateway. Empty for other providers. |
{
"input": {
"provider": "{{AI_Model_Provider_Name}}",
"uniqueName": "{{AI_Model_Unique_Name}}",
"url": "{{AI_Model_URL}}",
"apiKey": "{{AI_Model_API_Key}}",
"modelName": "{{AI_Provider_Model_Name}}",
"cfApiKey": ""
}
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "addAIModel": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation addAIModel($input: AIModelRequest!) {
addAIModel(input: $input)
}
Variables
{
"input": {
"provider": "{{AI_Model_Provider_Name}}",
"uniqueName": "{{AI_Model_Unique_Name}}",
"url": "{{AI_Model_URL}}",
"apiKey": "{{AI_Model_API_Key}}",
"modelName": "{{AI_Provider_Model_Name}}",
"cfApiKey": ""
}
}
Response
Status: 200 OK
{
"data": {
"addAIModel": null
}
}
Update AI Model
POST {{edgeUrl}}/analytics/v3
Update AI Model
Updates an existing AI model. The uniqueName outside input selects which model to update; the values inside input are the new fields. You can rotate the key, switch model, or move to a different provider -- all in one call.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation UpdateAIModel($input: AIModelRequest!, $uniqueName: String!) {
UpdateAIModel(input: $input, uniqueName: $uniqueName)
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
uniqueName |
String! |
Yes | The model's current unique name (selects which model to update). |
input |
AIModelRequest! |
Yes | New field values. Same shape as Add AI Model > input. Pass all fields, not just the changed ones. |
{
"input": {
"provider": "{{AI_Model_Provider_Name}}",
"uniqueName": "{{AI_Model_Unique_Name}}",
"url": "{{AI_Model_URL}}",
"apiKey": "{{AI_Model_API_Key}}",
"modelName": "{{AI_Provider_Model_Name}}",
"cfApiKey": ""
},
"uniqueName": "{{AI_Model_Unique_Name}}"
}
Response
200 OK -- application/json. No data returned on success.
{ "data": { "UpdateAIModel": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation UpdateAIModel($input: AIModelRequest!, $uniqueName: String!) {
UpdateAIModel(input: $input, uniqueName: $uniqueName)
}
Variables
{
"input": {
"provider": "{{AI_Model_Provider_Name}}",
"uniqueName": "{{AI_Model_Unique_Name}}",
"url": "{{AI_Model_URL}}",
"apiKey": "{{AI_Model_API_Key}}",
"modelName": "{{AI_Provider_Model_Name}}",
"cfApiKey": ""
},
"uniqueName":"{{AI_Model_Unique_Name}}"
}
Response
Status: 200 OK
{
"data": {
"UpdateAIModel": null
}
}
Delete AI Model
POST {{edgeUrl}}/analytics/v3
Delete AI Model
Removes a configured AI model. Processors that reference the deleted model's uniqueName will start failing on their next invocation -- either reassign them to a different model first, or be prepared for them to error.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation DeleteAIModel($input: String!) {
DeleteAIModel(name: $input)
}
The variable is named input but the GraphQL argument is name -- substitute the unique name as the value.
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | uniqueName of the model to delete. |
{ "input": "{{AI_Model_Unique_Name}}" }
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.DeleteAIModel |
Boolean |
true on success. |
{ "data": { "DeleteAIModel": true } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation DeleteAIModel($input: String!) {
DeleteAIModel(name: $input)
}
Variables
{
"input": "{{AI_Model_Unique_Name}}"
}
Response
Status: 200 OK
{
"data": {
"DeleteAIModel": true
}
}
Get TensorFlow Models
POST {{edgeUrl}}/analytics/v3
Get TensorFlow Models
Lists every TensorFlow SavedModel uploaded to the device. Includes the on-disk path and the size in bytes -- useful for capacity planning.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetModels {
GetModels {
AbsolutePath
Name
Size
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetModels |
[Model!]! |
All TensorFlow models on the device. |
data.GetModels[].AbsolutePath |
String |
On-disk path (e.g. /var/lib/loopedge-analytics2/models/motionModel). |
data.GetModels[].Name |
String |
Model name. Used as the key for Delete TensorFlow Model. |
data.GetModels[].Size |
Int |
On-disk size in bytes. |
{
"data": {
"GetModels": [
{ "AbsolutePath": "/var/lib/loopedge-analytics2/models/motionModel", "Name": "motionModel", "Size": 5094648 },
{ "AbsolutePath": "/var/lib/loopedge-analytics2/models/savedmodel4", "Name": "savedmodel4", "Size": 511197 }
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetModels {
GetModels {
AbsolutePath
Name
Size
}
}
Variables
{}
Response
Status: 200 OK
{
"data": {
"GetModels": [
{
"AbsolutePath": "/var/lib/loopedge-analytics2/models/motionModel",
"Name": "motionModel",
"Size": 5094648
},
{
"AbsolutePath": "/var/lib/loopedge-analytics2/models/savedmodel4",
"Name": "savedmodel4",
"Size": 511197
}
]
}
}
Delete TensorFlow Model
POST {{edgeUrl}}/analytics/v3
Delete TensorFlow Model
Removes a TensorFlow model from the device. Free disk space is reclaimed. Processors that reference the deleted model start failing on their next inference -- reassign or delete them first.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation DeleteModel($input: String!) {
DeleteModel(input: $input)
}
Variables
| Field | Type | Required | Description |
|---|---|---|---|
input |
String! |
Yes | Model name from Get TensorFlow Models. |
{ "input": "{{TensorFlow_model_name}}" }
Response
200 OK -- application/json. No data returned on success.
{ "data": { "DeleteModel": null } }
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation DeleteModel($input: String!) {
DeleteModel(input: $input)
}
Variables
{
"input": "{{TensorFlow_model_name}}"
}
Response
Status: 200 OK
{
"data": {
"DeleteModel": null
}
}
Step 1: Upload TensorFlow Model
DELETE {{edgeUrl}}/analytics/v2/upload_model/v2
Step 1: Upload TensorFlow Model (purge in-progress)
Step 1 of 3 in the resumable TensorFlow model upload flow. This call deletes any in-progress upload state held by the server, so that step 2 starts cleanly. Always call this before starting a fresh upload to recover from interrupted previous attempts.
Endpoint
DELETE {{edgeUrl}}/analytics/v2/upload_model/v2
Authentication
HTTP Basic Auth. Username is your API token, password is empty. Tokens are managed under System > Access Control > Tokens.
Parameters
None.
Response
200 OK on success. The next step is Step 2: Upload TensorFlow Model.
Errors
| HTTP status | When it happens |
|---|---|
400 Bad Request |
Missing or malformed query/body parameter. |
401 Unauthorized |
Missing or invalid credentials. |
403 Forbidden |
Token lacks permission for this operation. |
404 Not Found |
Target entity does not exist. |
5xx |
Service is unreachable, restarting, or internally errored. Inspect device logs under System > Support. |
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Response
Status: 204 No Content
Step 2: Upload TensorFlow Model
POST {{edgeUrl}}/analytics/v2/upload_model/v2
Step 2: Upload TensorFlow Model (initiate)
Step 2 of 3. Announces an upload by declaring the target model name and size. The server returns an id that step 3 uses as the upload session handle.
Endpoint
POST {{edgeUrl}}/analytics/v2/upload_model/v2
Content-Type: application/json
Authentication
HTTP Basic Auth. Username is your API token, password is empty. Tokens are managed under System > Access Control > Tokens.
Request body
{
"size": {{TensorFlow_model_size}},
"name": "{{TensorFlow_model_name}}.zip"
}
| Field | Type | Required | Description |
|---|---|---|---|
size |
integer | Yes | Total size of the ZIP archive in bytes. |
name |
string | Yes | File name. Must end in .zip. The model's directory name is taken from the part before .zip. |
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
id |
string | Upload session UUID. Use as {{TensorFlow_model_upload_id}} in step 3. |
{ "id": "94076e1c-9a59-46bb-8cc2-540da6505069" }
Errors
| HTTP status | When it happens |
|---|---|
400 Bad Request |
Missing or malformed query/body parameter. |
401 Unauthorized |
Missing or invalid credentials. |
403 Forbidden |
Token lacks permission for this operation. |
404 Not Found |
Target entity does not exist. |
5xx |
Service is unreachable, restarting, or internally errored. Inspect device logs under System > Support. |
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
{
"size": {{TensorFlow_model_size}},
"name": "{{TensorFlow_model_name}}.zip"
}
Response
Status: 200 OK
{
"id": "94076e1c-9a59-46bb-8cc2-540da6505069"
}
Step 3: Upload TensorFlow Model
PUT {{edgeUrl}}/analytics/v2/upload_model/v2/resume/{{TensorFlow_model_upload_id}}
Step 3: Upload TensorFlow Model (resume / stream chunks)
Step 3 of 3. Streams (or resumes streaming) the ZIP archive bytes for the upload session created in step 2. The endpoint accepts a chunked multipart upload and reports back the offset consumed so far -- if the connection drops, you can resume by streaming starting from that offset.
The Postman item posts the entire file in one PUT for simplicity. For robust transfer of large models, chunk client-side and re-issue this PUT with progressively larger offsets.
Endpoint
PUT {{edgeUrl}}/analytics/v2/upload_model/v2/resume/{{TensorFlow_model_upload_id}}
Content-Type: multipart/form-data
Authentication
HTTP Basic Auth. Username is your API token, password is empty. Tokens are managed under System > Access Control > Tokens.
Path parameters
| Location | Name | Required | Description |
|---|---|---|---|
| Path | {{TensorFlow_model_upload_id}} |
Yes | Upload session ID returned by step 2. |
Request body (form-data)
| Form key | Type | Description |
|---|---|---|
| (empty) | file | The ZIP archive (or next chunk thereof). |
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
id |
string | Echo of the upload session ID. |
offset |
integer | Bytes consumed so far. If less than the total size from step 2, resume from this offset. |
done |
boolean | true when the upload is fully consumed and the model is installed. |
{
"id": "f7ed9907-8f1c-4cf4-9e2c-fd558e0653d5",
"offset": 1024199,
"done": false
}
Once done: true, the model is unpacked and available via Get TensorFlow Models.
Errors
| HTTP status | When it happens |
|---|---|
400 Bad Request |
Missing or malformed query/body parameter. |
401 Unauthorized |
Missing or invalid credentials. |
403 Forbidden |
Token lacks permission for this operation. |
404 Not Found |
Target entity does not exist. |
5xx |
Service is unreachable, restarting, or internally errored. Inspect device logs under System > Support. |
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Headers
| Key | Value |
|---|---|
| Upload-Length | 1024199 |
| Upload-Offset | 0 |
Request Body
Response
Status: 200 OK
{
"id": "f7ed9907-8f1c-4cf4-9e2c-fd558e0653d5",
"offset": 1024199,
"done": false
}
Set Variables
POST {{edgeUrl}}/analytics/v3
Set Variables
Creates or updates a global variable that processors can read and write at runtime. Variables differ from parameters:
- Variables are read/write at runtime (a processor can mutate one), surfaced as
$variable("<name>"). - Parameters are read-only at runtime, surfaced as
$parameter("<name>")-- useSet Parametersto manage them.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation SetVariable($input: InputVariable!) {
SetVariable(input: $input)
}
Variables (input: InputVariable!)
| Field | Type | Required | Description |
|---|---|---|---|
Name |
String! |
Yes | Variable name. Unique across all variables. Creating a name that already exists updates it. |
Value |
String! |
Yes | Variable value (always a string at the wire level, regardless of DataType). |
DataType |
String! |
Yes | One of STRING, INT, FLOAT, BOOL, JSON. |
{
"input": {
"Name": "{{analytics_parameter_key}}",
"Value": "{{analytics_parameter_value}}",
"DataType": "STRING"
}
}
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.SetVariable.UniqueName |
String |
Variable name, echoed. |
data.SetVariable.DataType |
String |
Type, echoed. |
data.SetVariable.DBValue |
String |
Stored value (DB-encoded). |
data.SetVariable.IsReadWrite |
Boolean |
true for variables (always); false for parameters. |
data.SetVariable.IsPersistent |
Boolean |
true -- variables persist across Analytics service restarts. |
{
"data": {
"SetVariable": {
"UniqueName": "api_set_key",
"DataType": "STRING",
"DBValue": "api_set_value",
"IsReadWrite": true,
"IsPersistent": true
}
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation SetVariable($input: InputVariable!) {
SetVariable(input: $input)
}
Variables
{
"input": {
"Name": "{{analytics_parameter_key}}",
"Value": "{{analytics_parameter_value}}",
"DataType": "STRING"
}
}
Response
Status: 200 OK
{
"data": {
"SetVariable": {
"UniqueName": "api_set_key",
"DataType": "STRING",
"DBValue": "api_set_value",
"IsReadWrite": true,
"IsPersistent": true
}
}
}
Get Variables
POST {{edgeUrl}}/analytics/v3
Get Variables
Returns every global variable known to Analytics. Same shape as Instances > Get Parameters, but for variables (read/write at runtime).
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetVariables {
GetVariables {
DataType
Name
Value
}
}
No arguments.
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.GetVariables[].DataType |
String |
Type: STRING, INT, FLOAT, BOOL, JSON. |
data.GetVariables[].Name |
String |
Variable name. |
data.GetVariables[].Value |
String |
Variable value (serialized as string). |
{
"data": {
"GetVariables": [
{ "DataType": "STRING", "Name": "parameterKey", "Value": "parameterValue" },
{ "DataType": "STRING", "Name": "api_set_key", "Value": "api_set_value" }
]
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetVariables {
GetVariables {
DataType
Name
Value
}
}
Variables
{}
Response
Status: 200 OK
{
"data": {
"GetVariables": [
{
"DataType": "STRING",
"Name": "parameterKey",
"Value": "parameterValue"
},
{
"DataType": "STRING",
"Name": "api_set_key",
"Value": "api_set_value"
}
]
}
}
Set Parameters
POST {{edgeUrl}}/analytics/v3
Set Parameters
Creates or updates a global parameter. Parameters are read-only at processor runtime (compare with variables, which are read/write). Use parameters for configuration values that should remain stable across a pipeline run.
This mutation differs from Models > Parameters > Set Parameters (which operates on Digital Twins parameters); they share the name but live in different services.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
mutation SetParameter($input: InputParameter!) {
SetParameter(input: $input)
}
Variables (input: InputParameter!)
| Field | Type | Required | Description |
|---|---|---|---|
Name |
String! |
Yes | Parameter name. Unique across all parameters; creating a name that already exists updates it. |
Value |
String! |
Yes | Parameter value (always a string at the wire level). |
DataType |
String! |
Yes | One of STRING, INT, FLOAT, BOOL, JSON. |
{
"input": {
"Name": "{{analytics_parameter_key}}",
"Value": "{{analytics_parameter_value}}",
"DataType": "STRING"
}
}
Response
200 OK -- application/json
| Field | Type | Description |
|---|---|---|
data.SetParameter.UniqueName |
String |
Parameter name, echoed. |
data.SetParameter.DataType |
String |
Type, echoed. |
data.SetParameter.DBValue |
String |
Stored value. |
data.SetParameter.IsReadWrite |
Boolean |
true -- the parameter is read/write at this admin endpoint. Processors see it as read-only at runtime. |
data.SetParameter.IsPersistent |
Boolean |
true -- parameters persist across restarts. |
{
"data": {
"SetParameter": {
"UniqueName": "api_set_key",
"DataType": "STRING",
"DBValue": "api_set_value",
"IsReadWrite": true,
"IsPersistent": true
}
}
}
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
mutation SetParameter($input: InputParameter!) {
SetParameter(input: $input)
}
Variables
{
"input": {
"Name": "{{analytics_parameter_key}}",
"Value": "{{analytics_parameter_value}}",
"DataType": "STRING"
}
}
Response
Status: 200 OK
{
"data": {
"SetParameter": {
"UniqueName": "api_set_key",
"DataType": "STRING",
"DBValue": "api_set_value",
"IsReadWrite": true,
"IsPersistent": true
}
}
}
Retrieve Prometheus Metrics
POST {{edgeUrl}}/analytics/v3
Retrieve Prometheus Metrics
Returns Analytics runtime metrics in the Prometheus exposition format, wrapped in a GraphQL response. Unlike most Prometheus endpoints on the device, this one is delivered through /analytics/v3 rather than a plain text endpoint -- the body is GraphQL JSON whose data.GetMetrics field carries the exposition-format string.
For straight Prometheus scraping use the existing {{edgeUrl}}/analytics/v3 endpoint with the query body below; your client must extract data.GetMetrics from the JSON response and parse it as Prometheus text.
Endpoint
POST {{edgeUrl}}/analytics/v3
Content-Type: application/json
The operation is chosen by the GraphQL query body, not the URL path.
Authentication
HTTP Basic Auth. Username is your API token, password is empty. The same token is valid across /devicehub/v2, /analytics/v2, /cc, /opcua, and the other LE services.
Request body
query GetMetrics {
GetMetrics
}
No arguments.
Response
200 OK -- application/json. data.GetMetrics is a string in Prometheus text exposition format.
Metric reference
| Metric | Type | Description |
|---|---|---|
num_of_message_in |
gauge | Total messages consumed by Analytics since service start. |
num_of_message_out |
gauge | Total messages produced by Analytics since service start. |
processing_time_in_nano_sec |
gauge | Average per-message processing time in nanoseconds, last sample. |
Other per-function or per-processor metrics may also be emitted depending on the build -- treat the metric list as open-ended.
Example response
{
"data": {
"GetMetrics": "# HELP num_of_message_in\n# TYPE num_of_message_in gauge\nnum_of_message_in 2.937457e+06\n# HELP num_of_message_out\n# TYPE num_of_message_out gauge\nnum_of_message_out 3.1471953e+07\n# HELP processing_time_in_nano_sec\n# TYPE processing_time_in_nano_sec gauge\nprocessing_time_in_nano_sec 0.0679513251743302"
}
}
When un-escaped, the exposition payload reads:
# HELP num_of_message_in
# TYPE num_of_message_in gauge
num_of_message_in 2.937457e+06
# HELP num_of_message_out
# TYPE num_of_message_out gauge
num_of_message_out 3.1471953e+07
# HELP processing_time_in_nano_sec
# TYPE processing_time_in_nano_sec gauge
processing_time_in_nano_sec 0.0679513251743302
Useful PromQL recipes
These assume your scraper extracts data.GetMetrics and feeds it back into Prometheus:
# Messages-per-second over 5m
rate(num_of_message_in[5m])
# Output amplification (out/in ratio)
num_of_message_out / num_of_message_in
Errors
GraphQL endpoints return 200 OK even on logical errors. Inspect the errors array in the response body:
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
extensions.code |
Meaning |
|---|---|
UNAUTHENTICATED |
Missing or invalid API token. |
FORBIDDEN |
Token lacks permission for this operation. |
BAD_USER_INPUT |
Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
NOT_FOUND |
The targeted entity does not exist. |
INTERNAL_SERVER_ERROR |
DeviceHub fault. Retry, then escalate via System > Support. |
A non-200 HTTP response means DeviceHub itself is unreachable. See Dashboard > DeviceHub Status.
TLS note: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.
Request Body
GraphQL Query
query GetMetrics {
GetMetrics
}
Response
Status: 200 OK
# HELP num_of_message_in
# TYPE num_of_message_in gauge
num_of_message_in 2.937457e+06
# HELP num_of_message_out
# TYPE num_of_message_out gauge
num_of_message_out 3.1471953e+07
# HELP processing_time_in_nano_sec
# TYPE processing_time_in_nano_sec gauge
processing_time_in_nano_sec 0.0679513251743302