NAV Navbar

Introduction

Welcome to the API documentation for the Sustainder Brokerage Layer.

The URL of the Sustainder Brokerage Layer API is https://httpapi.sustainder.com/v2.

Note: If you are looking for the deprecated Regulus and Devices API documentation, click here.

Concepts

Before we continue, let's quickly introduce some important concepts in our API.

Media Type

An example HAL+JSON document:

{
    "_links": {
        "self": { "href": "/orders" },
        "next": { "href": "/orders?page=2" },
        "admin": [{
            "href": "/admins/2",
            "title": "Fred"
        }, {
            "href": "/admins/5",
            "title": "Kate"
        }]
    },
    "currentlyProcessing": 14,
    "shippedToday": 20,
    "_embedded": {
        "order": [{
            "_links": {
                "self": { "href": "/orders/123" },
                "customer": { "href": "/customers/7809" }
            },
            "total": 30.00,
            "currency": "EUR",
        }]
    }
}

All communication with the API uses JSON. Specifically, we support the standard media type HAL+JSON. This standard specifies (amongst other things) a format for links between resources as well as how resources can be embedded.

There are various libraries available to help integration with HAL+JSON, however none is required to successfully integrate with the API; all responses are valid JSON as well.

Dates and Times

All dates and times provided by the API will be in UTC. They will all follow the ISO8601 standard. An example: 2019-07-22T07:13:44Z.

Domain Description

Here we briefly introduce the entities in the domain of our API, together with their definitions. Understanding these terms will help greatly in integrating with the API.

Getting started

Authentication

Authentication is done by using Basic Access Authentication over HTTPS or by using JSON Web Tokens (JWT). Both these methods require a username and password, which will be provided to you by Sustainder.

JWT is the preferred method of authentication.

We've implemented a welcome command that is only accessible when you are authenticated. The below sections will walk you through testing your connection.

JSON Web Tokens

To retrieve a JWT token:

curl https://httpapi.sustainder.com/auth/jwt
  -X POST -d '{"username": "{username}", "password": "{password}"}'

Make sure to replace username and password with your credentials.

Example response:

{
    "name": "username",
    "token": "MyJWTToken",
    "auth-header": "JWT MyJWTToken"
}

To access the welcome command using your newly generated token:

curl https://httpapi.sustainder.com/v2/welcome
  -X POST -H "Authorization: JWT MyJWTToken"

JSON Web Tokens allow you to generate a token which can be used for a limited period to perform requests. This does not require you to store and send the password for every request, and as such is more suitable for situations where basic authentication is not secure enough.

We’ve implemented an endpoint to request a JWT. An example to request such a JWT token can be found on the right.

For subsequent requests, the provided token should be prefixed with “JWT” and should be sent as value of the Authorization header. For example:

Authorization: JWT MyJWTToken

In the next sections, authentication data will be omitted for brevity. It is however expected that it is always provided.

Basic Access Authentication

To access the welcome command:

curl https://httpapi.sustainder.com/v2/welcome
  -X POST -u username:password

Make sure to replace username and password with your credentials.

While simple to implement, this method requires you to send both the username and password on every request. This means it is not suitable for use on devices on which you cannot guarantee a secure storage of the password (such as mobile devices of users). We strongly recommend using the JWT authentication method instead.

Data Retrieval

curl https://httpapi.sustainder.com/v2

Once you are authenticated, you can inspect the root resource to see what you can do. The response will contain links to the various parts of the API you can access from this point.

curl https://httpapi.sustainder.com/v2/nodes

At this point, you will probably want to see the nodes that you can manage. See the request on the right. This will return a list of all nodes available for you. The nodes are found in the _embedded section, with the key “nodes”. A node represents a physical entity in the network, and amongst other things has a location (provided with a longitude and latitude).

https://httpapi.sustainder.com/v2/nodes/{node_id}

To only see the details of single node, you can follow the value for the “self” link for the specific node. An example is shown on the right. Please replace the ID with the one in the self link.

Every node provides one or more services. Our nodes can currently provide one or more of the following three services:

"_links": {
    "self": { "href": "/nodes/{node_id}" },
    "lcm": { "href": "/lcms/{lcm_id}" },
    "sensors": { "href": "/nodes/{node_id}/sensors" }
}

To see the services a node provides, you can look at the _links section for a specific node. The example on the right shows a node that provides both the LCM and Sensors service.

curl https://httpapi.sustainder.com/v2/lcms/{lcm_id}

To access the data of the LCM service, you can follow the “lcm” link. This will provide you with the data of the LCM service, with therein embedded the node data.

curl https://httpapi.sustainder.com/v2/nodes?service=lcm

If you are only interested in data from a specific service, you can of course also only see the nodes of this specific service.

curl https://httpapi.sustainder.com/v2/lcms

Or you can access the LCM list directly if you prefer.

Sensor Data

Retrieve all sensor types available in the system:

curl https://httpapi.sustainder.com/v2/types/sensors

Inspect the sensors of a specific node that provides the sensor service:

curl https://httpapi.sustainder.com/v2/nodes/{node_id}/sensors

Nodes can contain one or more sensors. These sensors provide the status of a node at a given time. We only provide the latest value for each sensor. We also provide a service to store data for a longer period of time with our Sensor Layer. Please contact us for more details.

