Skip to main content
Version: 0.13.1

Cumulocity Mapper

The Cumulocity mapper, referred to as c8y-mapper in the rest of this document, maps data in Thin Edge format into their equivalent Cumulocity format.

Registration​

Cumulocity keeps the record of all the registered devices and their associated metadata in its inventory. The c8y-mapper creates and maintains inventory entries for all the devices and services registered with thin-edge. The mapper subscribes to the following topics to get a list of all registered devices and services:

mosquitto_sub -t 'te/+' -t 'te/+/+' -t 'te/+/+/+' -t 'te/+/+/+/+'

The registration messages received for child devices and services are mapped as follows:

Child device​

Thin Edge (input)

Topic
te/device/child01
Payload
{
"@type": "child-device",
"name": "child01",
"type": "SmartHomeHub"
}

Cumulocity IoT (output)

Topic
c8y/s/us
Payload
101,<main-device-id>:device:child01,SmartHomeHub

Where the <main-device-id> is added as the prefix to the external id to avoid id clashes with devices using the same name in other tedge deployments connected to the same tenant.

Child device with explicit id​

Thin Edge (input)

Topic
te/device/child01
Payload
{
"@type": "child-device",
"@id": "child01",
"name": "child01",
"type": "SmartHomeHub"
}

Cumulocity IoT (output)

Topic
c8y/s/us
Payload
101,child01,SmartHomeHub

Where the provided @id is directly used as the external id.

Nested child device​

Thin Edge (input)

Topic
te/device/nested_child01
Payload
{
"@type": "child-device",
"@parent": "device/child01//",
"name": "nested_child01",
"type": "BatterySensor"
}

Cumulocity IoT (output)

Topic
c8y/s/us/<main-device-id>:device:child01
Payload
101,<main-device-id>:device:nested_child01,nested_child01,BatterySensor

Main device service​

Thin Edge (input)

Topic
te/device/main/service/nodered
Payload
{
"@type": "service",
"name": "Node-Red",
"type": "systemd"
}

Cumulocity IoT (output)

Topic
c8y/s/us
Payload
102,<main-device-id>:device:main:service:nodered,systemd,Node-Red,up

Child device service​

Thin Edge (input)

Topic
te/device/child01/service/nodered
Payload
{
"@type": "service",
"name": "Node-Red",
"type": "systemd"
}

Cumulocity IoT (output)

Topic
c8y/s/us/<main-device-id>:device:child01
Payload
102,<main-device-id>:device:child01:service:nodered,systemd,Node-Red,up

Where the unique external IDs to be used in the cloud are derived from the entity identifier subtopics, replacing the / characters with :.

note

The main device is registered with the cloud via the tedge connect c8y command execution and hence there is no mapping done for main device registration messages. Inventory data updates for the main device are handled differently.

Telemetry​

Telemetry data types like measurements, events and alarms are mapped to their respective equivalents in Cumulocity as follows:

Measurement​

Thin Edge (input)

Topic
te/device/main///m/environment
Payload
{
"temperature": 23.4
}

Cumulocity IoT (output)

Topic
c8y/measurement/measurements/create
Payload
{
"type": "environment",
"time": "2021-04-22T17:05:26.958340390+00:00",
"temperature": {
"temperature": {
"value": 23
}
}
}

Measurement without type​

Thin Edge (input)

Topic
te/device/main///m/
Payload
{
"temperature": 23.4
}

Cumulocity IoT (output)

Topic
c8y/measurement/measurements/create
Payload
{
"type": "ThinEdgeMeasurement",
"time": "2021-04-22T17:05:26.958340390+00:00",
"temperature": {
"temperature": {
"value": 23
}
}
}

Measurement of child device​

Thin Edge (input)

Topic
te/device/child01///m/
Payload
{
"temperature": 23.4
}

Cumulocity IoT (output)

Topic
c8y/measurement/measurements/create
Payload
{
"externalSource":{
"externalId":"<main-device-id>:device:child01",
"type":"c8y_Serial"
},
"type":"ThinEdgeMeasurement",
"time":"2013-06-22T17:03:14+02:00",
"temperature":{
"temperature":{
"value":23
}
}
}

Measurement with unit​

The unit is a metadata associated with measurements which can be registered as a metadata message for a given measurement type. If the following metadata message is registered for the environment measurement type:

tedge mqtt pub -r 'te/device/main///m/environment/meta' '{
"units": {
"temperature": "°C"
}
}'

Then subsequent messages will be mapped with the registered unit value as follows.

Thin Edge (input)

Topic
te/device/main///m/environment
Payload
{
"temperature": 23.4
}

Cumulocity IoT (output)

Topic
c8y/measurement/measurements/create
Payload
{
"type": "environment",
"time": "2021-04-22T17:05:26.958340390+00:00",
"temperature": {
"temperature": {
"value": 23,
"unit": "°C"
}
}
}

Events​

Thin Edge (input)

Topic
te/device/main///e/login_event
Payload
{
"text": "A user just logged in",
"time": "2021-01-01T05:30:45+00:00"
}

Cumulocity IoT (output)

Topic
c8y/s/us
Payload
400,login_event,"A user just logged in",2021-01-01T05:30:45+00:00

Event - Complex​

Thin Edge (input)

Topic
te/device/main///e/login_event
Payload
{
"text": "A user just logged in",
"time": "2021-01-01T05:30:45+00:00",
"customFragment": {
"nested": {
"value": "extra info"
}
}
}

Cumulocity IoT (output)

Topic
c8y/event/events/create
Payload
{
"externalSource":{
"externalId":"<main-device-id>",
"type":"c8y_Serial"
},
"type":"login_event",
"text":"A user just logged in",
"time":"2021-01-01T05:30:45+00:00",
"customFragment": {
"nested": {
"value": "extra info"
}
}
}

Alarms​

Thin Edge (input)

Topic
te/device/main///a/temperature_high
Payload
{
"severity": "critical",
"text": "Temperature is very high",
"time": "2021-01-01T05:30:45+00:00"
}

Cumulocity IoT (output)

Topic
c8y/s/us
Payload
301,temperature_high,"Temperature is very high",2021-01-01T05:30:45+00:00

Alarm - Complex​

Thin Edge (input)

Topic
te/device/main///a/pressure_alarm
Payload
{
"severity": "major",
"time": "2023-01-25T18:41:14.776170774Z",
"text": "Pressure alarm",
"customFragment": {
"nested": {
"value": "extra info"
}
}
}

Cumulocity IoT (output)

Topic
c8y/alarm/alarms/create
Payload
{
"externalSource": {
"externalId": "<main-device-id>",
"type": "c8y_Serial"
},
"type": "pressure_alarm",
"severity": "MAJOR",
"time": "2023-01-25T18:41:14.776170774Z",
"text": "Pressure alarm",
"customFragment": {
"nested": {
"value": "extra info"
}
},
}

Health status​

Thin Edge (input)

Topic
te/device/main/service/my-service/status/health
Payload
{
"status": "up",
"pid": "21037"
}

Cumulocity IoT (output)

Topic
c8y/s/us/<service-external-id>
Payload
104,up

Twin​

The twin metadata is mapped to inventory data in Cumulocity.

Twin - Main device​

A device's digital twin model can be updated by publishing to a specific topic.

The type part of the topic is used to group the data so it is easier for components to subscribe to relevant parts.

Thin Edge (input)

Topic (retain=true)
te/device/main///twin/device_OS
Payload
{
"family": "Debian",
"version": "11"
}

Cumulocity IoT (output)

Topic
c8y/inventory/managedObjects/update/<main-device-id>
Payload
{
"device_OS": {
"family": "Debian",
"version": "11"
}
}

Twin - Child Device​

Thin Edge (input)

Topic (retain=true)
te/device/child01///twin/device_OS
Payload
{
"family": "Debian",
"version": "11"
}

Cumulocity IoT (output)

Topic
c8y/inventory/managedObjects/update/<main-device-id>:device:child01
Payload
{
"device_OS": {
"family": "Debian",
"version": "11"
}
}

Twin - Service on Main Device​

Thin Edge (input)

Topic (retain=true)
te/device/main/service/tedge-agent/twin/runtime_stats
Payload
{
"memory": 3024,
"uptime": 86400
}

Cumulocity IoT (output)

Topic
c8y/inventory/managedObjects/update/<main-device-id>:device:main:service:tedge-agent
Payload
{
"runtime_stats": {
"memory": 3.3,
"uptime": 86400
}
}

Twin - Service on Child Device​

Thin Edge (input)

Topic (retain=true)
te/device/child01/service/tedge-agent/twin/runtime_stats
Payload
{
"memory": 3.3,
"uptime": 86400
}

