Since TB Version 2.0 |
Stores the incoming message payload as attribute data of the message originator.
Expected incoming message format
The node accepts messages of type POST_ATTRIBUTES_REQUEST
and expects incoming message payload to be an object where each property name represents an attribute key, and its corresponding value is the attribute value. For example:
1
2
3
4
{
"firmware_version": "1.0.1",
"serial_number": "SN-001"
}
Configuration: Processing settings
The save attributes node can perform three distinct actions, each governed by configurable processing strategies:
- Attributes: saves attribute data to the database.
- WebSockets: notifies WebSocket subscriptions about updates to the attribute data.
- Calculated fields: notifies calculated fields about updates to the attribute data.
For each of these actions, you can choose from the following processing strategies:
- On every message: perform the action for every incoming message.
- Deduplicate: perform the action only for the first message from a specific originator within a configurable time interval. Minimum value for a deduplication interval is 1 second and maximum is 1 day.
To determine whether a message falls within a previously processed interval, the system calculates a deduplication interval number using the following formula:
1
long intervalNumber = ts / deduplicationIntervalMillis;
Where:
ts
is the timestamp used for deduplication (in milliseconds).deduplicationIntervalMillis
is the configured deduplication interval (converted automatically to milliseconds).intervalNumber
determines the logical time bucket the message belongs to.
The timestamp
ts
is determined using the following priority:- If the message metadata contains a
ts
property (in UNIX milliseconds), it is used. - Otherwise, the time when the message was created is used.
All timestamps are UNIX milliseconds (in UTC).
- Skip: never perform the action.
Note: Processing strategies are available since TB version 4.0.
Processing strategies can be set using either Basic or Advanced processing settings.
- Basic processing settings - provide predefined strategies for all actions:
- On every message: applies the On every message strategy to all actions. All actions are performed for all messages.
- Deduplicate: applies the Deduplicate strategy (with a specified interval) to all actions.
- WebSockets only: for all actions except WebSocket notifications, the Skip strategy is applied, while WebSocket notifications use the On every message strategy. Effectively, nothing is stored in a database; data is available only in real-time via WebSocket subscriptions.
- Advanced processing settings - allow you to configure each action’s processing strategy independently.
When configuring the processing strategies in advanced mode, certain combinations can lead to unexpected behavior. Consider the following scenarios:
-
Skipping database storage
Choosing to disable one or more persistence actions (for instance, skipping database storage for Time series or Latest values while keeping WS updates enabled) introduces the risk of having only partial data available:
- If a message is processed only for real-time notifications (WebSockets) and not stored in the database, historical queries may not match data on the dashboard.
- When processing strategies for Time series and Latest values are out-of-sync, telemetry data may be stored in one table (e.g., Time series) while the same data is absent in the other (e.g., Latest values).
-
Disabling WebSocket (WS) updates
If WS updates are disabled, any changes to the time series data won’t be pushed to dashboards (or other WS subscriptions). This means that even if a database is updated, dashboards may not display the updated data until browser page is reloaded.
-
Skipping calculated field recalculation
If telemetry data is saved to the database while bypassing calculated field recalculation, the aggregated value may not update to reflect the latest data. Conversely, if the calculated field is recalculated with new data but the corresponding telemetry value is not persisted in the database, the calculated field’s value might include data that isn’t stored.
-
Different deduplication intervals across actions
When you configure different deduplication intervals for actions, the same incoming message might be processed differently for each action. For example, a message might be stored immediately in the Time series table (if set to On every message) while not being stored in the Latest values table because its deduplication interval hasn’t elapsed. Also, if the WebSocket updates are configured with a different interval, dashboards might show updates that do not match what is stored in the database.
-
Deduplication cache clearing
The deduplication mechanism uses an in-memory cache to track processed messages by interval. This cache retains up to 100 intervals for a maximum of 2 days, but entries may be cleared at any time due to its use of soft references. As a result, deduplication is not guaranteed, even under light loads. For example, with a deduplication interval of one day and messages arriving once per hour, each message may still be processed if the cache is cleared between arrivals. Deduplication should be treated as a performance optimization, not a strict guarantee of single processing per interval.
-
Whole message deduplication
It’s important to note that deduplication is applied to the entire incoming message rather than to individual time series keys. For example, if the first message contains key A and is processed, and a subsequent message (received within the deduplication interval) contains key B, the second message will be skipped—even though it includes a new key. To safely leverage deduplication, ensure that your messages maintain a consistent structure so that all required keys are present in the same message, avoiding unintended data loss.
Due to the scenarios described above, the ability to configure each persistence action independently—including setting different deduplication intervals—should be treated as a performance optimization rather than a strict processing guarantee.
Configuration: Scope
The node determines the attribute scope for each incoming message by evaluating the scope
property in its metadata.
The supported scope types are Client attributes, Shared attributes, and Server attributes. The algorithm is as follows:
- If the incoming message metadata contains a non-empty
scope
property, the node compares its value against the supported scope values:CLIENT_SCOPE
corresponds to Client attributesSHARED_SCOPE
corresponds to Shared attributesSERVER_SCOPE
corresponds to Server attributes
- If a match is found, the corresponding scope is applied, and processing continues.
- If no valid match is found, the message processing fails.
- If the
scope
property is absent or an empty string, the node uses the scope specified in the node configuration.
Configuration: Advanced settings
-
Save attributes only if the value changes – if enabled, the node first retrieves the current values for the specified attribute keys and then compares them with the incoming values. If an attribute is missing, its value has changed, or its data type differs from what’s stored, it is marked for saving. If no changes are detected, the node skips the save operation.
Note: Avoid concurrent writes of the same attributes because change-detection is not transactional and may produce unexpected results in such cases.
Note: If the attribute save is skipped because the value has not changed, the attribute’s last updated timestamp will not be updated.
- Send attributes updated notification – if enabled, and if the attribute scope is not
CLIENT_SCOPE
(i.e., forSHARED_SCOPE
andSERVER_SCOPE
), the node puts an Attributes Updated event to the queue namedMain
. - Force notification to the device - the node determines whether to notify the device about attribute updates by evaluating the Force notification to the device option and the
notifyDevice
property in the incoming message metadata. The algorithm is as follows:- If the Force notification to the device option is enabled, the node always sends attribute update notifications to the device, regardless of the
notifyDevice
metadata value. - If the option is disabled, the node checks the
notifyDevice
property in the message metadata:- If the property is absent or an empty string, it defaults to sending the notification.
- If the property is provided, the notification is sent only if its value is
true
(ignoring case).
- In all cases, the notification is only sent if the device has an active subscription for the updated (or deleted) attributes.
- Additionally, attribute notifications are not sent if:
- The attribute save is skipped because its value did not change (when Save attributes only if the value changes is enabled).
- The attribute save is skipped due to the configured processing strategy (e.g., set to Skip).
- If the Force notification to the device option is enabled, the node always sends attribute update notifications to the device, regardless of the
Output connections
- Success:
- If an incoming message was successfully processed.
- Failure:
- If an incoming message type is not
POST_ATTRIBUTES_REQUEST
. - If an incoming message payload cannot be parsed to attribute key-value pairs.
- If the incoming message metadata includes a non-empty
scope
property whose value does not match one of the valid attribute scopes (i.e.CLIENT_SCOPE
,SHARED_SCOPE
, orSERVER_SCOPE
). - If unexpected error occurs during message processing.
- If an incoming message type is not