Properties
Properties are key-value pairs that can be attached to a device. They can be used to store arbitrary, free-form JSON data related to a device. Properties can be used for everything from storing device configurations, to device state, and inventory information.
Reading and writing properties through Nexigon Agent:
nexigon-agent device properties set <property key> <property value>
nexigon-agent device properties get <property key>
Reading and writing properties through Nexigon CLI:
nexigon-cli devices properties set <device id> <property key> <property value>
nexigon-cli devices properties get <device id> <property key>
The property key is a string and the property value is a JSON string.
To avoid conflicts with existing properties, we recommend using a domain prefix.
For instance, we use dev.nexigon for properties whose structure is defined by Nexigon itself (e.g., system information under dev.nexigon.system.info).
Protected Properties​
Protected properties can only be read but not modified by the device. This is useful for storing device configurations and inventory information that must not be modified by the device itself (e.g., its serial number).
Versioning​
Every property carries a version, a monotonically increasing counter that is incremented on each update. The version can be used to detect changes and to implement optimistic concurrency control.
When reading a property, the response includes the current version:
{
"result": "Found",
"value": { "state": "idle" },
"version": 42
}
Compare-and-Swap​
The SetDeviceProperty action supports an optional expectedVersion field for compare-and-swap (CAS) semantics. When set, the property is only updated if its current version matches the expected value. If the version has changed since you last read it, the action returns VersionConflict instead of modifying the property.
{
"deviceId": "d_...",
"name": "dev.nexigon.ota.status",
"value": { "state": "installing" },
"expectedVersion": 42
}
If the property's version is still 42, the update succeeds and the version increments to 43:
{ "result": "Set" }
If another write happened in between (version is now 43), the update is rejected:
{
"result": "VersionConflict",
"currentVersion": 43
}
The caller can then re-read the property, merge or resolve the conflict, and retry.
When expectedVersion is not set, the property is updated unconditionally (the default behavior). For new properties that don't exist yet, the version check is skipped and the insert always succeeds with version 1.
This is useful when multiple systems write to the same property concurrently, or when a property is used to drive a state machine where transitions must be atomic. The writer reads the property, computes the new value, and writes it back with the version it read, ensuring no other write happened in between.