Relacionado
- Actualizaciones OTA — rollouts de firmware entregados sobre RPC persistente.
- Envío de telemetry — el sentido dispositivo→servidor.
- Seguridad y cumplimiento — scopes, el registro de auditoría y la redacción del hash de params.
La telemetry fluye dispositivo→servidor. La RPC fluye en el otro sentido: la plataforma envía un comando a un dispositivo — fijar la velocidad de un ventilador, leer de vuelta una config, reiniciar, iniciar una actualización de firmware. Esta página cubre los tres tipos de comando, el ciclo de vida de estados por el que pasa cada comando, cómo se correlacionan las respuestas, qué ocurre cuando el dispositivo está offline, y las reglas de autorización y auditoría en torno a los comandos.
| Tipo | ¿Espera un resultado? | ¿Sobrevive a un dispositivo offline? |
|---|---|---|
| Un sentido | No — disparar y olvidar | No (entregado solo si está online) |
| Dos sentidos | Sí — devuelve la respuesta del dispositivo | No (expira si está offline) |
| Persistente | Opcionalmente | Sí — almacenado y entregado al reconectar, reintentado |
setFan, setLed.timeout_ms y devuelven la respuesta del dispositivo
en línea. Úsalos para leer de vuelta el estado: getConfig, getStatus.Cada comando es un registro de RPC que pasa por un conjunto definido de estados:
stateDiagram-v2 [*] --> queued : RPC creada queued --> sent : el adapter publica al dispositivo sent --> delivered : el dispositivo confirma recepción delivered --> successful : el dispositivo devuelve resultado sent --> successful : un sentido / resultado rápido queued --> timeout : no persistente, dispositivo offline sent --> timeout : sin respuesta antes de timeout_ms delivered --> failed : el dispositivo reporta un error queued --> expired : persistente, pasó expiration_time sent --> queued : reintento persistente (sin ack) queued --> cancelled : el operador cancela sent --> cancelled : el operador cancela successful --> [*] timeout --> [*] failed --> [*] expired --> [*] cancelled --> [*]
El conjunto completo de estados: queued, sent, delivered, successful, timeout,
expired, failed, cancelled, deleted.
response_json.timeout_ms (o un comando no persistente para
un dispositivo offline).error_code se establece).expiration_time de un comando persistente pasó antes de la entrega.Cada comando lleva un correlation_id. El protocol adapter lo estampa en el
mensaje saliente; el dispositivo lo refleja en su respuesta; el adapter empareja la
respuesta de vuelta con el registro de RPC originario por ese id. Esto es lo que permite a un
dispositivo —o a toda una flota sobre un topic de respuesta MQTT compartido— responder de forma asíncrona
y que cada respuesta se enrute al comando correcto.
Una respuesta cuyo correlation_id no coincide con ninguna RPC activa se ignora (o se almacena como
un diagnóstico huérfano, según la config del adapter), y
corem_rpc_orphan_responses_total{protocol="…"} se incrementa.
Lo que le ocurre a un comando para un dispositivo offline depende enteramente de si es persistente.
Ningún adapter puede entregar el comando. Tras transcurrir timeout_ms la petición devuelve
DEADLINE_EXCEEDED / HTTP 504 y el registro de RPC pasa a timeout.
sequenceDiagram participant Op as Operador participant Core as CORE-M participant Dev as Dispositivo (offline) Op->>Core: SendDeviceRpc (no persistente) Core-->>Core: status=queued, dispositivo offline Note over Core: transcurre timeout_ms Core->>Op: DEADLINE_EXCEEDED / 504 (status=timeout) Dev--xCore: nunca alcanzado
El comando permanece queued y espera. Cuando el dispositivo se reconecta antes de
expiration_time, el adapter lo entrega. Si no llega ningún ack, vuelve a
queued y retries_remaining decrementa, reintentándose hasta el éxito, la cancelación,
la expiración o el máximo de reintentos. Si expiration_time pasa primero, pasa a
expired y nunca se entrega.
sequenceDiagram participant Op as Operador participant Core as CORE-M participant Dev as Dispositivo Op->>Core: SendDeviceRpc (persistente, expira +1h) Core-->>Core: status=queued (dispositivo offline) Note over Dev: el dispositivo se reconecta Dev->>Core: connect Core->>Dev: entregar comando (status=sent) Dev->>Core: ACK + resultado (status=successful)
El expiration_time de un comando persistente es un plazo estricto. Una vez que pasa, el
planificador de RPC marca el registro como expired, no se entrega ningún comando aunque el
dispositivo se reconecte más tarde, y se publica el evento rpc.expired.{tenant}.{rpc_id}.
Establece expiration_time al máximo tiempo durante el cual aún querrías que la acción ocurriese — un
reinicio que pusiste en cola hace días probablemente ya no se desea.
rpc. Un miembro sin él es
rechazado con PERMISSION_DENIED y no se crea ningún registro.rpc:execute. Un token con scope, por
ejemplo, telemetry:read que llame a RPC es rechazado con PERMISSION_DENIED y
rpc.denied registra reason="missing_scope".rpc.created con el actor, el
dispositivo, el método, la bandera de persistencia y un hash de los params. Si el
método está marcado como sensible, los params en bruto se redactan — solo se conserva el hash.Lee de vuelta la config de un dispositivo con una RPC de dos sentidos. Envías el comando y obtienes un
correlation_id; luego recuperas la respuesta emparejada.
Envía el comando. Llama al endpoint de RPC del dispositivo con el método, los params
JSON y un timeout. Necesitas el scope rpc:execute (token) o el permiso rpc
(usuario).
curl -X POST https://api.kronoxdata.com/api/v1/devices/dev_8f3a/rpc \ -H "Authorization: Bearer <token-with-rpc:execute>" \ -H "Content-Type: application/json" \ -d '{ "method": "getConfig", "params_json": "{}", "timeout_ms": 10000 }'Recibe el correlation id. La llamada devuelve de inmediato con el id que usas para recuperar el resultado.
{ "correlation_id": "c-7f3a91" }El dispositivo responde. El adapter entrega getConfig al dispositivo, el
dispositivo responde {"report_interval":30} estampado con c-7f3a91, y el
adapter lo empareja con el registro de RPC. El registro transiciona
queued → sent → delivered → successful y la respuesta aterriza en
response_json.
Obtén el resultado. Sondea por correlation id.
curl https://api.kronoxdata.com/api/v1/devices/rpc/c-7f3a91 \ -H "Authorization: Bearer <token-with-rpc:execute>"{ "found": true, "payload_json": "{\"report_interval\":30}"}El registro de RPC es agnóstico al transporte; el protocol adapter gestiona la entrega real y la correlación de la respuesta.
| Protocolo | Comando saliente | Correlación de respuesta |
|---|---|---|
| MQTT | Publicado en el topic de comandos configurado del dispositivo | El dispositivo publica en un topic de respuesta; el adapter empareja por correlation_id |
| HTTP | El dispositivo obtiene/hace long-poll; o el dispositivo envía un uplink de kind="rpc_response" | El uplink lleva el correlation_id |
| CoAP / LwM2M | Entregado sobre el canal CoAP del dispositivo | Respuesta emparejada por correlation_id / id de petición del protocolo |
| Gateway | Retransmitido a un dispositivo hijo vía su gateway | El gateway retransmite la respuesta del hijo con correlation_id |
Relacionado