Difference between revisions of "FAQ"

From Sensaphone.net
Jump to: navigation, search
m (References)
m (Paging through results)
 
(25 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
==Where's the API Documentation?==
 
==Where's the API Documentation?==
 
[[Sensaphone.net API|REST API docs]]
 
[[Sensaphone.net API|REST API docs]]
 +
 +
==How do I make REST calls?==
 +
We recommend the use of a REST client for developing and testing calls to our REST API.  Searching for 'rest client' in your favorite search engine will turn up many suitable results.
  
 
==How do I login?==
 
==How do I login?==
Line 10: Line 13:
  
 
<syntaxhighlight lang="JavaScript">
 
<syntaxhighlight lang="JavaScript">
GET https://rest.sensaphone.net/api/v1/login/{[email protected]}/{abc123_my_password}
+
POST https://rest.sensaphone.net/api/v1/login/{[email protected]}/{abc123_my_password}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 60: Line 63:
 
: List of one or more globally unique numeric ID's, each representing a "loggable" device zone.
 
: List of one or more globally unique numeric ID's, each representing a "loggable" device zone.
 
; begin_offset
 
; begin_offset
: The offset of the first record to be returned to the caller.  An offset of 0 indicates the beginning of the queried timerange.  Increasing this offset by 5 means we return results beginning with the fifth record obtained by the query.  Use this value to "page" through results in descending order, newest to oldest.   
+
: The offset of the first record to be returned to the caller.  An offset of 0 indicates the beginning of the queried timerange.  Increasing this offset by 50, for example, means we return results beginning with the fiftieth record obtained by the query.  Use this value to "page" through results in descending order, newest to oldest.  Experiment to find an offset value that works well for your application.
 
; record_offset
 
; record_offset
 
: Number of results to return per "page".
 
: Number of results to return per "page".
Line 79: Line 82:
 
   session = 1234aaa5678bbbb8765cccc4321dddd  # session token
 
   session = 1234aaa5678bbbb8765cccc4321dddd  # session token
  
=====1. List Devices=====
+
=====List Devices=====
 
First let's list all devices associated with our account and choose one from the results.
 
First let's list all devices associated with our account and choose one from the results.
  
 
<syntaxhighlight lang="JavaScript">
 
<syntaxhighlight lang="JavaScript">
POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/device
+
POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/dashboard
 +
{
 +
  "request_type": "read",
 +
  "resource": "dashboard",
 +
  "dashboard": {
 +
    "device": [
 +
      {
 +
        "device_id": null,
 +
        "name": null
 +
      }
 +
    ]
 +
  }   
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 89: Line 104:
 
   device_id = 9191
 
   device_id = 9191
  
=====2. List Log Points=====
+
=====List Log Points=====
 
With a device_id of 9191 in hand, we may now query for log_points associated with that device.
 
With a device_id of 9191 in hand, we may now query for log_points associated with that device.
  
Line 95: Line 110:
 
POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log_points
 
POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log_points
 
{
 
{
   "resource_type": "device",
+
   "request_type": "read",
   "history": {
+
  "resource": "history",
     "data_log_points": {
+
   "history": [
      "resource_type": "device",
+
     {
      "device_id": 9191
+
      "data_log_points": {
 +
        "resource_type": "device",
 +
        "device_id": 9191
 +
      }
 
     }
 
     }
   }
+
   ]
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Line 112: Line 130:
 
   15148853
 
   15148853
  
=====3. Calculate start and end timestamps=====
+
=====Calculate start and end timestamps=====
 
Calculate the '''start''' and '''end''' timestamps [[#How do I calculate Sensaphone-encoded timestamps?|as outlined here]].  The range of records returned will fall in the range ''(start, end]'', meaning records will be considered a match if the date of the record equals '''end''' all the way up to, but not including, '''start'''.
 
Calculate the '''start''' and '''end''' timestamps [[#How do I calculate Sensaphone-encoded timestamps?|as outlined here]].  The range of records returned will fall in the range ''(start, end]'', meaning records will be considered a match if the date of the record equals '''end''' all the way up to, but not including, '''start'''.
  
Line 121: Line 139:
 
   end  = November 01, 2020 12:00am --> sensaphone_time(2020, 10, 00, 00, 00, 00) --> 669600000
 
   end  = November 01, 2020 12:00am --> sensaphone_time(2020, 10, 00, 00, 00, 00) --> 669600000
  
=====4. Make the request=====
+
=====Make the request=====
 
Now that we have all the necessary data we can put it together and make our datalog request.
 
Now that we have all the necessary data we can put it together and make our datalog request.
  
Line 128: Line 146:
 
{
 
{
 
   "request_type": "read",
 
   "request_type": "read",
 +
  "resource": "history",
 
   "history": {
 
   "history": {
 
     "data_log": {
 
     "data_log": {
Line 142: Line 161:
 
Assuming records exist for those log_points during that time range, 10 of them will be returned.  Why just 10?  Recall that record_offset determines the maximum number of records to be returned per request.
 
Assuming records exist for those log_points during that time range, 10 of them will be returned.  Why just 10?  Recall that record_offset determines the maximum number of records to be returned per request.
  
=====5. Paging through results=====
+
=====Paging through results=====
 
If there are more records to be reviewed, we can page through our results by making another call.  This time we will increment the '''begin_offset''' by the number of records per page ('''record_offset''').
 
If there are more records to be reviewed, we can page through our results by making another call.  This time we will increment the '''begin_offset''' by the number of records per page ('''record_offset''').
  
<syntaxhighlight lang="JavaScript" highlight=9>
+
<syntaxhighlight lang="JavaScript" highlight=10>
 
POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log
 
POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log
 
{
 
{
 
   "request_type": "read",
 
   "request_type": "read",
 +
  "resource": "history",
 
   "history": {
 
   "history": {
 
     "data_log": {
 
     "data_log": {
Line 160: Line 180:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
=====Queries against zones of multiple devices=====
 +
Recall that zone ID's are unique across '''all''' devices.  If you wish to query for datalog records on zones across multiple devices, simply acquire the log points for the zones of the devices you wish to view and make your query as we have shown above.  The only difference here is that the log points used in the request represent zones across more than one device.
  
 
===References===
 
===References===
Line 172: Line 195:
 
Internally, the Sensaphone API uses a custom date encoding.  The only time a user of the REST API must worry about these encoded timestamps is when making requests against the [[Sensaphone.net API/history|history]] resource.
 
Internally, the Sensaphone API uses a custom date encoding.  The only time a user of the REST API must worry about these encoded timestamps is when making requests against the [[Sensaphone.net API/history|history]] resource.
  
The most important thing to keep in mind when converting to Sensaphone timestamps:  '''All data passed into the algorithm is base-0'''.  This means that the first day of the month is not 1, but 0.  Likewise January is not 1, but 0.  Due to the fact that we count our minutes and seconds from 0, you will not notice a difference when passing these values into the algorithm.  The same goes for the year. Where this base-0 concept will have the most noticeable impact will be ''hour of the day'', ''day of the month'', and ''month of the year''.
+
The most important thing to keep in mind when converting to Sensaphone timestamps:  <strong>All data passed into the algorithm is base-0</strong>.  This means that the first day of the month is not 1, but 0.  Likewise January is not 1, but 0.  Due to the fact that we count our minutes and seconds from 0, you will not notice a difference when passing these values into the algorithm.  The same goes for the year. Where this base-0 concept will have the most noticeable impact will be ''hour of the day'', ''day of the month'', and ''month of the year''.
  
 
Observe:
 
Observe:
Line 196: Line 219:
 
While all largely the same basic syntax, the following are implementations of the conversion algorithm in various languages.
 
While all largely the same basic syntax, the following are implementations of the conversion algorithm in various languages.
 
====Bash====
 
====Bash====
This snippet is useful if you are using cURL to make your REST calls.
+
This snippet is useful if you are using cURL to make your REST calls from the command line.
 
<syntaxhighlight lang="bash" line='line'>
 
<syntaxhighlight lang="bash" line='line'>
 
sensaphone_time() {
 
sensaphone_time() {
Line 254: Line 277:
  
 
===Example===
 
===Example===
Let's calculate a timestamp for November 18, 2020 12:30pm. Remember all numbers are base-0!
+
Here we calculate a timestamp for November 18, 2020 12:30pm Eastern Standard Time.
 +
 
 +
<strong>Remember all numbers are base-0!</strong>
  
 
<syntaxhighlight lang="JavaScript">
 
<syntaxhighlight lang="JavaScript">
// 0 seconds past the minute ---------.
+
// 0 seconds past the minute --------.
// 30 minutes past the hour ------.   |
+
// 30 minutes past the hour ------. |
// 12th hour of day ----------.  |   |
+
// 12th hour of day     -----.  | |
// 18th day of month -----.  |  |   |
+
// 18th day of month -----.  |  | |
// November ----------.  |  |  |   |
+
// November ----------.  |  |  | |
//                   |  |  |  |  |
+
// Year --------.    |  |  |  |  |
sensaphoneTime(2020, 10, 17, 12, 30, 00)
+
//              |    |  |  |  |
 +
sensaphoneTime(2020, 10, 17, 12, 30, 0)
 
</syntaxhighlight>
 
</syntaxhighlight>
  
This will return:
+
This will return the Sensaphone timestamp:
 
   671113800
 
   671113800
  

Latest revision as of 09:55, 11 October 2024

Where's the API Documentation?

REST API docs

How do I make REST calls?

We recommend the use of a REST client for developing and testing calls to our REST API. Searching for 'rest client' in your favorite search engine will turn up many suitable results.

How do I login?

Overview

To use the Sensaphone REST API, a login call must first be made. A successful login request will return an account number and a session token. These will be used in all subsequent requests. Two examples of login requests are shown below. First, the URI-mode version, followed by the JSON-mode version.

Examples

URI-mode:

POST https://rest.sensaphone.net/api/v1/login/{[email protected]}/{abc123_my_password}

JSON-mode:

POST https://rest.sensaphone.net/api/v1/login
{
  "request_type": "create",
  "resource": "login",
  "user_name": "[email protected]",
  "password": "abc123_my_password"
}

Reply

The reply to a successful login request will contain a result object and a response object. The result communicates the overall success of the call. The response contains the data in which we are interested: in this case, the account number (acctid), and the session token. The account number and session token will be used in every subsequent query submitted to the API.

{
  "result": {
    "success": true,
    "code": 0,
    "message": "Success"
  },
  "response": {
    "acctid": 21620750,
    "session": "1234ffffeeee5678aaaccda609cd8fb5099",
    "login_timestamp": 1605562465,
    "session_expiration": 86400,
    "user_id": 12345678
  }
}

References

  1. Login Resource: Additional information about the login resource
  2. URI-mode/JSON-mode: Information about URI-mode and JSON-mode

How do I access log data?

Overview

Queries to our logging facilities are one of the most popular uses of the Sensaphone API. Making a successful log query involves first acquiring multiple pieces of data from the API. Because of this fact, crafting your first log query will be a multi-step process. All logs are accessed through the history resource. Outlined below you will find a practical example of how to gather the data needed to make a successful query to the history resource. We will use JSON-mode for each request as we gather the info required to query for datalogs.

Examples

Datalog

Every device (e.g. Sentinel, Sentinel Pro, Stratus) associated with an account has input zones to which sensors may be connected. A device may be configured to log the value of any input zone at specific intervals. On www.sensaphone.net (the Website) the user may query a time range of datalog records for a single device. Users of the REST API can make similar queries against the input zones of one or more devices.

The data required to perform a datalog query are defined as follows:

log_points/data_log_points
List of one or more globally unique numeric ID's, each representing a "loggable" device zone.
begin_offset
The offset of the first record to be returned to the caller. An offset of 0 indicates the beginning of the queried timerange. Increasing this offset by 50, for example, means we return results beginning with the fiftieth record obtained by the query. Use this value to "page" through results in descending order, newest to oldest. Experiment to find an offset value that works well for your application.
record_offset
Number of results to return per "page".
start
The greatest (most recent) Sensaphone-encoded timestamp we are interested in, non-inclusive. Also see below for more details about how this value may be calculated.
end
The least (oldest) Sensaphone-encoded timestamp we are interested in, inclusive. Also see below for more details about how this value may be calculated.

We will take the following steps to retrieve the information necessary for a query to the datalog facility:

  1. Get a list of devices associated with an account
  2. Get a list of log_points from a device
  3. Calculate Sensaphone-encoded start and end timestamps
  4. Query for datalog records
  5. Page through the results

For the remainder of this example, let's assume the following:

 acctid = 12345678  # account_id
 session = 1234aaa5678bbbb8765cccc4321dddd  # session token
List Devices

First let's list all devices associated with our account and choose one from the results.

POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/dashboard
{
  "request_type": "read",
  "resource": "dashboard",
  "dashboard": {
    "device": [
      {
        "device_id": null,
        "name": null
      }
    ]
  }    
}

Under the response object in the reply from the server is an array of devices. The device_id is listed in this information. For the remainder of this example let's assume we have acquired the following device_id:

 device_id = 9191
List Log Points

With a device_id of 9191 in hand, we may now query for log_points associated with that device.

POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log_points
{
  "request_type": "read",
  "resource": "history",
  "history": [
    {
      "data_log_points": {
        "resource_type": "device",
        "device_id": 9191
      }
    }
  ]
}

The server's reply will contain data for each loggable zone, including input zones and output zones. The log_point value of each zone is unique across all devices. Therefore a log_point value of 78208181 will refer to one, and only one, zone. Extract log_point values for all zones to be queried.

Assume we have decided to pull datalog records for the following log points:

 15144093
 15145683
 15148853
Calculate start and end timestamps

Calculate the start and end timestamps as outlined here. The range of records returned will fall in the range (start, end], meaning records will be considered a match if the date of the record equals end all the way up to, but not including, start.

The timestamps are reverse of how you may be inclined to think of them at first. Start is the most recent date in your time range, and end is the oldest date in your time range. When records are returned to you, they will be returned in reverse order (newest first).

Let's assume we wish to query the following two dates:

 start = November 18, 2020 12:30pm --> sensaphone_time(2020, 10, 17, 12, 30, 00) --> 671113800
 end   = November 01, 2020 12:00am --> sensaphone_time(2020, 10, 00, 00, 00, 00) --> 669600000
Make the request

Now that we have all the necessary data we can put it together and make our datalog request.

POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log
{
  "request_type": "read",
  "resource": "history",
  "history": {
    "data_log": {
      "log_points": [ 15144093, 15145683, 15148853 ],
      "start": 671113800,
      "end": 669600000,
      "begin_offset": 0,
      "record_offset": 10
    }
  }
}

Assuming records exist for those log_points during that time range, 10 of them will be returned. Why just 10? Recall that record_offset determines the maximum number of records to be returned per request.

Paging through results

If there are more records to be reviewed, we can page through our results by making another call. This time we will increment the begin_offset by the number of records per page (record_offset).

POST https://www.sensaphone.net/api/v1/{12345678}/{1234aaa5678bbbb8765cccc4321dddd}/history/data_log
{
  "request_type": "read",
  "resource": "history",
  "history": {
    "data_log": {
      "log_points": [ 15144093, 15145683, 15148853 ],
      "start": 671113800,
      "end": 669600000,
      "begin_offset": 10,      "record_offset": 10
    }
  }
}
Queries against zones of multiple devices

Recall that zone ID's are unique across all devices. If you wish to query for datalog records on zones across multiple devices, simply acquire the log points for the zones of the devices you wish to view and make your query as we have shown above. The only difference here is that the log points used in the request represent zones across more than one device.

References

How do I calculate Sensaphone-encoded timestamps?

Overview

Internally, the Sensaphone API uses a custom date encoding. The only time a user of the REST API must worry about these encoded timestamps is when making requests against the history resource.

The most important thing to keep in mind when converting to Sensaphone timestamps: All data passed into the algorithm is base-0. This means that the first day of the month is not 1, but 0. Likewise January is not 1, but 0. Due to the fact that we count our minutes and seconds from 0, you will not notice a difference when passing these values into the algorithm. The same goes for the year. Where this base-0 concept will have the most noticeable impact will be hour of the day, day of the month, and month of the year.

Observe:

  • 0 - 59 seconds per minute
  • 0 - 59 minutes per hour
  • 0 - 23 hours per day (0 = 12am, 1, 2, ..., 23 = 11pm)
  • 0 - 30 are 31-day months
  • 0 - 29 are 30-day months
  • 0 - 27 most Februaries
  • 0 - 28 leap-year Februaries
  • 0 - 11 months per year
  • 2000 - ... the year

The algorithm in psuedo code:

 timestamp <-- (seconds mod 60) +                  // 0 - 59
               ((minutes * 60) mod 3600) +         // 0 - 59
               ((hours * 3600) mod 86400) +        // 0 - 23
               ((day * 86400) mod 2678400) +       // 0 - 31
               ((month * 2678400) mod 32140800) +  // 0 - 11
               ((year mod 100) * 32140800)         // 2000 - ...

Implementations

While all largely the same basic syntax, the following are implementations of the conversion algorithm in various languages.

Bash

This snippet is useful if you are using cURL to make your REST calls from the command line.

  1. sensaphone_time() {
  2.     local year=$1
  3.     local month=$2
  4.     local day=$3
  5.     local hours=$4
  6.     local minutes=$5
  7.     local seconds=$6
  8.  
  9.     local sensaphone_timestamp=$(( ( seconds          % 60) +
  10.                                    ((minutes      * 60) % 3600) +
  11.                                    ((hours        * 3600) % 86400) +
  12.                                    ((day          * 86400) % 2678400) +
  13.                                    ((month        * 2678400) % 32140800) +
  14.                                    (((year % 100) * 32140800)) ))
  15.     echo $sensaphone_timestamp
  16. }

Python

  1. def sensaphone_time(year, month, day, hours, minutes, seconds):
  2.     return (seconds % 60) + \
  3.       ((minutes     * 60) % 3600) + \
  4.       ((hours       * 3600) % 86400) + \
  5.       ((day         * 86400) % 2678400) + \
  6.       ((month       * 2678400) % 32140800) + \
  7.       ((year % 100) * 32140800)

PHP

  1. <?php
  2. function sensaphoneTime($year, $month, $day, $hours, $minutes, $seconds) {
  3.     return ( $seconds         % 60) +
  4.            (($minutes     * 60) % 3600) +
  5.            (($hours       * 3600) % 86400) +
  6.            (($day         * 86400) % 2678400) +
  7.            (($month       * 2678400) % 32140800) +
  8.            (($year % 100) * 32140800);
  9. }
  10. ?>

JavaScript

  1. function sensaphoneTime(year, month, day, hours, minutes, seconds) {
  2.     return ( seconds         % 60) +
  3.            ((minutes     * 60) % 3600) +
  4.            ((hours       * 3600) % 86400) +
  5.            ((day         * 86400) % 2678400) +
  6.            ((month       * 2678400) % 32140800) +
  7.            ((year % 100) * 32140800);
  8. }

Example

Here we calculate a timestamp for November 18, 2020 12:30pm Eastern Standard Time.

Remember all numbers are base-0!

// 0 seconds past the minute --------.
// 30 minutes past the hour ------.  |
// 12th hour of day      -----.   |  |
// 18th day of month -----.   |   |  |
// November ----------.   |   |   |  |
// Year --------.     |   |   |   |  |
//              |     |   |   |   |  |
sensaphoneTime(2020, 10, 17, 12, 30, 0)

This will return the Sensaphone timestamp:

 671113800

References