Un valor derivado es una clave que tus dispositivos no envían, sino que calculas a partir de lo que sí envían: una temperatura en otra unidad, un código de estado, el consumo desde la última lectura, una tasa. Lo calculas en un flujo y lo guardas con Save telemetry, de modo que se grafica, resume y alarma igual que cualquier otra clave.
La regla: deriva en el propio mensaje del dispositivo
Save telemetry guarda valores solo para el dispositivo que envió el mensaje (el originator del mensaje). Rechaza cualquier otro mensaje con not_a_device. Por tanto:
- Deriva valores en el root flow que recibe los mensajes del dispositivo, o en un flujo al que el root pasa el mensaje mediante Run flow (el mensaje, y su dispositivo, siguen siendo los mismos).
- Un flujo iniciado por un disparador Schedule, Inject, Event o Named timer tiene como originator la organización (o el flujo), no un dispositivo. No puede guardar telemetría de dispositivos.
- Un valor derivado se guarda por defecto en la hora del registro, de modo que coincide con la lectura de la que procede.
Dónde colocar los pasos
En el root flow por defecto, la telemetría va desde el switch Message type (salida telemetry) hasta Save telemetry. Inserta tus bloques en ese cable:
Device messages → Alarm rules → Message type ─ telemetry → [your blocks] → Save telemetry
Cada mensaje de telemetría contiene un registro: msg.payload es un objeto plano como {"temperature": 21.5, "humidity": 40}. Añade tus claves a msg.payload y todas se guardan juntas.
Si las reglas de alarma también deben ver la clave derivada, coloca tus bloques antes del bloque Alarm rules, y solo en mensajes de telemetría (por ejemplo, tras un Switch sobre msg.metadata.msgType).
No todos los dispositivos envían todas las claves en cada mensaje. Empieza tu rama con una comprobación (por ejemplo, un Switch con nempty sobre msg.payload.power), o el bloque que calcula falla o escribe null.
Ejemplo: conversión de unidades
Guarda temperature_f junto a temperature:
- Añade un bloque Calculate. expr:
round(msg.payload.temperature * 1.8 + 32, 1). target:msg.payload.temperature_f. - Conéctalo antes de Save telemetry.
Usa un bloque Scale para una conversión lineal de rangos, por ejemplo una señal de 4–20 mA a 0–10 bar (in_min 4, in_max 20, out_min 0, out_max 10, en la ruta propia de la clave).
Ejemplo: código de estado a partir de varios valores
Guarda status como número para gráficos y colores de sitio: 2 = crítico, 1 = advertencia, 0 = normal.
Añade un bloque Calculate con targetmsg.payload.status_codey expr:msg.payload.temperature > 8 ? 2 : (msg.payload.temperature > 6 ? 1 : 0)
Opcionalmente, un segundo Calculate con targetmsg.payload.statusy exprmsg.payload.status_code == 2 ? "critical" : (msg.payload.status_code == 1 ? "warning" : "ok")para las vistas de sitio 2D y 3D, que leen una clavestatus.
Ejemplo: consumo a partir de un contador
Un medidor envía un energy_kwh creciente. Guarda el consumo desde la lectura anterior como energy_delta:
- Añade un bloque Delta. Input:
msg.payload.energy_kwh. Output:msg.payload.energy_delta. Period:msg.payload.period_ms. - Seed:
latest, de modo que el primer mensaje tras un despliegue mide desde el último valor guardado en lugar de devolver 0. - When negative (
on_negative):zerosi el medidor puede reiniciarse; entonces un reinicio escribe 0 y el nuevo valor pasa a ser la base de referencia. - Conecta out a Save telemetry. Conecta también other (mensajes sin la clave) directamente a Save telemetry, de modo que las demás lecturas se sigan guardando.
El bloque Delta mantiene un valor anterior por dispositivo. Para consumo horario o diario no necesitas una clave derivada: lee el contador en bruto con el agregado increase. Consulta Aggregates and rollups.
Ejemplo: una tasa
A partir del ejemplo de Delta, añade un Calculate: target msg.payload.power_kw, expr msg.payload.period_ms > 0 ? msg.payload.energy_delta / (msg.payload.period_ms / 3600000) : 0. Es la potencia media desde la lectura anterior.
Ejemplo: combinar con un valor guardado
Para calcular un valor a partir de este mensaje y de otra clave que el dispositivo envió antes (por ejemplo, level ahora y capacity enviada una vez al día):
- Añade un bloque Latest values. keys:
capacity. target:msg.metadata.latest. When data is missing:skip. - Añade un Calculate: target
msg.payload.fill_pct, exprround(msg.payload.level / msg.metadata.latest.capacity * 100, 1).
Los valores bajo msg.metadata nunca se guardan; solo se guarda msg.payload. Para valores que pertenecen al dispositivo y no a una lectura (una capacidad, un límite), es preferible un atributo de servidor leído con Device details.
Ejemplo: suavizado
Un bloque Statistics (window count, size 10, salidas avg) reemplaza msg.payload por la media de los últimos 10 valores. Para conservar el registro original, usa un script, o calcula la media en una rama aparte y guárdala allí. Las medias derivadas rara vez son necesarias: los gráficos pueden promediar con el agregado avg.
Puntos a tener en cuenta
| Tema | Detalle |
|---|---|
| Límite de claves | Cada clave derivada es una clave nueva y cuenta para el límite de claves de tu plan. Consulta Telemetry keys. |
| Bloques de script | Un bloque Script puede calcular cualquier cosa, pero cuenta para los bloques de script de tu plan. Prefiere Calculate, Change y Delta. |
| Memoria | Delta, Statistics y bloques similares recuerdan valores por dispositivo. Desplegar un cambio en la configuración de uno de estos bloques vacía su memoria. |
| Datos tardíos | Los mensajes tardíos pasan por el root flow y se guardan, incluidos los valores derivados. |
| Pruebas | Test un flujo con un mensaje de muestra antes de desplegarlo: nada se guarda en una prueba. Consulta Versions, testing and rollback. |
| Otros registros | En el host General, el bloque Save reading guarda lecturas de otros tipos de registro que aceptan escrituras desde flujos (por ejemplo, contadores de activos, si tu plan los incluye). Los datos de dispositivos siempre pasan por Save telemetry. |
Consulta también IoT data blocks, Data transform blocks y el Flow cookbook.