{
    "_links": {
        "self": { "href": "/sensors/{node_id}" },
        "node": { "href": "/node/{node_id}" },
        "power": { "href": "/sensors/{node_id}/power" },
        "temperature": { "href": "/sensors/{node_id}/temperature" },
        "ambient": { "href": "/sensors/{node_id}/ambient" }
    }
}

All available sensors in the specific node can be seen in the _links section. See the right for an example.

curl https://httpapi.sustainder.com/v2/sensors/{node_id}/power

To view the latest value and other data of a specific sensor, you can follow the link of that sensor. This will provide you with the latest value, the date and time the sensor sent this value, and the unit of the value.

Lighting functions and settings

Our lighting control modules (LCMs) provide functions and settings that can be controlled through the API. Separate resources are implemented so that multiple LCMs can be controlled in single requests.

Set an override to one or more LCMs:

curl https://httpapi.sustainder.com/v2/lcms/functions/direct-control
  -X POST -d {json}
{
  "override": [
    {
      "lcm_id": "160524000001",
      "override": [
        100,
        100,
        100,
        100
      ]
    },
    {
      "lcm_id": "171224000196",
      "override": [
        20,
        100,
        20,
        100
      ]
    },
    {
      "lcm_id": "171224000148",
      "override": [
        80,
        0,
        0,
        0
      ]
    }
  ],
  "application_artkey": {{application_artkey}}
}

An override modifies the light value of an LCM immediately. If the nodes are online, the override values will be pushed to the nodes. Otherwise, the response will indicate that the nodes are offline and the values are discarded.

Please note the application_artkey field. A user can be part of one or more applications. Every request should include the unique application_artkey that the command is intended for. This artkey (artificial key) can be obtained from the /me resource.

Set the light levels of one or more LCMs:

curl https://httpapi.sustainder.com/v2/lcms/settings/light-levels
  -X POST -d {json}
{
    "light_levels": [{
        "lcm_id": "160524000001",
        "light_levels": [100,100,100,100]
    }, {
        "lcm_id": "171224000196",
        "light_levels": [20,100,20,100]
    }, {
        "lcm_id": "171224000148",
        "light_levels": 80
    }],
    "queue_when_offline": true,
    "application_artkey": {{application_artkey}}
}

Settings work in a similar way to functions, however settings can also be queued. For example, setting the light levels of an LCM is very similar to an override, but as you can see the optional field “queue_when_offline” is included here. If not set or set to false, the settings are discarded in case the nodes are offline. In case the value is true, as in this example, the setings will be queued. The next time the nodes come online, the system will configure the nodes with the queued settings. If the nodes are currently online, they will be configured with the settings immediately.

If multiple settings are queued sequentially for the same nodes, only the last settings will be applied to the nodes.

Grouping

View all existing groups:

curl https://httpapi.sustainder.com/v2/groups

It is possible to group multiple services of a certain node together.

Create a group:

curl https://httpapi.sustainder.com/v2/groups
  -X POST -d {json}

Request:

{
    "group_name": "LcmGroup1",
    "node_ids": ["160524000001", "171224000196"],
    "application_artkey": {{application_artkey}}
}

Response:

{
    "_links": {
        "": "/groups/"
    },
    "group_name": "LcmGroup1",
    "group_id": "28",
    "status": "queued",
    "node_ids": ["160524000001", "171224000196"]
}

The creation of a group will be queued if the devices are offline. A group can only be used to set settings when its status is complete.

Webhooks

The nodes that the Brokerage Layer manages communicate asynchronously. Using functions and configuring settings of nodes will immediately result in an action if the node is online, and will immediately result in an answer from the API. However, it can take a while before a response is propagated to the node itself. In addition, the nodes regularly send status updates and sensor data, depending on their configuration.

It is possible to subscribe to some of these changes through Webhooks allow you to set an URL to which we will send updates.

Request Webhook types

curl https://httpapi.sustainder.com/v2/webhooks

Response:

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/webhooks"
        },
        "dimming_scheme": {
            "href": "https://httpapi.sustainder.com/v2/webhooks/dimming_scheme"
        },
        "status_response": {
            "href": "https://httpapi.sustainder.com/v2/webhooks/status_response"
        },
        "status_push": {
            "href": "https://httpapi.sustainder.com/v2/webhooks/status_push"
        },
        "gateway_state_change": {
            "href": "https://httpapi.sustainder.com/v2/webhooks/gateway_state_change"
        }
    }
}

Subscribe to a Webhook

curl https://httpapi.sustainder.com/v2/webhooks/dimming_scheme
  -X POST -d {json}
{
    "remote_url": "https://mycompany.com/sustainder/dimming_scheme",
    "auth_method": "BASIC",
    "username": "myusername",
    "password_or_token": "mypassword",
    "application_artkey": {{application_artkey}}
}

It is possible to request all possible webhook types. The response will contain a list of all possible webhook types, as well as the URL to which to POST to create a Webhook or to GET to retrieve the details of the currently active Webhook configuration.

Resources overview

The following is an overview of all available resources in the API.

Root [GET]

Request

