Skip to content

Changing Data Fields tutorial

Change the fields of your dataset without re-configuring the Cloud Module ☁️

Published by Nando Kartoredjo, Tue Jun 04 2024

To (Re)configure 🛠️

The beauty of the Cloud Module ☁️ lies within its customisation of the data structures. Through UART or CAN, you can define a JSON structure which will meet most modern REST API's. This way, you can have direct access to your dataset without the need of some in between data processing. Take for example the following JSON structure:

json
{
  "value": 12
}

You can use the SDK 💼 to recreate this data structure by making use of the provided builder pattern:

c
/* main.c */
#include <cloudmodule.h>

/* Make sure the cloudmodule structure is declared. */
CloudModule cloudmodule = CloudModule();

void SendUart(char symbol) {
  /* Your implementation for sending out a symbol over UART */
}

int main(void) {
  /* Initialise for the CAN interface. */
  const CloudJson *json = cloudmodule.InitCan(SendUart);

  /* Configure the JSON structure */
  json->Add("value", 12)
      ->Done();

  return 0;
}

In the background, the SDK 💼 will send out multiple messages to the Cloud Module ☁️ to create an abstract syntax tree of the JSON structure. For a simple structure like this, the SDK 💼 will generate 13 single-line messages.

If you want to change the data for the "value" field to 13, you could reconfigure the Cloud Module ☁️ to make use of the new value:

c
/* Configure the JSON structure */
json->Add("value", 13)
    ->Done();

This requires sending yet another stream of 13 messages. For this small example, you might not think twice about sending a hand full of messages. However, you might feel more concerned when you start to introduce more and more fields to the structure.

One Message to Rule Them All! 👑

Of the 13 messages send in the previous example, one is specifically used to set the data for the "value" field. For our field with data 12—or 0C in hexadecimal—the message over UART looks something like this:

/* index 04 and sub-index 01 contains the value 0C */
5406_0400_01_0C000000_E9

It turns out, there is a single message containing the field data for each and every field! You might not be surprised that this is by design. Instead of figuring out yourself which index and sub-index belongs to the field data, you can also make use of the SDK 💼 instead.

Notice that the Add method provided by the CloudJson builder is actually a macro:

c
#define Add(key, value, ...)             \
  Add();                                 \
  _Generic((value),                      \
      int: CloudModule_AddInt,           \
      unsigned: CloudModule_AddUnsigned, \
      double: CloudModule_AddFloat,      \
      char *: CloudModule_AddString)     \
      (key, value, Ref(__VA_ARGS__))

Besides the _Generic around each common data type, the macro also includes a variadic argument. The type definition Ref is an object which will populate a pointer ptr with the index of the message containing the field data. By making use of this index, we can make use of another method called Change from our builder to change the JSON structure:

c
/* main.c */
#include <cloudmodule.h>

/* Make sure the cloudmodule structure is declared. */
CloudModule cloudmodule = CloudModule();

void SendUart(char symbol) {
  /* Your implementation for sending out a symbol over UART */
}

int main(void) {
  /* Initialise for the CAN interface. */
  const CloudJson *json = cloudmodule.InitCan(SendUart);

  /* Create a database for storing the value index */
  uint16_t value_index = 0;

  /* Configure the JSON structure */
  json->Add("value", 12, .ptr = &value_index)
      ->Done();


  /* Change the value in a later stage */
  json->Change(value_index, 13);

  return 0;
}

The Change method is a useful way to change a single value without reconfiguring the whole Cloud Module ☁️.

Last updated: