Devices

Inspecting Devices and metadata in the Ardexa Cloud

Note: Ardexa hosts clouds in multiple regions as subdomains of ardexa.com. Where you see a reference to mycloud in this document, replace it with the appropriate subdomain for your cloud, eg: mycloud.ardexa.com -> app.ardexa.com or eur1.ardexa.com

Viewing devices

To get a list of devices in a workgroup, make a GET request against the Devices endpoint:

GET mycloud.ardexa.com/api/v1/devices/<workgroupId>

This will return a list of all devices in the workgroup, fully populated with their current device metadata.

Alternatively, you can issue a GET against an individual device's UUID:

GET mycloud.ardexa.com/api/v1/devices/<workgroupId>/<deviceId>

Accessing device metadata

Device metadata is stored against the meta top-level property of the device. meta has a number of top-level properties containing lists of scenarios as described in Agent -> Manual Configuration and displayed in Devices -> Manual Configuration in the Ardexa Cloud.

The scenario types provided as of Agent version 2.4.1 are:

  • run: execute a task at a defined frequency / schedule. Optionally capture the output as an event to send to the Ardexa Cloud

  • tail: watch a text file for new lines. These are captured as events and sent to the Ardexa Cloud. This corresponds to the 'Capture' tab on the Device -> Manual Config page in the app

  • watch: watch a file for changes. When one is detected, send an event to the cloud, optionally attaching the file content

  • unix_socket: listens for events on a specified unix socket. These are captured and sent to the cloud

  • dynamic: tail scenarios detected dynamically by the Ardexa agent, see Dynamic Mapping below

External metadata scenarios are optionally stored separate to the device's configuration, within the settings.externalMeta property. These link data ingested to the cloud from a non-agent source, such as an external API, to the device.

Metadata terminology

Scenario: an individual unit of work performed by the agent. This usually involves executing a command at a specified interval or watching a file for changes. See Scenarios for more information. An important rule is that within a device's configuration, the combination of each scenario's table and source must be unique.

Static configuration: run, tail, watch, unix_socket and external define statically configured scenarios derived from the ardexa.yaml configuration file on the device. This was the first metadata configuration scheme implemented in the Ardexa Cloud.

Dynamic mapping: dynamic scenarios, introduced in agent version 2.3.0 are populated by the Ardexa agent. The agent watches specific file system locations on the device for dynamic run and dynamic tail scenarios, typically executable files in /opt/ardexa/run and latest.csv files in/opt/ardexa/logs respectively. This scheme scales well with large device configurations and is heavily used by the Machine Plugins system. For more information, see Dynamic Mapping.

Accessing fields

Where a scenario has an expect type of csv, the agent expects to receive a CSV-formatted record containing one or more fields. This record is transformed into an event which is sent to the Ardexa Cloud. The set of fields is determined by the fields property of the scenario.

An individual field has the following schema:

{
  name: 'field-name-string',
  expect: 'decimal|integer|bool|keyword|text|date'
  meta: {
    units: 'unit-string'
  }
}

There are three variants of field definition used in the Ardexa Cloud:

Hydrated metadata

If the fields property of a scenario is an array, the contents of the array define the exact set of fields collected by that scenario. When all scenarios in a device's configuration contain fields arrays we refer to it as "Hydrated" metadata. For larger device configurations with many scenarios collecting identical fields this results in many redundant field definitions.

Example:

{ ...
  meta: {
    ...
    tail: [{
        table: 'telemetry'
        source: 'widget-01',
        expect: 'csv',
        fields: [
          { name: 'temperature', expect: 'decimal', meta: { units: 'C' },
          { name: 'production', expect: 'integer' }
        ]
      }, {
        table: 'telemetry'
        source: 'widget-02',
        expect: 'csv',
        fields: [
          { name: 'temperature', expect: 'decimal', meta: { units: 'C' },
          { name: 'production', expect: 'integer' }
        ]
      
      }
    ]
  }
... 
}

Compact metadata

If the fields property contains a string without a period (.), the scenario is using a compact fields reference. The value of fields will resolve to a top-level property of the device's meta. This top-level property will contain an array of fields collected by the scenario.

Example:

{ ...
  meta: {
    ...
    tail: [{
      table: 'telemetry',
      source: 'widget-01',
      expect: 'csv',
      fields: 'widget_fields'
    }, {
      table: 'telemetry',
      source: 'widget-02',
      expect: 'csv',
      fields: 'widget_fields'
    }],
    ...
    widget_fields: [
      { name: 'temperature', expect: 'decimal', meta: { units: 'C' },
      { name: 'production', expect: 'integer' }
    ],
    ...
  }
}
    

Dynamic compact metadata

If the fields property contains a string with a single period (.), the scenario is using a dynamic compact fields reference. The format of the fields property will be <table>.<source> . The table and source refer to a scenario within the current scenario type (eg. dynamic) that contains the actual fields array used by both scenarios.

Note that the actual scenario that contains the field definition is set dynamically by the Ardexa Agent, so may change when a device's metadata is updated.

Example:

{ ...
  meta: {
    ...
    dynamic: [{
      table: 'telemetry',
      source: 'widget-01',
      expect: 'csv',
      fields: [
        { name: 'temperature', expect: 'decimal', meta: { units: 'C' },
        { name: 'production', expect: 'integer' }
      ]
    }, {
      table: 'telemetry',
      source: 'widget-02',
      expect: 'csv',
      fields: 'telemetry.widget-01'
    }],
    ...
  }
}

Viewing Device & Source General Information

Device & Source General Information (as displayed in Devices -> General Info in the app, or maintained in the Admin -> Workgroup -> Metadata section) is stored as a device setting on each device in a workgroup. Look-ups for this information must be retrieved from the Workgroup's deviceInfoKeys and sourceInfoKeys settings. Each id in these settings corresponds to the ID of a device setting, as returned in the settings property of the GET device endpoint.

Source-level metadata is stored as a map, keyed by source name.

GET /api/v1/orgs/myWorkgroupId/settings/deviceInfoKeys
-->
{
  "key": "deviceInfoKeys",
  "value": [
    {
      "id": "ae95703c-0ba4-49bf-8d7c-6d57054751d5",
      "name": "Latitude"
    },
    {
      "id": "526118f9-b552-4124-8a02-bab30e3606e6",
      "name": "Longitude"
    }
  ]
}

GET /api/v1/orgs/myWorkgroupId/settings
-->
{
    "key": "sourceInfoKeys",
    "value": [
        {
            "id": "111111111-0ba4-49bf-8d7c-6d57054751d5",
            "name": "Manufacturer"
        },
        {
            "id": "111111111-b552-4124-8a02-bab30e3606e6",
            "name": "Serial Number"
        }
}

GET /api/v1/devices/myWorkgroupId/device-id-1
--> 
{
  name: 'My device',
  ...,
  meta: {...},
  settings: {
    "ae95703c-0ba4-49bf-8d7c-6d57054751d5": -35.282, // Latitude device-level item
    "526118f9-b552-4124-8a02-bab30e3606e6": 149.129, // Longitude device-level item
    "111111111-0ba4-49bf-8d7c-6d57054751d5": { 
      // (Manufacturer source-level item)
      source-1: "ACME Widget Co",
      source-2: "Widgets r Us"
    },
    "111111111-b552-4124-8a02-bab30e3606e6": {
      // (Serial number source-level item)
      source-1: "111000999111-c",
      source-2: "445039956551-b"
    }
  }
}

Last updated