/v2/

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/"
        },
        "jwt": {
          "href": "https://httpapi.sustainder.com/v2/auth/jwt"
        },
        "me": {
          "href": "https://httpapi.sustainder.com/v2/auth/me"
        },
        "welcome": {
          "href": "https://httpapi.sustainder.com/v2/welcome"
        },
        "nodes": {
            "href": "https://httpapi.sustainder.com/v2/nodes"
        },
        "node": {
            "href": "https://httpapi.sustainder.com/v2/node/{node_id}"
        },
        "lcms": {
            "href": "https://httpapi.sustainder.com/v2/lcms"
        },
        "lcm": {
            "href": "https://httpapi.sustainder.com/v2/lcms/{lcm_id}"
        },
        "gateways": {
            "href": "https://httpapi.sustainder.com/v2/gateways"
        },
        "gateway": {
            "href": "https://httpapi.sustainder.com/v2/gateways/{gateway_id}"
        },
        "groups": {
            "href": "https://httpapi.sustainder.com/v2/groups"
        },
        "group": {
            "href": "https://httpapi.sustainder.com/v2/groups/{group_id}"
        },
        "issues": {
          "href": "https://httpapi.sustainder.com/v2/issues"
        },
        "webhooks": {
          "href": "https://httpapi.sustainder.com/v2/webhooks"
        }
    },
    "_total": null,
    "message": "Welcome to the Sustainder Brokerage Layer V2 API."
}

The root resource / is the entrypoint of the API for navigation of the different commands.

Auth

This section lists the authorization commands.

/auth/jwt/ [POST]

Request body

{
    "username": "{{username}}", 
    "password": "{{password}}"
}

Response

{
    "name": "{{username}}",
    "token": "{{JWT Token}}",
    "auth-header": "JWT {{JWT Token}}"
}

Used to request a JWT token for authenticating other commands.

The auth-header field is the full data for the HTTP auth-header field to use the JWT authentication.

/auth/jwt/refresh/ [POST]

Request body

{
    "token": "{{JWT Token}}"
}

Response

{
    "name": "{{username}}",
    "token": "{{JWT Token}}",
    "auth-header": "JWT {{JWT Token}}"
}

Used to refresh a valid JWT token.

/auth/reset-password/ [POST]

Request body

{
    "username": "{{username}}"
}

Response

{
    "message": "Password reset email sent."
}

Used to request for a reset password command to be send to the user.

/auth/change-password/ [POST]

Request body

{
    "username": "{{username}}",
  "old_password": "{{old_password}}",
  "new_password": "{{new_password}}",
}

Used to set a new password for the user. Please note that the password is checked for sufficient strength. In case the password isn't strong enough, an error will be returned.

/auth/me/ [GET]

Response

{
    "name": "{{username}}",
    "applications": [
      {
            "artkey": 35,
            "name": "City",
            "image": "{{Base64_Encoded_Image}}",
            "is_tilted_warning_threshold": 10.0,
            "is_tilted_error_threshold": 45.0,
            "permission_asset_management": true,
            "permission_tilted": true
      }
    ]
}

Used to request some information about the currently logged in user and his application(s).

image is the base 64 encoded image associated with the users system. Is null if not set.

Miscellaneous

This section lists some miscellaneous commands.

/welcome [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/welcome"
        },
        "root": {
            "href": "https://httpapi.sustainder.com/v2/"
        }
    },
    "_total": null,
    "message": "You are succesfully authenticated as user {{username}}"
}

Used to verify that the user is logged in correctly and can use the Sustainder V2 API. Postman example available here. If this is not working contact Sustainder.

/errors [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/errors"
        }
    },
    "_embedded": {
        "lcms": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    }
                },
                "_total": null,
                "lcm_id": "{{lcm_id}}",
                "name": "{{lcm_name}}",
                "status": "offline",
                "error_type": "LCM_NOT_RESPONDING"
            }
        ],
        "gateways": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}"
                    }
                },
                "_total": null,
                "gateway_id": "{{gateway_id}}",
                "name": null,
                "error_type": "GATEWAY_NOT_RESPONDING"
            }
        ]
    },
    "_total": null
}

Used to request a list of all lcms and gateways with an error.

/issues [GET]

see /errors

Lcms

This section deals with commands for LCMs, or Lighting Control Modules. It contains functions to set an override light level with the direct control command, clearing these overrides to switch back to the standard dimming scheme with the clear override command, changing the maximum light output of an LCM using the light levels command, or preview the new maximum light level using the preview light levels command.

/lcms [GET]

Request

/v2/lcms?page={{page_number}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms"
        },
        "direct_control": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/direct-control"
        },
        "preview_light_levels": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/preview-light-levels"
        },
        "set_light_levels": {
            "href": "https://httpapi.sustainder.com/v2/lcms/settings/light-levels"
        },
        "set_dimming_scheme": {
            "href": "https://httpapi.sustainder.com/v2/lcms/settings/dimming-scheme"
        }
    },
    "_embedded": {
        "lcms": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "lcms": {
                        "href": "https://httpapi.sustainder.com/v2/lcms"
                    }
                },
                "_total": null,
                "lcm_id": "{{lcm_id}}",
                "model": "{{model}}",
                "status": "{{status}}",
                "pole_number": "{{pole_number}}",
                "lighting_mode": "{{lighting_mode}}",
                "override_light_level": [
                    {{override_light_levels}}
                ],
                "light_level": [
                    {{light_levels}}
                ],
                "latest_energy_kwh": "{{latest_energy_kwh}}",
                "latest_energy_kwh_timestamp": "{{latest_energy_kwh_timestamp}}",
                "latest_power_watt": "{{latest_power_watt}}",
                "latest_power_watt_timestamp": "{{latest_power_watt_timestamp}}",
                "relative_tilt_angle": "{{relative_tilt_angle}}",
                "last_sensor_data_update": "{{last_sensor_data_update}}",
                "ambient": "{{ambient}}",
                "temperature_internal": "{{temperature_internal}}",
                "latest_running_hours": "{{latest_running_hours}}",
                "latest_running_hours_timestamp": "{{latest_running_hours_timestamp}}",
                "dimming_calendar_name": "{{dimming_calendar_name}}",
                "error_type": "{{error_type}}",
                "error_types": [{{error_types}}],
                "details": {
                    "production_date": "{{production_date}}",
                    "driver_type": "{{driver_type}}",
                    "lumen_output": "{{lumen_output}}",
                    "watt": "{{watt}}",
                    "armature_color": "{{armature_color}}",
                    "light_color": "{{light_color}}",
                    "clo": "{{clo}}",
                    "optics": "{{optics}}",
                    "dimming_scheme": "{{dimming_scheme}}",
                    "mounting_diameter": "{{mounting_diameter}}",
                    "guard": "{{guard}}",
                    "tilt_angle": "{{tilt_angle}}",
                    "cable_type": "{{cable_type}}",
                    "cable_length": "{{cable_length}}",
                    "optic_addon": "{{optic_addon}}",
                    "last_sensor_data_update": "{{last_sensor_data_update}}"
                }
            },
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "lcms": {
                        "href": "https://httpapi.sustainder.com/v2/lcms"
                    }
                },
                "_total": null,
                "lcm_id": "{{lcm_id}}",
                "model": "{{model}}",
                "status": "{{status}}",
                "pole_number": "{{pole_number}}",
                "lighting_mode": "{{lighting_mode}}",
                "override_light_level": [
                    {{override_light_levels}}
                ],
                "light_level": [
                    {{light_levels}}
                ],
                "latest_energy_kwh": "{{latest_energy_kwh}}",
                "latest_energy_kwh_timestamp": "{{latest_energy_kwh_timestamp}}",
                "latest_power_watt": "{{latest_power_watt}}",
                "latest_power_watt_timestamp": "{{latest_power_watt_timestamp}}",
                "relative_tilt_angle": "{{relative_tilt_angle}}",
                "last_sensor_data_update": "{{last_sensor_data_update}}",
                "ambient": "{{ambient}}",
                "temperature_internal": "{{temperature_internal}}",
                "latest_running_hours": "{{latest_running_hours}}",
                "latest_running_hours_timestamp": "{{latest_running_hours_timestamp}}",
                "dimming_calendar_name": "{{dimming_calendar_name}}",
                "error_type": "{{error_type}}",
                "error_types": [{{error_types}}],
                "details": null
            }
        ]
    },
    "_total": {{lcms_returned}}
}

This command lists all LCMs of your system. It can use paging to split the request into more manageable chunks, page number starts from 1. Request until lcms_returned in the response = 0

Response values: For an explanation of the parameters see /lcms/{lcm_id}

/lcms/{lcm_id} [GET]

Request

/v2/lcms/{{lcm_id}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
        },
        "lcms": {
            "href": "https://httpapi.sustainder.com/v2/lcms"
        }
    },
    "_embedded": {
        "node": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
                    },
                    "nodes": {
                        "href": "https://httpapi.sustainder.com/v2/nodes"
                    },
                    "sensors_service": {
                        "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
                    },
                    "lcm_service": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "gateway_service": {
                        "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}"
                    }
                },
                "_total": null,
                "node_id": "{{node_id}}",
                "name": "{{display_name}}",
                "area": "{{area}}",
                "street": "{{street}}",
                "status": "{{status}}",
                "group_name": "{{group_name}}",
                "is_locked": "{{is_locked}}",
                "longitude": "{{longitude}}",
                "latitude": "{{latitude}}",
                "software_version": "{{software_version}}",
                "last_status_update": "{{timestamp_of_last_status_update}}",
                "gateway_id": "{{gateway_id}}",
                "lcm_service_id": "{{lcm_id}}",
                "gateway_service_id": "{{gateway_id}}"
            }
        ]
    },
    "_total": null,
    "lcm_id": "{{lcm_id}}",
    "model": "{{model}}",
    "status": "{{status}}",
    "pole_number": "{{pole_number}}",
    "lighting_mode": "{{lighting_mode}}",
    "override_light_level": [
        {{override_light_levels}}
    ],
    "light_level": [
        {{light_levels}}
    ],
    "latest_energy_kwh": "{{latest_energy_kwh}}",
    "latest_energy_kwh_timestamp": "{{latest_energy_kwh_timestamp}}",
    "latest_power_watt": "{{latest_power_watt}}",
    "latest_power_watt_timestamp": "{{latest_power_watt_timestamp}}",
    "relative_tilt_angle": "{{relative_tilt_angle}}",
    "last_sensor_data_update": "{{last_sensor_data_update}}",
    "ambient": "{{ambient}}",
    "temperature_internal": "{{temperature_internal}}",
    "latest_running_hours": "{{latest_running_hours}}",
    "latest_running_hours_timestamp": "{{latest_running_hours_timestamp}}",
    "dimming_calendar_name": "{{dimming_calendar_name}}",
    "error_type": "{{error_type}}",
    "error_types": [{{error_types}}],
    "details": null
}

