Have you ever used go-c8y-cli?

Have you ever used go-c8y-cli ?

If you ever have wondered how go-c8y-cli can support you to integrate new devices, I would like to give you some tips and tricks to do so.
So first we need to create one or more devices. Here are some examples how to create devices.

/// create some devices by using go-c8y-cli Create Device

c8y devices create --name device_8777 --data "type=c8y_gsm,owner=kai.reinhard@software.co" --force
c8y devices create --name device_8988 --data "type=c8y_gsm_1,owner=kai.reinhard@software.co" --force
c8y devices create --name device_9371 --data "type=c8y_gsm_2,owner=kai.reinhard@software.co" --force
c8y devices create --name device_30155 --data "type=c8y_mp,owner=kai.reinhard@software.co" --force
c8y devices create --name device_330098 --data "type=c8y_ir_es,owner=kai.reinhard@software.co" --force
c8y devices create --name device_403654 --data "type=c8y_water,owner=kai.reinhard@software.co" --force

/// create some devices by using C8Y Rest API

If you prefer to choose Postman or any other REST-Client

{
"c8y_IsDevice": {},
"name": "device_403654"
"type": "c8y_water",
"owner": "kai.reinhard@software.co"
}

Add some Measurements

As a next step the devices needs some measurements. so we need to find out the managed object ID’s of the created devices to assign correctly the measurements.

c8y devices list --query "name eq  'device_*'" --includeAll

Output

| id               | name             | type                | owner                         | lastUpdated                   | c8y_availability.status |
|------------------|------------------|---------------------|-------------------------------|-------------------------------|-------------------------|
| 28182684202      | device_9371      | c8y_gsm_2           | kai.reinhard@software.co      | 2023-12-13T07:49:46.036Z      |                         |
| 62182687204      | device_8777      | c8y_gsm             | kai.reinhard@software.co      | 2023-12-13T07:49:44.968Z      |                         |
| 70182686204      | device_30155     | c8y_mp              | kai.reinhard@software.co      | 2023-12-13T07:49:46.442Z      |                         |
| 79182686203      | device_8988      | c8y_gsm_1           | kai.reinhard@software.co      | 2023-12-13T07:49:45.673Z      |                         |
| 84182683208      | device_403654    | c8y_water           | kai.reinhard@software.co      | 2023-12-13T07:49:49.410Z      |                         |
| 90182687205      | device_330098    | c8y_ir_es           | kai.reinhard@software.co      | 2023-12-13T07:49:46.791Z      |                         |

If you prefer to choose Postman or any other REST-Client

GET {{baseUrl}}/inventory/managedObjects?query=name eq  'device_*'

Output

{

    "next": "https://t401774272.emea.cumulocity.com/inventory/managedObjects?query=name%20eq%20%20'device_*'&pageSize=5&currentPage=2",
    ......
       "pageSize": 5,
        "currentPage": 1
    }
}

It takes a while to find out all id’s using Postman, so I could recommend using it for such cases c8ycli

Create Measurements

So if you have than the managed object ID’s it is time to create some measurements per device using c8ycli.

## c8y_gsm_2
# erstelle example MEA for device_9371
c8y measurements create --device 28182684202 --type c8y_Temperature --data "c8y_Temperature.Temperature.value=25.0,c8y_Temperature.Temperature.unit=°C" --force
c8y measurements create --device 28182684202 --type c8y_Battery --data "c8y_Battery.Battery.value=43,c8y_Battery.Battery.unit=%" --force
c8y measurements create --device 28182684202 --type c8y_SignalStrength --data "c8y_SignalStrength.SignalStrength.value=-63,c8y_SignalStrength.SignalStrength.unit=dbm" --force
c8y measurements create --device 28182684202 --type c8y_Condition --data "c8y_Condition.Turbidity.value= 3.37,c8y_Condition.Turbidity.unit=FNU,c8y_Condition.Injection.value=13.3,c8y_Condition.Injection.unit=V,c8y_Condition.Temperature.value=1,c8y_Condition.Temperature.unit=°C" --force

## c8y_gsm
# erstelle example MEA for  device_8777
c8y measurements create --device 62182687204 --type c8y_Temperature --data "c8y_Temperature.Temperature.value=25.0,c8y_Temperature.Temperature.unit=°C" --force
c8y measurements create --device 62182687204 --type c8y_Battery --data "c8y_Battery.Battery.value=43,c8y_Battery.Battery.unit=%" --force
c8y measurements create --device 62182687204 --type c8y_SignalStrength --data "c8y_SignalStrength.SignalStrength.value=-63,c8y_SignalStrength.SignalStrength.unit=dbm" --force
c8y measurements create --device 62182687204 --type c8y_Condition --data "c8y_Condition.Pressure.value=3.5,c8y_Condition.Pressure.unit=bar,c8y_Condition.Temperature.value=1,c8y_Condition.Temperature.unit=°C" --force

##  c8y_mp
# erstelle example MEA for  device_30155
c8y measurements create --device 70182686204 --type c8y_Temperature --data "c8y_Temperature.Temperature.value=25.0,c8y_Temperature.Temperature.unit=°C" --force
c8y measurements create --device 70182686204 --type c8y_Battery --data "c8y_Battery.Battery.value=43,c8y_Battery.Battery.unit=%" --force
c8y measurements create --device 70182686204 --type c8y_SignalStrength --data "c8y_SignalStrength.SignalStrength.value=-63,c8y_SignalStrength.SignalStrength.unit=dbm" --force
c8y measurements create --device 70182686204 --type c8y_Condition --data "c8y_Condition.Pressure.value=0,c8y_Condition.Pressure.unit=bar,c8y_Condition.Cel.value=25.1,c8y_Condition.Cel.unit=Cel" --force

## c8y_gsm_1
# erstelle example MEA for  device_8988
c8y measurements create --device 79182686203 --type c8y_Temperature --data "c8y_Temperature.Temperature.value=25.0,c8y_Temperature.Temperature.unit=°C" --force
c8y measurements create --device 79182686203 --type c8y_Battery --data "c8y_Battery.Battery.value=43,c8y_Battery.Battery.unit=%" --force
c8y measurements create --device 79182686203 --type c8y_SignalStrength --data "c8y_SignalStrength.SignalStrength.value=-63,c8y_SignalStrength.SignalStrength.unit=dbm" --force
c8y measurements create --device 79182686203 --type c8y_Condition --data "c8y_Condition.Pressure.value=5,c8y_Condition.Pressure.unit=bar,c8y_Condition.Max.value=7,c8y_Condition.Max.unit=bar,c8y_Condition.Min.value=2,c8y_Condition.Min.unit=bar" --force

## c8y_water
# create some example measurements for device_403654
c8y measurements create --device 84182683208 --type c8y_Temperature --data "c8y_Temperature.Temperature.value=25.0,c8y_Temperature.Temperature.unit=°C" --force
c8y measurements create --device 84182683208 --type c8y_Battery --data "c8y_Battery.Battery.value=43,c8y_Battery.Battery.unit=%" --force
c8y measurements create --device 84182683208 --type c8y_SignalStrength --data "c8y_SignalStrength.SignalStrength.value=-63,c8y_SignalStrength.SignalStrength.unit=dbm" --force
c8y measurements create --device 84182683208 --type c8y_Thresh --data "c8y_Thresh.Thresh.value=3,c8y_Thresh.Thresh.unit=,c8y_Thresh.Window.value=1" --force
c8y measurements create --device 84182683208 --type c8y_Thresh --data "c8y_Thresh.Thresh.value=5,c8y_Thresh.Thresh.unit=,c8y_Thresh.Window.value=1" --force
c8y measurements create --device 84182683208 --type c8y_Thresh --data "c8y_Thresh.Thresh.value=0.8,c8y_Thresh.Thresh.unit=,c8y_Thresh.Window.value=1" --force
c8y measurements create --device 84182683208 --type c8y_Thresh --data "c8y_Thresh.Thresh.value=1.4,c8y_Thresh.Thresh.unit=,c8y_Thresh.Window.value=0" --force
c8y measurements create --device 84182683208 --type c8y_Thresh --data "c8y_Thresh.Thresh.value=1.5,c8y_Thresh.Thresh.unit=,c8y_Thresh.Window.value=1" --force

# create some example measurements for device_8777 

## c8y_ir_es
# erstelle example MEA for  device_330098
c8y measurements create --device 90182687205 --type c8y_Temperature --data "c8y_Temperature.Temperature.value=25.0,c8y_Temperature.Temperature.unit=°C" --force
c8y measurements create --device 90182687205 --type c8y_Battery --data "c8y_Battery.Battery.value=43,c8y_Battery.Battery.unit=%" --force
c8y measurements create --device 90182687205 --type c8y_SignalStrength --data "c8y_SignalStrength.SignalStrength.value=-63,c8y_SignalStrength.SignalStrength.unit=dbm" --force
c8y events create --device 90182687205 --type c8y_door_Acc --text "Tür geschlossen 330098" --data "SerialNumber =330098,from=2023-12-13T13:53:39.500Z,to=,deviceId=90182687205" --force
c8y events create --device 90182687205 --type c8y_door_Acc --text "Tür offen 330098" --data "SerialNumber =330098,from=2023-12-13T13:53:39.500Z,to=,deviceId=90182687205" --force

My personal opinion is that using the c8ycli is much easier and more efficient than doing the same with Postman. eg. you should create a file and revise it into GitHub.

Dashboards

The next logical step would be then create Dashboards for each device Type. For the Moment there is no way or existing command to create a dashboard for a device using the go-c8y-cli neither Postman.

The recommendation from the Author is to use the Standard Functionality to create a Dashboard per Device Type.

001

Check the check Box
Apply dashboard to all devices of type … because under normal circumstances you need only different Dashboards per device type

002

