Liberty-IoT-OS is an operating system for IoT. Device access is indispensable operation for IoT systems.
Device Access Model
There are two types of device accesses.
- Command - A device send command to other devices. The command may or may NOT be result of a user action.
- Attributes - A device may report current attributes to other devices. A device may also query attributes from other devices.
A example is a dimmable light. User may send a command to a light, through a switch or a Smartphone.
Turn light to full on (level 255), light shall smoothly transition from current level to target level in 2 seconds.
A light may voluntarily report its state to other devices. State information is a collection of attributes. Each attribute has a predefined attribute ID and a value of predefined type.
Light reports that it’s “Current Level” is 255, which is a predefined as 8-bit unsigned integer.
A device (e.g. Liberty IoT Hub) can also query device for attributes.
Hub queries a light for “Current Level” and “On Transition Time”.
Command and Attribute
A command is composed of a “Command ID” and a set of extra parameters. Command ID is a 8-bit unsigned integer rangeing between 0 and 255.
An attribute is composed of a “Attribute ID” and “Attribute Value”. Attribute ID is unsigned 16-bit integer ranging between 0 and 65535.
A device supports on or more clusters. Cluster is another 16-bit unsigned integer, values between 0 and 65535.
In Libre Home, cluster is also called “capability”. For example, we have “On/off Cluster”, and “Level Control Cluster” etc.
A cluster is conceptually equivalent to “interface” in programming language.
In Libre Home, commands and attributes must be coupled with a Cluster.
Device API Design
The device API design must follow these guidelines:
- Full device access. Application must be able to make use of full potential of a device.
- Security. The API must be able to prevent potentially malicious application from compromising the system.
- Usability. The API must be easy to use for developers.
Treat Device Write More Restrictively Than Read
For security reason, device write (control) API are made more explicit and restrictive.
On the other hand, device read is more lenient in order to give application as much information about the device as possible.
Still, developer must understand the limitations by nature. For example, the flash memory built in devices are small, with a write life expectancy of about 100,000 cycles. Event if an API allows changing some persistent attributes of a device, that change may not be performed frequently to avoid potential write wearing.
Also, frequent changing states of device may cause wireless channel congestions.
Liberty-IoT-OS has some built-in mechanisms to detect potential abuse and may kill task and mark it “disabled” as a a result.
Let’s take a Level Control Device as an example.
Assume now the dimmable light is off (CurrentLevel = 0). In app, we call,
Libre_DeviceLevelSet(device, 255, 20)
The light will smoothly dim up to maximum level (255) in 2 seconds (20 * 100ms = 2 seconds).
The API will actually send a command to the dimmable light device.
If we have another Task thread actually subscribing event for that device, it shall see a event like this:
- Event Object
- t = 0 - Event type : Device command event
- id = actual_device_internal_ID
- ok = true - The state of the devie is working
- c = 0x0008 - Cluster of device event: CLUSTER_ID_GEN_LEVEL_CONTROL
- d = 0x00 - Command ID of device event: Move To Level
- v = An array below:
- 255 - Level
- 20 - Transition time
- a = A hashtable of attributes changed as the effect of the command
- 0x0000 (CurrentLevel) = 255 - The target level
- 0x0001 (RemainingTime) = 20 - Transition time left
- s = 5 - The event source, 5 = App engine, event is triggered by an App Task