This command can be used to request all data of a specific LCM.

Response values:

/lcms/functions/clear-override [POST]

Request body

{
  "lcm_ids": [
      {{lcm_ids}}
  ],
  "application_artkey": {{application_artkey}}
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/clear-override"
        }
    },
    "_total": null,
    "lcms_ok": [
        {{lcms_ok}}
    ],
    "lcms_nok":  [
        {{lcms_nok}}
    ]
}

This command can be used to clear a direct control override to go back to the dimming scheme.

Request parameters

Response parameters

/lcms/functions/direct-control [POST]

Request body

{
    "override": [
        {
            "lcm_id": "{{lcm_id}}",
            "override": [
                {{override_levels}}
            ],
            "duration": {{duration}}
        }
    ],
    "application_artkey": {{application_artkey}}
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/direct-control"
        }
    },
    "_total": null,
    "lcms_ok": [
        {{lcms_ok}}
    ],
    "lcms_nok":  [
        {{lcms_nok}}
    ],
    "application_artkey": {{application_artkey}}
}

This command can be used to set overrides on one or more LCMs, which will let the LCM run at a different light level than set by the dimming scheme, or a motion/ambient light override.

Request parameters

Response parameters

Explained at clear override command.

/lcms/functions/preview-light-levels [POST]

Request body

{
    "light_levels": [
        {
            "lcm_id": "{{lcm_id}}",
            "light_levels": [
                {{override_levels}}
            ]
        }
    ],
    "application_artkey": {{application_artkey}}
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/preview-light-levels"
        }
    },
    "_total": null,
    "lcms_ok": [
        {{lcms_ok}}
    ],
    "lcms_nok":  [
        {{lcms_nok}}
    ],
}

This command is similar to the Direct Control command. The main difference is that this shows the new maximum lightlevel. Which can be used to gauge if the new Light Levels would be as desired.

Request parameters

Response parameters

Explained at clear override command.

/lcms/settings/light-levels [POST]

Request body

{
    "light_levels": [
        {
            "lcm_id": "{{lcm_id}}",
            "light_levels": [
                {{light_levels}}
            ]
        }
    ],
    "queue_when_offline": {{allow_queuing_when_offline}},
    "application_artkey": {{application_artkey}}
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/light-levels"
        }
    },
    "_total": null,
    "lcms_ok": [
        {{lcms_ok}}
    ],
    "lcms_queued": [
        {{lcms_queued}}
    ],
    "lcms_nok":  [
        {{lcms_nok}}
    ]
}

This command can be used to change the maximum level of the armature. After this command is send the maximum level of 100% for direct control will be scaled with the light levels

Request parameters

Response parameters

Explained at clear override command. The only addition is the lcms_queued field. This indicates for which LCMs the setting was accepted, but because those LCMs are not currently online, the setting has been queued and it will be sent when next it comes online.

/lcms/settings/dimming-schemes [POST]

Request body

{
    "lcms": [
        {
            "lcm_id": "{{lcm_id}}",
            "calendar_name": "{{known_scheme}}"
        },
        {
            "lcm_id": "{{lcm_id}}",
            "calendar_name": "{{transient_calendar}}"
        }
    ],
    "calendars": [
        {
            "calendar_name": "{{transient_calendar}}",
            "dimming_scheme_rules": [
                {
                    "dimming_scheme_name": "{{transient_scheme}}",
                    "days": [
                        {{days_scheme_should_apply}}
                    ]
                }
            ]
        }
    ],
    "dimming_schemes": [
        {
            "dimming_scheme_name": "{{transient_scheme}}",
            "steps": [
                {{scheme_steps}}
            ]
        }
    ],
    "queue_when_offline": true,
    "application_artkey": {{application_artkey}}
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/lcms/functions/light-levels"
        }
    },
    "_total": null,
    "lcms_ok": [
        {{lcms_ok}}
    ],
    "lcms_queued": [
        {{lcms_queued}}
    ],
    "lcms_nok":  [
        {{lcms_nok}}
    ],
}

This command can be used to either link a known dimming scheme set with Dimming Scheme POST command, or set a transient dimming scheme. A transient dimming scheme is a permanent dimming scheme that can not be requested from the SBL. The transient scheme also allows for different schemes for different days, something not currently possible with known dimming schemes.

Request parameters

Response parameters

Explained at clear override command.

Dimming Schemes

Dimming step

"steps": [
   {
      "light_level": 100,
      "sunset": "-12"
   },
   {
      "light_level": 75,
      "time": "21:00"
   },
   {
      "light_level": 100,
      "time": "05:00"
   }
   {
      "light_level": 0,
      "sunrise": "9"
   }
]

A dimming scheme consists of steps that have a time component and a light level, these indicate that from that time until the next step the LCM should be the given lightlevel. So if there's a step at 20:00 that indicates 100% and one at 21:00 of 75% that indicates that the LCM from 20:00 until 21:00 will be 100% and from 21:00 onwards it will be at 75%. There are 3 different time components:

/dimming-schemes [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/dimming-schemes"
        }
    },
    "_embedded": {
        "dimming_schemes": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/dimming-schemes/{{scheme_id}}"
                    }
                },
                "_total": null,
                "dimming_scheme_id": {{scheme_id}},
                "dimming_scheme_name": "{{scheme_name}}",
                "steps": [
                    {{scheme_steps}}
                ]
            }
        ]
    },
    "_total": null
}

This command is used to request all dimming schemes associated with this system. This is the same list as is shown in the Sustainder app.

Response parameters

/dimming-schemes [POST]

Request body

{
    "dimming_scheme_name": "{{scheme_name}}",
    "steps": [
        {{scheme_steps}}
    ]
}

HTTP Response code

201 created

This command is used to create a new named dimming scheme. Which can be seen in the Sustainder app, as well as be requested with the Dimming Scheme List GET command.

Request parameters

/dimming-schemes/{dimming_scheme_id} [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/dimming-schemes/{{scheme_id}}"
        }
    },
    "_total": null,
    "dimming_scheme_id": {{scheme_id}},
    "dimming_scheme_name": "{{scheme_name}}",
    "steps": [
        {{scheme_steps}}
    ]
}

This command can be used to get the details of a specific dimming scheme.

Response parameters

Nodes

/nodes [GET]

Request

/v2/nodes?page={{page_number}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/nodes"
        }
    },
    "_embedded": {
        "nodes": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
                    },
                    "nodes": {
                        "href": "https://httpapi.sustainder.com/v2/nodes"
                    },
                    "sensors_service": {
                        "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
                    },
                    "lcm_service": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "gateway_service": {
                        "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}"
                    }
                },
                "_total": null,
                "node_id": "{{node_id}}",
                "name": "{{display_name}}",
                "status": "{{status}}",
                "longitude": "{{longitude}}",
                "latitude": "{{latitude}}",
                "last_status_update": "{{timestamp_last_status_update}}",
                "gateway_id": "{{gateway_id}}",
                "lcm_service_id": "{{lcm_id}}",
                "gateway_service_id": "{{gateway_id}}"
            },
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
                    },
                    "nodes": {
                        "href": "https://httpapi.sustainder.com/v2/nodes"
                    },
                    "sensors_service": {
                        "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
                    },
                    "lcm_service": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    }
                },
                "_total": null,
                "node_id": "{{node_id}}",
                "name": "{{display_name}}",
                "status": "{{status}}",
                "longitude": "{{longitude}}",
                "latitude": "{{latitude}}",
                "last_status_update": "{{timestamp_last_status_update}}",
                "gateway_id": "{{gateway_id}}",
                "lcm_service_id": "{{lcm_id}}",
                "gateway_service_id": "{{gateway_id}}"
            }
        ]
    },
    "_total": {{nodes_returned}}
}

This command lists all nodes of your system. It can use paging to split the request into more manageable chunks, page number starts from 1. Request until nodes_returned in the response = 0

Response values: For an explanation of the parameters see /lcms/{lcm_id}

/nodes/{node_id} [GET]

Request

/v2/nodes/{{node_id}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
        },
        "nodes": {
            "href": "https://httpapi.sustainder.com/v2/nodes"
        },
        "sensors_service": {
            "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
        },
        "lcm_service": {
            "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
        }
    },
    "_embedded": {
        "lcm_service": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "lcms": {
                        "href": "https://httpapi.sustainder.com/v2/lcms"
                    }
                },
                "_total": null,
                "lcm_id": "{{lcm_id}}",
                "model": "{{model}}",
                "status": "{{status}}",
                "lighting_mode": "{{lighting_mode}}",
                "override_light_level": [
                    {{override_light_levels}}
                ],
                "light_level": [
                    {{light_levels}}
                ],
                "error_type": "{{error_type}}",
                "error_types": [{{error_types}}]
            }
        ]
    },
    "_total": null,
    "node_id": "{{node_id}}",
    "name": "{{display_name}}",
    "status": "{{status}}",
    "longitude": "{{longitude}}",
    "latitude": "{{latitude}}",
    "last_status_update": "{{timestamp_of_last_status_update}}",
    "gateway_id": "{{gateway_id}}",
    "lcm_service_id": "{{lcm_id}}",
    "gateway_service_id": "{{gateway_id}}"
}

This command can be used to request all data of a specific LCM

Response values: For an explanation of the parameters see /lcms/{lcm_id}

/nodes/{node_id} [PATCH]

Request

/v2/nodes/{{node_id}}

Request body

{
    "name": "{{new_display_name}}",
    "latitude": "{{new_latitude}}",
    "longitude": "{{new_longitude}}"
}

HTTP Response code

200 OK

This command can be used to update the display name and/or GPS location of a node. If you wish to not change a value send null instead.

Groups

Groups are used to couple multiple nodes into a single controllable unit. Nodes can only be a part of one group at a time. If a node that is already in a group is added to a new group, it will be removed from its current group.

/groups [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/groups"
        }
    },
    "_embedded": {
        "groups": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/groups/{{group_id}}"
                    },
                    "groups": {
                        "href": "https://httpapi.sustainder.com/v2/groups"
                    }
                },
                "_total": null,
                "group_id": "{{group_id}}",
                "name": "{{group_name}}",
                "status": "{{group_installation_status}}",
                "node_ids": [
                    "{{node_id}}"
                ]
            }
        ]
    },
    "_total": null
}

This command lists all groups registered for your system.

/groups [POST]

Request body

{
    "group_name": "{{group_name}}",
    "node_ids": [
        {{node_ids}}
    ]
}

