Back to top

Whisker Labs API Reference

The Whisker Labs API provides programmatic access to data emitted by Whisker Labs sensor devices. The API adheres to the principles of REST and is accessible from any programming language that can speak HTTP.

The API is organized around a set of nouns: users, sources, streams, and time series. See below for the precise definitions and semantics of these abstractions.

Security

All API interactions must be encrypted by TLS/SSL. Any non-HTTPS API traffic will be rejected.

Authentication

All API interactions must be authenticated with an API key. Authentication occurs via HTTP Basic Auth. The API key is specified as the basic auth username without a password. e.g.

$ curl -X GET -u "abcdefghi123:" https://api.whskrlabs.com/streams

Note the trailing colon of the username:password pair, implying an empty password string.

It is extremely important that API keys be kept secret. Anyone with access to your key(s) can issue API requests on your behalf.

API key acquisition and use

API keys are generated during the user creation process (see POST /users endpoint, documented below). Successful requests to the POST /users endpoint result in a user object containing an API key. This API key must be provided within the authorization header of all subsequent requests for a given user.

There is currently no way provided to programmatically look up a user’s API key. This limitation is purposeful and helps ensure that keys are never mistakenly exposed. Thus it is extremely important to securely store the API key included in the POST /users response.

To authenticate HTTP requests as a Whisker Labs user, the API key value must be provided in a basic authorization header. Note that the API key value (and a blank password field) must be base64-encoded prior to inclusion within the header. For example, for an API key with value abcdefghi123:

$ echo "abcdefghi123:" | base64
YWJjZGVmZ2hpMTIzOgo=
$ curl -X GET -H "Authorization: Basic YWJjZGVmZ2hpMTIzOgo=" \
-H "Content-Type:application/json" \
https://api.whskrlabs.com/streams

On the command-line, one could alternatively use curl's -u option to specify the raw API key:

$ curl -X GET -u "abcdefghi123:" \
-H "Content-Type:application/json" \
https://api.whskrlabs.com/streams

Users

A Whisker Labs user is an individual who has access to the Whisker Labs API.

For the time-being, user creation is not supported by third-parties via the API. Please create users in the Whisker Labs data-plotter web application.

Users

Create a user
POST/users

Creates a user with a given email address and Amazon Cognito subject ID.

Example URI