Now we need to talk how to handle Dashboards. The Author recommends that you create a group with all devices where you need to create a generic Dashboard depending on the device type.
Once you have created the Dashboards for all devices you could fill up the Dashboard with widgets.

I have created a Dashboard as an example

Deploy Dashboard to another device - tenant independent

If your other devices differ just a little bit from this one the author used a way achieve this in an easy manner.
For that reason, you need to find out the managed object ID of the Dashboard. So grab the ID from the URL

.cumulocity.com/apps/cockpit/index.html#/device/62182687204/dashboard/74182686215

once you have it I recommend getting the managed object 74182686215 and grabbing the object with Postman

GET {{baseUrl}}/inventory/managedObjects/74182686215

as a Result you get

    "self": "https://t10452223.eu-latest.cumulocity.com/inventory/managedObjects/74182686215",
    "id": "74182686215",
    "name": "Dashboard",
    "lastUpdated": "2023-12-13T11:18:18.157Z",
    "creationTime": "2023-12-13T09:21:35.071Z",
    "owner": "kai.reinhard@software.co",
    "c8y_Dashboard!type!c8y_gsm": {},
    "c8y_Global": {},
    "c8y_Dashboard": {
        "deviceType": true,
        "deviceTypeValue": "c8y_gsm_1",
        "classes": {
            "dashboard-theme-light": true
        },
        "name": "Dashboard",
        "icon": "th",
        "widgetClasses": {
            "panel-title-regular": true
        },
        "priority": 10000
    }
}

If you want to use the dashboard on other devices or tenants the author recommends using Postman

PUT {{baseUrl}}/inventory/managedObjects/18182686216

Grab and copy everything between c8y_Dashboard and change the deviceTypeValue

    "c8y_Dashboard": {
        "deviceType": true,
        "deviceTypeValue": "c8y_gsm",
        "classes": {
            "dashboard-theme-light": true
        },
        "name": "Dashboard",
        "icon": "th",
        "widgetClasses": {
            "panel-title-regular": true
        },
        "priority": 10000
    }
}

With that, you now have updated the existing Dashboard of device_8988

The only thing now is that you have to change the DataPoints in the Data Points Graph

Works also great for Groups and Asset Dashboards to copy dashboards and is very helpful because a group/asset type-based Dashboard is not yet released.

Dashboard Cosmetics…

You do not like what you see on the datapoint labels … Hey then user go-c8y-cli to create some datapoint

c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Thresh,c8y_Kpi.color=#9d276a,c8y_Kpi.series=MainWindow,c8y_Kpi.label=Thresh → MainWindow" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.redRangeMax=10,c8y_Kpi.fragment=c8y_Battery,c8y_Kpi.unit=%,c8y_Kpi.minc=0,c8y_Kpi.color=#7d4174,c8y_Kpi.max=100,c8y_Kpi.series=Battery,c8y_Kpi.label=Battery Level,c8y_Kpi.yellowRangeMax=25,c8y_Kpi.yellowRangeMin=10,c8y_Kpi.redRangeMin=0" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Daily,c8y_Kpi.color=#52deb4,c8y_Kpi.series=Min,c8y_Kpi.label=Minimal" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_SignalStrength,c8y_Kpi.unit=dbm,c8y_Kpi.color=#a597b2,c8y_Kpi.series=SignalStrength,c8y_Kpi.label=SignalStrength" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Thresh,c8y_Kpi.color=#ca77b6,c8y_Kpi.series=Thresh,c8y_Kpi.label=Thresh" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Temperature,c8y_Kpi.unit=°C,c8y_Kpi.color=#6189f1,c8y_Kpi.series=Temperature,c8y_Kpi.label=Temperatur" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.unit=bar,c8y_Kpi.color=#9d276a,c8y_Kpi.series=Pressure,c8y_Kpi.label=Pressure" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.unit=°C,c8y_Kpi.color=#0352cd,c8y_Kpi.series=Temperature,c8y_Kpi.label=Temperatur" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.unit=bar,c8y_Kpi.color=#8d3f24,c8y_Kpi.series=Max,c8y_Kpi.label=Pressure max" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.unit=bar,c8y_Kpi.color=#fe6f46,c8y_Kpi.series=Min,c8y_Kpi.label=Pressure min" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.unit=FNU,c8y_Kpi.color=#52deb4,c8y_Kpi.series=Turbidity,c8y_Kpi.label=Turbidity" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.unit=V,c8y_Kpi.color=#a597b2,c8y_Kpi.series=Injection,c8y_Kpi.label=Injection" --force
c8y inventory create  --type c8y_Kpi --data "c8y_Kpi.fragment=c8y_Condition,c8y_Kpi.color=#ca77b6,c8y_Kpi.series=Cel,c8y_Kpi.label=Cel" --force

Resumeé

Both ways (Postman and c8ycli) have their right to be used for development and testing of Cumulocity functionality. I personally really like it when I easily can recreate a system or application within minutes. Also for the Topics traceability and repeatability.

So go for go-c8y-cli.



Kai Reinhardt

4 Likes