To get started with Flare, you'll need to tell the server where things are in your environment.

Before you can do that, make sure that you've got a Flare server up and running. Note that you don't have to import the sample data, as we'll add some real data instead.

This document will first describe how to create Flare objects that describe your enviroment, and then tell you how you can add them to the Flare server.

Flare objects

As a recap from the architecture page, there are four types of Flare objects:

  • Environments model a space such as a building. They have latitude/longitude coordinates, a bounding rectangle, and a compass orientation of the coordinate system.
  • Zones are spacial divisions inside of an environment, and have a perimeter rectangle.
  • Things are interesting objects inside a zone. They can be displays, beacons, lights, or even things that don't have any electronics. Things have a location inside the environment's coordinate system.
  • User devices are transient, and can exist inside of an environment. For example, when a user brings their mobile phone into an environment, it can create a device object. This object may be automatically deleted after a period of time with no updates.

All Flare objects are stored in JSON format, and have a certain number of properties in common:

  • The "_id", a unique identifier assigned by the database when an object is created. (Note that it starts with an underscore.)
  • The name of the object.
  • A brief description of the object.
  • The date created, set when the object is created.
  • The date modified, updated each time the object is modified using the REST or Socket.IO API.
  • A data object, which acts as a key/value store for arbitrary JSON data (including strings, numbers, arrays, and objects).

There are several ways of working with data values:

  • All data values for an object are included whenever you read the object using the REST API.
  • There are specific REST APIs for reading the data object of a thing or device.
  • You can replace the entire data object using a PUT API call.
  • You can send a getData message using the Socket.IO API to request the current data values.
  • You can use a setData message to change a particular data value.
  • If you subscribe to an object, you will receive notifications whenever another client changes a data value.

Environments

{
    "name": "New York",
    "description": "Cisco New York, One Penn Plaza",
    "geofence": {
        "latitude": 40.751267,
        "longitude": -73.99229,
        "radius": 500
    },
    "perimeter": {
        "origin": {
            "x": -1,
            "y": -1
        },
        "size": {
            "height": 100,
            "width": 100
        }
    },
    "angle": 29,
    "data": {
        "uuid": "2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"
    }
}

An environment represents a physical location with a coordinate space. You should create one environment for each physical location where you will be using Flare. For example, if you will be using Flare for retail, then you should create one environment for each store.

Geofence

"geofence": {
    "latitude": 40.751267,
    "longitude": -73.99229,
    "radius": 500
}

Each environment has a geofence that defines a circle on the surface of the earth. A device can use its GPS to find its current location, and then ask the Flare server for the current environment. The server will respond with an environment if the location is within the geofence of any environment in the database.

The geofence is an object with latitude and longitude coordinates that define a point at the center of the circle, and a radius that defines the distance from the center to the perimeter in meters. For large buildings, make sure to make the radius large enough to include all the doors that the user may use to enter the space, as GPS does not work well indoors. (That's why there's Flare!)

To find the latitude and longitude of any location on earth, search for it on Google maps and then copy the latitude and longitude from the URL. For example, the location used in the example can be taken from this URL:

https://www.google.com/maps/place/One+Penn+Plaza/... @40.751267,-73.99229,17z/

Perimeter