Cumulocity IoT (output)

Topic
c8y/inventory/managedObjects/update/<main-device-id>:device:child01:service:tedge-agent
Payload
{
"runtime_stats": {
"memory": 3.3,
"uptime": 86400
}
}

Twin data - Root fragments​

Data can be added on the root level of the twin by publishing the values directly to the topic with the key used as type. The payload can be any valid JSON value other than a JSON object. JSON objects must be published to their typed topics directly.

Thin Edge (input)

Topic (retain=true)
te/device/main///twin/subtype
Payload
"my-custom-type"

Cumulocity IoT (output)

Topic
c8y/inventory/managedObjects/update/<main-device-id>
Payload
{
"subtype": "my-custom-type"
}
warning

Updating the following properties via the twin channel is not supported

  • name
  • type

as they are included in the entity registration message and can only be updated with another registration message.

Twin - Deleting a fragment​

Thin Edge (input)

Topic (retain=true)
te/device/child01/service/tedge-agent/twin/runtime_stats
Payload
<<empty>>

Cumulocity IoT (output)

Topic
c8y/inventory/managedObjects/update/<main-device-id>:device:child01:service:tedge-agent
Payload
{
"runtime_stats": null
}

Base inventory model​

The contents of {tedge_config_dir}/device/inventory.json are used to populate the initial inventory fragments of the the main thin-edge device in Cumulocity. For example, if the inventory.json contains the following fragments:

inventory.json
{
"c8y_Firmware": {
"name": "raspberrypi-bootloader",
"version": "1.20140107-1",
"url": "31aab9856861b1a587e2094690c2f6e272712cb1"
},
"c8y_Hardware": {
"model": "BCM2708",
"revision": "000e",
"serialNumber": "00000000e2f5ad4d"
}
}

It is mapped to the following Cumulocity message:

Topic
c8y/inventory/managedObjects/update
Payload
{
"c8y_Agent": {
"name": "thin-edge.io",
"url": "https://thin-edge.io",
"version": "x.x.x"
},
"c8y_Firmware": {
"name": "raspberrypi-bootloader",
"version": "1.20140107-1",
"url": "31aab9856861b1a587e2094690c2f6e272712cb1"
},
"c8y_Hardware": {
"model": "BCM2708",
"revision": "000e",
"serialNumber": "00000000e2f5ad4d"
}
}

Where the c8y_Agent fragment is auto-generated by thin-edge and appended to the contents of the file before it is published.

The fragments in this file are also published to the te/device/main///twin/<fragment-key> topics so that the local twin metadata on the broker is also up-to-date and other components can also consume it. For example, the above inventory.json would result in the following twin messages:

Topic
te/device/main///twin/c8y_Agent
Payload
{
"name": "thin-edge.io",
"url": "https://thin-edge.io",
"version": "x.x.x"
}
Topic
te/device/main///twin/c8y_Firmware
Payload
{
"name": "raspberrypi-bootloader",
"version": "1.20140107-1",
"url": "31aab9856861b1a587e2094690c2f6e272712cb1"
}
Topic
te/device/main///twin/c8y_Hardware
Payload
{
"model": "BCM2708",
"revision": "000e",
"serialNumber": "00000000e2f5ad4d"
}
warning

The following keys in the inventory.json file are also ignored:

  • name
  • type

as they are included in the entity registration message and can only be updated with another registration message.

Updating entity type in inventory​

After updating the inventory with inventory.json file contents, the device type of the main device, set using the device.type tedge config key, is also updated in the inventory with the following message:

Topic
c8y/inventory/managedObjects/update
Payload
{
"type": "configured-device-type"
}

Operations/Commands​

Operations from Cumulocity are mapped to their equivalent commands in Thin Edge format.

Supported Operations/Capabilities​

All the supported operations of all registered devices can be derived from the metadata messages linked to their respective cmd topics with a simple subscription as follows:

mosquitto_sub -v -t 'te/+/+/+/+/cmd/+'

If that subscription returns the following messages:

Output
[te/device/main///cmd/restart] {}
[te/device/main///cmd/log_upload] { "types": ["tedge-agent", "mosquitto"] }
[te/device/child01///cmd/config_snapshot] { "types": ["mosquitto", "tedge", "collectd"] }
[te/device/child01///cmd/config_update] { "types": ["mosquitto", "tedge", "collectd"] }

The cmd metadata registered for both the main device and the child device child01 are mapped to the following supported operations messages:

[c8y/s/us] 114,c8y_Restart,c8y_LogfileRequest
[c8y/s/us/<main-device-id>:device:child01] 114,c8y_UploadConfigFile,c8y_DownloadConfigFile

The operation specific metadata like types for log_upload, config_snapshot and config_update are also mapped to their corresponding supported logs and supported configs messages as follows:

[c8y/s/us] 118,"tedge-agent", "mosquitto"
[c8y/s/us/<main-device-id>:device:child01] 119,"mosquitto", "tedge", "collectd"

Device Restart​

Request​

Cumulocity IoT (input)

Topic
c8y/s/ds
Payload
510,<main-device-id>

Thin Edge (output)

Topic
te/device/main///cmd/restart/<cmd-id>
Payload
{
"status": "init"
}

Response​

Even though operations on tedge can have different kinds of status for each operation type, the mapper recognizes and maps only the following status values as follows:

Thin Edge (input)Cumulocity (output)
Topic
te/device/main///cmd/restart/<cmd-id>
Payload
{
"status": "executing"
}
Topic
c8y/s/us
Payload
501,c8y_Restart
Topic
te/device/main///cmd/restart/<cmd-id>
Payload
{
"status": "successful"
}
Topic
c8y/s/us
Payload
503,c8y_Restart
Topic
te/device/main///cmd/restart/<cmd-id>
Payload
{
"status": "failed"
}
Topic
c8y/s/us
Payload
502,c8y_Restart

All other status values are just ignored.

Restart: Child device​

Cumulocity IoT (input)

Topic
c8y/s/ds
Payload
510,<main-device-id>:device:child01

Thin Edge (output)

Topic
te/device/child01///cmd/restart
Payload
{}

Software Update​

Cumulocity IoT (input)

Topic
c8y/s/ds
Payload
528,<main-device-id>,nodered::debian,1.0.0,<c8y-url>,install,collectd,5.7,,install,rolldice,1.16,,delete

Thin Edge (output)

Topic
te/device/main///cmd/software_update/<cmd_id>
Payload
{
"status": "init",
"updateList": [
{
"type": "debian",
"modules": [
{
"name": "nodered",
"version": "1.0.0",
"url": "<tedge-url>",
"action": "install"
},
{
"name": "collectd",
"version": "5.7",
"action": "install"
},
{
"name": "rolldice",
"version": "1.16",
"action": "remove"
}
]
}
]
}

Where the collectd binary from the <c8y-url> is downloaded to the tedge file transfer repository by the mapper, and the local <tedge-url> of that binary is included in the mapped request.

Configuration Snapshot​

Cumulocity IoT (input)

Topic
c8y/s/ds
Payload
526,<main-device-id>,collectd

Thin Edge (output)

Topic
te/device/main///cmd/config_snapshot/<cmd_id>
Payload
{
"status": "init",
"type": "collectd",
"url": "<tedge-url>"
}

Where the url is the target URL in the tedge file transfer repository to which the config snapshot must be uploaded.

Configuration Update​

Cumulocity IoT (input)

Topic
c8y/s/ds
Payload
524,<main-device-id>,<c8y-url>,collectd

Thin Edge (output)

Topic
te/device/main///cmd/config_update/<cmd_id>
Payload
{
"status": "init",
"type": "collectd",
"url": "<tedge-url>"
}

Where the collectd configuration binary from the <c8y-url> is downloaded to the tedge file transfer repository by the mapper, and the local <tedge-url> of that binary is included in the mapped request.

Log Upload​

Cumulocity IoT (input)

Topic
c8y/s/ds
Payload
522,<main-device-id>,tedge-agent,2013-06-22T17:03:14.000+02:00,2013-06-22T18:03:14.000+02:00,ERROR,1000

Thin Edge (output)

Topic
te/device/main///cmd/log_upload/<cmd_id>
Payload
{
"status": "init",
"type": "tedge-agent",
"tedgeUrl": "<tedge-url>",
"dateFrom": "2013-06-22T17:03:14.000+02:00",
"dateTo": "2013-06-23T18:03:14.000+02:00",
"searchText": "ERROR",
"lines": 1000
}

Where the url is the target URL in the tedge file transfer repository to which the config snapshot must be uploaded.