Digital Loggers


           TOKEN-BASED ACCESS


Only WiFi capable power controllers with firmware 1.10.x or greater support the REST API and token access.


These examples are using cURL. *Some curl versions may not authenticate properly when using digest authentication.
This version of curl is tested and works well in Windows.


To use the REST API, enable the "Allow REST-style API" on the External APIs page of the power controller


It is now possible to grant "clients" specific access permissions. These clients are separate from the users with access to the web UI. Clients must to use the RESTful API to control and query the power controller.

ACCESS TOKENS

First you must create the access tokens. It is easy to create the tokens buy using tools from within the secure shell of the controller itself.

TOKEN_RAW_DATA="Hello"
This is the raw, possibly 8-bit, data which everything else is derived from. You want to use a very random phrase.

TOKEN_BASE64URL="`echo -n "$TOKEN_RAW_DATA" | openssl base64 -e |tr -d '='|tr '+/' '-_'`"
That's the encoded token data you'll be sending in requests

TOKEN_HASH="`echo -n "$TOKEN_RAW_DATA" | openssl sha256 -r | awk '{print $1}'`"
This will be sent to the server for registration below

echo $TOKEN_HASH
For "Hello", it should output
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969

echo $TOKEN_BASE64URL
For "Hello", it should output SGVsbG8

Registration Example 1

Create a registration command that will register the client and permissions in the power controller.
curl -k -u admin:1234 -X PUT -H "X-CSRF: x" -H "Content-Type: application/json" --data-binary {\"name\":\"user2\",\"redirect_urls\":{},\"scopes\":{\"/relay/outlets/all;/=name/\":true,\"/relay/outlets/=1,3,5/=state,transient_state,physical_state/?access=get\":true,\"/relay/outlets/3/=state,transient_state/?access=modify\":true,\"/relay/outlets/5/=cycle/?access=invoke,get\":true,\"/meter/values/all;/value/\":true},\"refresh_tokens\":{},\"access_tokens\":{\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\":{\"remaining_use_count\":300000}}} --digest "https://192.168.0.100/restapi/auth/clients/testclient/"

The name must be alphanumeric with no spaces.
The client must be alphanumeric with no spaces.
It may be helpful for auditing if the client and the name are the same.
In this example, this is the scope of permissions for the above registration: *Remember REST API outlets are zero indexed.
{
\"/relay/outlets/all;/=name/\":true,-- Full control over all outlet names
\"/relay/outlets/=1,3,5/=state,transient_state,physical_state/?access=get\":true,-- Get the state of outlets 2, 4 and 6
\"/relay/outlets/3/=state,transient_state/?access=modify,get\":true,-- Turn on/off outlet 4, get the status
\"/relay/outlets/5/=cycle/?access=invoke,get\":true,-- Cycle outlet 6 only, get the results
\"/meter/values/all;/value/\":true-- Read all meter values
}


Command Examples 1

// Cycle outlet 6
curl -k -D - -H "Authorization: Bearer testclient.SGVsbG8" -X POST -H "X-CSRF: x" --digest "https://192.168.0.100/restapi/relay/outlets/5/cycle/"

// Turn on outlet 4
curl -k -D - -H "Authorization: Bearer testclient.SGVsbG8" -X PUT -H "X-CSRF: x" --data "value=true" --digest "https://192.168.0.100/restapi/relay/outlets/3/state/"

Log output:
2021-05-22 08:23:10 user.notice 192.168.0.98 auth[1261]: access allowed for user2 (testclient@68.65.227.210], bearer)
2021-05-22 08:23:10 user.notice 192.168.0.98 relay.state[1034]: Outlet 4: Configured state set to On by client testclient from 68.65.227.210] via web ui
2021-05-22 08:23:10 user.notice 192.168.0.98 relay.state[1034]: Outlet 4: Physical state set to On by relay hardware via relay

Notice that user2 is the testclient. For this reason, it makes sense to use the same name for the name and client name.


Registration Example 2

This registration command is using DaveSmith as the user name and the client name.

-- Turn ON/Off outlets 3, 4 and 6, Cycle outlets 3, 4 and 6, Get the state of all outtlets, Run a script, enable/disable WiFi
curl -u admin:1234 -k -X PUT -H "X-CSRF: x" -H "Content-Type: application/json" --data-binary {\"name\":\"DaveSmith\",\"redirect_urls\":{},\"scopes\":{\"/relay/outlets/all;/=name/\":true,\"/relay/outlets/all;/=state,transient_state,physical_state/?access=get\":true,\"/relay/outlets/=2,3,5;/=state,transient_state/?access=modify,get\":true,\"/relay/outlets/=2,3,6/=cycle/?access=invoke,get\":true,\"/network/wireless/enabled/?access=modify,get\":true,\"/script/start/?access=invoke\":true},\"refresh_tokens\":{},\"access_tokens\":{\"185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969\":{\"remaining_use_count\":300000}}} --digest "https://192.168.0.100/restapi/auth/clients/DaveSmith/"

Permissions breakout
{
\"/relay/outlets/all;/=name/\":true,// Full control over outlet names
\"/relay/outlets/all;/=state,transient_state,physical_state/?access=get\":true,//Get the stat us of all outelts
\"/relay/outlets/=2,3,5/=state,transient_state/?access=modify\":true, // turn on/off outlets 3, 4 and 6
\"/relay/outlets/=2,3,6/=cycle/?access=get,invoke\":true,// cycle outlets 3, 4 and 7
\"/network/wireless/enabled/?access=modify,get\":true,// enable/disable, get the state of WiFi
\"/script/start/?access=get,invoke\":true// run a script, get the results
}
Note: get,invoke access allows you to read the results of the command and get the same output as standard REST API usage.

Command Examples 2
// Turn on outlet 2
curl -D - -H "Authorization: Bearer DaveSmith.SGVsbG8" -k -X PUT -H "X-CSRF: x" --data "value=true" --digest "https://192.168.0.100/restapi/relay/outlets/1/state/"
// Cycle outlet 4
curl -k -D - -H "Authorization: Bearer DaveSmith.SGVsbG8" -X POST -H "X-CSRF: x" --digest "https://192.168.0.100/restapi/relay/outlets/3/cycle/"
// Run a script called cycle_schedule_1
curl -D - -H "Authorization: Bearer DaveSmith.SGVsbG8" -k -H "X-CSRF: x" -H "Content-Type: application/json" --data "[{\"user_function\":\"cycle_schedule_1\"}]" --digest "https://192.168.0.100/restapi/script/start/"
// Get the state of all outlets
curl -D - -H "Authorization: Bearer DaveSmith.SGVsbG8" -k -H "Accept:application/json" --digest https://192.168.0.100/restapi/relay/outlets/all;/physical_state/

Notice how the log is easier to read with the client and the name being the same:
Thu Jun 3 13:14:38 2021 user.notice auth[1271]: access allowed for DaveSmith (DaveSmith@192.168.0.10, bearer)
Thu Jun 3 13:14:38 2021 user.notice relay.state[1034]: Outlet 4: Cycle() by client DaveSmith from 192.168.0.10 via web ui
Thu Jun 3 13:14:38 2021 user.notice relay.state[1034]: Outlet 4: Physical state set to Off by relay hardware via relay
Thu Jun 3 13:14:43 2021 user.notice relay.state[1034]: Outlet 4: Physical state set to On by relay hardware via relay



Have a smart way to use your power switch?  We'll acknowledge your contribution. Learn more about scripting here or AutoPing here.