{
"perimeter": {
    "origin": {
        "x": -1,
        "y": -1
    },
    "size": {
        "height": 100,
        "width": 100
    }
}

Each environment has a perimeter object that defines the coordinate space in the environment. This is a rectangle, normally measured in meters, that encloses the maximum extent of all zones and things inside the environment. The perimeter has an origin point (with x and y values) and a size rectangle (with width and height values).

The origin represents the coordinates of the point in the environment with the smallest possible x and y values. If you want to count from one corner of the environment using only positive coordinates, set the origin to (0,0). If you want to count from the center of the environment using positive or negative coordinates, set the origin to the coordiantes of one corner of the room, such as (-10,-10).

Normally the coordinate space is measured in meters, but it is relative so you could use feet instead if you prefer, as long as you are consistent.

Angle

"angle": 29

The environment also has an angle value that describes the orientation of the coordinate space. This is important for apps that will use a device's compass to indicate directions. If the Y-axis points North, then set the angle to 0. Otherwise, set the angle to the number of degrees between North and the Y-axis.

For example, in New York, the avenues of Manhattan do not point due North, but rather have a compass heading of about 29°. So if you were to create an environment inside of a rectangular building the size of a New York block, you would want to set the angle to 29. That way if a Flare app on a device was able to determine that a nearby thing was "above" the device in the coordinate space, it could point towards 29° to indicate the actual direction.

Data

"data": {
    "uuid": "2F234454-CF6D-4A0F-ADF2-F4911BA9FFA6"
}

Environments may have a data object for storing arbitrary JSON data, such as the uuid of beacons in the environment. See the Beacons page for more information.

Zones

{
    "name": "Open Space",
    "description": "The open space near the elevators",
    "perimeter": {
        "origin": {
            "x": 5,
            "y": 5
        },
        "size": {
            "height": 10,
            "width": 10
        }
    },
    "data": {
        "major": 2
    },
}

An environment should have one or more zones, which are logical groupings inside the environment that enclose groups of things. For example, in a retail store there could be a zone for each department.

Perimeter

"perimeter": {
    "origin": {
        "x": 5,
        "y": 5
    },
    "size": {
        "height": 10,
        "width": 10
    }
}

Each zone has a perimeter that defines a rectangle using the environment's coordinate space. The origin defines a point at one corner of the zone, and the size defines the size of the zone.

Data

"data": {
    "major": 2
}

Zones may have a data object for storing arbitrary JSON data, such as the major value of beacons in the zone. See the Beacons page for more information.

Things

{
    "name": "Southwest",
    "description": "Flare 1.3",
    "position": {
        "x": 1,
        "y": 1
    },
    "data": {
        "minor": 3
    }
}

A thing represents an interesting or relevant object at a particular position in the environment. All things are contained within a zone, which itself is contained by the environment. Things can be computing devices, connected "IoT" things, beacons, or even devices without any electronics at all. A thing could run a Flare client app, but it doesn't have to.

Position

"position": {
    "x": 1,
    "y": 1
}

Each thing has a position that represents the coordinates of the object in the environment's coordinate system. While all things are contained within a zone, the position indicates the distance from the (0,0) point of the environment. The position of a thing is typically fixed, but it can be changed with either the REST or the Socket.IO API.

Data

"data": {
    "minor": 3
}

Things may have a data object for storing arbitrary JSON data, such as the minor value of a thing that is a beacon. See the Beacons page for more information.

Devices

{
    "name": "My iPhone",
    "description": "iPhone 6 (32 GB)",
    "position": {
        "x": 3,
        "y": 1
    },
    "data": {
        "color": "red",
        "angle": 90,
        "mac": "69:6b:a6:11:9a:3e"
    }
}

A device object represents a user device, such as a computer, tablet, phone or watch. Device objects are unique to a particular environment, and are relatively short-lived.

You don't need to create device objects in advance, as apps will create device objects on-the-fly as needed. See the functions getCurrentDevice, getSavedDevice and newDeviceObject in the Swift or Java sample code.

Position

Devices have a position object that represents the current position of the device. This value may be updated frequently as the device moves around inside the environment.

  • If using beacons, the device would determine its own position by calculating the relative distance to nearby beacons at known locations. The device would then send a setPosition message to the Flare server, which can update other clients that have subscribed to the device, and send out proximity notifications.
  • If using CMX, the CMX server can send notifications to the Flare server when a device has moved. When the Flare server receives such a message, it can find the device by its MAC address and update its position. It will then send a notification to the device, and any other clients that have also subscribed to be notified, as well as proximity notifications.

Data

"data": {
    "color": "red",
    "angle": 90,
    "mac": "69:6b:a6:11:9a:3e"
}

Things may have a data object for storing arbitrary JSON data, such as the mac address which can be used by the Flare server to identify devices when receiving position updates from CMX.

Adding data

To get started with your own instance of the server, you'll need to add some data to the database by creating some environment, zone, thing, and device objects. You can do this in several ways.

Server import script

node import.js model.json

You can load data into Flare from a JSON file using the import.js script. This is an efficient way to load many objects in a single step. You can load the sample data from the model.json file included with the server to get started learning Flare. You can also make your own JSON file to import data about your own environments.

You can use node to run the import.js script. It takes the name of a JSON file as an argument. Use model.json to import the sample data, or you can write you own file and use the name of that file instead.

{
    "environments": [
        {
            "name": "My environment",
            "zones": [
                {
                    "name": "My zone",
                    "things": [
                        {
                            "name": "My thing",
                            ...
                        },
                        ...
                    ],
                    ...
                },
                ...
            ],
            "devices": [
                {
                    "name": "My device",
                    ...
                },
                ...
            ],
            ...
        },
        ...
    ]
}

The JSON file has a hierarchical outline of all environments, zones and things:

  • The top-level object has an environments array with environment objects.
  • Each environment has a zones array with zone objects.
  • Each zone has a things array with thing objects.
  • Environments may also include a devices array with device objects, if you wish to preload some devices for testing purposes.

It is not necessary to specify object IDs, as these will be assigned automatically when added to the database. The server will also automatically add the date created and date modified.

The environments, zones, things and devices arrays are only used for grouping objects together in the JSON file that is being imported. These arrays do not become part of the objects on the server. Instead, each object is stored separately in the database along with the ID of its parent object. Things also store the ID of the environment that contains the zone that the thing is in.

See the Beacons page for a more detailed example on importing information about all the beacons in an environment. Each beacon has uuid, major and minor values. The uuid is stored in the environment data, the major value is stored in the zone data, and the minor value is stored in the thing data.

Client import scripts

Each of the sample code platforms includes an import script that you can use to import the same kind of JSON file client-side. The script reads a JSON file like the one above and then calls the API.

The import tutorial walks you through these scripts, including example code for each of the supported languages.

To import your own data, you can:

  • modify the JSON file with a description of your own environments
  • modify one of the import scripts to connect to your own data source
  • write your own script in the language of your choice that calls the API

Web Explorer

You can use the Explorer web app, which is part of the sample code, to create objects using a web interface.

Mac Explorer

You can use the Explorer Mac app, which is part of the sample code, to create objects using a graphical interface.

The Explorer app is perhaps the easiest way to import or export data:

  • If you choose File > Import, you can import a JSON file.
  • If you choose File > Export, it will import all the current environments to a JSON file.

If you want to make bulk changes to your environments using a text editor, you can export your data, edit the file, and then re-import the data. Your changes will then be merged into the existing environments.

Explorer Import

Calling the API directly

You can call the API directly using your favorite tool, such as curl or poster. For example, here's a command to create a device:

curl --data "{\"data\":{\"color\":\"red\"},\"description\": \"iPhone 6 (32 GB)\",\"name\": \"My iPhone\",\"position\": {\"x\": 3,\"y\": 1}}" -H "Content-Type: application/json" http://localhost:1234/environment/123/devices

Make sure to specify the Content-Type using the -H flag, or it won't work. Also make sure to include the complete JSON object in quotation marks, with all quotation marks inside escaped with backslashes.

API Console

You can use the REST API Console to create objects using POST requests. When you connect to /api-console on the server, you'll see a list of all REST API calls that are available.

  1. Click the POST tab for one of the /environments, /zones, /things or /devices endpoints.
  2. Click on “Try it” to try calling the API.
  3. Under URI parameters, fill in the environment ID (for zones, things and devices) and zone ID field (for things only).
  4. Edit the sample message body with the info for the object you want to create. (You do not need to include the environment ID or zone ID in the body.)
  5. Click the POST button. You'll see the new object in the response.

API Console

Try it

Mongoimport

If you have exported some data from a previous installation using mongoexport, you can use mongoimport to import the data back again. See the documentation for those tools for more information.