These blocks work on a device’s data on the IoT host: they store readings and attributes, evaluate alarm rules and add device facts to the message. Almost all of them need a message whose originator is a device: a device message, or a message a root handed on with Run flow. Messages started by a schedule, inject, event or timer are about the organisation, not a device; these blocks refuse them with not_a_device.
Save telemetry
Stores the message’s key-value pairs as the device’s telemetry. Only this block stores telemetry: a branch without it stores nothing. Only msg.payload is stored, never the metadata.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| keys | Only these keys | every key | key names |
| ts | Which time the record is stored at | record time | record time (msg.metadata.recordTs), receive time (msg.metadata.ts) |
| ts_path | With record time: re-time the record from this value | none | a path to epoch milliseconds (a number or numeric text) |
Outputs: out (once the values are committed), error with msg.error.code:
| Code | Meaning |
|---|---|
not_a_device | The originator is not a device |
invalid_value | The payload is not an object |
bad_ts | The time at ts_path is not epoch milliseconds |
too_old | Older than your organisation keeps raw data |
no_values | Nothing in the payload can be stored |
key_limit | No room for a new key under the plan’s key cap |
save_failed | The database refused the row (msg.error.ts is its time) |
- Messages are written in waves of up to 500, and the device’s next message waits for the commit, so it reads what this one stored.
- The same values at the same time are stored once; two different messages at the same time are both kept; the latest value moves only to a strictly newer time.
- When the database cannot be reached, nothing is lost: the run waits and is replayed when it is back.
- A test run stores nothing.
See How readings are stored and Telemetry keys.
Save attributes
Stores the message’s key-value pairs as the device’s client attributes (what the device reports about itself, such as its firmware version).
| Setting | Meaning | Default | Values |
|---|---|---|---|
| scope | Which attributes | client | client |
| keys | Only these keys | every key | key names |
Errors: not_a_device, invalid_value, save_failed. A message delivered again changes nothing; an older message never overwrites a newer value; an unchanged value is not written again. See Attributes.
Set shared attribute
Sets shared attributes of the message’s device. A connected device gets the change at once; an offline one when it next connects. Flows hear the change as an attributes_updated message.
| Setting | Meaning | Values |
|---|---|---|
| items | Key and value pairs | required; at most 32. Key: letters, digits, _, ., -, at most 57 characters. Value: a literal (true, 22.5, {"mode":"eco"}) or a path such as msg.payload.setpoint. |
Errors: not_a_device, device_not_found, invalid_value, bad_attribute, too_large, managed_by_settings (a cfg.* key of a device whose settings are managed on its Settings tab), limit (the device had too many commands and settings from flows in the last minute; default 30).
- Control level: deploying needs Deploy flows with control-level nodes and the flow’s name typed.
- Keys starting with
_,fw_orcurrent_fw_, andsession_limitsanddeleted, belong to the platform and cannot be set. - A late message changes nothing. A test run says what it would set.
Alarm rules
Evaluates the alarm rules of the device’s profile and opens, updates or clears the device’s alarms. The rules are edited on the device profile; this block decides where in the flow they run. The default root has it right after the entry.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| profile_rules | Evaluate the profile’s rules | on | on, off |
| rules | Only these alarm types | every rule | rule types of the profile |
Outputs:
out: the message, always, after the evaluation (a problem is logged and never stops the message, so the save blocks after it still run).created,updated,cleared: a copy of the message withmsg.msgTypealarm, the alarm inmsg.payloadandmsg.metadata.alarm(transition,isNew,isSeverityUpdated,isCleared,repeats,durationMs,ruleId).
Telemetry is evaluated against the rules that read one of its keys; connect, disconnect, activity and inactivity drive the offline rule. Late or out-of-order readings are evaluated as backfill (history marked Backfilled, nobody notified). Remove the block and alarm rules stop for the devices of this root; put it back and they continue. See Alarm rules on device profiles.
Device details
Adds facts and attributes of the message’s device to the message.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| fields | Device fields | name, profile | name, label, type, serial, model, fw_version, status, online, last_activity (epoch ms), profile, profile_id, is_gateway, gateway |
| attributes | Attributes: scope, key, name in the message | none | at most 50; scope client, shared or server |
| target | Where the object is written | msg.metadata.device | a path under msg.metadata or msg.payload |
| with_ts | Write attributes as { ts, value } | off | |
| on_missing | A field or attribute without a value | error | error, skip, null |
Example result: { "name": "Boiler 1", "profile": "Boilers", "online": true, "setpoint": 21 }. gateway is { id, name, online } for a device behind a gateway. Details are cached 30 seconds; attributes are read fresh. Errors: missing (with msg.error.keys), not_a_device, not_found, invalid_value, read_failed.
Latest values
Adds the stored latest values of chosen keys of the device.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| keys | Telemetry keys | required | at most 50 |
| target | Where | msg.metadata.latest | under msg.metadata or msg.payload |
| with_ts | { ts, value } instead of the value | off | |
| on_missing | A key without a stored value | error | error, skip, null |
A value of the message being processed is included only after its Save telemetry ran.
Profile details
Adds facts of the device’s profile.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| fields | Profile fields | name | name, id, transport, inactivity_timeout_s, rpc_timeout_s, downlink_max_bytes, online_rule, expected_interval_s |
| target | Where | msg.metadata.profile | under msg.metadata or msg.payload |
| on_missing | A field without a value | error | error, skip, null |
Related data
Adds data of assets and devices related to the message’s device or asset: the site a device is placed in, the devices an asset manages, an ancestor three levels up.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| direction | Follow relations from the originator, or to it | from | from, to |
| relation_types | Relation types followed | CONTAINS | e.g. CONTAINS, MANAGES, FEEDS, MONITORS or your own; none = any |
| exclude_types | Types never followed | none | |
| depth | Levels | 1 | 1 to 8 |
| last_level_only | Keep only the last level | off | |
| entity_kind | Which entities | any | any, asset, device |
| profiles, kinds | Only devices of these profiles, assets of these kinds | any | |
| max | How many entities | 1 | 1 to 100 (1 writes one object, more a list) |
| data | What is read | attributes | attributes, latest values (devices), fields |
| scope | Device attribute scope | server | server, shared, client |
| mapping | Keys read and their names in the message | required | at most 50 |
| target | Where | msg.metadata.related | under msg.metadata or msg.payload |
| with_ts, on_missing | As above | off, error |
The asset tree and device placements count as CONTAINS relations: direction to, CONTAINS, depth 3, last level only, assets finds a device’s site three levels up. The order is fixed, so max 1 picks the same entity every time. See Asset hierarchy.
Save reading (General host)
Stores key-value pairs as a reading of a record kind that accepts writes from flows (for example asset meters, where your plan includes them). Device data is never saved here.
| Setting | Meaning | Default | Values |
|---|---|---|---|
| kind | The record kind | required | a kind that accepts flow writes |
| entity_path | Where the record’s id is | msg.originator.id | a path to a UUID |
| ts, ts_path | As for Save telemetry | record time | |
| keys | Only these keys | every key |
Errors: invalid_value, invalid_entity, unknown_kind, kind_not_writable, entity_not_writable, bad_ts, save_failed.
Where metadata ends
Values written under msg.metadata are never stored; values under msg.payload are stored by a later Save telemetry. Put enrichment under msg.metadata unless you mean to store it.

