Additional Measurement Details via Thin-Edge

What product/components do you use and which version/fix level are you on?

Thin-Edge 0.9.0

Is your question related to the free trial, or to a production (customer) instance?

N/A

What are you trying to achieve? Please describe it in detail.

Customer would like to submit additional descriptive parameters of a measurement (unit of measure plus a classification of the measurement). In my work with thin edge, I have only been able to submit measurements in the form of key:value where key is the name of the property and value is a numerical entry. I know you can create complex measurements as well, but all values must be numerical. Is there something that I am missing that would enable me to pass these descriptive attributes with the measurement? I know that there are c8y JSON topics exposed that would enable me to send this in, but I believe that requires managing the IDs for the child assets which adds a layer of complexity when in a time crunch. If I can utilize the tedge topics, then I can reference the child devices by their external ids. Hoping I am missing something.

Do you get any error messages? Please provide a full error message screenshot and log file.

N/A

Have you installed all the latest fixes for the products and systems you are using?

Running latest

Currently the tedge measurement API is fairly restrictive (due to minimum via product implementation). We already have some open tickets to expand support for it, below are the open tickets that we have, though the priority is generally set via feedback from people using tedge because as much as we would like to implement everything at once, we just can’t.

We can look at prioritising these tickets if it is an urgent, though feedback on the GitHub tickets would be appreciated.

However the good news is that for occasions like this you can still use the direct Cumulocity topics (e.g. c8y/*, and you can still refer to the child device using the external identity (e.g. what you have to use in the MQTT topic to refer to the child device anyway).

Main device: Publishing custom measurement

Using the c8y/measurement/measurements/create MQTT topic is not bad for the main device as you don’t have to reference the external id of the main device as the linking is implicit. Note, you do have to specific the time property in the body.

tedge mqtt pub "c8y/measurement/measurements/create" '{"time":"2023-03-20T08:03:56.940907Z","environment":{"temperature":{"value":29.9,"unit":"°C"}},"type":"10min_average","meta":{"sensorLocation":"Brisbane, Australia"}}'

Output measurement (retrieved from Cumulocity IoT using API)

{
  "environment": {
    "temperature": {
      "unit": "°C",
      "value": 29.9
    }
  },
  "id": "812904",
  "meta": {
    "sensorLocation": "Brisbane, Australia"
  },
  "self": "https://{example}.c8y.io/measurement/measurements/812904",
  "source": {
    "id": "60812900",
    "self": "https://{example}.c8y.io/inventory/managedObjects/60812900"
  },
  "time": "2023-03-20T08:03:56.940Z",
  "type": "10min_average"
}

Child device: Publishing custom measurement

Publishing a custom Cumulocity IoT measurement to a child device requires an additional fragment externalId which contains the external id of the child device (Note, this is not the same as the id in Cumulocity IoT!). The external identity is essentially the name of the child device that you referenced, and you would have to refer to this name anyway when using the tedge measurement topic (tedge/measurements/{child_sn}).

tedge mqtt pub "c8y/measurement/measurements/create" '{"time":"2023-03-20T08:03:56.940907Z","externalSource":{"externalId":"{child_sn}","type":"c8y_Serial"},"environment":{"temperature":{"value":29.9,"unit":"°C"}},"type":"10min_average","meta":{"sensorLocation":"Brisbane, Australia"}}'

Output

{
  "environment": {
    "temperature": {
      "unit": "°C",
      "value": 29.9
    }
  },
  "id": "812896",
  "meta": {
    "sensorLocation": "Brisbane, Australia"
  },
  "self": "https://{example}.c8y.io/measurement/measurements/812896",
  "source": {
    "id": "66812895",
    "self": "https://{example}.c8y.io/inventory/managedObjects/66812895"
  },
  "time": "2023-03-20T08:03:56.940Z",
  "type": "10min_average"
}

Main differences between tedge/measurements and c8y/measurement/measurements/create

When using c8y/measurement/measurements/create you have to:

  • Specify the time field yourself following the standard Cumulocity IoT timestamp format (e.g. ISO8601). See docs under the “Date format” section.
  • Add the externalSource fragment if you want to create a measurement for a child device
4 Likes

Thank you very much for the detailed response.

Though it might be worth mentioning that just because you can add this meta information does not necessarily mean you should add it.

In the example above I showed how you could add another non-value fragment (e.g. meta) to the measurement structure. This is actually considered bad practice for measurements as measurements are meant to be more numeric data and only orientated via valueFragmentSeries/valueFragmentType. If you start to abuse custom fragments then you might be opening yourself up to some of the following topics:

  • Non-efficient usage of data (e.g. sending the location on every measurement for a device which is static does not make sense). You will be storing the same data fro each measurement.
  • Slow measurement queries. Custom fragments may not be indexed in the database, so querying for measurements based on this custom fragment will not be efficient
  • Incompatibilities with other products. This really depends on your exact schema, however the more complex/free form your data is, the more likely that you can not off-board it using DataHub as the schema needs to be known…but again it really depends on the use-case here.

If you wish to add additional meta information it would make more sense using one of the following options:

  1. Use the .type field of the measurement to classify the measurement. The type fragment is supported by the measurement API. Though using just the type field really depends on what information you would like to store there.
  2. send the data using events (the event API is designed for custom fragments, as it does not assume that the data is numeric)
  3. send the meta information about the sensor on the device managed object once on startup (or periodically at a relaxed interval or on-change)

I hope this additional context helps.

1 Like

I would also prefer these 3 options Reuben mentioned.
Just think about the increasing data throughput & size storing the meta information in each measurement instead of the managed object. If you have thousands of measurements per day that impact is quite huge

Also there is no default App that can work with the meta information stored in measurements, so when using custom Apps you can also have a map of measurement types correlated to meta information stored in managed object(s) or even better representing each sensor as (child) device.

1 Like

Very helpful. Still learning and this has been very informative. For their specific use case, the meta data is specific to the measurement, not the sensor. I think he was looking to be able to identify a measurement as a demo run or something like that. I did bring up the fact that they won’t be able to see the information in the UI and I think I have held off a need for this for now. Thanks again

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.