udmi

UDMI / Docs / Specs / Sequences / Writeback

Writeback

This file documents UDMI’s specification for cloud to device control i.e. writeback. At a high level, the cloud controls a device by writing to the pointset block in the device config. After receiving the config, the device updates its state to reflect the status of the writeback attempt e.g. success, failure, etc.

Basic writeback sequence diagram

Generated using <https://sequencediagram.org>

participant Device
participant Broker
entryspacing 0.1
Broker->Device: CONFIG MESSAGE\npointset.points.subject.set_value = X
note left of Device: point `subject`\n set to X
Device->Broker: STATE MESSAGE\npointset.points.subject.value_state = applied
space -2

Cloud Behavior

To write to a point, the cloud sets three fields in the device config:

Device Behavior

After receiving the config message, the device attempts to write the value to the point. Depending on the status of the write, the device should populate the value_state

value_state

The value_state field is an enumeration within a state message representing the status of a point’s writeback attempt.

Possible states for value_state:

In the case of any of the error states (failure, invalid, overridden), the status field for the point should be populated to provide additional debugging information about the error.

state_etag

The state_etag field is meant to prevent a race condition where the device could apply a config change based off an obsolete device state. The state_etag is a hash value of point units, config set values echo and value_states in the points block. The state_etag must be updated to reflect any updates in the pointset block. The specific calculation of state_etag is left up to implementation, but the value should be a unique hash of the state’s pointset. The state_etag should be included by state and config. When the device receives a new config with a valid state_etag, regardless of update success or failure.

Basic writeback sequence diagram

Example

An example of how the state_etag works and the race condition this field prevents: 1) The device is in state A. For example, it specifies units Fahrenheit for some writable point P. 2) The cloud sends a config update to write the value 70 to point P. 3) The device state changes state B, where point P is now using units Celsius. This change can happen manually through the BMS, or through other mechanisms. 4) The device receives the cloud’s config update, and sets the value of point P to 70 Celsius, instead of the intended 70 Fahrenheit.

state_etag prevents this race condition by ensuring that the device state doesn’t change between when the config was sent and received. i.e. in the previous example, the cloud’s config update would include a state_etag uniquely representing state A. Upon receiving the update, the device would detect that the current state_etag (uniquely representing state B) is not the same as the one in the config, and therefore set the value_state as invalid.

Value Expiration

When the device receives a config, it should check that set_value_expiry exists and is greater than the timestamp field in the config, sending an invalid value_state if not.

If the set_value_expiry has already passed, then there’s no write to perform, so the state of the device shouldn’t change (i.e. this is a no-op)

If the config passes these checks, then the device should 1) perform the write 2) set a timer to trigger at the given set_value_expiry, overwriting any existing timer.

When the timer expires, the device reverts to its base state (as if no set values have been indicated), and sends a state update to notify the cloud of the state change.