How to add a new setting to a Golioth project / device

When I’m creating a new project, I often want to implement the Golioth Settings service to have a common basis across all the devices in my fleet. Our most common example is LOOP_DELAY_S, which we use in the Reference Design Template to control how often we are taking a sensor reading and sending it back to the cloud (or updating the display, if available).

What if I want to create a new setting for my project?

Overview

  1. How to register a setting in device code (Zephyr)
  2. How to register a Setting on the Golioth Console / Cloud
  3. View the output when the device receives a new setting

1. How to register a setting in device code (Zephyr)

First, let’s look at how this is implemented in the RD Template to see how the existing setting is captured and updated. The RD Template breaks out each Golioth function into an associated .c and .h file, so we’ll look at app_settings.c:

static int32_t _loop_delay_s = 60;
#define LOOP_DELAY_S_MAX 43200
#define LOOP_DELAY_S_MIN 0

int32_t get_loop_delay_s(void)
{
	return _loop_delay_s;
}

static enum golioth_settings_status on_loop_delay_setting(int32_t new_value, void *arg)
{
	_loop_delay_s = new_value;
	LOG_INF("Set loop delay to %i seconds", new_value);
	wake_system_thread();
	return GOLIOTH_SETTINGS_SUCCESS;
}

int app_settings_register(struct golioth_client *client)
{
	struct golioth_settings *settings = golioth_settings_init(client);

	int err = golioth_settings_register_int_with_range(settings,
							   "LOOP_DELAY_S",
							   LOOP_DELAY_S_MIN,
							   LOOP_DELAY_S_MAX,
							   on_loop_delay_setting,
							   NULL);

	if (err) {
		LOG_ERR("Failed to register settings callback: %d", err);
	}

	return err;
}

The key points to note are that we need to register each new setting using the golioth_settings_register_<setting type> (there are different types of settings we’ll see on the Cloud side in the next section) and that we then need to utilize a callback we create.

Extending it for our example on the device

I want to create a new boolean value that I can synchronize with all of my devices in my fleet. I’m going to create a callback and register a new setting:


static enum golioth_settings_status on_status_led(bool new_value, void *arg)
{
	status_led = new_value;
	LOG_INF("Status LED is now %i", new_value);
	toggle_status_led(); // call public function in main.c that toggles LED
	return GOLIOTH_SETTINGS_SUCCESS;
}

In the existing app_settings_register function, add a registration for the new value

	err = golioth_settings_register_bool(settings,
						"STATUS_LED",
						on_status_led,
						NULL);

	if (err) {
		LOG_ERR("Failed to register settings callback: %d", err);
	}

And that’s it! I not only created a new setting registration, I tried out a different type. See all types of settings in the docs.

2. How to register a Setting on the Golioth Console / Cloud

The device only will receive a setting if it exists on the cloud. We can do that easily from the Golioth Console. There is a device-settings page on every project.

Extending it for our example on the cloud

I want to add a new setting, so I click the “Create” button on the status page and then select the type of setting I want to store. In this case it will be “Boolean”

I also set a default value for the fleet.

If I create a new value, it will alert me for how many devices are eligible for the update

.

3. View the output when the device receives a new setting

On devices that don’t have the setting code implemented, they will receive the update but only process the setting they are registering in the code.

For Devices

1 Like