HTTP Response code

202 accepted

This command can be used to create a group of the selected list of node ids.

/groups/{group_id} [GET]

Request

/v2/groups/{{group_id}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/groups/{{group_id}}"
        },
        "groups": {
            "href": "https://httpapi.sustainder.com/v2/groups"
        }
    },
    "_embedded": {
        "nodes": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
                    },
                    "nodes": {
                        "href": "https://httpapi.sustainder.com/v2/nodes"
                    },
                    "sensors_service": {
                        "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
                    },
                    "lcm_service": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "gateway_service": {
                        "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}"
                    }
                },
                "_total": null,
                "node_id": "{{node_id}}",
                "name": "{{display_name}}",
                "status": "{{status}}",
                "longitude": "{{longitude}}",
                "latitude": "{{latitude}}",
                "last_status_update": "{{timestamp_of_last_status_update}}",
                "gateway_id": "{{gateway_id}}",
                "lcm_service_id": "{{lcm_id}}",
                "gateway_service_id": "{{gateway_id}}"
            }
        ]
    },
    "_total": null,
    "group_id": "{{group_id}}",
    "name": "{{group_name}}",
    "status": "{{group_installation_status}}",
    "node_ids": [
        {{node_ids}}
    ]
}

This command lists the group and all the nodes associated with it.

Response values:

For an explanation of the other parameters see /lcms/{lcm_id}

/groups/{group_id} [DELETE]

Request

/v2/groups/{{group_id}}

HTTP Response code

200 ok

This command is used to delete an existing group.

/groups/functions/direct-control [POST]

Request body

{
    "override": [
        {
            "group_id": "{{group_id}}",
            "override": [
                {{override_levels}}
            ]
        }
    ]
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/groups/functions/direct-control"
        }
    },
    "_total": null,
    "groups_ok": [
        {{ok_group_ids}}
    ],
    "groups_nok": [
        {{failed_group_ids}}
    ]
}

This is the group variant of the LCM Direct Control command. It sends to a group_id instead of an lcm_id but is functionally the same.

/groups/functions/clear-override [POST]

Request body

{
    "group_ids": [
        {{group_ids}}
    ]
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/groups/functions/clear-override"
        }
    },
    "_total": null,
    "groups_ok": [
        {{ok_group_ids}}
    ],
    "groups_nok": [
        {{failed_group_ids}}
    ]
}

This is the group variant of the LCM Clear Override command. It sends to a group_id instead of an lcm_id but is functionally the same.

/groups/settings/light-levels [POST]

Request body

{
    "light_levels": [
        {
            "group_id": "{{group_id}}",
            "light_levels": [
                {{light_levels}}
            ]
        }
    ],
    "queue_when_offline": true
}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/groups/functions/light-levels"
        }
    },
    "_total": null,
    "groups_ok": [
        {{ok_group_ids}}
    ],
    "groups_nok": [
        {{failed_group_ids}}
    ]
}

This is the group variant of the LCM Update Maximum Light Levels command. It sends to a group_id instead of an lcm_id but is functionally the same.

Types

/types/error [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/types/error"
        }
    },
    "_total": null,
    "lcm_error_types": [
        "DIMMING",
        "BALLAST",
        "LAMP",
        "LCM_NOT_RESPONDING",
        "GATEWAY_NOT_RESPONDING"
    ],
    "gateway_error_types": [
        "GATEWAY_NOT_RESPONDING"
    ]
}

This command lists the available error types that can be returned by the SBL.

Gateways

Gateways are the devices that sit between the nodes and the SBL. This can either be an external device, or part of the node. For the LCMs it is an external device that can control up to 250 LCMs, which allows for communication between these LCMs, which allows them to react quickly to e.g. motion.

/gateways [GET]

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/gateways"
        }
    },
    "_embedded": {
        "gateways": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}"
                    },
                    "gateways": {
                        "href": "https://httpapi.sustainder.com/v2/gateways"
                    }
                },
                "_total": null,
                "gateway_id": "{{gateway_id}}",
                "gateway_status": "{{status}}",
                "timezone": "{{time zone}}"
            }
        ]
    },
    "_total": 1
}

This command lists all gateways of your system.

Response values:

For an explanation of the parameters see /gateways/{gateway_id}

/gateways/{gateway_id} [GET]

Request

/v2/gateways/{{gateway_id}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}"
        },
        "gateways": {
            "href": "https://httpapi.sustainder.com/v2/gateways"
        }
    },
    "_total": null,
    "gateway_id": "{{gateway_id}}",
    "gateway_status": "{{status}}",
    "timezone": "{{time_zone}}"
}

This command can be used to request all data of a specific gateway.

Response parameters

/gateways/{gateway_id}/sunsetsunrise [GET]

Request

/v2/gateways/{{gateway_id}}/sunsetsunrise

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/gateways/{{gateway_id}}/sunsetsunrise"
        }
    },
    "_embedded": {
        "switch_moments": [
            {
                "_total": null,
                "timestamp": "{{day_of_switch_moment}}",
                "sunset": "{{sunset_moment}}",
                "sunrise": "{{sunrise_moment}}"
            },
            ...
        ]
    },
    "_total": null
}

This command can be used to get an overview of when the Gateway is expecting sunset and sunrise to be.

Response parameters

Sensors

/sensors/{node_id} [GET]

Request

/v2/sensors/{{node_id}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
        },
        "node": {
            "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
        }
    },
    "_embedded": {
        "sensors": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/sensors/808/rf_strength"
                    },
                    "sensors": {
                        "href": "https://httpapi.sustainder.com/v2/sensors"
                    }
                },
                "_total": null,
                "sensor_name": "{{sensor_name}}",
                "value": "{{sensor_value}}",
                "unit": "{{sensor_unit}}",
                "last_updated": "{{timestamp_of_last_sensor_data_update}}"
            },
            ...
        ],
        "node": [
            {
                "_links": {
                    "self": {
                        "href": "https://httpapi.sustainder.com/v2/nodes/{{node_id}}"
                    },
                    "nodes": {
                        "href": "https://httpapi.sustainder.com/v2/nodes"
                    },
                    "sensors_service": {
                        "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}"
                    },
                    "lcm_service": {
                        "href": "https://httpapi.sustainder.com/v2/lcms/{{lcm_id}}"
                    },
                    "gateway_service": {
                        "href": "https://httpapi.sustainder.com/v2/gateways/352890061121289"
                    }
                },
                "_total": null,
                "node_id": "{{node_id}}",
                "name": "{{display_name}}",
                "status": "{{status}}",
                "longitude": "{{longitude}}",
                "latitude": "{{latitude}}",
                "last_status_update": "{{timestamp_of_last_status_update}}",
                "gateway_id": "{{gateway_id}}",
                "lcm_service_id": "{{lcm_id}}",
                "gateway_service_id": "{{gateway_id}}"
            }
        ]
    },
    "_total": null
}

This command can be used to request the data of all sensor of a node.

Response parameters

See /sensors/{node_id}/{sensor_name} for the Sensor parameters and /lcms/{lcm_id} for the rest.

/sensors/{node_id}/{sensor_name} [GET]

Request

/v2/sensors/{{node_id}}/{{sensor_name}}

Response

{
    "_links": {
        "self": {
            "href": "https://httpapi.sustainder.com/v2/sensors/{{node_id}}/{{sensor_name}}"
        },
        "sensors": {
            "href": "https://httpapi.sustainder.com/v2/sensors"
        }
    },
    "_total": null,
    "sensor_name": "{{sensor_name}}",
    "value": "{{sensor_value}}",
    "unit": "{{sensor_unit}}",
    "last_updated": "{{timestamp_of_last_sensor_data_update}}"
}

This command can be used to request the data of a single sensor of a node.

Response parameters

Push API

For a number of updates, our platform can send push updates to your system.

You need to make available an endpoint that can receive our messages. All of our messages are sent as HTTP POST requests, in the JSON format. We support authentication through basic auth over HTTPS, as well as through the use of a Bearer token.

Please provide your endpoint, plus your chosen method of authentication, to Sustainder to begin receiving push updates. All messages are sent to the same endpoint.

LCM push message

Example request: Basic data update.

{
  "node_id": "10c1a386-1bb0-44aa-a032-eda80df17f88",
  "lcm_id": "160524000001",
  "lcm_error_type": null,
  "lighting_mode": "DIMSCHEME",
  "measured_power": 5.8
}

Example request: Channel data update.

{
  "node_id": "10c1a386-1bb0-44aa-a032-eda80df17f88",
  "lcm_id": "160524000001",
  "lcm_error_type": null,
  "lighting_mode": "DIMSCHEME",
  "channel_data": [
    {
      "current_lightlevel": 80,
      "previous_lightlevel": 60,
      "burn_minutes": 485
    },
    {
      "current_lightlevel": 80,
      "previous_lightlevel": 60,
      "burn_minutes": 485
    },
    {
      "current_lightlevel": 80,
      "previous_lightlevel": 60,
      "burn_minutes": 485
    },
    {
      "current_lightlevel": 80,
      "previous_lightlevel": 60,
      "burn_minutes": 485
    }
  ],
  "software_version": "3.4.10",
  "measured_power": 5.8,
  "total_usage_wh": 324150
}

Example request: Switch moments update.

{
  "node_id": "10c1a386-1bb0-44aa-a032-eda80df17f88",
  "lcm_id": "160524000001",
  "switch_moments": [
    {
      "start_time": "2020-08-20T20:15:24Z",
      "light_levels": [80, 60, 60, 80]
    },
    {
      "start_time": "2020-08-20T23:00:48Z",
      "light_levels": [40, 40, 40, 40]
    }
  ]
}

Triggered when: As soon as new data arrives in the Sustainde Brokerage Layer for an LCM, or as soon as a change is detected, the relevant data will be sent.

Description: The LCM push message contains updated information about an LCM. At a minimum, it provides the LCM ID and the Node ID. Depending on the change, the following data can be sent:

A few examples can be found to the right.

Gateway push message

Example request: State change.

{
  "node_id": "10c1a386-1bb0-44aa-a032-eda80df17f88",
  "gateway_id": "352267077368016",
  "state_change": {
    "timestamp": "2020-08-20T09:11:52Z",
    "state": "online"
  }
}

Triggered when: As soon as new data arrives in the Sustainde Brokerage Layer regarding a gateway, or as soon as a change is detected, the relevant data will be sent.

Description: The Gateway push message contains updated information about a gateway. At a minimum, it provides the Gateway ID and the Node ID. Depending on the change, the following data can be sent: