Skip to main content
This guide walks you through device-side setup for Device RPC: enabling the Omega module, running the bundled echo example, and confirming the platform sees your service schema.

Enable the module

Add device-rpc to your Omega profile. The reference profile is omega/profiles/rpc-example.yaml — add an explicit bridge_id as in the minimal block below if the profile does not already set one. Minimal configuration:
Broker URL, TLS, credentials, and connection.root_topic come from the connection: block (or their env var overrides), not from device-rpc.
Connection env vars: OMEGA_MQTT_BROKER_URL, OMEGA_DEVICE_ID, OMEGA_ROOT_TOPIC, plus optional OMEGA_MQTT_USERNAME, OMEGA_MQTT_PASSWORD, and TLS cert paths (OMEGA_TLS_CA_PATH, OMEGA_TLS_CERT_PATH, OMEGA_TLS_KEY_PATH).

Run locally

Terminal 1 — MQTT broker:
Terminal 2 — Omega with the echo profile:
Omega connects to mosquitto, announces the gRPC schema, and serves the bundled golain.device.v1.EchoService.

Run against Golain

Register the device in the Console first, then point Omega at the Golain MQTT broker with mTLS credentials:
OMEGA_ROOT_TOPIC must match the root topic assigned in the Console for this device. A mismatch causes schema announce and invoke failures even when MQTT looks healthy.
Set device-rpc.bridge_id in your profile to match the device id you registered. Update bridge_id whenever you change the device identity.

Verify schema registration

After Omega connects, confirm the platform bound your service schema:
A bound device returns a descriptor_digest and a non-empty services array. Empty services means announce or reflection has not completed yet. Optional — force reflection (when the device is online but services are stale):
Requires can_write_device_metadata on the device.

Echo example service

The bundled example implements golain.device.v1.EchoService: Proto source: omega/modules/device-rpc/proto/golain/device/v1/echo.proto. Request body for Echo:
Success response prefixes the message:
Server-stream example — same request body, SSE response:
→ Full streaming guide: Invoking methods — Stream a method (SSE)

Example invoke

After schema binding, try a synchronous call from your machine:
→ Full caller guide: Invoking methods

Bring your own gRPC service

  1. Define .proto services and generate Go stubs.
  2. Register your service on a gRPC server with gRPC reflection enabled (required for platform schema registration).
  3. Wire your server into the Omega device-rpc module build.
  4. Regenerate embedded descriptors:
  5. Deploy the device. On connect, the platform reflects and binds your new schema automatically.
Any proto change produces a new descriptor_digest. Devices on old firmware keep their previous binding until they announce the new digest. Plan OTA rollouts accordingly; use POST .../rpc/reflect to verify binding after upgrade.

Idempotency for queued invoke

If cloud callers use Queued invoke, the platform may deliver the same RPC to your handler more than once. The platform does not attach call_id to the gRPC request bytes sent to the device.
Implement idempotency in every handler reachable via queued invoke. Non-idempotent operations (actuators, payments, counters) will double-apply unless you guard them. See Queued invoke — device-side idempotency.

Next steps

For announce-only testing without a live MQTT broker listener, set connection.transport: memory in a copied profile. Schema announce logic runs; the RPC listener is skipped.