Skip to main content

Step 7: Handle the sample-rate RPC

The dashboard also needs a way to change how often the device publishes. Expose an updateSampleRate RPC on the device.

Add the handler to device/main/device_task.cpp:

static void rpc_update_sample_rate(relay_rpc_request_t *req) {
cJSON *payload = cJSON_Parse(req->payload);
cJSON *rate_item = cJSON_GetObjectItem(payload, "rate");

if (!rate_item || !cJSON_IsNumber(rate_item)) {
rpc_send_error(req, "missing or non-numeric 'rate'");
cJSON_Delete(payload);
return;
}

int requested = rate_item->valueint;
if (requested < (int) SAMPLE_RATE_MIN_MS ||
requested > (int) SAMPLE_RATE_MAX_MS) {
rpc_send_error(req, "rate out of range");
cJSON_Delete(payload);
return;
}

g_sample_rate_ms.store(static_cast<uint32_t>(requested));

cJSON *resp = cJSON_CreateObject();
cJSON_AddNumberToObject(resp, "rate", requested);
cJSON_AddStringToObject(resp, "status", "ok");
req->respond(resp);

cJSON_Delete(resp);
cJSON_Delete(payload);
}

The next iteration of the sensor loop picks up the new rate automatically, since the loop reads g_sample_rate_ms on every cycle.

Register the handler alongside rpc_set_state:

g_device->rpc.listen(RPC_SET_STATE, rpc_set_state);
g_device->rpc.listen(RPC_UPDATE_RATE, rpc_update_sample_rate);

Test it

Two ways to verify, pick whichever fits where you are in the tutorial.

A. Local check. Reflash the device and watch the serial log. You should see both handlers registered:

I (4412) device-task: Registered RPC handler: state
I (4418) device-task: Registered RPC handler: updateSampleRate

B. End-to-end check. Complete Dashboard Step 6 to build the form that calls this RPC, then come back and apply a rate of 500 ms. The serial log should start printing a reading every 500 ms instead of every 10 seconds. Apply 10000 to restore the default cadence.