POST https://api.whskrlabs.com/users
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "verification_key": "686BA77E",
  "email_address": "bill@bigblue.com"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "verification_key": {
      "type": "string",
      "description": "F81E-4D58-ADF4-DC0A790227F6 (string, optional) - The subject ID of a user record stored in Amazon Cognito"
    },
    "email_address": {
      "type": "string",
      "description": "The user's email address"
    }
  },
  "required": [
    "email_address"
  ]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "verification_key": "686BA77E",
  "email_address": "bill@bigblue.com",
  "user_id": 1583331,
  "api_key": "lsjgy4t0jnxv7vxqhi8dscdw7iqighu",
  "created_at": 1436900136000,
  "updated_at": 1436900136000,
  "groups": [
    {
      "group_id": 1,
      "display_name": "Big Blue"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "verification_key": {
      "type": "string",
      "description": "F81E-4D58-ADF4-DC0A790227F6 (string, optional) - The subject ID of a user record stored in Amazon Cognito"
    },
    "email_address": {
      "type": "string",
      "description": "The user's email address"
    },
    "user_id": {
      "type": "number",
      "description": "The unique ID of the user"
    },
    "api_key": {
      "type": "string",
      "description": "The user's API key"
    },
    "created_at": {
      "type": "number",
      "description": "The timestamp at which the user record was created, in seconds since epoch"
    },
    "updated_at": {
      "type": "number",
      "description": "The timestamp at which the user record was last updated, in seconds since epoch"
    },
    "groups": {
      "type": "array",
      "description": "An array of groups of which the user is a member"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "email_address",
    "user_id",
    "created_at",
    "updated_at",
    "groups"
  ]
}

User

Retrieve a user
GET/users{?verification_key,email_address}

Retrieves a user record by either their email address or the Parse object ID associated with their Whisker Labs user account.

Exactly one of the verification_key or email_address query parameters must be provided. User objects returned by this endpoint contain all user metadata fields except for read API key.

User objects returned by this endpoint contain all user metadata fields except for API key.

Example URI

GET https://api.whskrlabs.com/users?verification_key=686BA77E&email_address=bill@bigblue.com
URI Parameters
HideShow
verification_key
string (required) Example: 686BA77E

F81E-4D58-ADF4-DC0A790227F6 (string, optional) - The subject ID of a user record stored in Amazon Cognito

email_address
string (optional) Example: bill@bigblue.com

The user’s email address

Request
HideShow
Headers
Content-Type: application/json
Hub-Serial-Number: 0DF9B929-F934-4D4C-949E-879CC5F10227
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "verification_key": "686BA77E",
  "email_address": "bill@bigblue.com",
  "user_id": 1583331,
  "api_key": "lsjgy4t0jnxv7vxqhi8dscdw7iqighu",
  "created_at": 1436900136000,
  "updated_at": 1436900136000,
  "groups": [
    {
      "group_id": 1,
      "display_name": "Big Blue"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "verification_key": {
      "type": "string",
      "description": "F81E-4D58-ADF4-DC0A790227F6 (string, optional) - The subject ID of a user record stored in Amazon Cognito"
    },
    "email_address": {
      "type": "string",
      "description": "The user's email address"
    },
    "user_id": {
      "type": "number",
      "description": "The unique ID of the user"
    },
    "api_key": {
      "type": "string",
      "description": "The user's API key"
    },
    "created_at": {
      "type": "number",
      "description": "The timestamp at which the user record was created, in seconds since epoch"
    },
    "updated_at": {
      "type": "number",
      "description": "The timestamp at which the user record was last updated, in seconds since epoch"
    },
    "groups": {
      "type": "array",
      "description": "An array of groups of which the user is a member"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "email_address",
    "user_id",
    "created_at",
    "updated_at",
    "groups"
  ]
}

Sites

A site is a physical location. A data source is typically associated with a site, meaning that the source resides at the site and any relevant sensors are installed at the site. In practice, sites are homes where Whisker Labs sensors are installed.

Sites

Create a site
POST/sites

Example URI

POST https://api.whskrlabs.com/sites
Request
HideShow
Headers
Content-Type: application/json
Body
{
  "site_id": 385,
  "address_line1": "1611 Telegraph Ave",
  "address_line2": "Suite 400",
  "state": "CA",
  "zip_code": 94612,
  "city": "Oakland",
  "country": "US",
  "groups": [
    {
      "group_id": 1,
      "display_name": "Big Blue"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "site_id": {
      "type": "number",
      "description": "The unique ID of the site"
    },
    "address_line1": {
      "type": "string",
      "description": "First line of the site's street address"
    },
    "address_line2": {
      "type": "string",
      "description": "Second line of the site's street address"
    },
    "state": {
      "type": "string",
      "description": "State, province, or region in which the site resides"
    },
    "zip_code": {
      "type": "number",
      "description": "The ZIP or postal code in which the site resides"
    },
    "city": {
      "type": "string",
      "description": "City or Town in which the site resides"
    },
    "country": {
      "type": "string",
      "description": "Country code of the country in which the site resides"
    },
    "pre_installation_photo": {
      "type": "string",
      "description": "A URL of a photo of a breaker panel prior to installation of a Whisker Labs sensor"
    },
    "post_installation_photo": {
      "type": "string",
      "description": "A URL of a photo of a breaker panel after installation of a Whisker Labs sensor"
    },
    "ac_nameplate_photo": {
      "type": "string",
      "description": "A URL of a photo of the nameplate of an AC unit"
    },
    "heater_nameplate_photo": {
      "type": "string",
      "description": "A URL of a photo of the nameplate of a heating unit"
    },
    "groups": {
      "type": "array",
      "description": "An array of groups with which this site is associated"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "site_id",
    "groups"
  ]
}
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "site_id": 385,
  "address_line1": "1611 Telegraph Ave",
  "address_line2": "Suite 400",
  "state": "CA",
  "zip_code": 94612,
  "city": "Oakland",
  "country": "US",
  "groups": [
    {
      "group_id": 1,
      "display_name": "Big Blue"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "site_id": {
      "type": "number",
      "description": "The unique ID of the site"
    },
    "address_line1": {
      "type": "string",
      "description": "First line of the site's street address"
    },
    "address_line2": {
      "type": "string",
      "description": "Second line of the site's street address"
    },
    "state": {
      "type": "string",
      "description": "State, province, or region in which the site resides"
    },
    "zip_code": {
      "type": "number",
      "description": "The ZIP or postal code in which the site resides"
    },
    "city": {
      "type": "string",
      "description": "City or Town in which the site resides"
    },
    "country": {
      "type": "string",
      "description": "Country code of the country in which the site resides"
    },
    "pre_installation_photo": {
      "type": "string",
      "description": "A URL of a photo of a breaker panel prior to installation of a Whisker Labs sensor"
    },
    "post_installation_photo": {
      "type": "string",
      "description": "A URL of a photo of a breaker panel after installation of a Whisker Labs sensor"
    },
    "ac_nameplate_photo": {
      "type": "string",
      "description": "A URL of a photo of the nameplate of an AC unit"
    },
    "heater_nameplate_photo": {
      "type": "string",
      "description": "A URL of a photo of the nameplate of a heating unit"
    },
    "groups": {
      "type": "array",
      "description": "An array of groups with which this site is associated"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "site_id",
    "groups"
  ]
}

Site

Retrieve a site
GET/sites/{site_id}

Retrieves a single site. Requested site must be accessible with the API key in use.

Example URI

GET https://api.whskrlabs.com/sites/385
URI Parameters
HideShow
site_id
number (required) Example: 385

A unique identifier of a site

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "site_id": 385,
  "address_line1": "1611 Telegraph Ave",
  "address_line2": "Suite 400",
  "state": "CA",
  "zip_code": 94612,
  "city": "Oakland",
  "country": "US",
  "groups": [
    {
      "group_id": 1,
      "display_name": "Big Blue"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "site_id": {
      "type": "number",
      "description": "The unique ID of the site"
    },
    "address_line1": {
      "type": "string",
      "description": "First line of the site's street address"
    },
    "address_line2": {
      "type": "string",
      "description": "Second line of the site's street address"
    },
    "state": {
      "type": "string",
      "description": "State, province, or region in which the site resides"
    },
    "zip_code": {
      "type": "number",
      "description": "The ZIP or postal code in which the site resides"
    },
    "city": {
      "type": "string",
      "description": "City or Town in which the site resides"
    },
    "country": {
      "type": "string",
      "description": "Country code of the country in which the site resides"
    },
    "pre_installation_photo": {
      "type": "string",
      "description": "A URL of a photo of a breaker panel prior to installation of a Whisker Labs sensor"
    },
    "post_installation_photo": {
      "type": "string",
      "description": "A URL of a photo of a breaker panel after installation of a Whisker Labs sensor"
    },
    "ac_nameplate_photo": {
      "type": "string",
      "description": "A URL of a photo of the nameplate of an AC unit"
    },
    "heater_nameplate_photo": {
      "type": "string",
      "description": "A URL of a photo of the nameplate of a heating unit"
    },
    "groups": {
      "type": "array",
      "description": "An array of groups with which this site is associated"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "site_id",
    "groups"
  ]
}

Modify a site
PATCH/sites/{site_id}

Modifies a site according to an ordered set of modifications.

Request body must adhere to JSON patch format. For example, to set a site’s ZIP code:

[
  {
    "op": "replace",
    "path": "/zip_code",
    "value": 94619
  }
]

Example URI

PATCH https://api.whskrlabs.com/sites/385
URI Parameters
HideShow
site_id
number (required) Example: 385

A unique identifier of a site

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Body
[
  {
    "op": "replace",
    "path": "/medium",
    "value": "Hello, world!"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}
Response  204

Sources

A source is a logical representation of a Whisker Labs hub device.

Source namespacing

A source is uniquely identified by a 32-bit integer referred to as a source namespace. The most-significant 32 bits of a stream ID number are equal to the namespace of the stream’s source. So, a source “namespaces” the set of streams that it emits in the sense that the streams’ IDs are prefixed with the source namespace.

As an example, consider the stream ID 39756866534. In hexidecimal, the ID is 0x941b1a3e6. From this, we know that the source of the stream can be identified by the most-significant 32 bits, or 0x9, or simply 9 in decimal.

This results in the handy property that a stream’s source can be determined from its ID alone.

Clarification of core API abstractions

At this point it’s worth clarifying the semantics of the core abstractions used by the Whisker Labs API. Just as people are represented as users in the API, hub devices are represented logically as sources and the data emitted by the sensors attached to a hub are encapsulated within streams.

Put precisely, there is a one-to-one correpondence in the Whisker Labs API between hubs and sources, sensors and streams, and people and users.

Sources

List sources
GET/sources{?group_id,hub_serial_number}

Retrieves all sources to which the authenticated API key has access.

Access to data emitted by a given hub device is determined by the user’s group-membership and hub-ownership settings. In practice, a user can retrieve sources that a) they own or b) are associated with groups of which they are a member.

Source listings can be filtered by a group ID or hub serial number provided as query parameters.

  • group_id: Only sources which are assigned to the group with the given ID will be returned.

  • hub_serial_number: Only the source associated with the given hub serial number will be returned. When this query parameter is provided, the list in the response payload will contain either zero or one source object.

Example URI

GET https://api.whskrlabs.com/sources?group_id=1&hub_serial_number=0DF9B929-F934-4D4C-949E-879CC5F10227
URI Parameters
HideShow
group_id
number (optional) Example: 1

The ID of a group

hub_serial_number
string (optional) Example: 0DF9B929-F934-4D4C-949E-879CC5F10227

A UUID serial number of a hub device

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
[
  {
    "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10227",
    "soc_serial_number": "530MWBCT10400918",
    "wifi_mac_address": "ac:8f:12:d2:02:2b",
    "bluetooth_mac_address": "8f:93:e0:0b:22:7c",
    "api_key": "GJH55IPEMQYMG5TFA4G867JNNQJ2QSUH",
    "tunnel_port": 25000,
    "lifecycle_stage": "installed_at_customer_home",
    "site": {
      "site_id": 385,
      "address_line1": "1611 Telegraph Ave",
      "address_line2": "Suite 400",
      "state": "CA",
      "zip_code": 94612,
      "city": "Oakland",
      "country": "US",
      "groups": [
        {
          "group_id": 1,
          "display_name": "Big Blue"
        }
      ]
    },
    "source_namespace": 381947,
    "latitude": 37.8044,
    "longitude": 122.2708,
    "line_voltage": 120,
    "line_voltage_updated_at": 1436900136000,
    "customer_domain": "bigblue",
    "display_name": "My house",
    "created_at": 1436900136000,
    "streams": [
      {
        "stream_id": 32723748291,
        "source_namespace": 7,
        "created_at": 1436900136000,
        "channels": [
          {
            "channel_index": 0,
            "name": "Voltage",
            "unit_symbol": "V"
          }
        ],
        "sensor_device": {
          "sensor_serial_number": "21A055AA-F5C1-4200-B097-A8A4BAE126D2",
          "sensor_device_type": "tokay"
        },
        "display_name": "Consumption",
        "url": "/streams/723748291"
      }
    ],
    "owners": [
      {
        "verification_key": "686BA77E",
        "email_address": "bill@bigblue.com",
        "user_id": 1583331,
        "api_key": "lsjgy4t0jnxv7vxqhi8dscdw7iqighu",
        "created_at": 1436900136000,
        "updated_at": 1436900136000,
        "groups": [
          {
            "group_id": 1,
            "display_name": "Big Blue"
          }
        ]
      }
    ],
    "groups": [
      {
        "group_id": 1,
        "display_name": "Big Blue"
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Source

Retrieve a source
GET/sources/{source_namespace}

Retrieves a single source. Requested source must be accessible with the API key in use.

Example URI

GET https://api.whskrlabs.com/sources/381947
URI Parameters
HideShow
source_namespace
number (required) Example: 381947

A unique identifier of a source

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10227",
  "soc_serial_number": "530MWBCT10400918",
  "wifi_mac_address": "ac:8f:12:d2:02:2b",
  "bluetooth_mac_address": "8f:93:e0:0b:22:7c",
  "api_key": "GJH55IPEMQYMG5TFA4G867JNNQJ2QSUH",
  "tunnel_port": 25000,
  "lifecycle_stage": "installed_at_customer_home",
  "site": {
    "site_id": 385,
    "address_line1": "1611 Telegraph Ave",
    "address_line2": "Suite 400",
    "state": "CA",
    "zip_code": 94612,
    "city": "Oakland",
    "country": "US",
    "groups": [
      {
        "group_id": 1,
        "display_name": "Big Blue"
      }
    ]
  },
  "source_namespace": 381947,
  "latitude": 37.8044,
  "longitude": 122.2708,
  "line_voltage": 120,
  "line_voltage_updated_at": 1436900136000,
  "customer_domain": "bigblue",
  "display_name": "My house",
  "created_at": 1436900136000,
  "streams": [
    {
      "stream_id": 32723748291,
      "source_namespace": 7,
      "created_at": 1436900136000,
      "channels": [
        {
          "channel_index": 0,
          "name": "Voltage",
          "unit_symbol": "V"
        }
      ],
      "sensor_device": {
        "sensor_serial_number": "21A055AA-F5C1-4200-B097-A8A4BAE126D2",
        "sensor_device_type": "tokay"
      },
      "display_name": "Consumption",
      "url": "/streams/723748291"
    }
  ],
  "owners": [
    {
      "verification_key": "686BA77E",
      "email_address": "bill@bigblue.com",
      "user_id": 1583331,
      "api_key": "lsjgy4t0jnxv7vxqhi8dscdw7iqighu",
      "created_at": 1436900136000,
      "updated_at": 1436900136000,
      "groups": [
        {
          "group_id": 1,
          "display_name": "Big Blue"
        }
      ]
    }
  ],
  "groups": [
    {
      "group_id": 1,
      "display_name": "Big Blue"
    }
  ]
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "hub_serial_number": {
      "type": "string",
      "description": "A valid UUID"
    },
    "soc_serial_number": {
      "type": "string",
      "description": "A serial number of a Samsung ARTIK system-on-module"
    },
    "wifi_mac_address": {
      "type": "string",
      "description": "A MAC address of a hub's WiFi wireless card"
    },
    "bluetooth_mac_address": {
      "type": "string",
      "description": "A MAC address of a hub's bluetooth device"
    },
    "api_key": {
      "type": "string",
      "description": "A Whisker Labs device API key"
    },
    "tunnel_port": {
      "type": "number",
      "description": "An integer indicating the port number that the hub uses to establish an SSH tunnel with its configured tunnel server"
    },
    "lifecycle_stage": {
      "type": "string",
      "description": "The stage of the device lifecycle"
    },
    "site": {
      "type": "object",
      "properties": {
        "site_id": {
          "type": "number",
          "description": "The unique ID of the site"
        },
        "address_line1": {
          "type": "string",
          "description": "First line of the site's street address"
        },
        "address_line2": {
          "type": "string",
          "description": "Second line of the site's street address"
        },
        "state": {
          "type": "string",
          "description": "State, province, or region in which the site resides"
        },
        "zip_code": {
          "type": "number",
          "description": "The ZIP or postal code in which the site resides"
        },
        "city": {
          "type": "string",
          "description": "City or Town in which the site resides"
        },
        "country": {
          "type": "string",
          "description": "Country code of the country in which the site resides"
        },
        "pre_installation_photo": {
          "type": "string",
          "description": "A URL of a photo of a breaker panel prior to installation of a Whisker Labs sensor"
        },
        "post_installation_photo": {
          "type": "string",
          "description": "A URL of a photo of a breaker panel after installation of a Whisker Labs sensor"
        },
        "ac_nameplate_photo": {
          "type": "string",
          "description": "A URL of a photo of the nameplate of an AC unit"
        },
        "heater_nameplate_photo": {
          "type": "string",
          "description": "A URL of a photo of the nameplate of a heating unit"
        },
        "groups": {
          "type": "array",
          "description": "An array of groups with which this site is associated"
        },
        "document": {
          "type": "object",
          "properties": {},
          "description": "A JSON document serving as a flexible schema for additional metadata"
        }
      },
      "required": [
        "site_id",
        "groups"
      ],
      "description": "The site at which the hub device is installed"
    },
    "source_namespace": {
      "type": "number",
      "description": "The ID of the source"
    },
    "latitude": {
      "type": "number",
      "description": "The latitude of the source's installation site, if known"
    },
    "longitude": {
      "type": "number",
      "description": "The longitude of the source's installation site, if known"
    },
    "line_voltage": {
      "type": "number",
      "description": "The line voltage at the site at which the source originates"
    },
    "line_voltage_updated_at": {
      "type": "number",
      "description": "The timestamp at which the source's line voltage field was last updated, in milliseconds since epoch"
    },
    "customer_domain": {
      "type": "string",
      "description": "The name of the customer domain with which the source is associated"
    },
    "display_name": {
      "type": "string",
      "description": "A human-friendly name used to label the source"
    },
    "created_at": {
      "type": "number",
      "description": "The timestamp at which the source was created, in milliseconds since epoch"
    },
    "streams": {
      "type": "array",
      "description": "An array of streams that originate from the source"
    },
    "owners": {
      "type": "array",
      "description": "An array of users that own the hub"
    },
    "groups": {
      "type": "array",
      "description": "An array of groups that are associated with the hub"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "hub_serial_number",
    "streams",
    "owners",
    "groups"
  ]
}

Modify a source
PATCH/sources/{source_namespace}

Modifies a source according to an ordered set of modifications.

Request body must adhere to JSON patch format. For example, to set the line voltage of the site from which a source originates:

[
  {
    "op": "replace",
    "path": "/line_voltage",
    "value": true
  }
]

Or to update the latitude and longitude of the location at which a source’s originating hub is installed:

[
  {
    "op": "replace",
    "path": "/latitude",
    "value": 37.80
  },
  {
    "op": "replace",
    "path": "/longitude",
    "value": 122.27
  }
]

Example URI

PATCH https://api.whskrlabs.com/sources/381947
URI Parameters
HideShow
source_namespace
number (required) Example: 381947

A unique identifier of a source

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Body
[
  {
    "op": "replace",
    "path": "/medium",
    "value": "Hello, world!"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}
Response  204

Groups

A user can be a member of any number of groups. A group can represent any logical grouping of users, either to identify them as a specific type of user or as a member of an organization. For instance, a user may be in a) the “Homeowners” group to indicate that they own a home at which a Whisker Labs device is installed and b) the SolarCo group to indicate that they are a customer of SolarCo.

The following named groups identify types of users. The names can be passed as a query paramter to GET /groups to retrieve a group object.

  • Homeowners (display_name=Homeowners): Owners of a home at which a Whisker Labs sensor is installed

  • Installers (display_name=Installers): Personnel of a partner organization whose role is to install Whisker Labs sensors at customers’ homes

Groups

List groups
GET/groups{?display_name}

Retrieves all groups to which the authenticated API key has access. Members of the Whisker Labs group have access to all groups. Other users have access to the groups of which they are members.

Example URI

GET https://api.whskrlabs.com/groups?display_name=
URI Parameters
HideShow
display_name
string (optional) 

A human-friendly name used to label a group

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
[
  {
    "group_id": 1,
    "display_name": "Big Blue"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Sensors

A sensor is a device which emits data streams. A number of types of sensor devices are supported:

  • tokay: A Whisker Labs stick-on energy sensor. “Tokay” is the codename for the sensor hardware itself.

    {
        "sensor_device_type": "tokay",
        "sensor_serial_number": "21A055AA-F5C1-4200-B097-A8A4BAE126D2"
      }
  • virtual: A logical sensor device used to represent derived data streams. A derived data stream is one which contains data that is computed from other streams’ data. For example, virtual streams are used to represent the total amount of energy consumed by a home (which is the sum of the data from the sensors attached to the home’s mains breakers).

  • hub_system_metrics: A logical sensor device used to encapsulate metrics relating to the hardware and operating system of hub devices.

  • neurio: A sensor that uses CT clamps to monitor power and energy usage.

    {
        "sensor_device_type": "neurio",
        "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10249",
        "sensor_id": "0x0000C47F510179FE"
      }
  • neurio (Submeter): A sensor that is an extension of a neurio sensor that is used to submeter electrical loads.

    {
        "sensor_device_type": "neurio",
        "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10249",
        "sensor_id": "0x0000C47F510179FE",
        "neurio_channel_number": 4
      }
  • smartthings: A collection of IoT devices such as smart energy meters.

    {
        "sensor_device_type": "smartthings",
        "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10249",
        "device_id": "3fd5af49-48b7-0000-0000-3fe03eb3bd99"
      }
  • solaredge (Consumption): A meter that reports energy consumption for solar panels.

    {
        "sensor_device_type": "solaredge",
        "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10249",
        "site_id": 1,
        "meter_type": "CONSUMPTION"
      }
  • solaredge (Generation): A meter that reports energy production for solar panels.

    {
        "sensor_device_type": "solaredge",
        "hub_serial_number": "0DF9B929-F934-4D4C-949E-879CC5F10249",
        "site_id": 1,
        "meter_type": "GENERATION"
      }

Sensor

Retrieve a sensor
GET/sensors/{sensor_serial_number}

Retrieves a single sensor device. Requested sensor must be accessible with the API key in use.

Example URI

GET https://api.whskrlabs.com/sensors/F9897604-0E6B-4E1B-9649-C48374C84A46
URI Parameters
HideShow
sensor_serial_number
string (required) Example: F9897604-0E6B-4E1B-9649-C48374C84A46

A UUID uniquely identifying a sensor

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Body
{
  "sensor_serial_number": "21A055AA-F5C1-4200-B097-A8A4BAE126D2",
  "sensor_device_type": "tokay"
}
Response  200
HideShow
Headers
Content-Type: application/json

Streams

A stream represents a set of time series emitted by a source. Streams are structured as multi-dimensional time series, or panels. They are uniquely identified by 64-bit integers.

Conceptually, streams are emitted by sensors within the context of a source. Sampled readings are contained within and conveyed by streams.

Channels

A stream is composed of channels, which are ordinary time series. All channels within a stream are synchronized, meaning that their timestamps align.

In this way, a stream is used to represent the output of a sensor that measures a set of phenomena instantaneously.

Channel types

Streams and channels are typed according to a collection of pre-defined measurement types and units. The following stream types (and constituent measurement types) are currently supported:

  • Energy data

    • Electrical current (instantaneous and RMS), measured in amperes
    • Voltage (instantaneous and RMS), measured in volts
    • Power, measured in watts
  • Computer system metrics

    • Uptime, measured in hours
    • CPU user, idle, kernel, iowait, and irc, measured as percentages
    • CPU temperature, in degrees centigrade
    • Memory and disk usage, measured as percentages
    • Consumed network bandwidth, ingress and egress, measured in bits/second
    • Radio signal strength, measured in decibel-milliwatts

Streams

List streams
GET/streams{?source_namespace,sensor_serial_number,group_id,circuit_breaker_type_id,sensor_position,sensor_device_type}

Retrieves all streams to which the authenticated API key has access.

Access to a given stream is determined by the user’s group-membership and hub-ownership settings. In practice, a user can retrieve streams emitted by sources that a) they own or b) are associated with groups of which they are a member.

Consider a customer who owns a hub with two voltage/current sensors. The user’s account is associated with one data source containing two streams, each of which consist of a number of data channels. Additionally, there are three other data sources with two streams apiece registered within the user’s group. A GET /streams request with this user’s API key would produce the metadata of eight streams from the four sources.

Query filtration

Query parameters can be provided to filter the retrieved list of streams. For instance, a source_namespace query parameter can be passed to filter results to a single source (assuming that source is accessible to the authenticated API key).

This endpoint accepts arbitrary key-value pairs as query parameters in order to provide stream retrieval by arbitrary metadata. This API reference lists example query parameters of known metadata that can be associated with a source. In addition to these examples, any flexible schema key can be used to filter stream retrieval. However, behavior is undefined for arbitrary keys and any requests with invalid query parameters will result in an empty list.

Example URI

GET https://api.whskrlabs.com/streams?source_namespace=&sensor_serial_number=21A055AA-F5C1-4200-B097-A8A4BAE126D2&group_id=1&circuit_breaker_type_id=&sensor_position=&sensor_device_type=tokay
URI Parameters
HideShow
source_namespace
number (optional) 

A unique identifier of a source

sensor_serial_number
string (optional) Example: 21A055AA-F5C1-4200-B097-A8A4BAE126D2

A serial number of A sensor device

group_id
number (optional) Example: 1

The ID of a group

circuit_breaker_type_id
string (optional) 

The ID of a circuit breaker type

sensor_position
number (optional) 

An integer code corresponding to a circuit breaker position

sensor_device_type
string (optional) Example: tokay

A type of sensor device

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
[
  {
    "stream_id": 32723748291,
    "source_namespace": 7,
    "created_at": 1436900136000,
    "channels": [
      {
        "channel_index": 0,
        "name": "Voltage",
        "unit_symbol": "V"
      }
    ],
    "sensor_device": {
      "sensor_serial_number": "21A055AA-F5C1-4200-B097-A8A4BAE126D2",
      "sensor_device_type": "tokay"
    },
    "display_name": "Consumption",
    "url": "/streams/723748291"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Stream

Retrieve a stream
GET/streams/{stream_id}

Retrieves a single stream. Requested stream must be accessible with the API key in use.

Example URI

GET https://api.whskrlabs.com/streams/32723748291
URI Parameters
HideShow
stream_id
number (required) Example: 32723748291

A unique identifier of a stream

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "stream_id": 32723748291,
  "source_namespace": 7,
  "created_at": 1436900136000,
  "channels": [
    {
      "channel_index": 0,
      "name": "Voltage",
      "unit_symbol": "V"
    }
  ],
  "sensor_device": {
    "sensor_serial_number": "21A055AA-F5C1-4200-B097-A8A4BAE126D2",
    "sensor_device_type": "tokay"
  },
  "display_name": "Consumption",
  "url": "/streams/723748291"
}
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "object",
  "properties": {
    "stream_id": {
      "type": "number",
      "description": "The ID of the stream"
    },
    "source_namespace": {
      "type": "number",
      "description": "The ID of the source that emitted the stream"
    },
    "created_at": {
      "type": "number",
      "description": "The timestamp at which the stream was created, in milliseconds since epoch"
    },
    "channels": {
      "type": "array",
      "description": "An array of channels contained within the stream"
    },
    "sensor_device": {
      "type": "object",
      "properties": {
        "sensor_serial_number": {
          "type": "string",
          "description": "The serial number of the sensor device"
        },
        "sensor_device_type": {
          "type": "string",
          "description": "A string indicating which type of sensor the object represents"
        }
      },
      "required": [
        "sensor_device_type"
      ],
      "description": "The sensor from which the stream originates"
    },
    "display_name": {
      "type": "string",
      "description": "A human-friendly name used to label the stream"
    },
    "url": {
      "type": "string",
      "description": "The URL of the stream's API resource"
    },
    "document": {
      "type": "object",
      "properties": {},
      "description": "A JSON document serving as a flexible schema for additional metadata"
    }
  },
  "required": [
    "stream_id",
    "source_namespace",
    "created_at",
    "channels",
    "sensor_device",
    "url"
  ]
}

Modify a stream
PATCH/streams/{stream_id}

Modifies a stream according to an ordered set of modifications.

Request body must adhere to JSON patch format. For example, to set the visibility state of a stream (for instance, to hide it from the Whisker Labs Plotter application):

[
  {
    "op": "replace",
    "path": "/visible",
    "value": false
  }
]

The following paths on the stream object are patchable using this endpoint.

  • /document/* (number, string, boolean)

  • /visible (boolean)

  • /display_name (string)

For example, to mark a stream as invisible, one would pass the following in a PATCH request body.

[{"op": "replace","path": "/visible", "value": false}]

Or to update a hypothetical notes property within a stream’s document object:

[{"op": "replace","path": "/document/notes","value": "something cool happened to this stream"}]

Example URI

PATCH https://api.whskrlabs.com/streams/32723748291
URI Parameters
HideShow
stream_id
number (required) Example: 32723748291

A unique identifier of a stream

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Body
[
  {
    "op": "replace",
    "path": "/medium",
    "value": "Hello, world!"
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}
Response  204

Time Series

A time series is a series of datapoints indexed by time.

The APIs provided for retrieving time series data operate in terms of channels. As described above, hub devices are represented logically as sources which emit streams of data. These streams are subdivided into channels, which are the basic entities that convey time series data. A channel represents an infinite series of sampled measurements and is typed according to the type of data that is conveys. In this way, a stream can be thought of as a matrix or multi-dimensional array, where each column is a channel.

A channel is characterized by the type of measurements it contains. For instance, a power channel contains samples of power data measured in Watts. Channels are uniquely identified by the combination of a stream ID and a channel index, which is analogous to the channel’s column number within the stream.

Temporal resolution

A numerical temporal_resolution can optionally be provided to specify the desired precision of data with respect to time. For instance, a temporal resolution of 10 implies data sampled every 10-seconds.

Note that requesting a temporal resolution that is higher than the native data results in down-sampling. The temporal_resolution parameter is advisory, meaning that there is no guarantee that it will be heeded by the server. If the resolution is either unspecified or invalid the server will automatically down-sample the requested data according to the follow defaults:

Duration of requested data Resolution period
0 - 1 hour 10 second
1 - 4 hours 20 seconds
4 - 8 hours 30 seconds
8 - 12 hours 40 seconds
12 - 24 hours 90 seconds
1 - 2 days 120 seconds
2 - 7 days 300 seconds
1 - 2 weeks 600 seconds
2 - 4 weeks 1200 seconds
1 - 2 months 2400 seconds
2 - 12 months 3600 seconds
> 1 year 86400 seconds (1 day)

User-specified parameters must not request resolutions lower than these defaults.

Range query

Retrieve a range of time series data
GET/timeseries{?stream_id,channel_index,start_at,end_at,temporal_resolution,smooth_data}

Retrieve a slice of a time series data between two timestamps.

This endpoint offers a means to perform range queries on time series identified by a stream ID and a channel index.

Example URI

GET https://api.whskrlabs.com/timeseries?stream_id=32723748291&channel_index=0&start_at=1445447819&end_at=1445457879&temporal_resolution=10&smooth_data=false
URI Parameters
HideShow
stream_id
number (required) Example: 32723748291

The ID of the stream from which to fetch data

channel_index
number (required) Example: 0

The index of the channel within its encompassing stream

start_at
number (optional) Example: 1445447819

A timestamp representing the lower bound of requested data, in seconds since epoch

end_at
number (optional) Example: 1445457879

A timestamp representing the upper bound of requested data, in seconds since epoch

temporal_resolution
number (optional) Example: 10

An advisory precision for requested data with respect to time (e.g. one data point every 10 seconds)

smooth_data
boolean (optional) Example: false

A boolean indicating whether the data should be smoothed. Defaults to false.

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
[
  {
    "t": 1445447819000,
    "v": 15
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Most-recent-datapoints query

Retrieve latest datapoints from accessible streams
GET/timeseries/latest{?stream_id,channel_index}

Retrieve the most-recent datapoints contained within streams to which the authenticated has access.

A stream ID or channel index may optionally be specified to filter the results down to individual streams or channels.

Example URI

GET https://api.whskrlabs.com/timeseries/latest?stream_id=32723748291&channel_index=0
URI Parameters
HideShow
stream_id
number (optional) Example: 32723748291

The ID of the stream from which to fetch data

channel_index
number (optional) Example: 0

The index of the channel within its encompassing stream

Request
HideShow
Headers
Content-Type: application/json
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Response  200
HideShow
Headers
Content-Type: application/json
Body
[
  {
    "stream_id": 32723748291,
    "channel_index": 0,
    "temporal_resolution": 10,
    "data": [
      {
        "t": 1445447819000,
        "v": 15
      }
    ]
  }
]
Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "type": "array"
}

Generated by aglio on 29 Jan 2018