Any application built on the Appivo-platform can have IoT-functionality – meaning you can have devices connected to your application that contribute functionality. Examples of this could be a device monitoring the temperature of a room, controlling a doorlock or displaying information on a TV. An application may even have several kinds of devices connected to it and these different device may need to run different code. That’s why an appivo-application can have several deviceprofiles. A deviceprofile is the collection of code required for a certain type of device when being connected to your application.

The deviceprofile contains a set of event-handlers as the programming model for a device is strictly event-based. The platform emits a few fundamental events – such as App.Start and App.Stop – as you might guess these events are emitted when the application starts and stops, on the device that is. Typically you will initialize datastructures and features when the app starts and then clean everything up when it stops.

Devices can also have timers that emit “tick”-events according to a schedule that you determine, this way you can for instance collect data from a sensor at a regular interval. The device may also “listen” for messages being received on messaging-topics – this allows the device to interact with the part of your application running in the cloud, as well as other devices of course.

Devices may also make use of various plugins, there are plugins for interfacing with hardware components  such as I²C, SPI and GPIO – but that’s not all, there is also a plugin for controlling an embedded chrome-browser which can be used to open up web-based user-interfaces that are also part of your application. This makes it very easy to build a digital signage system that can be used with a regular TV.

The DeviceContext API

The DeviceContext is the main interface when interacting with the device. Through it you can get access to hardware-features and general functionality. Notice that when interacting with the database this API is asynchronous and related methods return a Promise. This section of the document provides a description of the DeviceContext API:

MethodArgumentsDescription
logmessage (string)Logs a message to the application log at INFO-level
loglevel (string – TRACE, DEBUG, INFO, WARN, ERROR)
message (string)
Logs a message to the application log at the specified level
setDatakey (string)
value (anything)
scope (optional string – GLOBAL, APP, PROFILE, LOCAL)
Stores a key/value-pair on the device within the specified scope. GLOBAL means that the key is available in any app running on the device, APP means it is available in any device-profile belonging to this app, PROFILE means it is available only within the current device-profile and LOCAL is the same as PROFILE but not persistent (i.e. will not survive and app-restart or device-reboot).
getDatakey (string)Gets the value of the given key
clearDatakey (string)Removes the value for the given key
sleepmilliseconds (integer)
nanoseconds (optional integer)
Sleeps for the given amount of time
getApplianceGets a record that describes the local appliance
getMilliTimeGets the time in ms since 1970-01-01
getModulemodule (string)Gets a handle to the module with the given name
getUserGets the current user
createRecordmodel (model/string)
data (map/object) attribute-data
Create a Record of the given model with the provided values. Does NOT write it to the database.
createrecord (record/object)Returns a promise which will resolve to newly created Record upon success
udaterecordReturns a promise which will resolve to the updated Record upon success
getmodel (string/object) model or name of model
ID (string/ID) ID of record to get
Returns a promise which will resolve to the requested Record
deletemodel (string/object) model or name of model)
ID (string/ID) ID of record to get
Returns a promise which will resolve to true if record was successfully deleted
queryquery (string) query in ASQL or #query-name
params (object/map) query-parameters
Returns a promise which will resolve to the queried Records in the form of an array
publishtopic (string) topic to publish message to
message (map/object) message-payload
headers (map/object) optional headers
Publishes a message to the given topic

Examples

1. Creating a record and storing it in the database.

Note: in this example my SensorValue-model has a relationship to the appliance, so I populate the “appliance_id”-attribute with the appliance-ID.

var sensorData = 7;
var appliance = context.getAppliance();
var record = context.createRecord("SensorValue", {
   "appliance_id": appliance.id,
   "Value": sensorData
});
context.create(record);

2. Getting a record from the database

context.get("Sensor", sensorId).then(function(record) {
   context.log("Got record from database " + record.id);
});

3. Executing a query

context.query("#MyQuery", {
   "threshold": 100
}).then(function(records) {
   for (var i = 0; i < records.length; i++) {
      var record = records[i];
      context.log("Got record " + i + " with id " + record.id);
   }
});

4. Publish a message

context.publish("#mytopic", {
   value: 10,
   status: "OPEN"
});

5. Storing data locally

var counter = compute();
context.setData("counter", counter, "APP");

And retrieving it at a later time:

var counter = context.getData("counter");

The GPIO Module

MethodArgumentsDescription
getPinpinName (string) – A provisioned GPIO pin (e.g. “GPIO 0”)Gets the instance of the GPIO pin
provisionPinoptions (object) –{ pin: string – GPIO pin name (e.g. “GPIO 0”), mode: string – INPUT, OUTPUT, INPUT_OUTPUT }Provisions and returns a GPIO pin, if the pin has already been provisioned, it will just be returned.
setValuepinName (string) – A provisioned GPIO pin (e.g. “GPIO 0”)
value (boolean)
Sets the value of the specified pin (no operation on input pin)
getValuepinName (string) – A provisioned GPIO pin (e.g. “GPIO 0”)Returns a boolean representing the current state of the specified pin

Examples

//Make GPIO pin 0 blink 
context.getModule("gpio").getPin("GPIO 0").blink(500);

GPIO Pin

MethodArgumentsDescription
setValuevalue (boolean)Sets the value of the pin (no operator for input pin)
getValueGets the value of the pin

GPIO Input Pin

Inherits all methods from GPIO Pin

MethodArgumentsDescription
isHighReturns true if the input pin state is high
isLowReturns true if the input pin state is low
addListenerlistener (function) – receives 1 argument with methods getState and getEdgeAdds a state listener to the pin. Returns the pin itself

GPIO Output Pin

Inherits all methods from GPIO Pin

MethodArgumentsDescription
blinkdelay (number)
duration (optional number)
Toggles the pin back and forth between high and low staying in one state for delay ms and running for duration (infinite if not specified)
pulsedelay (number)Pulses the pin high for delay ms
pulseLowdelay (number)Pulses the pin low for delay ms
addListenerlistener (function) – receives 1 argument with methods getState and getEdgeAdds a state listener to the pin. Returns the pin itself
toggleToggles the pins state (pin.state = !pin.state)
highSets the pin high
lowSets the pin low
stopStops any ongoing pulse or blinking. Is called by all methods except getValue internally to make behaviour predictable

GPIO Input/Output Pin

Inherits all methods from GPIO Pin

MethodArgumentsDescription
stopStops any ongoing pulse or blinking
setModeInputCalls stop and sets the pin to input mode
setModeOutputCalls stop and sets the pin to output mode
getModeReturns the current mode of the pin (“INPUT”, “OUTPUT”)
getValueCalls setModeInput then returns the current state of the pin.
setValueCalls setModeOutput then set the current state of the pin.
isHighCalls setModeInput then returns if the pin state is high.
isLowCalls setModeInput then returns if the pin state is low.
addListenerlistener (function) – receives 1 argument with methods getState and getEdgeAdds a state listener to the pin. Returns the pin itself
pulsedelay (number)Calls setModeOutput then pulses the pin high for delay ms
toggleCalls setModeOutput then toggles the pins state (pin.state = !pin.state)
highCalls setModeOutput then sets the pin high
lowCalls setModeOutput then sets the pin low
stopStops any ongoing pulse or blinking. Is called by all methods except getValue internally to make behaviour predictable

The I2C Module

MethodArgumentsDescription
getDevicebus (number)
address (number)
Gets the i2c device with the specified address on the bus (on raspberry pi the only available bus i 1)

Examples

// Get the i2c module
var i2c = context.getModule("i2c");

// Get the device on bus 1, address 0x29
var device = i2c.getDevice(1, 0x29);

// Write 0x30 to the internal register address 0x8A
device.write(0x8A, 0x30);

I2C Device

MethodArgumentsDescription
readaddress (optional number)
size (optional number)
Reads from the internal register(s) on the i2c device. Returns a number if size is not defined and an array if it is.
writeaddress (optional number)
data (number | array<number>)
Write to the internal register(s) on the i2c device.
closeRelease the device reference

The SPI Module

MethodArgumentsDescription
getDevicecs (number)
channel (number)
Gets the spi device with the specified cs connection on the channel (for most devices channel is not needed so can just be 0)

Examples

// Get the SPI-module
var spi = context.getModule("spi");

// Get the device on CS 0
var device = spi.getDevice(0, 0);

//Write 0x0A, 0x0B, 0xC to the device using CS 0 and store the result (2 bytes)
var bytes = device.write([0x0A, 0x0B, 0x0C]);

//assemble the 2 bytes into a single 16-bit unsigned integer (assuming big endian byte order)
var uInt16 = bytes[0] << 8 | bytes[1];

SPI Device

MethodArgumentsDescription
writedata (array<number>)Writes bytes to the spi device and returns the response.
writedata (string)
charset (string)
Writes a string to the device and returns the response