Now is the time to describe your device in terms of attributes and values. The Attribute Definition window is where you will do this. Before we start editing, take a minute to think about how your device’s functions map to attributes and values.
Think of an attribute as a variable shared between your IoT device and the end-user’s Afero mobile app. Your device sets that variable/attribute in ASR to a value reflecting device state. That value is communicated to the Afero Cloud (for ASR-1 via either a standalone or “softhub” built into the Afero mobile app), and from there to the end-user’s mobile app. This causes the app UI to update, reflecting the current value of the attribute. Conversely, the end-user can manipulate the mobile app UI to cause a change in the value of an attribute: the new value is communicated to ASR in your device via the Afero Cloud then hub, and a device action is triggered by that attribute value.
A simple control used by many devices is Power. The values, or possible settings, are On and Off. When the device is turned Off, that state is reflected in a dedicated Power attribute. The attribute Off value is sent to the Afero Cloud via a hub, and from there to the Afero mobile app on the end-user’s mobile device. The device representation on the mobile app would most likely include a Power switch control, which would then be switched to Off. If the end-user then set the switch to On, the updated attribute value would be sent back the other way: app → Afero Cloud → hub (for ASR-1) → ASR, and the device would be turned on.
Not all attributes are Boolean; a more sophisticated device might use an attribute to represent Cleaning Mode; the settings (values) could be Spot Clean, Scheduled Clean, and Full Clean. For more about attribute modeling, read Great Attribute Modeling.
A Modulo reserves 4 kB of memory as space available for developer-defined attributes – your profile cannot exceed this. As you add attributes to your profile, check the Profile RAM Usage indicator at the top of the Attributes window to see remaining space:
The blue bar indicates space used by developer-defined attributes. Hover over the indicator to view actual remaining space, in bytes and percentage. For more details, read Device Attribute RAM Size.
There are two types of devices that could use ASR:
Devices without an MCU - A relatively simple device may not have a microcontroller, but still have sensors or controls. For this type of application, ASR exposes four GPIO pins that can be connected to a device that does not need to perform any processing beyond communicating attribute state with Afero. These four attributes are referred to as GPIO attributes.
GPIO attributes are, of course, tied directly to GPIO pin state, and therefore are defined by characteristics you would expect from pin interfaces: they can be Input or Output, you can activate internal pull-up or pull-down resistors, etc.
Devices with an MCU - A more complicated device might include an MCU, and so might perform logic involving attribute values communicated with Afero. For this purpose, ASR allows you to define 1024 attributes that are not directly tied to the state of a pin on ASR. These are referred to as MCU Attributes.
MCU attributes can be Read-Only or Read/Write, and you can specify the data type for each. (Read Define MCU Attributes for details on data types.)
Two MCU serial protocols are supported:
We’ll start by defining the GPIO attributes. Note that not all modules have GPIO pins.
Click Attributes in the Navigation pane to open the Attribute Definition window. (We’ll talk about the MCU Protocol drop-down menu when we define MCU attributes, later.) By default the GPIO attributes appear, ready to be defined:
Click an attribute’s On/Off toggle switch to turn it On and open the attribute’s definition editor. Depending on the Operation Mode you select for your GPIO pin (Input vs. Output), different options will appear:
If you turn an attribute Off, you will lose its current definition. To retain your attribute definition but close that attribute’s editor, click the name of the attribute shown in orange at the top-left of the editor. Save your work at any time by clicking the Save button in the upper-right of the window.
Complete the fields using the information in the table below:
|Attribute Name||Type a name that will help you identify this attribute in other contexts. This name will never be visible to the end-user.|
Input - Inputs are read-only.
Output - Outputs are both read and write.
|Active||By default, an attribute value of 1 sets the I/O voltage to High. To invert that setting so a value of 1 sets the voltage to Low, select that option. Active Low can be set for all GPIOs that are configured as Input or Output, but are not configured as Toggle (for Input) or PWM (for Output).|
|Bind to Attributes||Use binding to have changes from one attribute propagate to another attribute locally, without having to go through the Afero Cloud. Read More About Binding, below, for details.|
|Store in Flash||
This option is available to GPIO Output attributes not set to Pulse (see note below). Selecting this checkbox ensures that an attribute value persists in flash memory if power is interrupted. A good example of this is when a powered-on plug loses, then regains, power. When power is restored, you want the plug to return to the “on” state, the same state it was in prior to losing power.
There is a reason Store in Flash is not available to Output attributes set to Pulse. If a pulsing attribute values were stored in flash, the value would be written with every pulse, and that could result in exhausting flash lifetime earlier than expected.
This option gives you a straightforward way to have a GPIO pin send pulses of a defined duration in response to an attribute change. An easy way to visualize this operation is to set up a pulsing GPIO attribute with a slider control. From the mobile app, set the attribute value using the slider… and then watch as the slider moves back down to zero as the pin pulses.
Note that the number of pulses is not among the fixed parameters you defined for the attribute. You could define an attribute and always use it as a one-shot pulse (by always setting the attribute value to one), or you could define an attribute that pulses a variable number of times (perhaps blinking an LED for a number of times requested by a UI setting) – the difference would be in the run-time attribute value, not in the attribute definition.
Finally, let’s clarify the behavior of the default value. The default value sets the initial attribute value (the pulse count), and pulses are emitted as that value counts down to 0. This happens only once, and won’t be repeated until ASR resets to initial conditions. Given this, it is anticipated that most users will specify a default value of 0, so that no pulsing occurs until the attribute value is explicitly set; but the “pulse at startup” capability is there if you need it.
We’ll use an example of binding to explain its use further. A good example is an Afero controlled power outlet, in which you would have an attribute that enables or disables power to the socket. On the power outlet itself, you’d also have a switch so the user can manually enable or disable power. What you want to do is “bind” the value of the switch attribute to the value of the power attribute so that if the user operates the switch, the outlet turns on and off. If the user changes the power value from the Afero Cloud, the attribute value for the switch will also update. For example:
|Operation||Power Attribute||Switch Attribute||Notes|
|All off||0||0||Start with a steady state.|
|User presses switch on outlet.||0||1||Switch attribute toggles to 1.|
|1||1||Binding causes power attribute to match switch attribute.|
|User turns off power via the Afero mobile app.||0||1||Power attribute goes to 0.|
|0||0||Binding causes switch attribute to match power attribute.|
In the case of binding, there is always a source attribute that is the changeable one, and a destination attribute that is being updated to match the value of the source attribute. In some cases, the destination attribute will not be writable. In these cases, the update operation will silently fail. Picture a case where you want an I/O input attribute to bind to an I/O output attribute. If the input attribute changes, the output attribute updates to match the new value. But if the output attribute is changed (via the Afero mobile app for example), the input attribute is not updated. This allows binding to work in one direction and not fail in the other.
Binding causes a change in one IO’s attribute value to update the value of another. As some IO attribute values are controlled by external hardware, binding can only work with certain IO configurations.
|Input||No||Attribute value is controlled by external signal.|
|Input Toggle||Yes||Attribute value is independent of external signal. Pull configuration does not matter.|
|Output PWM||Yes||Since value is 0 to 100 (instead of 0 or 1), a PWM can only be used to bind to another PWM output.|
To add an MCU attribute, click the MCU Protocol drop-down menu and select the protocol your MCU is using, either SPI or UART. A new attribute definition editor opens:
Complete the fields using the information in the table below:
|Attribute ID||Accept the default attribute ID that pre-populates the field, or type another number between 1 and 1023, inclusive. The number must be unique to the profile.|
|Attribute Name||Type a name that will help you identify this attribute in other contexts. This name is not visible to the end-user.|
|Default Value||Type a value that will be the initial setting for this function. Keep in mind that the Default Value must be compatible with the Data Type; if it’s not, you’ll be warned when you try to save. Also remember that every time a device loses power and restarts, default values are restored. Think about how this could affect the end-user.|
ASR uses the data type to allocate the storage size for the attribute. Select from the following:
|Max Size||Maximum size, in bytes, of the attribute data. The max size is pre-defined for all data types except UTF8S and BYTES. When defining attributes with those data types, you will want to define the smallest max size that you can to optimize use of limited memory available for attributes. However, keep in mind that attribute memory is preallocated in ASR, so choose a max that will definitely handle your application needs; if you exceed allocated space at runtime, you will almost certainly overwrite something else.|
|Writable||MCU attributes are Read-Only by default. If you need to write attributes to your device, then select this checkbox.|
Here are some helpful tips when editing attribute definitions: