Flare API
This document describes the Flare API, as well as client libraries for various platforms that can connect to it:
- JavaScript: flare.js
- Swift: FlareManager.swift
- Java: FlareManager.java
- Python: flare.py
GET /environments/123
GET /environments/123/zones
Click one of the languages above for detailed information about developing with that language.
You'll notice four tabs in the column to the right. Click "API" to see the raw REST or Socket.IO API call that you can call on the platform of your choice. Click on JavaScript, Swift or Java to see an example of how to call the API using a client library.
In most client libraries, the functions that call the Flare REST API run asynchronously. The functions return immediately after performing a request. The last argument to each of these functions is a block of code that will be called with the parsed response when it is available.
- JavaScript: the last argument is an anonymous function that takes a single object or an array of objects.
- Swift: the last argument is a closure that takes either a JSONDictionary or a JSONArray.
- Java: the last argument is a lambda, either a FlareManager.Handler that takes a JSONObject or a FlareManager.ListHandler that takes an ArrayList
. See the Developing with Java page for information on adding support for Java 8 lambda expressions to Android. - Python: the functions run synchronously and return the result.
Console
If you have a Flare server running, you can try out these APIs in realtime using the API Console. (Substitute the name of your server in the link if your server is not running on localhost.)
Constructor
Creates a FlareManager object.
(Not used in JavaScript or Python.)
Connect
Connects to the server to send and receive Socket.IO messages. Not necessary for REST messages, which are stateless.
(Not used in JavaScript or Python, as the client stays connected to the server.)
Disconnect
Disconnects from the server.
If apps on your mobile platform are put to sleep when they are in the background, it may not be possible for them to receive notifications. If that is the case, then it would be better to disconnect the socket before entering the background (which will unsubscribe automatically), and to reconnect and subscribe again when the app returns to the foreground.
(Not used in JavaScript or Python, as the client stays connected to the server.)
Environments
List environments
GET /environments
GET /environments?latitude={latitude}&longitude={longitude}
GET /environments?key={key}&value={value}
Gets a list of all environments.
Params can include the following:
- If latitude and longitude are specified, gets a list of environments whose geofence contains the given point. The geofence of each environment includes all points within a particular distance from a point on earth.
- If key and value are specified, returns environments whose data objects contain the given key/value pair.
New environment
POST /environments
Creates a new environment from the template.
Get environment
GET /environments/{environment_id}
Gets an environment.
Update environment
PUT /environments/{environment_id}
Updates an environment. The message can contain just the properties of the object to be updated.
Delete environment
DELETE /environments/{environment_id}
Deletes an environment.
Zones
List zones
GET /environments/{environment_id}/zones
GET /environments/{environment_id}/zones?x={x}&y={y}
GET /environments/{environment_id}/zones?key={key}&value={value}
Gets a list of all zones in the environment.
Params can include the following:
- If x and y coordinates are specified, returns a list of all zones in the environment containing the given point.
- If key and value are specified, returns zones whose data objects contain the given key/value pair.
New zone
POST /environments/{environment_id}/zones
Creates a new zone from the template.
Get zone
GET /environments/{environment_id}/zones/{zone_id}
Gets a zone.
Update zone
PUT /environments/{environment_id}/zones/{zone_id}
Updates a zone. The message can contain just the properties of the object to be updated.
Delete zone
DELETE /environments/{environment_id}/zones/{zone_id}
Deletes a zone.
Things
List things
GET /environments/{environment_id}/zones/{zone_id}/things
GET /environments/{environment_id}/zones/{zone_id}/things?x={x}&y={y}&distance={distance}
GET /environments/{environment_id}/zones/{zone_id}/things?key={key}&value={value}
Gets a list of all things in a zone.
Params can include the following:
- If x, y and distance values are specified, returns a list of all things in the zone that are within the given distance from the given point.
- If key and value are specified, returns things whose data objects contain the given key/value pair.
New thing
POST /environments/{environment_id}/zones/{zone_id}/things
Creates a new thing from the template.
Get thing
GET /environments/{environment_id}/zones/{zone_id}/things/{thing_id}
Gets a thing.
Get thing data
GET /environments/{environment_id}/zones/{zone_id}/things/{thing_id}/data
Gets all data values for a thing by making a REST call.
You can also get the data for a thing using the getData Socket.IO call.
Get thing data value
/environments/{environment_id}/zones/{zone_id}/things/{thing_id}/data/{key}
Gets a single data value for a thing.
Get thing position
/environments/{environment_id}/zones/{zone_id}/things/{thing_id}/position
Gets the position for a thing by making a REST call.
You can also get the position of a thing using the getPosition Socket.IO call.
Update thing
PUT /environments/{environment_id}/zones/{zone_id}/things/{thing_id}
Updates a thing. The message can contain just the properties of the object to be updated.
Delete thing
DELETE /environments/{environment_id}/zones/{zone_id}/things/{thing_id}
Deletes a thing.
Devices
List devices
GET /environments/{environment_id}/devices
GET /environments/{environment_id}/devices?x={x}&y={y}&distance={distance}
GET /environments/{environment_id}/devices?key={key}&value={value}
Gets a list of all devices in the environment.
Params can include the following:
- If x, y and distance values are specified, returns a list of all devices in the environment that are within the given distance from the given point.
- If key and value are specified, returns devices whose data objects contain the given key/value pair.
New device
POST /environments/{environment_id}/devices
Creates a new device from the template.
Get device
GET /environments/{environment_id}/devices/{device_id}
Gets a device.
Get device data
GET /environments/{environment_id}/devices/{device_id}/data
Gets all data values for a device by making a REST call.
You can also get the data for a device using the getData Socket.IO call.
Get device data value
/environments/{environment_id}/devices/{device_id}/data/{key}
Gets a single data value for a device.
Get device position
/environments/{environment_id}/devices/{device_id}/position
Gets the position for a device by making a REST call.
You can also get the position of a device using the getPosition Socket.IO call.
Update device
PUT /environments/{environment_id}/devices/{device_id}
Updates a device. The message can contain just the properties of the object to be updated.
Delete device
DELETE /environments/{environment_id}/devices/{device_id}
Deletes a device.
Socket.IO (client to server)
These messages are sent from the client to the server using Socket.IO.
Each Flare Socket.IO API applies to one Flare object, such as an environment, zone, thing or device.
- JavaScript: the first argument to these functions is an object with a single property containing the ID of a Flare object as a string, e.g. {environment:"123"}, {zone:"456"}, {thing:"789"}, or {device:"234"}.
- Swift/Java: the first argument to these functions is a subclass of a Flare object, such as Environment, Zone, Thing or Device.
When an application launches or a web page loads, it creates a socket and connects to the server. Each client can subscribe to one or more Flare objects to receive relevant messages about them. Clients can send a subscribe message to start receiving messages about an object, and later send an unsubscribe message to stop receiving messages about the object. The connection is stateful, so the server remembers which clients have subscribed to which objects. This prevents clients from receiving messages about objects that they don't care about.
Clients apps can have a socket connection that subscribes to one or more objects. Typically, a client represents a single Flare object: a native app on a mobile phone can represent a device object, and a web app on a computer attached to a big screen could represent a thing. In each case, the app would normally subscribe to the object it represents when it starts up. It is not always necessary to unsubscribe, as closing a connection will unsubscribe automatically and the server will clean up its internal state.
Clients may also subscribe to other objects for a short time. For example, the app for a device may subscribe to a thing when the device is physically near to the thing, or when the user wants to interact with it. When the device is no longer near the thing or the user has finished interacting, then the app can unsubscribe from that thing. While devices can be notified when they are near or far from a thing, subscribing and unsubscribing is the responsibility of the app and is not automatic.
If apps on your mobile platform are put to sleep when they are in the background, it may not be possible for them to receive notifications. If that is the case, then it would be better to disconnect the socket before entering the background (which will unsubscribe automatically), and to reconnect and subscribe again when the app returns to the foreground.
Clients that subscribe to an object will not necessarily receive all messages about the object:
- When a client gets a data value for an object, a data message will be sent back to that client only.
- When a client changes a data value of an object, all other subscribers will receive a notification. However, the client that sent the original message will not receive a notification because it would be redundant; presumably it already has the latest information.
- Events that originate from the server (as the result of an action, or as a side effect of a device's position changing) will be sent to all subscribers.
Console
If you have a Flare server running, you can try out these APIs in realtime using the Socket.IO Console. (Substitute the name of your server in the link if your server is not running on localhost.)
Subscribe
subscribe {environment:"123", "all": true}
subscribe {zone:"456", "all": false}
subscribe {thing:"789"}
subscribe {device:"234"}
Sent by the client when it wants to subscribe to an object.
Schema:
- environment | zone | thing | device: string (required)
- all: boolean (optional)
The client will receive notifications about the object, for example when a data value or the position is changed, or when an action is performed on the object (and not handled by the server).
The all flag is optional. If all is true, messages will also be broadcast to all of an environment's zones, things and devices; and to all of a zone's things.
Unsubscribe
unsubscribe {"zone": "456"}
Sent by the client when it wants to unsubscribe from an object.
Schema:
- environment | zone | thing | device: string
The client will no longer receive notifications about the object.
Note: It is not necessary to unsubscribe when the client app wants to receive notifications about an object until the connection is closed.
Get data
getData {"zone": "456"}
getData {"thing": "789", "key": "color"}
Sent by the client when it wants to get some or all data values for an object.
Schema:
- environment | zone | thing | device: string (required)
- key: string (optional)
The client will be sent a data message containing some or all data values for the object. If a key is included in the message, then only the corresponding key/value pair will be returned. Otherwise, all key/value pairs will be returned.
This is equivalent to calling the following REST APIs:
- /environments/{environment_id}/zones/{zone_id}/things/{thing_id}/data to get all data about a thing
- /environments/{environment_id}/zones/{zone_id}/things/{thing_id}/data/{key} to get a specific field
- /environments/{environment_id}/devices/{device_id}/data to get all data about a device
- /environments/{environment_id}/devices/{device_id}/data/{key} to get a specific field
An app can use the REST or Socket.IO interfaces for getting data, depending upon which is more convenient.
Set data
{"thing": "789", "key": "color", "value": "purple"}
{"thing": "789", "key": "volume", "value": 11, "sender":"234"}
Sent by the client when it wants to change a data value for an object.
Schema:
- environment | zone | thing | device: string
- key: string
- value: mixed
- sender: string (optional)
Other subscribers to the object will receive a data message with the key/value pair that has been changed.
Note: The client that sent the original setData message will not receive a notification because it would be redundant; presumably it already has the latest information.
A client representing a Flare object can optionally include its ID for logging purposes. When another object receives a data message, the sender's ID will be included.
Get position
getPosition {"device": "234"}
getPosition {"thing": "789"}
Sent by the client when it wants to get the position of a thing or device.
Schema:
- thing | device: string
This is equivalent to calling the following REST APIs:
- /environments/{environment_id}/zones/{zone_id}/things/{thing_id}/position to get the position for a thing
- /environments/{environment_id}/devices/{device_id}/position to get the position of a device
An app can use the REST or Socket.IO interfaces for getting data, depending upon which is more convenient.
Set position
setPosition {"thing": "789", "position": {"x": 1.2, "y": 2.3}}
setPosition {"device": "234", "position": {"x": 4.5, "y": 5.6}}
Sent by the client when it wants to change the position of an object.
Schema:
- thing | device: string
- position: object
- x: number
- y: number
- sender: string (optional)
Other subscribers to the object will receive a position message with the new position.
The client that sent the original setPosition message will not receive a notification because it would be redundant; presumably it already has the latest information.
When a device position changes, it may trigger one of the following messages:
- enter: when a device has moves inside a zone
- exit: when a device is no longer inside a zone
- near: when a device has become near to a thing
- far: when a device is no longer near to a thing
See the documentation below for those messages.
A client representing a Flare object can optionally include its ID for logging purposes. When another object receives a position message, the sender's ID will be included.
Perform action
performAction {"zone": "234", "action": "next", "sender":"234"}
Sent by the client when it wants to perform an action on an object. Actions are identified by strings.
Schema:
- environment | zone | thing | device: string
- action: string
- sender: string (optional)
The action can be handled by the server or the client. For the server to handle the action, a function with the name of the action should be defined in the file actions.js on the server. The function can interact with the specified object or other objects (by manipulating them directly), and may case other messages to be sent.
If the server does not handle the action, then a handleAction message (identical to the performAction message) will be sent to all subscribers of the object, including the sender. The client can then interact with the specified object or other objects (by sending more messages to the server).
Actions do not have input or output values, but they can operate on data values. For example, an action can optionally use one or more data values as input, and can optionally use one or more data values as output. For example, a "next" message could increment the "page" value, which would cause a data message to be sent to subscribers of the object.
You don't need to use an action to simply change a data value. You can use setData to set the value directly, and any subscribers for the object will be notified of the change.
A client representing a Flare object can optionally include its ID for logging purposes. When another object receives a handleAction message, the sender's ID will be included.
Socket.IO (server to client)
These messages are sent from the server to the client, usually in response to other messages that have been sent to the server. Depending upon the event that triggered the message, the could be sent to the sender of the original message, to all other subscribers of an object, or to all subscribers of an object (including the sender).
Generally the class that uses the FlareManager should implement these functions:
- In JavaScript, all callback functions are optional.
- In Swift, the delegate should implement the FlareManagerDelegate protocol. All callback functions are optional.
- In Java, the delegate should implement the FlareManager.Delegate interface. All callback functions are required.
- In Python, the delegate should inherit from the FlareDelegate class. All callback functions are optional.
See the platform-specific pages for detailed instructions on implementiong the callback functions.
Data
data {"zone": "456", "data": {"page": 3, "mood": "chill"}}
data {"thing": "789", "data": {"color": "red"}, "sender":"234"}
Sent by the server to a client who has requested the current data by sending a getData message, or to all other subscribers when a client has changed a data value by sending a setData message.
Schema:
- environment | zone | thing | device: string
- data: object
- sender: string (optional)
If a key was included in the getData message, then only the corresponding key/value pair will be returned. Otherwise, all key/value pairs will be returned.
If a sender ID was included in the setData message, then it will be included in the data message.
Position
position {"device": "234", "position": {"x": 2.3, "y": 3.4}}
Sent by the server to a client who has requested the current position by sending a getPosition message, or to all other subscribers when a client has changed the current position by sending a setPosition message.
Schema:
- thing | device: string
- position: object
- x: number
- y: number
- sender: string (optional)
If a sender ID was included in the setPosition message, then it will be included in the position message.
Enter
enter {"device": "234", "zone": "456"}
Sent by the server when a device has entered the perimeter of a zone, as a result of a setPosition call for the device. The message is sent to all subscribers of the device and all subscribers of the zone.
Schema:
- device: string
- zone: string
A device is only considered to be inside one zone at a time. If a device is inside the perimeter of two zones that overlap, the device may be considered to be inside one zone or the other. A zone, on the other hand, may have several devices that are inside it.
The device may continue to move around inside a zone. An enter message will only be sent when a device enters the zone, and an exit message will only be sent when the device leaves the zone.
Exit
exit {"device": "234", "thing": "789"}
Sent by the server when a device is no longer near to a thing, as a result of a setPosition call for the device. The message is sent to all subscribers of the device and all subscribers of the thing.
Schema:
- device: string
- zone: string
Near
near {"device": "234", "thing": "789", "distance": 0.91}
Sent by the server when a device has become near to a thing, as a result of a setPosition call for the device. The message is sent to all subscribers of the device and all subscribers of the thing. A device is considered near to a device when the diagonal distance is less than a certain threshold defined by the server (by default, 1 meter).
Schema:
- device: string
- thing: string
- distance: number
When a device and a thing are nearby, they can interact. Typically, the client representing the device can subscribe to the thing, and the client representing the thing can subscribe to the device.
A device is only considered to be near to one thing at a time, so if it is within the given threshold of several devices, it is considered to only be near to the closest one. A thing, on the other hand, may have several devices that are near it.
The device may continue to move around inside a circle around the thing defined by the minimum threshold. A near message will only be sent when a device enters the circle, and a far message will only be sent when the device leaves the circle (unless the device becomes closer to another thing).
The distance value in the near message is the distance between the device and the thing at the time that the server received a setPosition message that caused it to become near to the thing. If the client representing the thing subscribes to the device, then it can continue to receive position updates for the device as it moves around. It should check the ID of the object in the position message to know if it applies to the thing or a nearby device.
Far
far {"device": "234", "thing": "789"}
Sent by the server when a device is no longer near to a thing, as a result of a setPosition call for the device. The message is sent to all subscribers of the device and all subscribers of the thing.
Schema:
- device: string
- thing: string
When a device and a thing are no longer nearby, they may not want to interact anymore. Typically, the client representing the device can unsubscribe from the thing, and the client representing the thing can unsubscribe from the device.
Handle action
handleAction {"thing": "789", "action": "buy"}
Sent by the server to all subscribers of an object when a client has sent a performAction message, and the server did not handle the message. The client may then take any appropriate action.
Schema:
- environment | zone | thing | device: string
- action: string
- sender: string (optional)
If a sender ID was included in the setData message, then it will be included in the data message.
Object methods
These functions in the Swift framework and the Java library work with Flare objects.
Load environment
Asynchronously loads all zones and things for one environment, and then calls the handler.
Load environments
Asynchronously loads the complete environment / zone / thing / device hierarchy, and then calls the handler.
Get flare
Gets the up-to-date JSON for a Flare object from the server.
New flare
Creates a new Flare object on the server:
- If the flare is nil, creates an environment
- If the flare is an environment, creates a zone
- If the flare is a zone, creates a thing
Update flare
Updates the JSON for a Flare object on the server. The JSON object can contain a partial copy of the object, and only the included properties will be updated.
Delete flare
Deletes a Flare object on the server.
Add to index
Adds a new Flare object to the index. All objects should be added to the index so that the high-level functions that work with objects (near, far, etc.) can convert object IDs to objects.
Flare with name
Returns the Flare object in the list whose name matches the given string.
Flare for message
Given a message from the server, returns the object from the index with the given ID.
Environment for flare
Returns the environment for the given Flare object:
- Environment: returns the object itself
- Zone: returns the environment that contains the zone
- Thing: returns the environment chat contains the zone that contains the thing
- Device: returns the environment that contains the device
Get current device
Tries to get the saved device, otherwise creates a new device.
Get saved device
If a device object has previously been created in the current environment, gets the device info from the server and returns the device object.
New device object
Creates a new device object (using the default values specified in the tempalte) and saves its ID in the preferences.