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¤tPage=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.
Check the check Box
Apply dashboard to all devices of type … because under normal circumstances you need only different Dashboards per device type
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.