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.