Getting Started

TempoIQ is a cloud service for monitoring, storing, and analyzing sensor data.

Connect your devices and sensors, and stream in data in realtime. TempoIQ watches all incoming data for anomalies and sends you push alerts (webhook, email, etc) right when something happens. We also store all of your sensor data, and provide flexible APIs to look back and do analyses like summaries, rollups, aggregations, and interpolations.

Organizing your data

You’ve got devices and sensors connected all over the world, measuring things and generating time series data non-stop. TempoIQ helps you organize your raw data by tagging your devices and sensors.

It’s really easy: each sensor stores a time series of numeric values. Group sensors together in a device.

_images/device_model.png

Some examples of devices and sensors you might have in your application:

  • Device: Thermostat
    • Sensors: Temperature, Humidity
  • Device: Solar Inverter
    • Sensors: DC Power, AC Power, Voltage, Current

After you’ve grouped your sensors into devices, you can further organize your devices and sensors by tagging them with attributes (key/value pairs). You could add a tag to a device like, “location=home”, or you could add a tag to a sensor like “unit=celsius”.

Attributes are very flexible, and you can create hierarchies between devices or arbitrary grouping. This becomes very powerful when running queries later. You could ask a question like, “give me the max temperature in location=home on an hourly basis for the last week”

Your raw data might not have an obvious mapping to this model. Don’t worry, we’re here to help. See the Organize your Sensors page for a deeper look at how to organize your sensor data.

Example

If you haven’t done so already, contact us for a test drive account.

For your first device, create a thermostat device with two sensors: temperature and humidity. The device key is the main identifier for the device. It can be anything you’d like, as long as it’s unique. Sensor keys just need to be unique within their device.

Like most TempoIQ functions, you can create a device via the web UI or the API. From the main console, go to Device List -> Create Device:

_images/create_device.png

To create a device through the API, start by downloading one of our SDKs. First you will need to instantiate a client object with your individual host, key, and secret. These can be found on the management console. You can also use our HTTP API directly with curl or from any language which supports HTTPS requests.

  • import tempoiq.session
    
    client = tempoiq.session.get_session(
                                "https://your-url.backend.tempoiq.com",
                                "your-key",
                                "your-secret")
    
  • var tempoiq = require('tempoiq');
    var creds = {
      key: "your-key",
      secret: "your-secret",
      hostname: "your-hostname"
    };
    var client = tempoiq.Client(creds.key, creds.secret, creds.hostname);
    return client;
    
  • require 'tempoiq/client'
    client = TempoIQ::Client.new("my-key", "my-secret", "my-company.backend.tempoiq.com")
    
  • // import com.tempoiq.*;
    
    InetSocketAddress host = new InetSocketAddress("my-company.backend.tempoiq.com", 443);
    Credentials credentials = new Credentials("my-key", "my-secret");
    Client client = new Client(credentials, host, "https");
    
  • using TempoIQ;
    var client = new Client("my-key", "my-secret",
                            "my-company.backend.tempoiq.com");
    
  • curl -X $METHOD -u $KEY:$SECRET "https://$BACKEND/$ENDPOINT" -d 'request body goes here'
    

Then, use the client object to create the device:

  • from tempoiq.protocol.device import Device
    from tempoiq.protocol.sensor import Sensor
    import tempoiq.response
    
    temp_sensor = Sensor("temperature")
    humid_sensor = Sensor("humidity")
    
    device = Device("thermostat.0",
                    attributes={"model": "v1"},
                    sensors=[temp_sensor, humid_sensor])
    response = client.create_device(device)
    
    if response.successful != tempoiq.response.SUCCESS:
        print("Error creating device!")
    
  • client.createDevice(new tempoiq.Device("thermostat.0",
      {
        name: "Test Thermostat",
        attributes: {
          model: "v1"
        },
        sensors: [
          new tempoiq.Sensor("temperature"),
          new tempoiq.Sensor("humidity")
        ]
      }),
      function(err, device) {
        if (err) throw err;
        // Successfully created device
      }
    );
    
  • device = client.create_device('thermostat.0', '',
                                  'model' => 'v1',
                                  TempoIQ::Sensor.new('temperature'),
                                  TempoIQ::Sensor.new('humidity'))
    
  • // import java.util.*;
    // import com.tempoiq.*;
    // import org.joda.time.*;
    
    // create device attributes
    Map<String, String> attributes = new HashMap<String, String>();
    attributes.put("model", "v1");
    
    // create sensors
    Sensor sensor1 = new Sensor("temperature");
    Sensor sensor2 = new Sensor("humidity");
    List<Sensor> sensors = new ArrayList<Sensor>();
    sensors.addAll(Arrays.asList(sensor1, sensor2));
    
    // create device with key "thermostat.0" with attributes and sensors
    Device device = new Device("thermostat.0", "", attributes, sensors);
    
    // store in TempoIQ
    Result<Device> result = client.createDevice(device);
    
    // Check that the request was successful
    if(result.getState() != State.SUCCESS) {
      System.out.format("Error creating device! %s", result.getMessage()).println();
    }
    
  • attributes = new Dictionary<String, String>();
    attributes.Add("model", "v1");
    
    sensor1 = new Sensor("temperature");
    sensor2 = new Sensor("humidity");
    sensors = new List<Sensor> {sensor1, sensor2};
    
    device = new Device("thermostat.0", "", attributes, sensors)
    
    client.CreateDevice(device);
    
  • curl -X "POST" -u $KEY:$SECRET "https://$BACKEND/v2/devices/" -d '
       {"key": "thermostat.0",
         "attributes": {"model": "v1"},
         "sensors": [
           {"key": "temperature"},
           {"key": "humidity"}
         ]
       }'
    >>
    {"key":"thermostat.0","name":"","attributes":{"model":"v1"},"sensors":
    [{"key":"temperature","name":"","attributes":{}},{"key":"humidity","name":"",
    "attributes":{}}]}
    

Note: TempoIQ will automatically create devices and sensors as you write data, but it’s still helpful to know how to explicitly create devices.

Data collection

_images/datapoint_model.png

Each sensor has associated data in the form of a time series of numeric values. Our data collection APIs enable you to stream or batch write this sensor data. Then you can visualize, analyze, or transform the data in TempoIQ.

If your devices have direct access to the internet, they can write their data directly to TempoIQ, or you can use a gateway or cloud server to aggregate and write the data.

Example

In the example above, you created a device ‘thermostat.1’ which has two sensors, ‘temperature’ and ‘humidity’. Now try writing some data points to these sensors. Each point consists of a timestamp and a value. It’s possible to write multiple data points to one or more sensors or devices in a single API call:

  • import datetime
    from tempoiq.protocol.point import Point
    
    t1 = datetime.datetime(2015, 1, 1, 0, 0)
    t2 = t1 + datetime.timedelta(minutes=5)
    
    device_data = {"temperature": [Point(t1, 68), Point(t2, 67.5)],
                   "humidity": [Point(t1, 71.5), Point(t2, 70.0)]}
    
    response = client.write({"thermostat.0": device_data})
    
    if res.successful != tempoiq.response.SUCCESS:
        print("Error writing data!")
    
  • var device = "thermostat.0";
    var t1 = new Date("2015-01-01T00:00:00Z");
    var t2 = new Date("2015-01-01T00:00:05Z");
    
    var data = new tempoiq.BulkWrite();
    
    data.push(device, "temperature",
              new tempoiq.DataPoint(t1, 68));
    data.push(device, "temperature",
              new tempoiq.DataPoint(t2, 67.5));
    data.push(device, "humidity",
              new tempoiq.DataPoint(t1, 71.5));
    data.push(device, "humidity",
              new tempoiq.DataPoint(t2, 70));
    
    client.writeBulk(data, function(err) {
        if (err) throw err;
    });
    
  • // import java.util.*;
    // import com.tempoiq.*;
    // import org.joda.time.*;
    
    // create datapoint at 2015-01-01T00:00:00.000Z for sensors temperature and humidity
    DateTime dt1 = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeZone.UTC);
    Map<String, Number> points1 = new HashMap<String, Number>();
    points1.put("temperature", 68);
    points1.put("humidity", 71.5);
    MultiDataPoint mp1 = new MultiDataPoint(dt1, points1);
    
    // create another datapoint, five minutes later, at 2015-01-01T00:05:00.000Z for sensors temperature and humidity
    DateTime dt2 = dt1.plus(Period.minutes(5));
    Map<String, Number> points2 = new HashMap<String, Number>();
    points2.put("temperature", 67.5);
    points2.put("humidity", 70.0);
    MultiDataPoint mp2 = new MultiDataPoint(dt2, points2);
    
    // Store datapoints in TempoIQ
    Device device = new Device("thermostat.0");
    Result<WriteResponse> result = client.writeDataPoints(device, Arrays.asList(mp1, mp2));
    
    // Check that the request was successful
    if(result.getState() != State.SUCCESS) {
      System.out.format("Error writing data! %s", result.getMessage()).println();
    }
    
  • curl -X "POST" -i -u $KEY:$SECRET "https://$BACKEND/v2/write" -d '
      {
        "thermostat.0": {
          "temperature": [
            {"t": "2015-01-05T00:00:00Z", "v": 68},
            {"t": "2015-01-05T00:05:00Z", "v": 67.5}
          ],
          "humidity": [
            {"t": "2015-01-05T00:00:00Z", "v": 71.5},
            {"t": "2015-01-05T00:05:00Z", "v": 70.0}
          ]
        }
      }'
    

