Ir al contenido

Envío de telemetry

La telemetry es todo el sentido de conectar un dispositivo. Cualquiera que sea el transporte que uses — HTTP, MQTT, CoAP, LwM2M, SNMP— cada lectura se normaliza en una sola forma interna: el TelemetryPoint. Esta página es la referencia definitiva de esa forma, los decodificadores que convierten tu formato de cable en ella, la validación que un punto debe pasar y qué hace CORE-M con un punto una vez aceptado.

Un TelemetryPoint es una lectura de un dispositivo en un instante. Lleva una identidad, un timestamp y dos mapas de valores con nombre:

message TelemetryPoint {
string device_id = 1;
string tenant_id = 2;
google.protobuf.Timestamp timestamp = 3;
map<string, double> numeric_values = 4;
map<string, string> string_values = 5;
}
CampoSignificado
device_idEl identificador de CORE-M para el dispositivo (no el hardware_id).
tenant_idEl tenant propietario. Derivado de tu credencial — nunca lo estableces a algo que tu key no posea.
timestampCuándo se tomó la lectura, RFC 3339 en el cable. Truncado a segundos enteros para anchoring — ver abajo.
numeric_valuesMapa de nombre de métrica → double. Úsalo para cualquier cosa medida: temperature, humidity, rpm, battery_v.
string_valuesMapa de nombre de métrica → string. Úsalo para estados y etiquetas: status, mode, firmware.

Elige el mapa según qué es el valor, no según cómo se imprime:

  • Numérico para mediciones que vas a graficar, umbralar o agregar. 22.5, 1013.2, -40.0. Incluso los enteros van aquí como doubles.
  • Texto para estados discretos e identificadores que vas a filtrar o mostrar. "online", "heating", "v2.0.0".

Un solo punto puede mezclar ambos — comparten el mismo timestamp:

{
"numeric_values": { "temperature": 22.5, "humidity": 65 },
"string_values": { "status": "ok", "mode": "auto" }
}

El timestamp son segundos Unix para anchoring

Sección titulada «El timestamp son segundos Unix para anchoring»

En el cable el timestamp es RFC 3339 (2026-05-29T14:30:00Z). Pero cuando un punto se hashea para anchoring en blockchain, ese timestamp se toma como segundos Unix — los nanosegundos se descartan. El hash canónico es:

SHA256( device_id_utf8 || timestamp_uint64_be(seconds) || jcs_payload_utf8 )

donde jcs_payload_utf8 es el payload canonicalizado según RFC 8785 (JCS).

Esto importa porque un verificador externo puede tener solo precisión de segundos. Al truncar a segundos enteros, CORE-M garantiza que el verificador puede reproducir el mismo hash exacto a partir de la misma lectura lógica. Si envías dos puntos para el mismo dispositivo en el mismo segundo, se hashean contra el mismo timestamp — dales valores distintos o sepáralos al menos un segundo si cada uno debe anclarse de forma independiente. Consulta Anchoring y Merkle proofs para ver cómo ese hash se convierte en una proof on-chain.

Los dispositivos rara vez hablan protobuf de forma nativa. Los adapters de ingesta de CORE-M decodifican formatos de cable comunes en la forma TelemetryPoint. La vía HTTP canónica (POST /api/v1/telemetry, puerto 8080) toma JSON; los dispositivos MQTT y CoAP pueden usar JSON, CBOR, protobuf binario, CSV o un mapeo de campos personalizado configurado en el device profile.

El formato por defecto y más simple. Las claves se mapean directamente sobre los campos del TelemetryPoint.

POST /api/v1/telemetry HTTP/1.1
Host: api.kronoxdata.com:8080
Authorization: Bearer sk_live_9Qk3pR2wXn7vJ4mB...
Content-Type: application/json
{
"points": [
{
"device_id": "dev_8f3a",
"timestamp": "2026-05-29T14:30:00Z",
"numeric_values": { "temperature": 22.5, "humidity": 65 },
"string_values": { "status": "ok" }
}
]
}

Un punto decodificado aún no está aceptado. Primero debe pasar la validación.

  1. Autenticación. La credencial debe ser válida y estar autorizada a ingerir para el tenant reclamado. Un punto no autenticado se rechaza y nunca se publica; la métrica telemetry_rejected_total{reason="auth"} se incrementa.

  2. Dispositivo conocido. El device_id debe existir en el registro del tenant. Si no, el punto se descarta silenciosamente —no se publica en el subject validado— y telemetry_dropped_total{reason="unknown_device"} se incrementa, con un log de advertencia que lleva contexto de traza. Esta es la causa más común de “mis datos no aparecen”: el dispositivo no fue aprovisionado, o estás enviando el device_id equivocado.

  3. Validación de esquema (si el profile define uno). Si el profile del dispositivo lleva un telemetry_schema, el punto se comprueba contra él. Un profile que requiere la clave numérica temperature rechaza un punto que la omita con INVALID_ARGUMENT, y corem_telemetry_schema_rejections_total{profile="…"} se incrementa. Los profiles sin esquema aceptan cualquier punto bien formado.

Una vez que un punto pasa la validación, ocurren muchas cosas — y el dispositivo no espera por ninguna de ellas. El borde confirma de inmediato y el punto se propaga de forma asíncrona:

flowchart TB
  IN["Punto aceptado<br/>telemetry.raw.{tenant}"] --> VAL["validar + enriquecer<br/>(dispositivo conocido, esquema, last_seen)"]
  VAL --> VD["telemetry.validated.{tenant}"]
  VD --> HOT[("Aerospike hot<br/>CDT list · 900s TTL")]
  VD --> COLD[("TimescaleDB cold<br/>archivo histórico")]
  VD --> LIVE["telemetry.live.{tenant}.{device}<br/>fan-out en tiempo real"]
  VD --> ANC["en cola para anchoring<br/>(Merkle batch → on-chain)"]

Concretamente, en la aceptación CORE-M:

  • Actualiza last_seen en el registro del dispositivo, y si el dispositivo estaba offline, lo cambia a online y publica un evento de cambio de estado.
  • Enriquece el punto con el nombre, los grupos y los tags del dispositivo.
  • Hace doble escritura: lo añade a la lista CDT hot de Aerospike (con clave {tenant}:{device}:{metric}, ventana de TTL de ~900 segundos — una caché rápida, no el sistema de registro) y lo inserta en la hypertable cold de TimescaleDB (en lotes para throughput) como el registro histórico duradero.
  • Hace fan-out a telemetry.live.{tenant}.{device} para que los paneles y los suscriptores WebSocket lo vean en tiempo real.
  • Lo pone en cola para anchoring — su hash se une a un Merkle batch que más tarde se compromete en la blockchain.

Que falle la escritura hot no bloquea la escritura cold; la vía cold siempre procede. Consulta Consulta y retención de telemetry para ver cómo se consultan los stores hot y cold y cuánto tiempo se conservan los datos.