Currently, it’s not possible to write arbitrary sensor data via the web UI. However, we do have a demo where TempoIQ can collect volume data from your computer’s microphone. Check out the demo here.

Building your app

_images/apps_diagram.png

Regardless of whether your app needs to analyze, alert on, or visualize your sensor data, TempoIQ can help. The Applications section goes into much more detail, but to start, let’s retreive the last hour of data from one device to be graphed in your application.

Example

Read the last hour of data from the “thermostat.0” device. In the web UI, Open the Data Visualization app. Select the device with key “thermostat.0”:

_images/viz_select.png

Specify a time range of the last hour, and click save to run the query:

_images/viz_result.png

You will see the data points for the selected sensors plotted on the graph. Cool!

Our libraries provide an analagous interface for reading historical data. The result is a list of points, which you can then visualize with a graphing library of your choice:

  • from tempoiq.protocol.device import Device
    from tempoiq.protocol.sensor import Sensor
    
    result = client.query(Sensor) \
                   .filter(Device.key == "thermostat.0") \
                   .read(start=datetime.datetime(2015, 1, 1),
                         end=datetime.datetime(2015, 1, 2))
    
    for row in result.data:
        for ((device, sensor), value) in row:
            print(row.timestamp, device, sensor, value)
    
  • var selection = {
      devices: {
        key: "thermostat.0"
      }
    };
    var start = new Date("2015-01-01T00:00:00Z");
    var end = new Date("2015-01-01T01:00:00Z");
    
    client.read(selection, start, end, null, function(err, data) {
      if (err) throw err;
      data.forEach(function(row) {
        var timestamp = row.ts;
        var values = [];        // List of sensor values at a timestamp
        for (var device in row.values) {
            for (var sensor in row.values[device]) {
                values.push(row.values[device][sensor]);
            }
        }
      });
    });
    
  • // import java.util.*;
    // import com.tempoiq.*;
    // import org.joda.time.*;
    
    // Set up the time range to read [2015-01-01, 2015-01-02)
    DateTime start = new DateTime(2015, 1, 1, 0, 0, 0, 0, DateTimeZone.UTC);
    DateTime end = new DateTime(2015, 1, 2, 0, 0, 0, 0, DateTimeZone.UTC);
    
    Device device = new Device("thermostat.0");
    Selection selection = new Selection()
      .addSelector(Selector.Type.DEVICES, Selector.key(device.getKey()));
    
    Cursor<Row> cursor = client.read(selection, start, end);
    for(Row row : cursor) {
      System.out.format("timestamp %s, temperature: %f, humidity: %f",
            row.getTimestamp(),
            row.getValue("thermostat.0", "temperature"),
            row.getValue("thermostat.0", "humidity")).println();
    }
    
  • curl -X GET -u $KEY:$SECRET "https://$BACKEND/v2/read/" -d '
      {
        "search": {
          "select": "sensors",
          "filters": {
            "devices": {
              "key": "thermostat.0"
            }
          }
        },
        "read": {
          "start": "2015-01-01T00:00:00.000Z",
          "stop": "2015-01-02T00:00:00.000Z"
        }
      }'
    >>
    {
      "data": [
        {
          "t": "2015-01-01T00:00:00.000Z",
          "data": {
            "thermostat.0": {
              "humidity": 71.5,
              "temperature": 68
            }
          }
        },
        {
          "t": "2015-01-01T00:05:00.000Z",
          "data": {
            "thermostat.0": {
              "humidity": 70.1,
              "temperature": 67.5
            }
          }
        }
      ]
    }
    

Next steps

This guide just scratches the surface of TempoIQ’s capabilities. Read on to learn more about Organizing your Sensors, Collecting your Data, and Building your App.