NAV Navbar
python shell

Introduction

The SLV NorthBound API allows developers to access data, features and services from a SLV Central Management Server. This includes the configuration and the geolocalization of smart city devices, the analysis of failures and energy consumptions and the real time control and command of devices.

The SLV API provides answers in two formats, JSON and XML.

This set of methods is updated periodically with new ones. We may occasionally deprecate features. If you have a problem, please reach out to us at support@streetlight-vision.com

We provide code examples in Python and Shell. They can be viewed in the dark area to the right.

Version history

7.12

7.10

7.8

6.1.1

Authentication

In SLV 6 and SLV 7 until 7.7

Authentication to the API is performed via HTTP Basic Auth.

Your SLV CMS credentials serve as API credentials as well. They are represented in the code examples by USERNAME and PASSWORD.

API requests without authentication will fail with some random-looking HTML content.

To authenticate against an SLV CMS using HTTP Basic Auth, use the following code:

import urllib.request

# This code assumes that all requests will be made with urllib.request

auth_handler = urllib.request.HTTPBasicAuthHandler()
auth_handler.add_password(realm="Authentication required",
                          uri=HOST,
                          user=USERNAME,
                          passwd=PASSWORD)
opener = urllib.request.build_opener(auth_handler)
urllib.request.install_opener(opener)
# With shell, you can just pass your username and password with each request
curl "api_endpoint_here"
  -u USERNAME:PASSWORD

Depending on your programmaing language, you may have to specify a URI or hostname. In the Python example, it is represented by the HOST parameter. HOST is the IP address or domain name of the SLV CMS. Make sure to add the port (separated by a colon) when it is different from 80 and 443, e.g. mydomain.com:8080

SLV 7.8 and above

Starting with SLV 7.8, additional CSRF protection has been added, which requires all third-party applications that interface with SLV through the API to be modified to use a more secure authentication scheme. Third-party applications must obtain a CSRF token before making any other API call. To do so, clients must call the API method userprofile/getCurrentUser with the following request headers: X-CSRF-Token = "Fetch" X-Requested-With = "XMLHttpRequest"

SLV will then provide a CSRF token in the response header X-CSRF-Token. To make a subsequent API call, clients must include the token as part of the request headers, using the key X-CSRF-Token.

It is also highly recommended to create and reuse a single session for all SLV API requests to avoid having to follow this authentication process before each request. By creating and reusing a single session, the token request needs to be made only once and HTTP Basic Auth credentials can be omitted from subsequent API calls.

Example with the API getGeozoneRoot

import requests

# SLV CMS parameters
SLV_URL = <your SLV CMS URL>
SLV_USERNAME = <your SLV CMS username>
SLV_PASSWORD  =<your SLV CMS password>

# Create a session
my_session = requests.Session()

# Get the CSRF token
token_request_headers = {
  'X-CSRF-Token': 'Fetch',
  'X-Requested-With': 'XMLHttpRequest'
}

token_response = my_session.post(SLV_URL + "/api/userprofile/getCurrentUser", auth=(SLV_USERNAME, SLV_PASSWORD), headers=token_request_headers)

# Save the token
token_header = {'X-CSRF-Token': token_response.headers['X-CSRF-Token']}

# Make the getGeozoneRoot call
# Note the reuse of the session, the use of the CSRF token and the absence of other credentials
payload = {
  'computeHierarchyInfos': 'true',
  'ser': 'json'
}
r = my_session.get(SLV_URL + "/api/asset/getGeozoneRoot", params=payload, headers=token_header)
# Do something with the result

CSRF Token Expiration and Error Handling

A token expires along with its associated SLV CMS session. By default, a session expires after a period of inactivity of thirty minutes. Requests that do not include a CSRF token or that include an incorrect or invalid token are rejected by CMS with the HTTP code 403 and with the response header X-CSRF-Token set to required.

Single-sign on with CAAS

If your SLV CMS instance is using single-sign on with CAAS (available from SLV 7.10), you must take the following into consideration: - your CAAS user account must have the role Stateless authentication enabled, - each call to the SLV API must include your basic auth crendentials in addition to the CSRF token.

Error codes

Error code Description
400 INVALID REQUEST
601 CONNECT EXCEPTION
602 IO EXCEPTION
603 ID NAME ALREADY USED
604 UNAUTHORIZED NULL PARAMETER
605 MISSING PARAMETER
606 UNKNOWN HOST EXCEPTION
610 GEOZONE NOT FOUND
611 DEVICE NOT FOUND
612 COMMAND NOT FOUND
613 ITEM NOT FOUND
614 RESOURCE NOT FOUND
620 OPERATION NOT SUPPORTED
630 OPERATION NOT AUTHORIZED
999 UNKNOWN ERROR
1001 TIMEZONE NOT FOUND

1. User profiles

The user profile

A user profile is a set of properties shared by several users: it is more commonly called a user group.

It is referenced by its name. Below are its main attributes:

Attributes
name Profile name
blockedActions List of actions that cannot be performed
locale Language following the format lg_CN. lg is the ISO-639 language code, CN is the ISO-3166 country code.
geoZoneRootId ID of the top-level (root) geozone
skin Name of the skin

1.01 Create a user profile

Create a new user profile called My profile and having access to the geozone ID 1

import requests

payload = {
  'profilName': 'My profile', 
  'geoZoneId': '1',
  'ser': 'json'
}
r = requests.get(SLV_URL + "/api/userprofile/createProfil", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
   "name" : "My profile",
   "properties" :
      [
         {
            "key" : "css",
            "value" : "/resources/css/default.css"
         },
         {
            "key" : "skin",
            "value" : "streetlight"
         },
         {
            "key" : "img.bottombanner",
            "value" : "/resources/img/bottomBar.gif"
         },
         {
            "key" : "providerRootId",
            "value" : ""
         },
         {
            "key" : "locale",
            "value" : "en_US"
         },
         {
            "key" : "img.topbanner",
            "value" : "/resources/img/topbanner_left.gif"
         },
         {
            "key" : "customerRootId",
            "value" : ""
         },
         {
            "key" : "desktop",
            "value" : "desktopApplicationDefault.xml"
         },
         {
            "key" : "geoZoneRootId",
            "value" : "1"
         },
         {
            "key" : "maintenanceAccessFromDeviceCard",
            "value" : "false"
         },
         {
            "key" : "hilitable",
            "value" : "/resources/js/hilitableTable.js"
         },
         {
            "key" : "blockedActions",
            "value" : ""
         },
         {
            "key" : "hide.topbanner",
            "value" : "true"
         },
         {
            "key" : "hide.bottombanner",
            "value" : "true"
         },
         {
            "key" : "userType",
            "value" : "unknown"
         },
         {
            "key" : "img.topcenterbanner",
            "value" : "/resources/img/topbanner_center.gif"
         },
         {
            "key" : "img.toprightbanner",
            "value" : "/resources/img/topbanner_right.gif"
         }
      ]
}

To create a user profile, you should call the method createProfil available at /api/userprofile.

Arguments
profilName (required) Name of the new profile
geoZoneId (required) ID of the top-level (root) geozone

1.02 Update a user profile

Update the user profile called My profile with typical profile attributes

import requests

payload = {
  'profilName': 'My profile', 
  'property.locale': 'en_US',
  'property.skin': 'streetlight',
  'property.geoZoneRootId': 1,
  'property.blockedActions': 'SLVAssetManagementAPI!deleteGeoZone,SLVAssetManagementAPI!deleteDevice',
  'ser': 'json'
}
r = requests.get(SLV_URL + "/api/userprofile/updateProfilProperties", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

"OK"

After creating a user profile, you will probably want to update its attributes. Call the method updateProfilProperties at /api/userprofile.

Arguments
profilName (required) Name of the profile to update
property.key Attribute to update, specified by key

1.03 Delete a user profile

Delete the user profile called My profile

import requests

payload = {
  'profilName': 'My profile', 
  'ser': 'json'
}
r = requests.get(SLV_URL + "/api/userprofile/deleteProfil", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
   "errorCode" : "0",
   "errorCodeLabel" : null,
   "message" : null,
   "status" : "OK",
   "statusError" : false,
   "statusOk" : true,
   "value" : null
}

To delete a user profile, call the method deleteProfil at /api/userprofile.

Arguments
profilName (required) Name of the profile to delete

1.04 Retrieve the profile of the current user

Get the current user profile

import requests

payload = {
  'ser': 'json'
}
r = requests.get(SLV_URL + "/api/userprofile/getCurrentProfil", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
   "name" : "My profile",
   "properties" :
      [
         {
            "key" : "css",
            "value" : "/resources/css/default.css"
         },
         {
            "key" : "skin",
            "value" : "streetlight"
         },
         {
            "key" : "img.bottombanner",
            "value" : "/resources/img/bottomBar.gif"
         },
         {
            "key" : "providerRootId",
            "value" : ""
         },
         {
            "key" : "locale",
            "value" : "en_US"
         },
         {
            "key" : "img.topbanner",
            "value" : "/resources/img/topbanner_left.gif"
         },
         {
            "key" : "customerRootId",
            "value" : ""
         },
         {
            "key" : "desktop",
            "value" : "desktopSilverlight.xml"
         },
         {
            "key" : "geoZoneRootId",
            "value" : "1"
         },
         {
            "key" : "maintenanceAccessFromDeviceCard",
            "value" : "false"
         },
         {
            "key" : "hilitable",
            "value" : "/resources/js/hilitableTable.js"
         },
         {
            "key" : "blockedActions",
            "value" : ""
         },
         {
            "key" : "hide.topbanner",
            "value" : "true"
         },
         {
            "key" : "hide.bottombanner",
            "value" : "true"
         },
         {
            "key" : "userType",
            "value" : "unknown"
         },
         {
            "key" : "img.topcenterbanner",
            "value" : "/resources/img/topbanner_center.gif"
         },
         {
            "key" : "img.toprightbanner",
            "value" : "/resources/img/topbanner_right.gif"
         }
      ]
}

To know the attributes of the current user profile, call getCurrentProfil at /api/userprofile. This method has no required parameter.

The method getProfilProperties at /api/asset can also be used and provides the same information with a slightly different output; it provides only the profile properties, not the profile name.

1.05 Retrieve all profiles

Get all user profiles available at the geozone ID 1 and all of its sub-geozones

import requests

payload = {
  'geoZoneId': 1,
  'recurse': 'true',
  'ser': 'json'
}
r = requests.get(SLV_URL + "/api/userprofile/getGeoZoneProfils", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

[
   {
      "name" : "My profile",
      "properties" :
         [
            {
               "key" : "css",
               "value" : "/resources/css/default.css"
            },
            {
               "key" : "skin",
               "value" : "streetlight"
            },
            {
               "key" : "img.bottombanner",
               "value" : "/resources/img/bottomBar.gif"
            },
            {
               "key" : "providerRootId",
               "value" : ""
            },
            {
               "key" : "locale",
               "value" : "en_US"
            },
            {
               "key" : "img.topbanner",
               "value" : "/resources/img/topbanner_left.gif"
            },
            {
               "key" : "customerRootId",
               "value" : ""
            },
            {
               "key" : "desktop",
               "value" : "desktopSilverlight.xml"
            },
            {
               "key" : "geoZoneRootId",
               "value" : "1337"
            },
            {
               "key" : "maintenanceAccessFromDeviceCard",
               "value" : "false"
            },
            {
               "key" : "hilitable",
               "value" : "/resources/js/hilitableTable.js"
            },
            {
               "key" : "blockedActions",
               "value" : ""
            },
            {
               "key" : "hide.topbanner",
               "value" : "true"
            },
            {
               "key" : "hide.bottombanner",
               "value" : "true"
            },
            {
               "key" : "userType",
               "value" : "unknown"
            },
            {
               "key" : "img.topcenterbanner",
               "value" : "/resources/img/topbanner_center.gif"
            },
            {
               "key" : "img.toprightbanner",
               "value" : "/resources/img/topbanner_right.gif"
            }
         ]
   },
   {
   ...
   }
]

You can obtain the list of all user profiles with a specific top-level geozone using the method getGeoZoneProfils at /api/userprofile.

Arguments
geoZoneId (required) Desired top-level geozone
recurse If set to true, this method will also return the user profiles that have a top-level geozone being a child of the geozone specified by geoZoneId. Set to false if not specified.

1.06 Retrieve all user profile attributes

Example request

import requests

payload = {
  'ser': 'json'
}
r = requests.get(SLV_URL + "/api/userprofile/getProfilPropertyDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

[
   {
      "dataFormat" : null,
      "enumValues" :
         [
            {
               "label" : "Unknown",
               "properties" : null,
               "value" : "unknown"
            },
            {
               "label" : "Human",
               "properties" : null,
               "value" : "human"
            },
            {
               "label" : "Controller",
               "properties" : null,
               "value" : "controller"
            }
         ],
      "format" : null,
      "label" : "??profil.property.name.userType??",
      "labelKey" : "profil.property.name.userType",
      "name" : "userType",
      "type" : "enum.single"
   },
   {
     ...
   }  
]

To obtain the list of all user profile attributes available, use the method getProfilPropertyDescriptors at /api/userprofile. It has no required parameter.

If an attribute has a specific set of accepted values, its type will be enum.single and enumValues will list all accepted values.

2. Users

The user

A user is defined by its login name and the user profile it belongs to. Additionnal info can be defined for a user, most importantly her email address since it is used not only for sending alarms and reports but also for the password recovery process!

Users are referenced by their login name. Below are the main attributes of a user:

Attributes
login Login name
password Password
profilName User profile
geoZoneRootId ID of the top-level (root) geozone
contact Contact object (see below)
properties Array of key/value pairs storing UI configuration properties

The contact

A contact is a simple list of properties referenced by a numeric ID:

Attributes
id ID
address Address
mail Email address
name Name
pager Pager number
phone Phone number

2.01 Create a user

Create a user belonging to the profile My profile with the login johndoe and some other example attributes

import requests

payload = {
  'login': 'johndoe', 
  'password': 'Johndoe-2016',
  'firstName': 'John',
  'lastName': 'Doe',
  'profilName': 'My profile',
  'email': 'johndoe@streetlight-vision.com',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/userprofile/createUser", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
 "admin" : true,
 "contact" :
  {
   "address" : null,
   "id" : 11,
   "mail" : "johndoe@streetlight-vision.com",
   "name" : null,
   "pager" : null,
   "phone" : null
  },
 "firstName" : "John",
 "lastName" : "Doe",
 "login" : "johndoe",
 "password" : "",
 "profilName" : "My profile",
 "properties" :
  [
  ]
}

To create a user profile, you should call the method createUser available at /api/userprofile.

Arguments
login (required) Login name
password (required) Password
profilName (required) User profile
firstName First name
lastName Last name
address Address
phone Phone number
pager Pager number
email Email address

2.02 Update a user

Update the email address of johndoe

import requests

payload = {
  'login': 'johndoe', 
  'email': 'johndoe-new@streetlight-vision.com',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/userprofile/updateUser", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

"OK"

To update any of the attribute set when creating a user with createUser (except the user password), you may use the method updateUser available at /api/userprofile.

It takes the same parameters:

Arguments
login (required) Login name
profilName User profile
firstName First name
lastName Last name
address Address
phone Phone number
pager Pager number
email Email address

2.03 Update user UI properties

Update two dummy properties property1 and property2 for the user johndoe

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('userLogin', 'johndoe'), 
  ('propertyName', 'property1'),
  ('propertyValue', 'value1'),
  ('propertyName', 'property2'),
  ('propertyValue', 'value2'),
  ('ser', 'json')
])

r = requests.post(SLV_CMS + "/api/userprofile/updateUserProperty", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

"OK"

Since user UI properties are actually an array of key/value pairs, a specific method is provided to update them: updateUserProperty available at /api/userprofile. It takes an arbitrary number of key/value pairs.

Arguments
userLogin (required) Login name
propertyName Property key
propertyValue Property value

2.04 Retrieve the current user

Example request

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/userprofile/getCurrentUser", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
 "admin" : true,
 "contact" :
  {
     "address" : null,
     "id" : 11,
     "mail" : "johndoe-new@streetlight-vision.com",
     "name" : null,
     "pager" : null,
     "phone" : null
  },
 "firstName" : "John",
 "lastName" : "Doe",
 "login" : "johndoe",
 "password" : "",
 "profilName" : "My profile",
 "properties" :
  [
   {
      "key" : "property2",
      "value" : "value2"
   },
   {
      "key" : "property1",
      "value" : "value1"
   }
  ]
}

To retrieve the attributes of the current user, call getCurrentUser at /api/userprofile. This method has no required parameter.

2.05 Retrieve all users

Get all users that we have access to

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/userprofile/getAllUsers", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
 {
  "admin" : true,
  "contact" :
   {
      "address" : null,
      "id" : 11,
      "mail" : "johndoe-new@streetlight-vision.com",
      "name" : null,
      "pager" : null,
      "phone" : null
   },
  "firstName" : "John",
  "lastName" : "Doe",
  "login" : "johndoe",
  "password" : "",
  "profilName" : "My profile",
  "properties" :
   [
    {
       "key" : "property2",
       "value" : "value2"
    },
    {
       "key" : "property1",
       "value" : "value1"
    }
   ]
 },
 ...
]

To obtain the list of all users, call getAllUsers at /api/userprofile. This method has no required parameter.

2.06 Retrieve users under a specific geozone

Get all users under the geozone ID 1 and all of its sub-geozones

import requests

payload = {
  'geoZoneId': 1,
  'recurse': 'true',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/userprofile/getGeoZoneUsers", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

[
 {
  "admin" : true,
  "contact" :
   {
      "address" : null,
      "id" : 11,
      "mail" : "johndoe-new@streetlight-vision.com",
      "name" : null,
      "pager" : null,
      "phone" : null
   },
  "firstName" : "John",
  "lastName" : "Doe",
  "login" : "johndoe",
  "password" : "",
  "profilName" : "My profile",
  "properties" :
   [
    {
       "key" : "property2",
       "value" : "value2"
    },
    {
       "key" : "property1",
       "value" : "value1"
    }
   ]
 },
 ...
]

To obtain the list of all users whose user profile is under a specific geozone , call getGeoZoneUsers at /api/userprofile.

Arguments
geoZoneId (required) Desired top-level geozone
recurse If set to true, this method will also return the users whose user profile have a top-level geozone being a child of the geozone specified by geoZoneId. Set to false if not specified.

2.07 Delete a user

Delete the user test42

import requests

payload = {
  'login': 'test42', 
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/userprofile/deleteUser", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" : null
}

To delete a user, call the method deleteUser available at /api/userprofile. Note that if you try to delete a user that is not visible to you, you will get an error.

Arguments
login (required) Login name

2.08 Update the current user password

Set the password to newPass-1

import requests

payload = {
  'previousPassword': 'PASSWORD',
  'newPassword': 'newPass-1',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/userprofile/changePassword", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

"OK"

There is a specific method to update the current user password as the old password is required before a new password can be set. The method changePassword at /api/userprofile must be called to change a password. It only applies to the user who is currently logged in.

Arguments
previousPassword (required) Previous password
newPassword (required) New password

2.09 Recover a forgotten password

Ask the server to initiate the password recovery process for johndoe

import requests

payload = {
  'login': 'johndoe',
  'ser': 'json'
}

r = requests.post(SLV_URL + "/public/api/publicconfig/sendResetPasswordRequestByMail", data=payload)

Example response

"OK"

To trigger the password recovery mechanism, call the method sendResetPasswordRequestByMail available at /public/api/publicconfig. This method does not require any authentication!

Arguments
login (required) Login name

2.10 Verify a password

Check that the password PASSWORD is correct for the current user

import requests

payload = {
  'password': 'PASSWORD',
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/userprofile/checkPassword", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" : true
}

Even though you are already logged in, you may call the method checkPassword available at /api/userprofile to check that a password matches the password stored in the database for the current user.

Arguments
password (required) Password for the current user

3. Providers

The provider

A provider represents an electricity provider (a utility). It has a display name and holds a pollution rate, which enables the server to generate pollution saving numbers.

Provides are referenced by an internal ID generated by the server.

Attributes
id Internal ID (int)
name Name
pollution Number of kg of emitted CO2 per generated KWh
type provider by default

3.01 Create a provider

Create a provider called My new provider

import requests

payload = {
  'name': 'My new provider', 
  'pollutionRate': 0.42,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/assetmanagement/createProvider", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
  "id" : 3826,
  "name" : "My new provider",
  "pollution" : 0.42,
  "type" : "provider"
}

To create a new provider, call the method createProvider available at /api/assetmanagement.

Arguments
name (required) Provider name
pollutionRate (required) Number of kg of emitted CO2 per generated KWh (float)

3.02 Retrieve all providers

Get all providers

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getAllProviders", params=payload, auth=('USERNAME', 'PASSWORD'))

Example response

[
 {
  "id" : 4,
  "name" : "EDF",
  "pollution" : 0.11,
  "type" : "provider"
 },
 {
  "id" : 5,
  "name" : "RWE",
  "pollution" : 0.783,
  "type" : "provider"
 },
 ...
]

To retrieve the list of all providers, call the method getAllProviders available at /api/asset. This method has no required parameter.

3.03 Update a provider

Change the pollution rate of the provider ID 3826

import requests

payload = {
  'providerId': 3826,
  'newName': 'My new provider',
  'pollutionRate': 0.11,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/assetmanagement/updateProvider", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
 "id" : 3826,
 "name" : "My new provider",
 "pollution" : 0.11,
 "type" : "provider"
}

To change the name or the pollution rate of provider, you may call updateProvider available at /api/assetmanagement.

Arguments
providerId (required) Provider ID
newName (required) Provider name
pollutionRate (required) Number of kg of emitted CO2 per generated KWh (float)

3.04 Delete a provider

Delete the provider ID 3826

import requests

payload = {
  'id': 3826,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/assetmanagement/deleteProvider", data=payload, auth=('USERNAME', 'PASSWORD'))

Example response

{
 "errorCode" : "0",
 "errorCodeLabel" : null,
 "message" : null,
 "status" : "OK",
 "statusError" : false,
 "statusOk" : true,
 "value" : null
}

To delete a provider, call the method deleteProvider available at /api/assetmanagement.

Arguments
id (required) Provider ID

4. Lamp types

The lamp type (brand)

A brand is an object representing a lamp type in the SLV CMS. It is referenced by its internal server ID. Below are its main attributes:

Attributes
id Internal server ID (int)
name Brand textual ID
description Brand display name

A lamp type also has numerous optional attributes. The list of those attributes should be obtained directly from the server.

4.01 Create a lamp type

Creating a new lamp type identified as slv-lamp and called SLV Lamp with a couple of sample properties

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('name', 'slv-lamp'), 
  ('description', 'SLV Lamp'),
  ('propertyName', 'LampPower'),
  ('propertyValue', '85'),
  ('propertyName', 'Vno'),
  ('propertyValue', '230'),
  ('ser', 'json')
])

r = requests.post(SLV_CMS + "/api/assetmanagement/createBrand", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "label" : "SLV Lamp",
  "properties" :
    {
      "Vno" : "230",
      "name" : "slv-lamp",
      "description" : "SLV Lamp",
      "LampPower" : "85",
      "id" : "1163",
      "lifeTime" : "null"
    },
  "value" : 1163
}

To create a new lamp type, the method createBrand available at /api/assetmanagement should be used. A lamp type can have any number of arbitrary properties, so this method can take any number of propertyName/propertyValue pairs in addition to its required parameters.

Arguments
name (required) Brand textual ID
description (required) Brand display name
propertyName Property name
propertyValue Property value

The server reponse contains the server-generated internal ID (properties.id) that should be used for further operations on lamp types.

4.02 Update a lamp type

Updating the properties LampPower and Vno of the lamp type ID 1163

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('id', '1163'), 
  ('propertyName', 'LampPower'),
  ('propertyValue', '48'),
  ('propertyName', 'Vno'),
  ('propertyValue', '110'),
  ('ser', 'json')
])

r = requests.post(SLV_CMS + "/api/assetmanagement/updateBrand", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
 "label" : "SLV Lamp",
 "properties" :
    {
      "Vno" : "110",
      "name" : "slv-lamp",
      "description" : "SLV Lamp",
      "LampPower" : "48",
      "id" : "1163",
      "lifeTime" : "null"
    },
 "value" : 1163
}

To update the attributes of a lamp type, use the method updateBrand available at /api/assetmanagement. This method can take any number of propertyName/propertyValue pairs in addition to the required id.

Arguments
id (required) Internal server ID (int)
newName New brand textual ID
newDescription New drand display name
propertyName Property name
propertyValue Property value

4.03 Delete a lamp type

Deleting the lamp type ID 1163

import requests

payload = {
  'brandId': '1163', 
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/assetmanagement/deleteBrand", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" : null
}

To delete a lamp type from the server, use the method deleteBrand available at /api/assetmanagement.

Arguments
brandId (required) Internal server ID (int)

4.04 Retrieve all lamp types

Retrieving all lamp types

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getAllBrands", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "label" : "HPS 70W Ferro",
    "properties" :
      {
        "ILevel2min" : "0",
        "Vmax" : "250",
        "ILevel1min" : "100",
        "description" : "HPS 70W Ferro",
        "Ino" : "100",
        "CLOValue" : "100",
        "WarmUpTime" : "10",
        "CLOBHLimit" : "0",
        "Pmax" : "70",
        "PFmin" : "0.6",
        "Vmin" : "200",
        "ILevel1max" : "1300",
        "ILevel2max" : "2000",
        "Vno" : "180",
        "name" : "/SLV/HPS/70/MAG",
        "BHmax" : "20000",
        "id" : "1",
        "lifeTime" : "20000",
        "ControlVoltMax" : "0",
        "minOutputValue" : "0",
        "Interface" : "EM"
      },
    "value" : 1
  },
  ...
]

To retrieve all lamp types, use the method getAllBrands available at /api/asset. This method has no required parameter.

4.05 Retrieve all lamp type attributes

Retrieving all lamp type attributes

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/assetmanagement/getBrandPropertyDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
 {
    "category" : "standard",
    "criticity" : 0,
    "dataFormat" :
      {
        "defaultValue" : "Manufacturer/LampTechno/Power/BallastType"
      },
    "failure" : false,
    "help" : null,
    "label" : "Identifier",
    "labelKey" : "brand.property.strId.label",
    "name" : "LampType",
    "type" : "string",
    "unit" : null
 },
 ...
]

To retrieve the list of all lamp type attributes available on the server, use the method getBrandPropertyDescriptors available at /api/assetmanagement. This method has no required parameter.

If an attribute has a specific set of accepted values, its type will be select and dataFormat will list all accepted values.

4.06 Import lamp types with a CSV

The CSV file should be formatted as follows:

attribute1_name;attribute2_name;...;attributeN_name
lamptype1_attribute1_value;lamptype1_attribute2_value;...;lamptype1_attributeN_value
...
lamptypeM_attribute1_value;lamptypeM_attribute2_value;...;lamptypeM_attributeN_value

Importing lamp types from the file lamptypes.csv

import requests

with open('lamptypes.csv', 'r') as myfile:
  data=myfile.read()

payload = {
  'csvFile': data,
  'ser': 'json'
}
r = requests.post(SLV_URL + "/api/assetmanagement/importBrandsFromCsvFileAsync", data=payload, auth=('USERNAME', 'PASSWORD'))

print (r.text)

Sample response

{
  "batchId" : "1483606585540",
  "batchProgressMessage" : null,
  "batchProgressValue" : 0,
  "batchRunning" : true,
  "cancelRequested" : false,
  "cancelled" : false,
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    {
       "lineResults" :
          [
             {
                "errorMessages" : null,
                "errorMessagesCount" : 0,
                "inError" : false,
                "index" : 0,
                "infoMessagesCount" : 0,
                "messages" : null,
                "messagesCount" : 0,
                "ok" : false,
                "properties" : null,
                "state" : 0,
                "stateStr" : "-",
                "warning" : false,
                "warningMessages" : null,
                "warningMessagesCount" : 0
             }
          ],
       "lineResultsErrorCount" : 0,
       "lineResultsOkCount" : 0,
       "lineResultsUndefinedCount" : 1,
       "lineResultsWarningCount" : 0,
       "linesResultsCount" : 1,
       "properties" : null,
       "running" : true,
       "totalLinesResultsCount" : 1
    }
}

You may create new lamp types from a CSV file that contains their definition. To do so, use the method importBrandsFromCsvFileAsync available at /api/assetmanagement. It returns a batch object.

Arguments
csvFile (required) Content of the CSV file

5. Geozones

The geozone

A geozone is the equivalent of a folder in a file system. It can contain other geozones (sub-geozones) and devices. It also represents an rectangular area of the world map. It is identified by a server-generated ID. Below are its main attributes:

Attributes
id Geozone ID (int)
name Geozone name
type It will always be geozone
parentId ID of the parent geozone
idsPath List of geozone IDs that lead from the top-level geozone to this geozone
namesPath List of geozone names that lead from the top-level geozone to this geozone
latMax Maximum latitude (float)
latMin Minimum latitude (float)
lngMax Maximum longitude (float)
lngMin Minimum longitude (float)
devicesCount Number of devices
childrenCount Number of sub-geozones

5.01 Create a geozone

Creating a geozone called My new geozone under the geozone ID 1

import requests

payload = {
  'name': 'My new geozone', 
  'parentId': 1,
  'latMin': 48.79035455868981,
  'latMax': 48.92655972351346,
  'lngMin': 2.1097183227539067,
  'lngMax': 2.5491714477539067,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/assetmanagement/createGeozone", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "activityCardsCount" : 0,
  "childrenCount" : 0,
  "devicesCount" : 0,
  "hierarchyActivityCardsCount" : -1,
  "hierarchyDevicesCount" : -1,
  "id" : 3831,
  "idsPath" : "1/3831",
  "latMax" : 48.92655972351346,
  "latMin" : 48.79035455868981,
  "lngMax" : 2.5491714477539067,
  "lngMin" : 2.1097183227539067,
  "name" : "My new geozone",
  "namesPath" : "GeoZones/My new geozone",
  "parentId" : 1,
  "properties" : null,
  "type" : "geozone"
}

To create a geozone, call the method createGeozone available at /api/assetmanagement.

Arguments
name (required) Geozone name
parentId (required) ID of the parent geozone
latMax (required) Maximum latitude (float)
latMin (required) Minimum latitude (float)
lngMax (required) Maximum longitude (float)
lngMin (required) Minimum longitude (float)

5.02 Update a geozone

Updating the geozone ID 3831 with some additional properties

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('geozoneId', '3831'), 
  ('newName', 'Paris'), 
  ('lngMax', '2.5491714477539067'),
  ('lngMin', '2'),
  ('latMax','48.92655972351346'),
  ('latMin','48.79035455868981'),
  ('propertyName', 'virtual.energy.consumption.jan'),
  ('propertyValue', '18000'),
  ('propertyName', 'virtual.energy.consumption.feb'),
  ('propertyValue', '17500'),
  ('ser', 'json')
])

r = requests.post(SLV_CMS + "/api/assetmanagement/updateGeozone", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
   "activityCardsCount" : 0,
   "childrenCount" : 0,
   "devicesCount" : 0,
   "hierarchyActivityCardsCount" : -1,
   "hierarchyDevicesCount" : -1,
   "id" : 3831,
   "idsPath" : "1/3824/3831",
   "latMax" : 48.92655972351346,
   "latMin" : 48.79035455868981,
   "lngMax" : 2.5491714477539067,
   "lngMin" : 2.0,
   "name" : "Paris",
   "namesPath" : "GeoZones/Paris",
   "parentId" : 1,
   "properties" : null,
   "type" : "geozone"
}

To modify an existing geozone, call the method updateGeozone available at /api/assetmanagement. In addition to its main attribute, a geozone can have any number of optional arbitrary properties, so this method may take any number of propertyName/propertyValue pairs in addition to its required parameters.

Arguments
geozoneId (required) Geozone ID
newName (required) Geozone name
latMax (required) Maximum latitude (float)
latMin (required) Minimum latitude (float)
lngMax (required) Maximum longitude (float)
lngMin (required) Minimum longitude (float)
parentId ID of the new parent geozone
propertyName Property name
propertyValue Property value

5.03 Delete a geozone

Deleting the geozone ID 3831 and everything belonging to it

import requests

payload = {
  'geozoneId': '3831', 
  'pullUpContent': 'false',
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/assetmanagement/deleteGeozone", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

"OK"

To delete a geozone, use the method deleteGeozone available at /api/assetmanagement.

Arguments
geozoneId (required) Geozone ID
pullUpContent If set to true, moves the content of the geozone under the parent geozone. If set to false, deletes everything under the geozone. True by default

5.04 Retrieve all geozones

Retrieving all geozones

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getAllGeozones", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "activityCardsCount" : 0,
    "childrenCount" : 10,
    "devicesCount" : 7,
    "hierarchyActivityCardsCount" : -1,
    "hierarchyDevicesCount" : -1,
    "id" : 1,
    "idsPath" : "1",
    "latMax" : 80.0,
    "latMin" : -80.0,
    "lngMax" : 179.9999,
    "lngMin" : -179.9999,
    "name" : "GeoZones",
    "namesPath" : "GeoZones",
    "parentId" : null,
    "properties" : null,
    "type" : "geozone"
  },
...
]

To retrieve all geozones visible by the current user, use the method getAllGeozones available at /api/asset. It has no required parameter.

The method getGeozones available at /api/asset is equivalent to this method.

5.05 Retrieve a geozone

Retrieving the geozone ID 1

import requests

payload = {
  'id': 1,
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getGeozone", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "activityCardsCount" : 0,
  "childrenCount" : 4,
  "devicesCount" : 1,
  "hierarchyActivityCardsCount" : -1,
  "hierarchyDevicesCount" : -1,
  "id" : 1,
  "idsPath" : "1",
  "latMax" : 80.0,
  "latMin" : -80.0,
  "lngMax" : 179.9999,
  "lngMin" : -179.9999,
  "name" : "GeoZones",
  "namesPath" : "GeoZones",
  "parentId" : null,
  "properties" : null,
  "type" : "geozone"
}

To retrieve the basic properties of a geozone, you may use the method getGeozone available at /api/asset.

Arguments
geozoneId (required) Geozone ID

5.06 Retrieve optional properties

Retrieving the optional properties of the geozone ID 1

import requests

payload = {
  'geozoneId': 1,
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/assetmanagement/getGeozoneValueDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "standard",
    "criticity" : 0,
    "dataFormat" :
       {
          "min" : "0"
       },
    "failure" : false,
    "help" : null,
    "label" : "January kWh",
    "labelKey" : "db.meaning.virtual.energy.consumption.jan.label",
    "name" : "virtual.energy.consumption.jan",
    "type" : "int",
    "unit" : null
  }
  ...
]

To retrieve the optional properties of a geozone, you may use the method getGeozoneValueDescriptors available at /api/logging.

Arguments
geozoneId (required) Geozone ID

5.07 Retrieve optional values

Retrieving two optional values for geozone ID 1

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('geozoneId', '1'), 
  ('valueName', 'virtual.energy.consumption.jan'),
  ('valueName', 'virtual.energy.consumption.feb'),
  ('ser', 'json')
])

r = requests.post(SLV_CMS + "/api/logging/getGeozoneLastValues", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "eventTime" : "2016-12-05 00:00:00",
    "groupId" : 1,
    "info" : "",
    "meaningLabel" : "January kWh",
    "name" : "virtual.energy.consumption.jan",
    "updateTime" : "2016-12-05 00:00:00",
    "value" : 20000.0
  },
  {
    "eventTime" : "2016-12-05 00:00:00",
    "groupId" : 1,
    "info" : "",
    "meaningLabel" : "February kWh",
    "name" : "virtual.energy.consumption.feb",
    "updateTime" : "2016-12-05 00:00:00",
    "value" : 19000.0
  }
]

To retrive the values of those optional properties, use the method getGeozoneLastValues available at /api/logging. This method takes any number of valueName. The server response includes values in the same order as the request parameters.

Arguments
geozoneId (required) Geozone ID
valueName (required) Name of the optional attribute

5.08 Retrieve the top-level geozone

Retrieving the root geozone with geozone tree data

import requests

payload = {
  'computeHierarchyInfos': 'true',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getGeozoneRoot", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
   "activityCardsCount" : 0,
   "childrenCount" : 4,
   "devicesCount" : 1,
   "hierarchyActivityCardsCount" : 0,
   "hierarchyDevicesCount" : 43,
   "id" : 1,
   "idsPath" : "1",
   "latMax" : 80.0,
   "latMin" : -80.0,
   "lngMax" : 179.9999,
   "lngMin" : -179.9999,
   "name" : "GeoZones",
   "namesPath" : "GeoZones",
   "parentId" : null,
   "properties" : null,
   "type" : "geozone"
}

To retrieve the top-level (or root) geozone for the current user, use the method getGeozoneRoot available at /api/asset. This method has no required parameter.

Arguments
computeHierarchyInfos Set to true to obtain data about the whole geozone tree (e.g. hierarchyDevicesCount for the total number of devices). If set to false, the server will return -1 for that data. Defaults to false

5.09 Retrieve a geozone tree

Retrieving the geozone tree starting from geozone ID 1

import requests

payload = {
  'geozoneId': 1,
  'includeParentId': 'true',
  'includeIdsPath': 'true',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getGeoZoneHierarchyLight", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "label" : "GeoZones",
    "properties" :
       {
          "idsPath" : "1",
          "parentId" : "null"
       },
    "value" : 1
  },
  {
    "label" : "Chalais",
    "properties" :
       {
          "idsPath" : "1/28/24",
          "parentId" : "28"
       },
    "value" : 24
  },
  ...
]

To retrieve the list of all sub-geozones having a specific ancestor, use the method getGeozoneHierarchyLight available at /api/asset.

Arguments
geozoneId (required) Geozone ID
includeParentId Set to true to obtain the parent geozone ID in a separate variable in the response. Defaults to false
includeIdsPath Set to true to obtain the ID of all ancestors of each geozone listed, starting from the root geozone. Defaults to false

5.10 Retrieve direct sub-geozones

Retrieving the direct sub-geozone of geozone ID 1

import requests

payload = {
  'geozoneId': 1,
  'computeHierarchyInfos': 'true',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getGeoZoneChildrenGeoZones", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "activityCardsCount" : 0,
    "childrenCount" : 1,
    "devicesCount" : 0,
    "hierarchyActivityCardsCount" : 0,
    "hierarchyDevicesCount" : 4,
    "id" : 28,
    "idsPath" : "1/28",
    "latMax" : 48.93039429902821,
    "latMin" : 48.794425751649555,
    "lngMax" : 2.524795532226563,
    "lngMin" : 2.150230407714844,
    "name" : "Paris",
    "namesPath" : "GeoZones/Paris",
    "parentId" : 1,
    "properties" : null,
    "type" : "geozone"
  },
  ...
]

You may retrieve only the direct sub-geozones of a specific geozone by calling the method getGeozoneChildrenGeozones available at /api/asset.

Arguments
geozoneId (required) Geozone ID
computeHierarchyInfos Set to true to obtain data about the sub-geozone tree starting from that geozone (e.g. hierarchyDevicesCount for the total number of devices). If set to false, the server will return -1 for that data. Defaults to false

5.11 Search for a geozone by name

Searching for a geozone which name contains par

import requests

payload = {
  'name': 'par',
  'partialMatch': 'true',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/searchGeozones", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "activityCardsCount" : 0,
    "childrenCount" : 1,
    "devicesCount" : 0,
    "hierarchyActivityCardsCount" : -1,
    "hierarchyDevicesCount" : -1,
    "id" : 28,
    "idsPath" : "1/28",
    "latMax" : 48.93039429902821,
    "latMin" : 48.794425751649555,
    "lngMax" : 2.524795532226563,
    "lngMin" : 2.150230407714844,
    "name" : "Paris",
    "namesPath" : "GeoZones/Paris",
    "parentId" : 1,
    "properties" : null,
    "type" : "geozone"
  }
]

You can search for a geozone by name by using the method searchGeozones available at /api/asset.

Arguments
name (required) Name to search for
partialMatch Set to true to obtain results that partially match. Defaults to false

6. Batches

The batch

A batch is the result of an asynchronous operation (e.g. commissioning devices) that may take longer than a few seconds to complete. This enables any client to avoid blocking while waiting for the operation to complete. Below are its attributes:

Attributes
batchId Batch ID (int)
batchProgressMessage Message describing the status of the batch
batchProgressValue Percentage of completion of the batch. May be equal to -1 if the info is not available yet
batchRunning Indicates whether the batch has completed or not (boolean)
cancelRequested Indicates whether a cancel order has been issued for the batch (boolean)
cancelled Indicates whether the batch has been cancelled (boolean)
errorCode Error code
errorCodeLabel Description of the error
message Message describing the status of the batch
status Status of the batch (OK or ERROR)
statusError Indicates whether any error occured processing this batch (boolean)
statusOk Indicates whether any error occured processing this batch (boolean)
value Data structure provided by the underlying process

6.01 Retrieve the status of a batch

Retrieving the status of batch ID 1481016600181

import requests

payload = {
  'batchId': 1481016600181,
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/batch/getBatchResult", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "batchId" : "1481016600181",
  "batchProgressMessage" : "Commissioning process finished.",
  "batchProgressValue" : 100,
  "batchRunning" : false,
  "cancelRequested" : false,
  "cancelled" : false,
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    {
      "errorMessagesCount" : 0,
      "infoMessagesCount" : 4,
      "login" : "admin",
      "status" : 0,
      "stepResults" :
        [
          {
            "errorMessages" :
              [
              ],
            "errorMessagesCount" : 0,
            "infoMessages" :
              [
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "Inventory has been checked in the database and is consistent"
                }
              ],
            "infoMessagesCount" : 1,
            "label" : "Check database configuration",
            "messages" :
              [
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "Inventory has been checked in the database and is consistent"
                }
              ],
            "status" : 0,
            "stepLabel" : "Check database configuration",
            "stepName" : "check",
            "warningMessages" :
              [
              ],
            "warningMessagesCount" : 0
          },
          {
            "errorMessages" :
              [
              ],
            "errorMessagesCount" : 0,
            "infoMessages" :
              [
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "Devices configs are pushed using mode 'LIST'."
                },
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "2 devices in list. 2 were pushed. 0 were ignored and 0 were not pushed because not found on controller."
                },
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "All messages and configuration data have been sent and accepted by the controller"
                }
              ],
            "infoMessagesCount" : 3,
            "label" : "Commissioning",
            "messages" :
              [
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "Devices configs are pushed using mode 'LIST'."
                },
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "2 devices in list. 2 were pushed. 0 were ignored and 0 were not pushed because not found on controller."
                },
                {
                  "status" : 0,
                  "statusText" : "OK",
                  "text" : "All messages and configuration data have been sent and accepted by the controller"
                }
              ],
            "status" : 0,
            "stepLabel" : "Commissioning",
            "stepName" : "commissioning",
            "warningMessages" :
              [
              ],
            "warningMessagesCount" : 0
          }
        ],
      "warningMessagesCount" : 0
    }
}

To retrieve the status of a batch, use the method getBatchResult available at /api/batch.

Arguments
batchId (required) Batch ID (int)

7. Devices

The device

A device is identified by a server-generated ID. Despite its name, it may represent any object apart from a geozone. A device is always attached to a controller and has its own identifier on that controller.

Attributes
id Device ID (int)
name Device name
categoryStrId Device category
geozoneId ID of the parent geozone
controllerStrId Controller to which the device is attached
idOnController Device identifier on the controller
lat Latitude
lng Longitude

7.01 Retrieve all device categories

Retrieving all device categories

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getCategories", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
   {
      "displayName" : "Vehicle Charging Station",
      "hidden" : false,
      "strId" : "vehicleChargingStation"
   },
   {
      "displayName" : "Environmental Sensor",
      "hidden" : false,
      "strId" : "envSensor"
   },
   ...
] 

To retrive all device categories, use the method getCategories available at /api/asset. It has no required parameter.

7.02 Create a device

Creating a new controller device

import requests

payload = {
  'userName': 'My controller', 
  'categoryStrId': 'controllerdevice',
  'controllerStrId': 'mycontroller',
  'idOnController': 'controllerdevice',
  'geoZoneId':3837,
  'lat':48.84031689136024,
  'lng':2.3790979385375977,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/assetmanagement/createCategoryDevice", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "address" : null,
  "categoryStrId" : "controllerdevice",
  "controllerStrId" : "mycontroller",
  "functionId" : null,
  "geoZoneId" : 3837,
  "geoZoneNamesPath" : "GeoZones/My new geozone",
  "id" : 16872,
  "idOnController" : "controllerdevice",
  "lat" : 48.84031689136024,
  "lng" : 2.3790979385375977,
  "modelName" : null,
  "name" : "My controller",
  "nodeTypeStrId" : null,
  "properties" :
    [
      {
        "key" : "controller.firmwareVersion",
        "value" : null
      },
      {
        "key" : "firmwareVersion",
        "value" : null
      },
      {
        "key" : "controller.model",
        "value" : null
      },
      {
        "key" : "controller.host",
        "value" : null
      },
      {
        "key" : "controller.installDate",
        "value" : "2016/12/06 11:47:36"
      },
      {
        "key" : "controller.updateTime",
        "value" : ""
      },
      {
        "key" : "power",
        "value" : null
      },
      {
        "key" : "powerCorrection",
        "value" : null
      },
      {
        "key" : "tooltip",
        "value" : ""
      }
    ],
  "technologyStrId" : null,
  "type" : "device"
}

To create a device, use the method createCategoryDevice available at /api/assetmanagement. Since a device is always attached to a controller, you must specify a controller when creating a device.

Arguments
userName (required) Device name
categoryStrId (required) Device category
geozoneId (required) ID of the parent geozone
controllerStrId (required) Controller to which the device is attached. Use only lowercase letters and digits
idOnController (required) Device identifier on the controller. Use only lowercase letters and digits
lat (required) Latitude (float)
lng (required) Longitude (float)

7.03 Retrieve a device

Retrieving the device ID 16872

import requests

payload = {
  'deviceId': '16872',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getDevice", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "address" : null,
  "categoryStrId" : "controllerdevice",
  "controllerStrId" : "mycontroller",
  "functionId" : null,
  "geoZoneId" : 3837,
  "geoZoneNamesPath" : "GeoZones/My new geozone",
  "id" : 16872,
  "idOnController" : "controllerdevice",
  "lat" : 48.84031689136024,
  "lng" : 2.3790979385375977,
  "modelName" : null,
  "name" : "My controller",
  "nodeTypeStrId" : null,
  "properties" :
    [
      {
        "key" : "controller.firmwareVersion",
        "value" : "xmltech.v1"
      },
      {
        "key" : "firmwareVersion",
        "value" : "xmltech.v1"
      },
      {
        "key" : "controller.model",
        "value" : null
      },
      {
        "key" : "controller.host",
        "value" : "localhost:8005"
      },
      {
        "key" : "controller.installDate",
        "value" : "2016/12/06 11:47:36"
      },
      {
        "key" : "controller.updateTime",
        "value" : ""
      },
      {
        "key" : "power",
        "value" : null
      },
      {
        "key" : "powerCorrection",
        "value" : null
      },
      {
        "key" : "userproperty.ControllerCacheMode",
        "value" : "default"
      },
      {
        "key" : "userproperty.controller.auth.password",
        "value" : "password"
      },
      {
        "key" : "userproperty.reportFrequency",
        "value" : 60
      },
      {
        "key" : "userproperty.reportTime",
        "value" : "06:00"
      },
      {
        "key" : "userproperty.serverMsgUrl.webapp",
        "value" : "http://localhost:8080/reports"
      },
      {
        "key" : "userproperty.TimeZoneId",
        "value" : "Europe/Paris"
      },
      {
        "key" : "userproperty.timeout",
        "value" : 30000
      },
      {
        "key" : "userproperty.controller.auth.username",
        "value" : "user"
      },
      {
        "key" : "tooltip",
        "value" : ""
      }
    ],
  "technologyStrId" : null,
  "type" : "device"
}

To retrieve a device, use the method getDevice available at /api/asset.

Arguments
deviceId (required) Device ID (int)

7.04 Retrieve devices by geozone

Retrieving all streetlight and switch devices belonging to geozone ID 1 and its sub-geozones

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('geozoneId', 1),
  ('recurse','true'),
  ('categoryStrId', 'streetlight'),
  ('categoryStrId', 'switch'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/asset/getGeozoneDevices", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "address" : null,
    "categoryStrId" : "streetlight",
    "controllerStrId" : "meifoo",
    "functionId" : "Lamp1",
    "geoZoneId" : 1,
    "geoZoneNamesPath" : "GeoZones",
    "id" : 5238,
    "idOnController" : "227.lamp1",
    "lat" : 22.3476744529559,
    "lng" : 114.109046459198,
    "modelName" : "SysNode double DALI ballasts",
    "name" : "227.lamp1",
    "nodeTypeStrId" : "sysnode_dali_2b",
    "properties" :
       [
          {
             "key" : "dimmable",
             "value" : true
          },
          {
             "key" : "controller.firmwareVersion",
             "value" : "talq"
          },
          {
             "key" : "power",
             "value" : 100.0
          },
          {
             "key" : "powerCorrection",
             "value" : 20.0
          },
          {
             "key" : "lampTypeName",
             "value" : "/SLV/HPS/70/MAG"
          },
          {
             "key" : "lampLifeTime",
             "value" : 20000
          },
          {
             "key" : "userproperty.ballast.dimmingtype",
             "value" : "DALI LOG"
          },
          {
             "key" : "userproperty.DimmingGroupName",
             "value" : ""
          },
          {
             "key" : "userproperty.location.locationtype",
             "value" : "LOCATION_TYPE_PREMISE"
          },
          {
             "key" : "userproperty.network.highvoltagethreshold",
             "value" : 245
          },
          {
             "key" : "userproperty.network.lowvoltagethreshold",
             "value" : 215
          },
          {
             "key" : "userproperty.network.supplyvoltage",
             "value" : "120 Volts"
          },
          {
             "key" : "userproperty.OffLuxLevel",
             "value" : 30.0
          },
          {
             "key" : "userproperty.OnLuxLevel",
             "value" : 10.0
          },
          {
             "key" : "userproperty.PowerFactorThreshold",
             "value" : 0.6
          },
          {
             "key" : "tooltip",
             "value" : "SysNode double DALI ballasts[First ballast] - HPS 70W Ferro"
          }
       ],
    "technologyStrId" : "lonworks",
    "type" : "device"
  },
  ...
]

To retrieve all devices belonging to a specific geozone, use the method getGeozoneDevices available at /api/asset. You may restrict your search to certain device categories by specifying them using categoryStrId.

Arguments
geozoneId (required) Geozone ID (int)
recurse Set to true to obtain devices belonging to the whole geozone tree under the specified geozone. Defaults to false
categoryStrId Category ID (string)

7.05 Retrieve devices by controller

Retrieving all devices belonging to controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getControllerDevices", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "address" : "1-3 Rue de Chalais",
    "categoryStrId" : "streetlight",
    "controllerStrId" : "mycontroller",
    "functionId" : "dimmer0",
    "geoZoneId" : 24,
    "geoZoneNamesPath" : "GeoZones/Paris/Chalais",
    "id" : 45,
    "idOnController" : "lamp002",
    "lat" : 48.77389325261077,
    "lng" : 2.331140041351319,
    "modelName" : "XML Light Point v1",
    "name" : "Lamp 002",
    "nodeTypeStrId" : "xmllightpoint.v1",
    "properties" :
       [
          {
             "key" : "dimmable",
             "value" : true
          },
          {
             "key" : "controller.firmwareVersion",
             "value" : null
          },
          ...
       ],
    "technologyStrId" : "xmltech",
    "type" : "device"
  },
  ...
]

To retrieve all devices belonging to a specific controller, use the method getControllerDevices available at /api/asset.

Arguments
controllerStrId (required) Controller ID (string)

7.06 Retrieve devices within boundaries

Retrieving all devices with a latitude between 48.840 and 48.841 and a longitude between 2.378 and 2.381

import requests

payload = {
  'latMin':48.840,
  'latMax':48.841,
  'lngMin':2.378,
  'lngMax':2.381,
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getDevicesInBounds", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "address" : "5 Boulevard de Bercy",
    "categoryStrId" : "controllerdevice",
    "controllerStrId" : "newcontroller",
    "functionId" : null,
    "geoZoneId" : 3837,
    "geoZoneNamesPath" : "GeoZones/My new geozone",
    "id" : 16871,
    "idOnController" : "controllerdevice",
    "lat" : 48.84031689136024,
    "lng" : 2.3790979385375977,
    "modelName" : null,
    "name" : "New Controller",
    "nodeTypeStrId" : null,
    "properties" : null,
    "technologyStrId" : null,
    "type" : "device"
  },
  ...
]

To retrieve all devices within a certain geographical area, you may use the method getDevicesInBounds available at /api/asset.

Arguments
latMin (required) Minimum latitude (float)
latMax (required) Maximum latitude (float)
lngMin (required) Minimum longitude (float)
lngMax (required) Maximum longitude (float)
light If set to true, always returns properties=null. Defaults to true

7.07 Retrieve devices closest to a location

Retrieving the device closest to latitude 48.7735 and longitude 2.331145

import requests

payload = {
  'latMin': '48.773',
  'latMax': '48.774',
  'lngMin': '2.33114',
  'lngMax': '2.33115',
  'maxDevices': '1',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getDevicesNearCenter", params=payload, auth=('USERNAME', 'PASSWORD'))

print (r.text)

Sample response

[
  {
    "address" : "1-3 Rue de Chalais",
    "categoryStrId" : "streetlight",
    "controllerStrId" : "mycontroller",
    "functionId" : "dimmer0",
    "geoZoneId" : 24,
    "geoZoneNamesPath" : "GeoZones/Paris/Chalais",
    "id" : 45,
    "idOnController" : "lamp002",
    "lat" : 48.77389325261077,
    "lng" : 2.331140041351319,
    "modelName" : "XML Light Point v1",
    "name" : "Lamp 002",
    "nodeTypeStrId" : "xmllightpoint.v1",
    "properties" :
       [
          {
             "key" : "dimmable",
             "value" : true
          }
       ],
    "technologyStrId" : "xmltech",
    "type" : "device"
  }
]

You may also retrieve all devices within a certain geographical area and closest to the center of that area by using the method getDevicesNearCenter available at /api/asset.

Arguments
latMin (required) Minimum latitude (float)
latMax (required) Maximum latitude (float)
lngMin (required) Minimum longitude (float)
lngMax (required) Maximum longitude (float)
lightDevices If set to true, always returns properties=null. Defaults to true
maxDevices Maximum number of results to return. Unlimited by default

7.08 Retrieve a device timezone

Retrieve the timezone of device ID 16871

import requests

payload = {
  'deviceId':16871,
  'ser': 'json'
}


r = requests.get(SLV_URL + "/api/asset/getDeviceTimeZone", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
   "displayName" : "Central European Time [+01:00]",
   "dstSaving" : 3600000,
   "id" : "Europe/Paris",
   "rawOffset" : 3600000
}

To retrieve the timezone of a device, call the method getDeviceTimeZone available at /api/asset. The id provided in the result follows the nomenclature used in tzdata.

Arguments
deviceId (required) Device ID (int)

7.09 Retrieve all timezones

Retrieving all timezones available

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/controller/getAvailableTimezones", params=payload, auth=('admin', 'password'))

Sample response

[
  {
    "displayName" : "Niue Time [-11:00]",
    "dstSaving" : 0,
    "id" : "Pacific/Niue",
    "rawOffset" : -39600000
  },
  {
    "displayName" : "Samoa Standard Time [-11:00]",
    "dstSaving" : 0,
    "id" : "Pacific/Midway",
    "rawOffset" : -39600000
  },
  ...
]

You may retrieve the list of all timezones available on the server by calling the method getAvailableTimezones available at /api/controller. This method has no required parameter.

7.10 Retrieve all controllers

Retrieving all controllers

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getAllControllers", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "controllerDevice" :
       {
          "address" : "32 Avenue du Général Leclerc",
          "categoryStrId" : "controllerdevice",
          "controllerStrId" : "mycontroller",
          "functionId" : null,
          "geoZoneId" : 24,
          "geoZoneNamesPath" : "GeoZones/Chalais",
          "id" : 43,
          "idOnController" : "controllerdevice",
          "lat" : 48.77430688385805,
          "lng" : 2.3315960168838505,
          "modelName" : null,
          "name" : "My Controller",
          "nodeTypeStrId" : null,
          "properties" :
             [
                {
                   "key" : "controller.firmwareVersion",
                   "value" : null
                },
                {
                   "key" : "firmwareVersion",
                   "value" : null
                },
                {
                   "key" : "controller.model",
                   "value" : null
                },
                {
                   "key" : "controller.host",
                   "value" : "localhost:8005"
                },
                {
                   "key" : "controller.installDate",
                   "value" : "2016/01/04 16:32:28"
                },
                {
                   "key" : "controller.updateTime",
                   "value" : ""
                },
                {
                   "key" : "power",
                   "value" : null
                },
                {
                   "key" : "powerCorrection",
                   "value" : null
                },
                {
                   "key" : "tooltip",
                   "value" : ""
                }
             ],
          "technologyStrId" : null,
          "type" : "device"
       },
    "firmwareVersion" : null,
    "geoZoneNamesPath" : "GeoZones/Chalais",
    "host" : "10.0.0.1:8123",
    "id" : null,
    "installDate" : "2016-01-04 16:32:28",
    "model" : null,
    "name" : "My Controller",
    "strId" : "mycontroller",
    "type" : "controller",
    "updateDate" : null
  },
  ...
]

You may retrieve the list of all devices of type "Controller" created on the server by calling the method getAllControllers available at /api/asset. This method has no required parameter.

7.11 Retrieve a controller

Retrieving the controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getController", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "controllerDevice" :
    {
       "address" : "32 Avenue du Général Leclerc",
       "categoryStrId" : "controllerdevice",
       "controllerStrId" : "mycontroller",
       "functionId" : null,
       "geoZoneId" : 24,
       "geoZoneNamesPath" : "GeoZones/Paris/Chalais",
       "id" : 43,
       "idOnController" : "controllerdevice",
       "lat" : 48.77430688385805,
       "lng" : 2.3315960168838505,
       "modelName" : null,
       "name" : "My Controller",
       "nodeTypeStrId" : null,
       "properties" :
          [
             {
                "key" : "controller.firmwareVersion",
                "value" : null
             },
             {
                "key" : "firmwareVersion",
                "value" : null
             },
             {
                "key" : "controller.model",
                "value" : null
             },
             {
                "key" : "controller.host",
                "value" : "localhost:8005"
             },
             {
                "key" : "controller.installDate",
                "value" : "2016/01/04 16:32:28"
             },
             {
                "key" : "controller.updateTime",
                "value" : ""
             },
             {
                "key" : "power",
                "value" : null
             },
             {
                "key" : "powerCorrection",
                "value" : null
             },
             {
                "key" : "tooltip",
                "value" : ""
             }
          ],
       "technologyStrId" : null,
       "type" : "device"
    },
  "firmwareVersion" : null,
  "geoZoneNamesPath" : "GeoZones/Paris/Chalais",
  "host" : "localhost:8005",
  "id" : null,
  "installDate" : "2016-01-04 16:32:28",
  "model" : null,
  "name" : "My Controller",
  "strId" : "mycontroller",
  "type" : "controller",
  "updateDate" : null
}

You may retrieve a Controller device by its ID by using the method getController available at /api/asset.

Arguments
controllerStrId (required) Controller ID (string)

7.12 Retrieve controllers using a dimming group

Retriving all controllers that are using the dimming group DimmingLED in geozone ID 1

import requests

payload = {
  'name': 'DimmingLED',
  'geozoneId': '1',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/asset/getControllerStrIdsFromDimmingGroup", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample result

[
  "SLV_Demo",
  "mycontroller"
]

You may identify controllers that are using a specific dimming group by using the method getControllerStrIdsFromDimmingGroup available at /api/asset

Arguments
name (required) Dimming group name
geozoneId Geozone ID (int). Defaults to the user's root geozone

7.12 Retrieve device clusters

Retrieving three clusters for streetlight devices with a latitude between 48 and 49 and a longitude between 2 and 3, belonging to geozone ID 1

import requests

payload = {
  'latMin': '48',
  'latMax': '49',
  'lngMin': '2',
  'lngMax': '3',
  'geozoneId': '1',
  'categoryStrId': 'streetlight',
  'clustersCount': 3,
  'recurse': 'true',
  'ser': 'json'
}


r = requests.get(SLV_URL + "/api/asset/getDevicesClusters", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "count" : 6,
    "latCentroid" : 48.87324464444057,
    "latMax" : 48.8733940038274,
    "latMin" : 48.8729958829734,
    "lngCentroid" : 2.3232760045190664,
    "lngMax" : 2.32348952227755,
    "lngMin" : 2.32307431094284,
    "mass" : 6.0,
    "variance" : 3.5834473048150056E-7
  },
  {
    "count" : 3,
    "latCentroid" : 48.773893252457334,
    "latMax" : 48.7740452713285,
    "latMin" : 48.773741233432744,
    "lngCentroid" : 2.331140041351319,
    "lngMax" : 2.3312956094741826,
    "lngMin" : 2.330984473228455,
    "mass" : 3.0,
    "variance" : 9.4623402446814E-8
  },
  {
    "count" : 9,
    "latCentroid" : 48.873119329399664,
    "latMax" : 48.8734423459107,
    "latMin" : 48.8727135300601,
    "lngCentroid" : 2.3218937703299423,
    "lngMax" : 2.32268138241508,
    "lngMin" : 2.3209068826408,
    "mass" : 9.0,
    "variance" : 0.0000032950002138123737
  }
]

You may retrieve device clusters by calling the method getDevicesClusters available at /api/asset. You may restrict the results to certain device categories by specifying them using categoryStrId.

Arguments
latMin (required) Minimum latitude (float)
latMax (required) Maximum latitude (float)
lngMin (required) Minimum longitude (float)
lngMax (required) Maximum longitude (float)
geozoneId Geozone ID (int). Defaults to the root geozone
categoryStrId Device categories
clusterCount Maximum number of clusters to return. Defaults to 10
recurse Set to true to include devices belonging to sub-geozones. Defaults to false

7.13 Update a device

Updating the location of the device mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId','mycontroller'),
  ('idOnController','controllerdevice'),
  ('valueName', 'lat'),
  ('value','48.84031689136024'),
  ('valueName', 'lng'),
  ('value','2.3790979385375977'),
  ('doLog', 'true'),
  ('ser', 'json')
])

r = requests.post(SLV_CMS + "/api/loggingmanagement/setDeviceValues", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
   "errorCode" : "0",
   "errorCodeLabel" : null,
   "message" : null,
   "status" : "OK",
   "statusError" : false,
   "statusOk" : true,
   "value" :
      [
         "OK:48.84031689136024",
         "OK:2.3790979385375977"
      ]
}

To update a device, use the method setDeviceValues available at /api/loggingmanagement. You must specify the device to update by its controllerStrId and idOnController attributes. The method setDeviceValues can be used to set any number of arbitrary device attributes by taking any number of valueName/value pairs.

You may also use the method setDeviceValue (without the final "s"). However, it accepts only a single (valueName,value) pair.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
valueName (required) Attribute name
value (required) Attribute value
doLog Set to true to log historical changes in the database. Defaults to false
eventTime Date and time at which the device has been created, in the format YYYY-MM-DD HH:mm:ss (e.g. 2016-08-02 11:45:00). If not specified, it will be automatically generated by the server
createDevice Set to true to create the specified device if it does not exist. Defaults to false

7.14 Delete a device

Deleting the device lamp3 on controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'lamp3',
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/assetmanagement/deleteDevice", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response python "OK"

To delete a single device, use the method deleteDevice available at /api/assetmanagement

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

7.15 Delete devices

Deleting devices lamp1 and lamp2 on controller mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp1'),
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp2'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/assetmanagement/deleteDevices", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    [
      "OK",
      "OK"
    ]
}

To delete devices in bulk, use the method deleteDevices available at /api/assetmanagement and specify any number of controllerStrId/idOnController pairs.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

7.16 Replace lamps

Replacing the lamps of both devices lamp1 and lamp2 on controller mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp1'),
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp2'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/monitoringmanagement/replaceLamps", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    [
      "OK",
      "OK"
    ]
}

You may replace the lamp on a streetlight device by calling the method replaceLamps available at '/api/monitoringmanagement'. It is possible to specify any number of devices on which to perform this operation by using multiple controllerStrId/idOnController pairs.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

7.17 Replace smart nodes

Replacing the smart nodes of both devices lamp1 (new unique address: A1) and lamp2 (new unique address: A2) on controller mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp1'),
  ('newNetworkId','A1'),
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp2'),
  ('newNetworkId', 'A2'),
  ('ser','json')
])

r = requests.post(SLV_URL + "/api/monitoringmanagement/replaceOLCs", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    [
      "OK",
      "OK"
    ]
}

You may replace the smart node on a streetlight device by calling the method replaceOLCs available at '/api/monitoringmanagement'. It is possible to specify any number of devices on which to perform this operation by using multiple controllerStrId/idOnController/newNetworkId tuples.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
newNetworkId (required) Unique address of the new smart node

7.18 Commission controllers

Commissioning the controller configuration and devices on controller mycontroller

import requests

payload = {
  'controllerStrId':'mycontroller',
  'flags': 5,
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/controllermanagement/commissionControllerAsync", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "batchId" : "1481018818069",
  "batchProgressMessage" : null,
  "batchProgressValue" : -1,
  "batchRunning" : true,
  "cancelRequested" : false,
  "cancelled" : false,
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    {
      "errorMessagesCount" : 0,
      "infoMessagesCount" : 0,
      "login" : "admin",
      "status" : 0,
      "stepResults" :
        [
        ],
      "warningMessagesCount" : 0
    }
}

To commission a controller, i.e. the controller itself and all devices attached to it, use the method commissionControllerAsync available at /api/controllermanagement.

Arguments
controllerStrId (required) Controller to commission
flags (required) Indicates which items should be commissioned (int)

The flags parameter should be specified depending on whether you would like to commission the controller configuration, the dimming schedules applicable to the controller devices or/and the controller devices.

Flag Value
Controller configuration 1
Calendar and schedules 2
Controller devices 4

If you want to commission more than one item, simply add the corresponding values.

As commissioning a controller may take a long time, this method returns a batch object.

7.19 Commission specific devices

Commissioning devices lamp1 and lamp2 on controller mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId', 'mycontroller'),
  ('idOnController','lamp1'),
  ('idOnController','lamp2'),
  ('ser','json')
])

r = requests.post(SLV_URL + "/api/controllermanagement/commissionControllerDevicesListAsync", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "batchId" : "1481011141616",
  "batchProgressMessage" : null,
  "batchProgressValue" : -1,
  "batchRunning" : true,
  "cancelRequested" : false,
  "cancelled" : false,
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    {
      "errorMessagesCount" : 0,
      "infoMessagesCount" : 0,
      "login" : "admin",
      "status" : 0,
      "stepResults" :
        [
        ],
      "warningMessagesCount" : 0
    }
}

To commission a list of devices that are not controllers, use the method commissionControllerDevicesListAsync available at /api/controllermanagement. It is possible to commission multiple devices at once as long as they all belong to the same controller. To do so, specify multiple idOnController.

As commissioning devices may take a long time, this method returns a batch object.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

7.20 Import devices with a CSV

The CSV file should be formatted as follows:

attribute1_name;attribute2_name;...;attributeN_name
device1_attribute1_value;device1_attribute2_value;...;device1_attributeN_value
...
deviceM_attribute1_value;deviceM_attribute2_value;...;deviceM_attributeN_value

Importing devices via a CSV file (devices.csv)

import requests

with open('devices.csv', 'r') as myfile:
  data=myfile.read()

payload = {
  'csvFile': data,
  'ser': 'json'
}

r = requests.post(SLV_URL + "/api/loggingmanagement/importDevicesFromCsvFileAsync", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "batchId" : "1483515808928",
  "batchProgressMessage" : null,
  "batchProgressValue" : 0,
  "batchRunning" : true,
  "cancelRequested" : false,
  "cancelled" : false,
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    {
       "lineResults" :
          [
             null
          ],
       "lineResultsErrorCount" : 0,
       "lineResultsOkCount" : 0,
       "lineResultsUndefinedCount" : 0,
       "lineResultsWarningCount" : 0,
       "linesResultsCount" : 0,
       "properties" : null,
       "running" : true,
       "totalLinesResultsCount" : 1
    }
}

You may create devices in bulk by importing a CSV file. The method to use is importDevicesFromCsvFileAsync, available at /api/loggingmanagement.

Arguments
csvFile (required) Content of the CSV file
separatorChar CSV separator. Defaults to semicolon
quoteChar CSV quote character. Defaults to null

7.21 Import devices with a SDP

Importing devices via an SDP file (devices.sdp)

import requests

params = {'ser': 'json'}
payload = {'importSchedulers': 'false'}
files = {'sdpFile': ('devices.sdp', open('devices.sdp', 'rb'), 'application/octet-stream')}


r = requests.post(SLV_URL + "/api/loggingmanagement/importDevicesFromSdpFileAsync", params=params, data=payload, files=files, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "batchId" : "1483517633500",
  "batchProgressMessage" : null,
  "batchProgressValue" : -1,
  "batchRunning" : true,
  "cancelRequested" : false,
  "cancelled" : false,
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    {
       "login" : "admin",
       "project" : null,
       "projectDisplayName" : null,
       "properties" : null,
       "running" : true,
       "status" : 0,
       "stepResults" :
          [
          ]
    }
}

You may also create devices in bulk by importing a SDP file for powerline projects. The method to use in this case is importDevicesFromSdpFileAsync, available at /api/loggingmanagement.

Arguments
sdpFile (required) Content of the SDP file
importSchedulers Set to true to also import schedulers contained in the SDP file. Defaults to true

7.22 Search for devices

Searching for devices whose name contain lamp in geozone ID 1, limiting results to 2

import requests

payload = {
  'geozoneId': '1',
  'recurse': 'true',
  'returnedInfo': 'lightDevicesList',
  'attributeName': 'name',
  'attributeOperator': 'partial-match-i',
  'attributeValue': 'lamp',
  'maxResults': 2,
  'ser': 'json'
}


r = requests.get(SLV_URL + "/api/asset/searchDevicesExt", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    [
       {
          "address" : "1-3 Rue de Chalais",
          "categoryStrId" : "streetlight",
          "controllerStrId" : "mycontroller",
          "functionId" : "dimmer0",
          "geoZoneId" : 24,
          "geoZoneNamesPath" : "GeoZones/Chalais",
          "id" : 44,
          "idOnController" : "lamp001",
          "lat" : 48.7740452713285,
          "lng" : 2.3312956094741826,
          "modelName" : "XML Light Point v1",
          "name" : "Lamp 001",
          "nodeTypeStrId" : "xmllightpoint.v1",
          "properties" :
             [
                {
                   "key" : "dimmable",
                   "value" : true
                }
             ],
          "technologyStrId" : "xmltech",
          "type" : "device"
       },
       {
          "address" : "1-3 Rue de Chalais",
          "categoryStrId" : "streetlight",
          "controllerStrId" : "mycontroller",
          "functionId" : "dimmer0",
          "geoZoneId" : 24,
          "geoZoneNamesPath" : "GeoZones/Chalais",
          "id" : 45,
          "idOnController" : "lamp002",
          "lat" : 48.77389325261077,
          "lng" : 2.331140041351319,
          "modelName" : "XML Light Point v1",
          "name" : "Lamp 002",
          "nodeTypeStrId" : "xmllightpoint.v1",
          "properties" :
             [
                {
                   "key" : "dimmable",
                   "value" : true
                }
             ],
          "technologyStrId" : "xmltech",
          "type" : "device"
       }
    ]
}

You may search for devices by using the method searchDevicesExt available at /api/asset. Each search criterion requires you to specify the attribute name being searched for, the search operator and the searched value. It is possible to add multiple search critiera by specifying multiple tuples (attributeName,attributeOperator,attributeValue); they will be linked with a logical AND by the server.

Arguments
geozoneId ID of the geozone to search into. Defaults to the root geozone
recurse Set to true to search in all sub-geozones recursively. Defaults to false
returnedInfo Determines what kind of result is provided by the server, see below. Defaults to lightDevicesList
attributeName Searched attribute name
attributeOperator Search operator (see getDevicesLastValuesExtAsPaginatedArray for the list of accepted operators)
attributeValue Searched value. If the search operator is binary, the two values should be separated by a pipe
maxResults Maximum number of results to be returned by the server

Below is a description of each possible value for returnedInfo:

Value Description
lightDevicesList List of matching devices with only basic information about each device
devicesList List of matching devices with extended information about each device
ids List of the IDs of matching devices
devicesCount Number of matching devices

8. Device attributes

8.01 Retrieve device inventory attributes

Retrieving all inventory attributes for the device mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'controllerdevice',
  'configFilePath': 'adminEquipmentsDeviceCardConfigs.xml',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/logging/getDeviceValueDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "internal",
    "criticity" : 0,
    "dataFormat" :
      {
        "readOnly" : "true",
        "max.length" : "32",
        "format" : "[a-zA-Z0-9\\[\\]_\\-@!:\\. ]+",
        "mainGroup" : "controller.identity",
        "mainGroup.labelKey" : "mainGroup.controller.identity.label",
        "subGroup" : "controller.identity.group1",
        "subGroup.labelKey" : "subGroup.controller.identity.group1.label",
        "mainGroup.label" : "Identity",
        "subGroup.label" : "Identity of the controller"
      },
    "failure" : false,
    "help" : null,
    "label" : "Controller ID",
    "labelKey" : "db.meaning.controllerstrid.label",
    "name" : "controllerStrId",
    "type" : "string",
    "unit" : null
  },
  ...
]

To retrieve all inventory attributes available for a device, use the method getDeviceValueDescriptors available at /api/logging.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
configFilePath (required) Always set to adminEquipmentsDeviceCardConfigs.xml

8.02 Retrieve virtual device inventory attributes

Retrieving the inventory attributes for electrical meters. Note that in this example, for illustrative purposes we have added a second property (geozone) which actually has no influence on the server response.

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('propertyName', 'categoryStrId'),
  ('propertyValue', 'electricalCounter'),
  ('propertyName', 'geozone'),
  ('propertyValue', 'GeoZones/Paris'),
  ('configFilePath', 'adminEquipmentsDeviceCardConfigs.xml'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getVirtualDeviceValueDescriptors", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "internal",
    "criticity" : 0,
    "dataFormat" :
       {
          "max.length" : "32",
          "editable" : "false",
          "mandatory" : "true",
          "format" : "[a-zA-Z0-9\\[\\]_\\-@!:\\. ]+",
          "select.listingApiCall" : "SLVAssetAPI!getAllControllers",
          "select.listingApiCall.labelPropertyName" : "name",
          "select.listingApiCall.valuePropertyName" : "strId",
          "mainGroup" : "energymeter.identity",
          "mainGroup.labelKey" : "mainGroup.energymeter.identity.label",
          "subGroup" : "energymeter.identity.group1",
          "subGroup.labelKey" : "subGroup.energymeter.identity.group1.label",
          "mainGroup.label" : "Identity",
          "subGroup.label" : "Identity of the energy meter"
       },
    "failure" : false,
    "help" : null,
    "label" : "Controller ID",
    "labelKey" : "db.meaning.controllerstrid.label",
    "name" : "controllerStrId",
    "type" : "select",
    "unit" : null
  },
  ...
]

You can also retrieve all inventory attributes available for a type of device without specifying an existing device. To do so, use the method getVirtualDeviceValueDescriptors available at /api/logging. This method takes an arbitrary number of (propertyName, propertyValue) pairs, but you will probably want to use a single pair to specify the device type, for instance propertyName = categoryStrId and propertyValue = streetlight.

Arguments
propertyName (required) Device attribute name
propertyValue (required) Device attribute value
configFilePath (required) Always set to adminEquipmentsDeviceCardConfigs.xml

8.03 Retrieve all device inventory attributes

Retrieving all device inventory attributes available

import requests

payload = {
  'configFilePath': 'adminEquipmentsDeviceCardConfigs.xml',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/logging/getAllDevicesMeteringValueDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "internal",
    "criticity" : 0,
    "dataFormat" :
       {
          "max.length" : "32",
          "editable" : "false",
          "mandatory" : "true",
          "format" : "[a-zA-Z0-9\\[\\]_\\-@!:\\. ]+",
          "select.listingApiCall" : "SLVAssetAPI!getAllControllers",
          "select.listingApiCall.labelPropertyName" : "name",
          "select.listingApiCall.valuePropertyName" : "strId",
          "mainGroup" : "networkcomponent.identity",
          "mainGroup.labelKey" : "mainGroup.networkcomponent.identity.label",
          "subGroup" : "networkcomponent.identity.group1",
          "subGroup.labelKey" : "subGroup.networkcomponent.identity.group1.label",
          "mainGroup.label" : "Identity",
          "subGroup.label" : "Identity of the Network Component"
       },
    "failure" : false,
    "help" : null,
    "label" : "Controller ID",
    "labelKey" : "db.meaning.controllerstrid.label",
    "name" : "controllerStrId",
    "type" : "select",
    "unit" : null
  },
  ...
]

To retrieve all device inventory attributes available, you may call the method getAllDevicesMeteringValueDescriptors available at /api/logging.

Arguments
configFilePath (required) Always set to adminEquipmentsDeviceCardConfigs.xml

8.04 Retrieve device logging attributes

Retrieving all inventory attributes for the device mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'controllerdevice',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/logging/getDeviceValueDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "standard",
    "criticity" : 0,
    "dataFormat" : null,
    "failure" : false,
    "help" : null,
    "label" : "Digital Input 1",
    "labelKey" : "db.meaning.digitalinput1.label",
    "name" : "DigitalInput1",
    "type" : "boolean",
    "unit" : null
  },
  ...
]

To retrieve all logging attributes available for a device, use the method getDeviceValueDescriptors available at /api/logging without specifying any configFilePath.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

8.05 Retrieve device attributes by name

Retrieving the description of the attributes lat and lng

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('valueName', 'lat'),
  ('valueName', 'lng'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getDeviceValueDescriptorsByName", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" :
    [
      {
        "category" : "internal",
        "criticity" : 0,
        "dataFormat" :
           {
           },
        "failure" : false,
        "help" : null,
        "label" : "lat",
        "labelKey" : null,
        "name" : "lat",
        "type" : "double",
        "unit" : null
      },
      {
        "category" : "internal",
        "criticity" : 0,
        "dataFormat" :
           {
           },
        "failure" : false,
        "help" : null,
        "label" : "lng",
        "labelKey" : null,
        "name" : "lng",
        "type" : "double",
        "unit" : null
      }
    ]
}

You may retrieve the description and details of device attributes if you always know their name by using the method getDeviceValueDescriptorsByName available at /api/logging. You may specify any number of attributes.

Arguments
valueName (required) Attribute name

8.06 Retrieve existing values for an attribute

Retrieving all existing values for the attribute luminaire.type

import requests

payload = {
  'valueName': 'luminaire.type',
  'quick': 'true',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/logging/getDistinctExistingValues", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "properties" :
      {
        "count" : "2"
      },
    "value" : "Type A"
  },
  {
    "properties" :
      {
        "count" : "1"
      },
    "value" : "Type B"
  }
]

You may retrieve the list of existing values for an inventory attribute by calling the method getDistinctExistingValues available at /api/logging.

Arguments
valueName (required) Attribute name
quick Defaults to false
geozoneId Geozone ID (int). Defaults to the user's root geozone
recurse Set to true to search through devices belonging to all sub-geozones. Defaults to true

8.07 Retrieve attributes by file

Retrieve all device attributes in gcCustomReportReportValuesSelected.xml

import requests

payload = {
  'configFilePath': 'gcCustomReportReportValuesSelected.xml',
  'ser': 'json'
}


r = requests.get(SLV_URL + "/api/logging/getAllDevicesValueDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "internal",
    "criticity" : 0,
    "dataFormat" :
      {
        "max.length" : "77",
        "mainGroup" : "controller.inventory",
        "mainGroup.labelKey" : "mainGroup.controller.inventory.label",
        "subGroup" : "controller.inventory.location",
        "subGroup.labelKey" : "subGroup.lightpoint.inventory.location.label",
        "subGroup.collapsed" : "true",
        "ExcludeFromCommissioning" : "true",
        "mainGroup.label" : "Inventory",
        "subGroup.label" : "Location"
      },
    "failure" : false,
    "help" : null,
    "label" : "Address 1",
    "labelKey" : "db.meaning.address.label",
    "name" : "address",
    "type" : "string",
    "unit" : null
  },
  ...
]

You may retrieve all device attributes listed in a server-side configuration file by calling the method getAllDevicesValueDescriptors available at /api/logging.

Arguments
configFilePath (required) File name

The following file names are available:

File name Description
gcCustomReportReportValues.xml
gcCustomReportReportValuesSelected.xml
gcCustomReportReportValuesFavorites.xml
gcDataHistoryReportValues.xml
gcDataHistoryReportValuesSelected.xml
gcDataHistoryReportValuesFavorites.xml
gcEquipmentsReportValues.xml
gcEquipmentsReportValuesSelected.xml
gcEquipmentsReportValuesFavorites.xml

8.08 Retrieve devices attributes by file and category

Retrieving electrical counter attributes from the server configuration file batchApplicationDeviceCardConfigs.xml

import requests

payload = {
  'categoryStrId': 'electricalCounter',
  'configFilePath': 'batchApplicationDeviceCardConfigs.xml',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/logging/getCategoryDevicesValueDescriptors", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "category" : "standard",
    "criticity" : 0,
    "dataFormat" : null,
    "failure" : false,
    "help" : null,
    "label" : "Lamp wattage (W)",
    "labelKey" : "db.meaning.power.label",
    "name" : "Power",
    "type" : "float",
    "unit" : "W"
  },
  {
    "category" : "standard",
    "criticity" : 0,
    "dataFormat" : null,
    "failure" : false,
    "help" : null,
    "label" : "Power - L1 (W)",
    "labelKey" : "db.meaning.phase1power.label",
    "name" : "PowerPhase1",
    "type" : "float",
    "unit" : "W"
  },
  ...
]

You may retrieve device attributes listed in a server-side configuration for specific categories and that are applicable to existing devices only by calling the method getCategoryDevicesValueDescriptors available at /api/logging.

Arguments
categoryStrId (required) Device category. Muutiple categories can be specified by separating them with a pipe character
configFilePath (required) File name

8.09 Retrieve attributes values for a single device

Retrieving the latitude and longitude of device ID 16879

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('param0', '16879'),
  ('valueName', 'lat'),
  ('valueName', 'lng'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getDeviceLastValues", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "controllerStrId" : "mycontroller",
    "deviceId" : 16879,
    "errorMessage" : null,
    "eventTime" : null,
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "lamp1",
    "info" : null,
    "meaningLabel" : null,
    "name" : "lat",
    "status" : "OK",
    "updateTime" : null,
    "value" : 48.84032042200468
  },
  {
    "controllerStrId" : "mycontroller",
    "deviceId" : 16879,
    "errorMessage" : null,
    "eventTime" : null,
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "lamp1",
    "info" : null,
    "meaningLabel" : null,
    "name" : "lng",
    "status" : "OK",
    "updateTime" : null,
    "value" : 2.3801171779632573
  }
]

To retrieve the latest values for a single device attributes, use the method getDeviceLastValues available at /api/logging. You may retrieve the value of multiple attributes at once by specifying multiple valueName.

Arguments
param0 (required) Device ID (int)
valueName (required) Attribute name
returnTimeAges Set to true to retrieve information about when those values have been recorded. Defaults to false

8.10 Retrieve attributes values for multiple devices

Retrieving the latitude and longitude of devices ID 16879 and 16880

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('param0', '16879'),
  ('param0', '16880'),
  ('param1', 'lat'),
  ('param1', 'lng'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getDevicesLastValues", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "controllerStrId" : "mycontroller",
    "deviceId" : 16879,
    "errorMessage" : null,
    "eventTime" : null,
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "lamp1",
    "info" : null,
    "meaningLabel" : null,
    "name" : "lat",
    "status" : "OK",
    "updateTime" : null,
    "value" : 48.84032042200468
  },
  {
    "controllerStrId" : "mycontroller",
    "deviceId" : 16879,
    "errorMessage" : null,
    "eventTime" : null,
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "lamp1",
    "info" : null,
    "meaningLabel" : null,
    "name" : "lng",
    "status" : "OK",
    "updateTime" : null,
    "value" : 2.3801171779632573
  },
  {
    "controllerStrId" : "mycontroller",
    "deviceId" : 16880,
    "errorMessage" : null,
    "eventTime" : null,
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "lamp2",
    "info" : null,
    "meaningLabel" : null,
    "name" : "lat",
    "status" : "OK",
    "updateTime" : null,
    "value" : 48.840272758283675
  },
  {
    "controllerStrId" : "mycontroller",
    "deviceId" : 16880,
    "errorMessage" : null,
    "eventTime" : null,
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "lamp2",
    "info" : null,
    "meaningLabel" : null,
    "name" : "lng",
    "status" : "OK",
    "updateTime" : null,
    "value" : 2.380476593971253
  }
]

To retrieve the latest values for multiple devices, use the method getDevicesLastValues available at /api/logging. You may specify multiple param0 and param1 to retrieve the value of several attributes on more than one device.

Arguments
param0 (required) Device ID (int)
param1 (required) Attribute name

8.11 Retrieve attributes values for multiple devices in an array

Retrieving the latitude and longitude of devices ID 10828 and 10829

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('deviceId', '10828'),
  ('deviceId', '10829'),
  ('valueName', 'lat'),
  ('valueName', 'lng'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getDevicesLastValuesAsArray", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "columnLabels" : null,
  "columns" :
    [
       "lat",
       "lng"
    ],
  "columnsCount" : 2,
  "properties" :
    {
    },
  "rowsCount" : 2,
  "values" :
    [
       [
          35.15467904755724,
          129.12042617797854
       ],
       [
          35.154731678957035,
          129.12062466144565
       ]
    ]
}

To retrieve the latest values for multiple devices in a more condensed format, use the method getDevicesLastValuesAsArray available at /api/logging. You may specify multiple deviceId and valueName to retrieve the value of several attributes on more than one device.

Arguments
devceId (required) Device ID (int)
valueName (required) Attribute name

8.12 Retrieve attributes values for a whole geozone

Retrieving the name, latitude and longitude of all streetlights and controllers in geozone ID 3837. We also want to rename the columns in the result from lat and lng to Latitude and Longitude.

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('geozoneId', '3837'),
  ('categoryStrId', 'streetlight'),
  ('categoryStrId', 'controllerdevice'),
  ('valueName', 'name'),
  ('valueName', 'lat'),
  ('valueName', 'lng'),
  ('columnName', 'lat:Latitude'),
  ('columnName', 'lng:Longitude'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getGeoZoneDevicesLastValuesAsArray", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "columnLabels" : null,
  "columns" :
    [
       "name",
       "Latitude",
       "Longitude"
    ],
  "columnsCount" : 3,
  "properties" :
    {
    },
  "rowsCount" : 4,
  "values" :
    [
       [
          "New Controller",
          48.84031689136024,
          2.3790979385375977
       ],
       [
          "My controller",
          48.84031689136024,
          2.3790979385375977
       ],
       [
          "Lamp 1",
          48.84032042200468,
          2.3801171779632573
       ],
       [
          "Lamp 2",
          48.840272758283675,
          2.380476593971253
       ]
    ]
}

To retrieve the latest values for all devices belonging to a geozone, use the method getGeozoneDevicesLastValuesAsArray available at /api/logging. You may specify multiple categories and attributes by adding multiple categoryStrId and valueName to your request.

In the server response, columns will list the attribute names by default. If you would like to receive different names instead, you may specify multiple columnName, one per attribute to rename, in the format attribute name:desired column name.

Arguments
geozoneId (required) Geozone ID (int)
categoryStrId (required) Category
valueName (required) Attribute name
columnName Mapping between the attribute name and the desired column name
recurse Set to true to obtain devices belonging to the whole geozone tree under the specified geozone. Defaults to false

8.13 Retrieve paginated attributes values for a whole geozone

Retrieving the name, latitude and longitude of all devices in geozone ID 3837, with two devices per page and reading the second page.

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('geozoneId', '3837'),
  ('returnedValueName', 'name'),
  ('returnedValueName', 'lat'),
  ('returnedValueName', 'lng'),
  ('pageSize', '2'),
  ('pageIndex', '1'),
  ('recurse', 'false'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getDevicesLastValuesExtAsPaginatedArray", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "columnLabels" : null,
  "columns" :
    [
       "name",
       "lat",
       "lng"
    ],
  "columnsCount" : 3,
  "pageIndex" : 1,
  "pageSize" : 2,
  "pagesCount" : 3,
  "properties" :
    {
    },
  "rowsCount" : 2,
  "totalSize" : 5,
  "values" :
    [
       [
          "My controller",
          48.84031689136024,
          2.3790979385375977
       ],
       [
          "Lamp 1",
          48.84032042200468,
          2.3801171779632573
       ]
    ]
}

To retrieve the latest values for all devices belonging to a geozone, but with a paginated response from the server, use the method getDevicesLastValuesExtAsPaginatedArray available at /api/logging. You may specify multiple attributes by adding multiple returnedValueName to your request.

Arguments
geozoneId (required) Geozone ID (int)
returnedValueName (required) Attribute name
pageSize (required) Number of devices per page
pageIndex (required) Page number, starting from zero
recurse (required) Set to true to obtain devices belonging to the whole geozone tree under the specified geozone
addEventTimeColumns Set to true to retrieve the date and time at which those values have been recorded. Defaults to false
filterAttributeName Searched attribute name
filterAttributeOperator Search operator
filterAttributeValue Searched value. If the search operator is binary, the two values should be separated by a pipe
sortColumn Sort attribute name
sortDesc Set to true to sort in descending order, false in ascending order

You may also restrict the results by adding search criteria. Each search criterion requires you to specify the attribute name being searched for, the search operator and the searched value. It is possible to add multiple search critiera by specifying multiple tuples (filterAttributeName, filterAttributeOperator, filterAttributeValue). Search operators available are listed below:

Operator Description
eq EQUAL
ne NOT EQUAL
eq-i EQUAL IGNORE CASE
like LIKE
like-i LIKE IGNORE CASE
partial-match PARTIAL MATCH
partial-match-i PARTIAL MATCH IGNORE CASE
in IN
gt GREATER THAN
ge GREATER OR EQUAL
lt LOWER THAN
le LOWER OR EQUAL
nin NOT IN
begins BEGINS
begins-i BEGINS IGNORE CASE
ends ENDS
ends-i ENDS IGNORE CASE
between BETWEEN

8.14 Retrieve attributes values for a whole geozone in a CSV file

Creating a CSV file called All devices named -lamp- in geozone 3837 with the name, latitude and longitude of all devices in geozone ID 3837 whose name contain lamp

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('geozoneId', '3837'),
  ('returnedValueName', 'name'),
  ('returnedValueName', 'lat'),
  ('returnedValueName', 'lng'),
  ('recurse', 'false'),
  ('filterAttributeName', 'name'),
  ('filterAttributeOperator', 'partial-match-i'),
  ('filterAttributeValue', 'lamp'),
  ('csvPropertyName', 'fileBaseName'),
  ('csvPropertyValue', 'All devices named -lamp- in geozone 3837'),
  ('csvPropertyName', 'separatorChar'),
  ('csvPropertyValue', ';'),
  ('csvPropertyName', 'header'),
  ('csvPropertyValue', 'true'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/createDevicesLastValuesExtAsPaginatedArrayCsvFileUrl", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode" : "0",
  "errorCodeLabel" : null,
  "message" : null,
  "status" : "OK",
  "statusError" : false,
  "statusOk" : true,
  "value" : "/repository/protected-files/exports/admin/e036605902c02dd00b6e4574cc4b9f53/All%20devices%20named%20-lamp-%20in%20geozone%203837.csv"
}

To obtain the latest values for all devices belonging to a geozone inside a CSV file, call the method createDevicesLastValuesExtAsPaginatedArrayCsvFileUrl available at /api/logging.

Arguments
geozoneId (required) Geozone ID (int)
returnedValueName (required) Attribute name
recurse (required) Set to true to obtain devices belonging to the whole geozone tree under the specified geozone
addEventTimeColumns Set to true to retrieve the date and time at which those values have been recorded. Defaults to false
filterAttributeName Searched attribute name
filterAttributeOperator Search operator
filterAttributeValue Searched value. If the search operator is binary, the two values should be separated by a pipe
csvPropertyName CSV property name
csvPropertyValue CSV property value

CSV properties are described below. Note that it is possible to specify multiple properties by adding several couples csvPropertyName/csvPropertyValue to your request.

CSV property name Description
fileBaseName CSV filename (excluding the .csv extension)
separatorChar CSV separator
header If set to true, includes a header line in the CSV file

The server responds with a file path in value. You may then download the file from the concatenation of SLV_URL and value.

8.15 Retrieve device logging history

Retrieving the values of LampLevel and LampCommandLevel on devices ID 5229 and 5230 between Nov 1st 2016 1:00pm and Nov 17th 2016 1:00pm

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('deviceId', '5229'),
  ('deviceId', '5230'),
  ('name', 'LampLevel'),
  ('name', 'LampCommandLevel'),
  ('from', '01/11/2016 13:00:00'),
  ('to', '17/11/2016 13:00:00'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/logging/getDevicesLogValues", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

[
  {
    "controllerStrId" : "flowermarket",
    "deviceId" : 5230,
    "errorMessage" : null,
    "eventTime" : "2016-11-07 11:00:00",
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "stl0002",
    "info" : "",
    "meaningLabel" : null,
    "name" : "LampLevel",
    "status" : "OK",
    "updateTime" : "2016-11-07 18:08:07",
    "value" : 100.0
  },
  {
    "controllerStrId" : "flowermarket",
    "deviceId" : 5229,
    "errorMessage" : null,
    "eventTime" : "2016-11-07 18:02:26",
    "eventTimeAgeInSeconds" : null,
    "idOnController" : "stl0001",
    "info" : "",
    "meaningLabel" : null,
    "name" : "LampCommandLevel",
    "status" : "OK",
    "updateTime" : "2016-11-07 18:02:26",
    "value" : 55.0
  },
   ...
]

To retrieve the values of a device logging attribute over a period of time, use the method getDevicesLogValues available at /api/logging. You may specify multiple devices and/or multiple attributes.

Arguments
deviceId (required) Device ID (int)
name (required) Attribute name
from (required) Start date and time in the format dd/MM/yyyy HH:mm:ss
to (required) End date and time in the format dd/MM/yyyy HH:mm:ss

9. Schedules

The schedule

A schedule is, in its simplest representation, a list of events (turn on, turn off, dim to a certain level) that devices must perform at specific times; those times may be absolute (e.g. 23:00) or relative to sunrise or sunset (e.g. five minutes before sunset). It is identified by a server-generated numeric ID and is attached to a geozone.

Attributes
id Schedule ID (int)
name Device name
type Always set to schedule
category Always set to STREETLIGHT_DIMMING
color Color used to represent the schedule on the user interface. This attribute provides individual numerical values for red, green, blue and alpha channels in addition to the HTML color code
description Textual description of the schedule
geozonePath Geozone path attached to the schedule
readOnly Indicates whether the current user is allowed to edit it (boolean)
template Unused
timeline Either T_12_12 for noon-to-noon or T_00_24 for midnight-to-midnight

See the next chapter for more details about schedule events.

9.01 Create a schedule

Creating a new schedule called "Simple schedule" with a few attributes

import requests

payload = {
  'name': 'Simple schedule', 
  'category': 'STREETLIGHT_DIMMING',
  'color': '#FF424242',
  'description': 'A sample schedule',
  'timeline': 'T_12_12',
  'template': '',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/createSchedule", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": 8
}

To create a new schedule, use the method createSchedule available at /api/dimmingscheduler. It returns the ID of the new schedule in value. A new schedule is always empty, so you need to add events to it: see the Schedule Events chapter for more details.

Arguments
name (required) Schedule name
color HTML code of the color used to represent the schedule on the user interface, including alpha channel
category Only STREETLIGHT_DIMMING is supported
description Textual description of the schedule
template Unused, leave empty
timeline Either T_12_12 for noon-to-noon or T_00_24 for midnight-to-midnight

9.02 Retrieve all schedules

Retrieving all schedules in the category 'STREETLIGHT_DIMMING'

import requests

payload = {
  'category': 'STREETLIGHT_DIMMING',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/dimmingscheduler/getSchedules", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": [
    {
      "category": "STREETLIGHT_DIMMING",
      "color": {
        "alpha": 255,
        "blue": 58,
        "code": "#ffb3313a",
        "green": 49,
        "red": 179
      },
      "description": "",
      "geoZonePath": "GeoZones",
      "id": 1,
      "name": "Simple scheduler",
      "readOnly": false,
      "template": "",
      "timeline": "T_12_12",
      "type": "schedule"
    }
  ]
}

To retrieve all schedules, use the method getSchedules available at /api/dimmingscheduler

Arguments
category Only STREETLIGHT_DIMMING is supported

9.03 Update a schedule

Updating schedule ID 8

import requests

payload = {
  'scheduleId': 8,
  'name': 'Simple SLV schedule', 
  'color': '#FFFF0000',
  'description': 'A simple updated schedule',
  'timeline': 'T_12_12',
  'template': '',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/updateSchedule", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": null
}

To update an existing schedule, use the method updateSchedule available at /api/dimmingscheduler.

Arguments
scheduleId (required) Schedule ID (int)
name Schedule name
color HTML code of the color used to represent the schedule on the user interface, including alpha channel
description Textual description of the schedule
template Unused, leave empty
timeline Either T_12_12 for noon-to-noon or T_00_24 for midnight-to-midnight

9.04 Delete a schedule

Deleting schedule ID 8

import requests

payload = {
  'scheduleId': 8,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/deleteSchedule", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": null
}

To delete a schedule, use the method deleteSchedule available at /api/dimmingscheduler.

Arguments
scheduleId (required) Schedule ID (int)

10. Schedule events

The schedule event

A schedule event can be either punctual or occur over a time period. In the former case, it only has a start time. In the latter case, it has both a start and an end time. In addition, when an event occurs over a sun-based time period, it can include other sub-events; those sub-events cannot occur if they fall outside of the time period of the parent event.

Note that schedule events are never updated: they are deleted then recreated if necessary.

Attributes
id Event ID (int)
name Event name
type Event type
start Start time
end End time
events List of events happening between start and end
level Dimming level (0 - 100)

Absolute start and end times are represented as follows:

Attributes
hour Hour (0-23)
minutes Minutes (0-59)
seconds Seconds (0-59)
milliseconds Milliseconds (0-999)
afterNoon Indicates whether the event occurs before or after noon (boolean)
afterNoonOrEqual Indicates whether the event occurs before or after noon (boolean)
beforeNoon Indicates whether the event occurs before or after noon (boolean)
beforeNoonOrEqual Indicates whether the event occurs before or after noon (boolean)
noon Indicates whether the event occurs exactly at noon (boolean)

Sun-based start and end times are represented as follows:

Attributes
offsetInSeconds Offset with the sun-based event in seconds. A negative number indicates a number of seconds before the event, while a positive number indicates a number of seconds after the event
sunEvent SUNRISE or SUNSET
afterNoon Indicates whether the event occurs before or after noon (boolean)
afterNoonOrEqual Indicates whether the event occurs before or after noon (boolean)
beforeNoon Indicates whether the event occurs before or after noon (boolean)
beforeNoonOrEqual Indicates whether the event occurs before or after noon (boolean)
noon Indicates whether the event occurs exactly at noon (boolean)

10.01 Add a sun-based schedule event

Adding a turn on event at 100% five minutes after sunset to schedule ID 9

import requests

payload = {
  'scheduleId': 9,
  'level':100,
  'startSunEvent':'SUNSET',
  'startOffsetInSeconds':300,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/addSunEventDayTimeScheduleEvent", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": 21
}

To add a sub-based schedule event, use the method addSunEventDayTimeScheduleEvent available at /api/dimmingscheduler. This method returns the event ID generated by the server.

Arguments
scheduleId (required) Schedule ID (int)
startSunEvent (required) Type of start event: SUNRISE or SUNSET
startOffsetInSeconds (required) Offset with the start event in seconds. A negative number indicates a number of seconds before the event, while a positive number indicates a number of seconds after the event
level (required) Dimming level (0 - 100)
endSunEvent Type of end event: SUNRISE or SUNSET
endOffsetInSeconds Offset with the end event in seconds. A negative number indicates a number of seconds before the event, while a positive number indicates a number of seconds after the event
parentEventId Parent event ID when the event is a child of another event
name Name of the event

10.02 Add an absolute schedule event

Adding a dimming event to 78% at 22:30:00 to schedule ID 9

import requests

payload = {
  'scheduleId': 9,
  'level':78,
  'startHour':22,
  'startMinute':30,
  'startSecond':0,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/addAbsoluteDayTimeScheduleEvent", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": 24
}

To add an absolute schedule event, use the method addAbsoluteDayTimeScheduleEvent available at /api/dimmingscheduler. This method returns the event ID generated by the server.

Arguments
scheduleId (required) Schedule ID (int)
startHour (required) Hour (0-23)
startMinute (required) Minutes (0-59)
startSecond (required) Seconds (0-59)
level (required) Dimming level (0 - 100)
parentEventId Parent event ID when the event is a child of another event
name Name of the event

10.03 Retrieve schedule events

Retrieving all events of the schedule ID 1

import requests

payload = {
  'scheduleId': 1,
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/dimmingscheduler/getScheduleEvents", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": [
    {
      "end": {
        "afterNoon": false,
        "afterNoonOrEqual": false,
        "beforeNoon": true,
        "beforeNoonOrEqual": true,
        "noon": false,
        "offsetInSeconds": -300,
        "sunEvent": "SUNRISE"
      },
      "events": [
        {
          "end": null,
          "events": [],
          "id": 2,
          "level": 50,
          "name": "",
          "start": {
            "afterNoon": false,
            "afterNoonOrEqual": false,
            "beforeNoon": true,
            "beforeNoonOrEqual": true,
            "hour": 0,
            "milliseconds": 0,
            "minutes": 0,
            "noon": false,
            "seconds": 0
          },
          "type": null
        },
        {
          "end": null,
          "events": [],
          "id": 3,
          "level": 100,
          "name": "",
          "start": {
            "afterNoon": false,
            "afterNoonOrEqual": false,
            "beforeNoon": true,
            "beforeNoonOrEqual": true,
            "hour": 4,
            "milliseconds": 0,
            "minutes": 0,
            "noon": false,
            "seconds": 0
          },
          "type": null
        }
      ],
      "id": 1,
      "level": 100,
      "name": "",
      "start": {
        "afterNoon": true,
        "afterNoonOrEqual": true,
        "beforeNoon": false,
        "beforeNoonOrEqual": false,
        "noon": false,
        "offsetInSeconds": 300,
        "sunEvent": "SUNSET"
      },
      "type": null
    }
  ]
}

To retrieve the list of all events in a schedule, use the method getScheduleEvents available at /api/dimmingscheduler.

Arguments
scheduleId (required) Schedule ID (int)

10.04 Delete schedule events

Deleting schedule event ID 28 from schedule ID 9

import requests

payload = {
  'scheduleId': 9,
  'scheduleEventId': 28,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/removeScheduleEvent", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": null
}

To delete an event from a schedule, use the method removeScheduleEvent available at /api/dimmingscheduler.

Arguments
scheduleId (required) Schedule ID (int)
scheduleEventId (required) Schedule event ID (int)

11. Schedulers

The scheduler

A scheduler is a list of rules indicating when devices should follow certain schedules. They are not to be confused with schedules! In the SLV user interface, they are also called dimming groups or calendars.

Attributes
id Scheduler ID (int)
name Scheduler name
description Textual description of the scheduler
geozonePath Geozone path attached to the scheduler
readOnly Indicates whether the current user is allowed to edit the scheduler (boolean)
type Always scheduler
start Unused
end Unused

11.01 Create a scheduler

Creating a new scheduler called "Simple calendar"

import requests

payload = {
  'name': 'Simple calendar', 
  'category': 'STREETLIGHT_DIMMING',
  'description': 'My new calendar',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/createScheduler", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": 6
}

To create a new scheduler, use the method createScheduler available at /api/dimmingscheduler. It returns the identifier of the new scheduler.

Arguments
name (required) Scheduler name
category Only STREETLIGHT_DIMMING is supported
description Textual description of the scheduler

11.02 Retrieve all schedulers

Retrieving all schedules in the category 'STREETLIGHT_DIMMING'

import requests

payload = {
  'category': 'STREETLIGHT_DIMMING',
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/dimmingscheduler/getSchedulers", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": [
    {
      "description": "My new calendar",
      "end": null,
      "geoZonePath": "GeoZones",
      "id": 6,
      "name": "Simple calendar",
      "readOnly": false,
      "start": null,
      "type": "scheduler"
    }
  ]
}

To retrieve all schedules, use the method getSchedulers available at /api/dimmingscheduler

Arguments
category Only STREETLIGHT_DIMMING is supported

11.03 Update a scheduler

Updating scheduler ID 6

import requests

payload = {
  'schedulerId': 6,
  'name': 'Simple calendar', 
  'description': 'Updated calendar',
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/updateScheduler", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": null
}

To update an existing scheduler, use the method updateScheduler available at /api/dimmingscheduler.

Arguments
schedulerId (required) Scheduler ID (int)
name Scheduler name
description Textual description of the scheduler

11.04 Add a schedule to a scheduler on a daily basis

Adding schedule ID 120 to the calendar ID 1234 on January 1st, 2019.

import requests

payload = {
  'schedulerId': 1268,
  'scheduleId': 120,
  'start': '01/01/2019',
  'end': '01/01/2019',
  'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/dimmingscheduler/addEveryDaySchedulerItemAt", data=payload, headers=token_header)

Sample response

{
  "status": "OK",
  "errorCode": "0",
  "errorCodeLabel": null,
  "value": {
    "scheduleId": 120,
    "recurrence": {
      "id": 771,
      "step": 1
    },
    "start": {
      "day": 1,
      "month": 1,
      "year": 2019
    },
    "end": {
      "day": 1,
      "month": 1,
      "year": 2019
    },
    "id": 771
  },
  "message": null,
  "statusOk": true,
  "statusError": false
}

To add a schedule to an existing scheduler on a daily basis, use the method addEveryDaySchedulerItemAt available at /api/dimmingscheduler.

Arguments
schedulerId (required) Scheduler ID (int)
scheduleId (required) Schedule ID (int)
start (required) Beginning of the period during which the specified schedule should be active, in the format DD/MM/YYYY
end (required) End of the period during which the specified schedule should be active, in the format DD/MM/YYYY

11.05 Add a schedule to a scheduler on a weekly basis

Adding schedule ID 120 to the calendar ID 1234 every Monday.

import requests

payload = {
  'schedulerId': 1234,
  'scheduleId': 120,
  'onMonday': 'true',
  'onTuesday': 'false',
  'onWednesday': 'false',
  'onThursday': 'false',
  'onFriday': 'false',
  'onSaturday': 'false',
  'onSunday': 'false',
  'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/dimmingscheduler/addEveryWeekSchedulerItemAt", data=payload, headers=token_header)

Adding schedule ID 30 to the calendar ID 1234 to every third Wednesday on the month.

import requests

payload = {
  'schedulerId': 1268,
  'scheduleId': 30,
  'onMonday': 'false',
  'onTuesday': 'false',
  'onWednesday': 'true',
  'onThursday': 'false',
  'onFriday': 'false',
  'onSaturday': 'false',
  'onSunday': 'false',
  'rankInMonth': 3,
  'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/dimmingscheduler/addEveryWeekSchedulerItemAt", data=payload, headers=token_header)

Sample response

{
  "status": "OK",
  "errorCode": "0",
  "errorCodeLabel": null,
  "value": {
    "scheduleId": 120,
    "recurrence": {
      "id": 514,
      "step": 1,
      "onMonday": true,
      "onTuesday": false,
      "onWednesday": false,
      "onThursday": false,
      "onFriday": false,
      "onSaturday": false,
      "onSunday": false,
      "rankInMonth": null,
      "lastRankInMonth": false
    },
    "start": null,
    "end": null,
    "id": 514
  },
  "message": null,
  "statusOk": true,
  "statusError": false
}

To add a schedule to an existing scheduler on a weekly basis, use the method addEveryWeekSchedulerItemAt available at /api/dimmingscheduler.

A schedule can be added on a specified day every week; in that case, do not set lastRankInMonth and rankInMonth.

It can also be added on the specified day on the N-th week every month. To do so, set rankInMonth to N.

Finally, to apply a schedule on the specified day on the last week every month, set lastRankInMonth to true.

Arguments
schedulerId (required) Scheduler ID (int)
scheduleId (required) Schedule ID (int)
onMonday (required) Set to true if the specified schedule applies to Mondays
onTuesday (required) Set to true if the specified schedule applies to Tuesdays
onWednesday (required) Set to true if the specified schedule applies to Wednesdays
onThursday (required) Set to true if the specified schedule applies to Thursdays
onFriday (required) Set to true if the specified schedule applies to Fridays
onSaturday (required) Set to true if the specified schedule applies to Saturdays
onSunday (required) Set to true if the specified schedule applies to Sundays
lastRankInMonth When set to true, the specified schedule only applies to the last week of each month. Defaults to false
rankInMonth When set, specifies which week of each month the schedule applies to (int)

11.06 Add a schedule to a scheduler on a monthly basis

Adding schedule ID 120 to calendar ID 1234 from the 5th to the 8th every month

import requests

payload = {
  'schedulerId': 1234,
  'scheduleId': 120,
  'fromDayInMonth': 5,
  'toDayInMonth': 8,
  'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/dimmingscheduler/addEveryMonthSchedulerItemAt", data=payload, headers=token_header)

Sample response

{
  "status": "OK",
  "errorCode": "0",
  "errorCodeLabel": null,
  "value": {
    "scheduleId": 120,
    "recurrence": {
      "id": 722,
      "step": null,
      "fromDayOfMonth": 5,
      "toDayOfMonth": 8,
      "lastDayOfMonth": null
    },
    "start": null,
    "end": null,
    "id": 722
  },
  "message": null,
  "statusOk": true,
  "statusError": false
}

To add a schedule to an existing scheduler on a monthly basis, use the method addEveryMonthSchedulerItemAt available at /api/dimmingscheduler. You may add a schedule to a single day of the month by specifying the same value for fromDayInMonth and toDayInMonth. You may also add a schedule that only applies to the last day of each month by setting lastDayInMonth to true.

Arguments
schedulerId (required) Scheduler ID (int)
scheduleId (required) Schedule ID (int)
fromDayInMonth Beginning of the monthly period during which the specified schedule should be active (1-31)
toDayInMonth End of the monthly period during which the specified schedule should be active. Must be greater or equal to fromDayInMonth
lastDayInMonth When set to true, the specified schedule only applies to the last day of each month. Defaults to false

11.07 Add a schedule to a scheduler on a yearly basis

Adding schedule ID 120 to calendar ID 1234 from February 14th to February 20th every year

import requests

payload = {
  'schedulerId': 1234,
  'scheduleId': 120,
  'fromMonth': 2,
  'fromDayInMonth': 14,
  'toMonth': 2,
  'toDayInMonth': 20,
  'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/dimmingscheduler/addEveryYearSchedulerItemAt", data=payload, headers=token_header)

Sample response

{
  "status": "OK",
  "errorCode": "0",
  "errorCodeLabel": null,
  "value": {
    "scheduleId": 120,
    "recurrence": {
      "id": 757,
      "step": null,
      "fromMonth": 2,
      "toMonth": 2,
      "fromDayInMonth": 14,
      "toDayInMonth": 20,
      "lastDayInMonth": null
    },
    "start": null,
    "end": null,
    "id": 757
  },
  "message": null,
  "statusOk": true,
  "statusError": false
}

To add a schedule to an existing scheduler on a yearly basis, use the method addEveryYearSchedulerItemAt available at /api/dimmingscheduler. You may add a schedule to a single day of the year by specifying the same value for the pairs <fromMonth, fromDayInMonth> and <toMonth, toDayInMonth>.

Arguments
schedulerId (required) Scheduler ID (int)
scheduleId (required) Schedule ID (int)
fromMonth Month of the beginning of the yearly period during which the specified schedule should be active (1-12)
fromDayInMonth Day of the beginning of the yearly period during which the specified schedule should be active (1-31)
toMonth Month of the end of the yearly period during which the specified schedule should be active (1-12)
toDayInMonth Day of the end of the yearly period during which the specified schedule should be active (1-31)

11.08 Remove all items from a scheduler

Removing all items from scheduler ID 42

import requests

payload = {
  'schedulerId': 42,
  'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/dimmingscheduler/removeAllSchedulerItems", data=payload, headers=token_header)

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": null
}

To clear a scheduler, use the method removeAllSchedulerItems available at /api/dimmingscheduler.

Arguments
schedulerId (required) Scheduler ID (int)

11.09 Delete a scheduler

Deleting scheduler ID 6

import requests

payload = {
  'schedulerId': 6,
  'ser': 'json'
}

r = requests.post(SLV_CMS + "/api/dimmingscheduler/deleteScheduler", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": null
}

To delete a scheduler, use the method deleteScheduler available at /api/dimmingscheduler.

Arguments
schedulerId (required) Scheduler ID (int)

11.10 Retrieve the number of devices using each scheduler

Retrieving the number of devices using each scheduler

import requests

payload = {
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/dimmingscheduler/getDimmingSchedulersUsage", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": [
    {
      "properties": {
        "count": "1"
      },
      "value": 3
    },
    {
      "properties": {
        "count": "0"
      },
      "value": 5
    },
    {
      "properties": {
        "count": "2"
      },
      "value": 1
    },
    {
      "properties": {
        "count": "0"
      },
      "value": 2
    },
    {
      "properties": {
        "count": "10829"
      },
      "value": 4
    }
  ]
}

To obtain the number of devices associated with each scheduler, you may use the method getDimmingSchedulersUsage available at /api/dimmingscheduler. This method takes no parameter and provides those numbers for all schedulers visible to the current user.

In the server response, value contains the scheduler ID while properties.count provides the corresponding number of devices.

11.11 Retrieve controllers using a scheduler

Retrieve controllers using the scheduler ID 4

import requests

payload = {
  'schedulerId': 4,
  'ser': 'json'
}

r = requests.get(SLV_URL + "/api/dimmingscheduler/getDimmingSchedulerUsage", params=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
   "errorCode" : "0",
   "errorCodeLabel" : null,
   "message" : null,
   "status" : "OK",
   "statusError" : false,
   "statusOk" : true,
   "value" :
      {
         "properties" :
            {
               "controllerNames" : "Controller 1, Controller 2",
               "count" : "10829",
               "controllerStrIds" : "controller1,controller2"
            },
         "value" : 4
      }
}

To retrieve the list of all controllers using a specific scheduler, use the method getDimmingSchedulerUsage available at /api/dimmingscheduler.

Arguments
schedulerId (required) Scheduler ID (int)

The list of controllers is provided in the server response in properties.controllerStrIds and properties.controllerNames. controllerStrIds lists the controllers by their IDs while controllerNames lists them by their display name, all separated by commas. Both variables list controllers in the same order.

value repeats the schedulerId and properties.count contains the total number of devices using the specified scheduler.

11.12 Commission a scheduler

Commissioning scheduler ID 4 on two controllers controller1 and controller2

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('schedulerId', 4),
  ('controllerStrId', 'controller1'),
  ('controllerStrId', 'controller2'),
  ('ser', 'json')
])

r = requests.post(SLV_URL + "/api/dimmingscheduler/commissionControllersSchedulers", data=payload, auth=('USERNAME', 'PASSWORD'))

Sample response

{
  "batchId": "1490953624522",
  "batchProgressMessage": null,
  "batchProgressValue": 0,
  "batchRunning": true,
  "cancelRequested": false,
  "cancelled": false,
  "errorCode": "0",
  "errorCodeLabel": null,
  "message": null,
  "status": "OK",
  "statusError": false,
  "statusOk": true,
  "value": {
    "errorMessagesCount": 0,
    "infoMessagesCount": 0,
    "login": null,
    "status": 0,
    "stepResults": [
      {
        "errorMessages": [],
        "errorMessagesCount": 0,
        "infoMessages": [],
        "infoMessagesCount": 0,
        "label": "Task for commissioning schedulers on controller 'controller1'",
        "messages": [],
        "status": 0,
        "stepLabel": "Task for commissioning schedulers on controller 'controller1'",
        "stepName": "controller1",
        "warningMessages": [],
        "warningMessagesCount": 0
      },
      {
        "errorMessages": [],
        "errorMessagesCount": 0,
        "infoMessages": [],
        "infoMessagesCount": 0,
        "label": "Task for commissioning schedulers on controller 'controller2'",
        "messages": [],
        "status": 0,
        "stepLabel": "Task for commissioning schedulers on controller 'controller2'",
        "stepName": "controller2",
        "warningMessages": [],
        "warningMessagesCount": 0
      }
    ],
    "warningMessagesCount": 0
  }
}

To commission a scheduler on a controller, i.e. to ask the server to send the relevant scheduling information to the controller onsite, you may call the method commissionControllersSchedulers available at /api/dimmingscheduler.

Arguments
schedulerId (required) Scheduler ID (int)
controllerStrId (required) Controller ID (string)

It is possible to commission multiple controllers at once by specifying multiple controllerStrId.

This method returns a batch object.

12. Real-time control

12.01 Retrieve the dimming level of a device

Retrieve the dimming level of mydevice associated with the controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'mydevice',
  'ser': 'json'
}

r = my_session.get(SLV_URL + "/api/dimming/getDimmingLevel", params=payload, headers=token_header)

Sample response

100.0

To retrieve the dimming level of a device, use the method getDimmingLevel available at /api/dimming. It returns a float between 0 and 100 corresponding to the current dimming level reported by the device.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
maxAge Maximum age of the value to be returned (float). Support may vary depending on the control technology. Set it to zero to retrieve the dimming level from the device (as opposed to from the SLV database). Defaults to zero.

12.02 Update the dimming level of a device

Change the dimming level of mydevice associated with the controller mycontroller to 42%

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'mydevice',
  'dimmingLevel': '42',
  'ser': 'json'
}

r = my_session.get(SLV_URL + "/api/dimming/setDimmingLevel", params=payload, headers=token_header)

Sample response

"OK"

To update the dimming level of a device, use the method setDimmingLevel available at /api/dimming. It returns a string indicating whether the command has been successfully sent to the device.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
dimmingLevel (required) Target dimming level (integer from 0 to 100)

12.03 Retrieve the dimming mode of a device

Retrieve the dimming mode of mydevice associated with the controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'mydevice',
  'ser': 'json'
}

r = my_session.get(SLV_URL + "/api/dimming/getDimmingMode", params=payload, headers=token_header)

Sample response

["AUTOMATIC"]

To retrieve the dimming mode of a device, use the method getDimmingMode available at /api/dimming. It returns either AUTOMATIC or MANUAL.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
maxAge Maximum age of the value to be returned (float). Support may vary depending on the control technology. Set it to zero to retrieve the dimming level from the device (as opposed to from the SLV database). Defaults to zero.

12.04 Move a device back to automatic mode

Move mydevice associated with the controller mycontroller back to automatic mode

import requests

payload = MultiDict([
  ('controllerStrId','mycontroller'),
  ('idOnController','mydevice'),
  ('ser', 'json')
])

r = my_session.post(SLV_URL + "/api/dimming/exitManualModes", data=payload, headers=token_header)

Sample response

{
    "status": null,
    "errorCode": "0",
    "errorCodeLabel": null,
    "value": [
        "OK"
    ],
    "message": null,
    "statusError": false,
    "statusOk": false
}

To move a device back to automatoc mode, use the method exitManualModes available at /api/dimming. You may specify multiple pairs of controllerStrId and idOnController to move several devices back to automatic mode at once.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

12.05 Retrieve device metering attributes

Retrieve all metering attributes for the device mydevice associated with the controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'mydevice',
  'ser': 'json'
}

r = my_session.get(SLV_URL + "/api/dimming/getDeviceMeteringValueDescriptors", params=payload, headers=token_header)

Sample response

[
    {
        "category": "standard",
        "criticity": 0,
        "dataFormat": null,
        "failure": false,
        "help": null,
        "label": "Lamp level feedback",
        "labelKey": "db.meaning.lamplevel.label",
        "name": "LampLevel",
        "type": "float",
        "unit": "%"
    },
    ...

To retrieve the device metering attributes available for a device, use the method getDeviceMeteringValueDescriptors available at /api/dimming. You can then retrieve their value in real-time using the method getDeviceFormattedMeteringValues.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

12.06 Retrieve values of device metering attributes

Retrieve the real-time value of Current and MainVoltage for the device mydevice associated with the controller mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId', 'mycontroller'),
  ('idOnController', 'mydevice'),
  ('meteringValueName', 'Current'),
  ('meteringValueName', 'MainVoltage'),
  ('ser', 'json')
])

r = my_session.post(SLV_URL + "/api/dimming/getDeviceFormattedMeteringValues", data=payload, headers=token_header)

Sample response

["0.436A","248.8V"]

To retrieve the value of metering attributes on a device, use the method getDeviceFormattedMeteringValues available at /api/dimming. You may retrieve the value of multiple attributes at once by specifying multiple meteringValueName.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
meteringValueName (required) Name of the attribute to retrieve
maxAge Maximum age of the value to be returned (float). Support may vary depending on the control technology. Set it to zero to retrieve values from the device (as opposed to from the SLV database). Defaults to zero.

12.07 Retrieve device failure attributes

Retrieve all failure attributes for the device mydevice associated with the controller mycontroller

import requests

payload = {
  'controllerStrId': 'mycontroller',
  'idOnController': 'mydevice',
  'ser': 'json'
}

r = my_session.get(SLV_URL + "/api/dimming/getDeviceFailureDescriptors", params=payload, headers=token_header)

Sample response

[
    {
        "category": "standard",
        "criticity": 1,
        "dataFormat": null,
        "failure": true,
        "help": null,
        "label": "Lamp failure",
        "labelKey": "db.failuremeaning.lampfailure.label",
        "name": "LampFailure",
        "type": "boolean",
        "unit": null
    },
    ...

To retrieve the device failure attributes available for a device, use the method getDeviceFailureDescriptors available at /api/dimming. You can then retrieve their value in real-time using the method getDeviceFailureOnValues.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller

12.08 Retrieve values of device failure attributes

Retrieve the real-time value of Lamp failure and Low lamp voltage for the device mydevice associated with the controller mycontroller

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('controllerStrId', 'mycontroller'),
  ('idOnController', 'mydevice'),
  ('failureName', 'LampFailure'),
  ('failureName', 'LowLampVoltage'),
  ('ser', 'json')
])

r = my_session.post(SLV_URL + "/api/dimming/getDeviceFailureOnValues", data=payload, headers=token_header)

Sample response

[false,false]

To retrieve the value of failure attributes on a device, use the method getDeviceFailureOnValues available at /api/dimming. You may retrieve the value of multiple attributes at once by specifying multiple failureName.

It returns an array of boolean values.

Arguments
controllerStrId (required) Controller to which the device is attached
idOnController (required) Device identifier on the controller
failureName (required) Name of the attribute to retrieve
maxAge Maximum age of the value to be returned (float). Support may vary depending on the control technology. Set it to zero to retrieve values from the device (as opposed to from the SLV database). Defaults to zero.

13. Reports

The report object

A report object corresponds to a report definition as visible in the Report Manager application in the SLV UI. It controls the computation on fixed schedules of reports that can be sent by email or FTP. Reports are always defined for a particular GeoZone.

Attributes Description
id Report ID (string)
name Report name
scheduledReportTemplateImplClassName Report type (see section Report types below)
geoZoneId Identifier of the GeoZone attached to the report
propertyValues Report properties
lastScheduledTime Time of the last scheduled run
nextScheduledTime Time of the next scheduled run
schedulerInfo Textual description of the report schedule
timeZone Time zone in which lastScheduledTime and nextScheduledTime are expressed

Report types

Below is the list of default report types available in SLV:

Name in the SLV UI scheduledReportTemplateImplClassName
Advanced Search Report com.slv.reporting.scheduledreports.impl.search.AdvancedSearchReportTemplate
Citigis report com.slv.reporting.scheduledreports.impl.citigis.CitigisScheduledReportTemplate
Day Burner Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.DayBurner
Failures HTML report com.slv.reporting.scheduledreports.impl.failures.FailuresApplicationReportTemplate
Failures processing time com.slv.reporting.scheduledreports.impl.failures.FailureProcessingTimeReportTemplate
Failures report com.slv.reporting.scheduledreports.impl.failures.DailyFailuresReportTemplate
Generic device last values com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesReportTemplate
Generic device values com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableValuesReportTemplate
Generic device values [Run Once] com.slv.reporting.scheduledreports.impl.devicevariablevalues.SingleScheduledDateGroupDevicesVariableValuesReportTemplate
Latency Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.CommandFeedbackLatencyReportTemplate
Lifetime report com.slv.reporting.scheduledreports.impl.lifetime.ForecastApplicationReportTemplate
Location change report com.slv.reporting.scheduledreports.impl.asset.MapDeviceLocationChangeReportTemplate
Low Power Factor Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.PowerFactorTooLow
LPC availability com.slv.reporting.scheduledreports.impl.operations.NetworkOperationsReportTemplate
No data ever received com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.DataNeverReceived
No power for more than 24 hours com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.NoPowerForMoreThan24Hours
OnOff segment report com.slv.reporting.scheduledreports.impl.onoffsegment.OnOffSegmentReportTemplate
Over 140V Voltage Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.OverVoltage140V
Over Voltage Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.OverVoltage
Over Wattage Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.OverWattage
Real-time operations service level com.slv.reporting.scheduledreports.impl.operations.DeviceOnDemandOperationsServiceLevelReportTemplate
Symology report com.slv.reporting.scheduledreports.impl.symology.SymologyScheduledReportTemplate
UMSUG report com.slv.reporting.scheduledreports.impl.umso.UmsoScheduledReportTemplate
Unbalanced 3-Phase Cabinets Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.UnbalancedCabinet
Under 110V Voltage Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.UnderVoltage110V
Under Voltage Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.UnderVoltage
Under Wattage Report com.slv.reporting.scheduledreports.impl.devicevariablevalues.GroupDevicesVariableLastValuesConfigurableReportTemplate.UnderWattage
Weekly Energy Report com.slv.reporting.scheduledreports.impl.energy.WeeklyEnergyReportTemplate

This list can also be fetched dynamically by calling the method getRegisteredScheduledReportTemplateImplementations available at /api/reportingmanagement.

Report scheduling

Starting from SLV 7.12, most reports can be scheduled on a daily, weekly or monthly basis. Schedules are controlled by properties, and should be updated using the attributes propertyNameand propertyValue. See the section 13.02 Update a report for more information.

To run a report daily, simply set its property repeat to daily.

To run a report weekly, set repeat to weekly and use onForWeekly to choose the day of the week (in English and lowercase, e.g. monday).

To run a report monthly, set repeat to monthly. If you would like a report to run on a given day of the month, set onForMonthly to dayOfTheMonth and day to the desired number (from 1 to 31). day also accepts the special value last that allows to run a report on the last day of every month. If you would like to run a report monthly but on a particular day of a chosen week (e.g. Tuesday of the second week), set onForMonthly to first, second, third, fourth or last, and dayOfTheWeek to the desired day (in English and lowercase, e.g. monday).

In all cases, the property time controls the time at which reports are computed and should be set in 24-hour format, e.g. 14:00 for 2pm.

13.01 Create a report

Create a new Failures HTML report called My new report on the top level GeoZone (geozone ID 1)

import requests

payload = {
    'name': 'My new report',
    'geoZoneId': '1',
    'scheduledReportTemplateImplClassName': 'com.slv.reporting.scheduledreports.impl.failures.FailuresApplicationReportTemplate',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/reportingmanagement/createScheduledReportTemplateDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "id": "FailuresApplicationReportTemplate-1585571007024",
    "name": "My new report",
    "scheduledReportTemplateImplClassName": "com.slv.reporting.scheduledreports.impl.failures.FailuresApplicationReportTemplate",
    "geoZoneId": 1,
    "propertyValues": {
        "onForWeekly": "monday",
        "repeat": "weekly",
        "time": "13:00",
        "detail": 0,
        "htmlFormat": false
    },
    "lastScheduledTime": null,
    "nextScheduledTime": null,
    "schedulerInfo": "Weekly on Monday at 13:00 [Greenwich Mean Time]",
    "timeZone": "GMT"
}

To create a report, use the method createScheduledReportTemplateDefinition available at /api/reportingmanagement. It returns a report object.

Arguments
name (required) Report name
geoZoneId (required) GeoZone identifier
scheduledReportTemplateImplClassName (required) Report type

13.02 Update a report

Update the report FailuresApplicationReportTemplate-1585571007024 to set its time to 8 a.m. on Tuesdays

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('id', 'FailuresApplicationReportTemplate-1585571007024'),
  ('propertyName', 'time'),
  ('propertyValue', '08:00'),
  ('propertyName', 'onForWeekly'),
  ('propertyValue', 'tuesday'),
  ('ser', 'json')
])

r = my_session.post(SLV_URL + "/api/reportingmanagement/updateScheduledReportTemplateDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "id": "FailuresApplicationReportTemplate-1585571007024",
    "name": "My new report",
    "scheduledReportTemplateImplClassName": "com.slv.reporting.scheduledreports.impl.failures.FailuresApplicationReportTemplate",
    "geoZoneId": 1,
    "propertyValues": {
        "onForWeekly": "tuesday",
        "time": "08:00",
...
    },
    "lastScheduledTime": "3/30/20 1:00:00 PM UTC",
    "nextScheduledTime": "3/31/20 8:00:00 AM CEST",
    "schedulerInfo": "Weekly on Tuesday at 08:00 [Central European Time]",
    "timeZone": "Europe/Paris"
}

To update a report, use the method updateScheduledReportTemplateDefinition available at /api/reportingmanagement. It returns the specified report object with its updated parameters. This method takes an arbitrary number of key/value pairs, each pair corresponding to one parameter to update.

Arguments
id (required) Report identifier
name Report name
propertyName (required) Parameter name
propertyValue (required) New parameter value

13.03 Delete a report

Delete the report FailuresApplicationReportTemplate-1585571007024

import requests

payload = {
    'id': 'FailuresApplicationReportTemplate-1585571007024',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/reportingmanagement/deleteScheduledReportDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "status": "OK",
    "errorCode": "0",
    "errorCodeLabel": null,
    "value": null,
    "message": null,
    "statusOk": true,
    "statusError": false
}

To delete a report, use the method deleteScheduledReportDefinition available at /api/reportingmanagement.

Arguments
id (required) Report identifier

13.04 Retrieve all report parameters available

Report parameters that can be specified in updateScheduledReportTemplateDefinition vary by report type. The method getScheduledReportTemplateEditablePropertyDescriptors available at /api/reportingmanagement allows clients to retrieve all report parameters available for a given report.

The reponse is a long list of objects. Each object has at least a name which should be used as the parameter propertyName in updateScheduledReportTemplateDefinition. For report parameters that only accept specific values, the corresponding object in the response will contain another object enumValues which lists all acceptable values.

Arguments
id (required) Report identifier

Retrieve all report parameters available for the report FailuresApplicationReportTemplate-1585571007024

import requests

payload = {
    'id': 'FailuresApplicationReportTemplate-1585571007024',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/reportingmanagement/getScheduledReportTemplateEditablePropertyDescriptors", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "dataFormat": {},
        "enumValues": null,
        "format": "",
        "label": "description",
        "labelKey": null,
        "name": "description",
        "type": "string"
    },
    ...
]

If the specified report does not exist, this method returns an SLVResult object with a status of ERROR and the error code 613.

Sample response when the specified report does not exist

{
    "status": "ERROR",
    "errorCode": "613",
    "errorCodeLabel": "Item not found",
    "value": "streetlight.util.ItemNotFoundException: Item 'FailuresApplicationReportTemplate-158557063012' not found as 'interface com.slv.reporting.scheduledreports.ScheduledReport'!",
    "message": "Item 'FailuresApplicationReportTemplate-158557063012' not found as 'interface com.slv.reporting.scheduledreports.ScheduledReport'!",
    "statusOk": false,
    "statusError": true
}

13.05 Retrieve a report

To retrieve a report, use the method getScheduledReportTemplateDefinition available at /api/reportingmanagement. It returns the corresponding report object.

Arguments
id (required) Report identifier

Retrieve the report FailuresApplicationReportTemplate-1585571007024

import requests

payload = {
    'id': 'FailuresApplicationReportTemplate-1585571007024',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/reportingmanagement/getScheduledReportTemplateDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "id": "FailuresApplicationReportTemplate-1585571007024",
    "name": "My new report",
    "scheduledReportTemplateImplClassName": "com.slv.reporting.scheduledreports.impl.failures.FailuresApplicationReportTemplate",
    "geoZoneId": 1,
    "propertyValues": {
...
    },
    "lastScheduledTime": "3/30/20 1:00:00 PM UTC",
    "nextScheduledTime": "3/31/20 8:00:00 AM CEST",
    "schedulerInfo": "Weekly on Tuesday at 08:00 [Central European Time]",
    "timeZone": "Europe/Paris"
}

If the specified report does not exist, this method returns an SLVResult object with a status of ERROR and the error code 613.

Sample response when the specified report does not exist

{
    "status": "ERROR",
    "errorCode": "613",
    "errorCodeLabel": "Item not found",
    "value": "streetlight.util.ItemNotFoundException: Item 'FailuresApplicationReportTemplate-158557063012' not found as 'interface com.slv.reporting.scheduledreports.ScheduledReport'!",
    "message": "Item 'FailuresApplicationReportTemplate-158557063012' not found as 'interface com.slv.reporting.scheduledreports.ScheduledReport'!",
    "statusOk": false,
    "statusError": true
}

13.06 Retrieve all reports

To retrieve all reports , use the method getAllScheduledReportTemplateDefinitions available at /api/reportingmanagement. It returns all report objects visible to the current user.

Arguments
propertyDescriptors Set to true to obtain report properties. When it is set to false, only the common basic report attributes are provided in the response. Defaults to false
includeScheduledTimes Set to true to obtain the last and next report execution times. Defaults to false

Retrieve all reports without their properties or execution times

import requests

payload = {
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/reportingmanagement/getAllScheduledReportTemplateDefinitions", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "id": "AdvancedSearchReportTemplate-1585346157508",
        "name": "Report 1",
        "scheduledReportTemplateImplClassName": "com.slv.reporting.scheduledreports.impl.search.AdvancedSearchReportTemplate",
        "geoZoneId": 197,
        "propertyValues": null,
        "lastScheduledTime": null,
        "nextScheduledTime": null,
        "schedulerInfo": "Daily at 15:00 [Pacific Standard Time]",
        "timeZone": "America/Los_Angeles"
    },
    {
        "id": "DeviceOnDemandOperationsServiceLevelReportTemplate-1585328418088",
        "name": "Report 2",
        "scheduledReportTemplateImplClassName": "com.slv.reporting.scheduledreports.impl.operations.DeviceOnDemandOperationsServiceLevelReportTemplate",
        "geoZoneId": 197,
        "propertyValues": null,
        "lastScheduledTime": null,
        "nextScheduledTime": null,
        "schedulerInfo": "Daily at 15:00 [Pacific Standard Time]",
        "timeZone": "America/Los_Angeles"
    }
]

14. Alarms

The alarm object

An alarm object corresponds to an alarm definition as visible in the Alarm Manager application in the SLV UI. Alarms are always defined under a particular GeoZone.

Attributes Description
id Alarm ID (string)
name Report name
triggerConditionImplClassName Alarm type (see section Alarm types below)
geoZoneId Identifier of the GeoZone attached to the alarm
propertyValues List of alarm properties
alarmStateChangeActionImplClassNames Action to be performed when the alarm triggers

Alarm types

Below is the list of alarm types available in SLV:

Name in the SLV UI triggerConditionImplClassName
Controller alarm: comparison between four I/Os com.slv.alarming.trigger.SCMultipleIOStateAlarmTriggersGenerator
Controller alarm: comparison between three I/Os com.slv.alarming.trigger.SCMultipleIOStateComparisonAlarmTriggersGenerator
Controller alarm: comparison between two I/Os com.slv.alarming.trigger.SCIOStateComparisonAlarmTriggersGenerator
Controller alarm: last known state of an I/O com.slv.alarming.trigger.ControllerInputStateCondition
Controller alarm: ON/OFF at dusk/dawn com.slv.alarming.trigger.ControllerSunEventSwitchTriggerGenerator
Controller alarm: ON/OFF times vs previous day com.slv.alarming.trigger.SCSwitchingOnAndOffAlarm
Controller alarm: no data received com.slv.alarming.trigger.ControllerUpdateTimeAlarm
Controller alarm: state of the I/Os in the last hours com.slv.alarming.trigger.ControllerInputCondition
Device alarm: critical failure or warning on a single device com.slv.alarming.trigger.DeviceFailureCondition
Device alarm: data analysis vs previous day com.slv.alarming.trigger.SmartMeteringDeviceAnalyticsAlarmTriggersGenerator
Device alarm: data analysis vs previous day (fixed time) com.slv.alarming.trigger.SmartMeteringDeviceDayTimeAnalyticsAlarmTriggersGenerator
Device alarm: failure ratio in a group com.slv.alarming.trigger.GroupFailureRatioCondition
Device alarm: multiple failures on multiple devices com.slv.alarming.trigger.MultiAlarmMultiDeviceFailureCondition
Device alarm: No data received com.slv.alarming.trigger.DevicesUpdateTimeRatioTriggersGenerator
Device alarm: single failure on multiple devices com.slv.alarming.trigger.MonoAlarmMultiDeviceFailureCondition
Device alarm: too many failures in an area com.slv.alarming.trigger.DevicesInAreaTriggersGenerator
Generic alarm: multiple triggered alarms com.slv.alarming.trigger.MetaAlarmTriggersGenerator
Meter alarm: comparison to a trigger com.slv.alarming.trigger.SmartMeteringValueAlarmTriggersGenerator
Meter alarm: data analysis vs previous day com.slv.alarming.trigger.SmartMeteringAnalyticsAlarmTriggersGenerator
Meter alarm: data analysis vs previous day (at fixed time) com.slv.alarming.trigger.SmartMeteringDayTimeAnalyticsAlarmTriggersGenerator

This list can also be fetched dynamically by calling the method getRegisteredTriggerConditionImplementations available at /api/alarmmanagement.

Alarm actions

Below is the list of alarm actions available in SLV:

Name in the SLV UI alarmStateChangeActionImplClassNames
Notify by eMail com.slv.alarming.action.SendEMailAction
Send HTTP request com.slv.alarming.action.HttpRequestAction
Send report com.slv.alarming.action.TriggerScheduledReportAction

This list can also be fetched dynamically by calling the method getRegisteredAlarmStateChangeActionImplementations available at /api/alarmmanagement.

14.01 Create an alarm

To create an alarm, use the method createSingleActionAlarmDefinition available at /api/alarmmanagement. It returns an alarm object.

Arguments
name (required) Report name
triggerConditionImplClassName (required) Alarm type
alarmStateChangeActionImplClassName (required) Alarm action
geoZoneId (required) GeoZone identifier

Create a new alarm of type Device alarm: no data received called New alarm 1 on the top level GeoZone (geozone ID 1) with the action Notify by email

import requests

payload = {
    'name': 'New alarm 1',
    'geoZoneId': '1',
    'triggerConditionImplClassName': 'com.slv.alarming.trigger.DevicesUpdateTimeRatioTriggersGenerator',
    'alarmStateChangeActionImplClassName': 'com.slv.alarming.action.SendEMailAction',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/createSingleActionAlarmDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "alarmStateChangeActionImplClassNames": [
        "com.slv.alarming.action.SendEMailAction"
    ],
    "id": "DevicesUpdateTimeRatioTriggersGenerator",
    "name": "New alarm 1",
    "geoZoneId": 1,
    "triggerConditionImplClassName": "com.slv.alarming.trigger.DevicesUpdateTimeRatioTriggersGenerator",
    "propertyValues": {
        "autoAcknowledge": false,
        "triggerCondition.timeMode": 0,
        "newAlarmWhenAcknowledged": true,
        "refreshRate": 0,
        "action[0].message": "${TC}",
        "alarmName": "New alarm 1",
        "disabled": false,
        "alarmPriority": 0,
        "triggerCondition.triggeredDevicesRatioLimitPercent": 0,
        "triggerCondition.delayTriggeringValueInMinutes": 120,
        "triggerCondition.meaningCategories": [
            0
        ]
    }
}

If the specified alarm name is already used or the specified alarm action or type do not exist, this method returns an SLVResult object with a status of ERROR and the error code 500.

14.02 Update an alarm

To update an alarm, use the method updateAlarmDefinition available at /api/alarmmanagement. It returns the specified alarm object with its updated parameters. This method takes an arbitrary number of key/value pairs, each pair corresponding to one parameter to update.

Arguments
id (required) Alarm identifier
name Alarm name
propertyName (required) Parameter name
propertyValue (required) New parameter value

Update the alarm DevicesUpdateTimeRatioTriggersGenerator to set its refresh rate to 5 minutes and enable auto-acknowledgement

import requests
from webob.multidict import MultiDict

payload = MultiDict([
  ('id', 'DevicesUpdateTimeRatioTriggersGenerator'),
  ('propertyName', 'refreshRate'),
  ('propertyValue', '300000'),
  ('propertyName', 'autoAcknowledge'),
  ('propertyValue', 'true'),
  ('ser', 'json')
])

r = my_session.post(SLV_URL + "/api/alarmmanagement/updateAlarmDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "alarmStateChangeActionImplClassNames": [
        "com.slv.alarming.action.SendEMailAction"
    ],
    "id": "DevicesUpdateTimeRatioTriggersGenerator",
    "name": "New alarm 1",
    "geoZoneId": 1,
    "triggerConditionImplClassName": "com.slv.alarming.trigger.DevicesUpdateTimeRatioTriggersGenerator",
    "propertyValues": {
        "autoAcknowledge": true,
        "triggerCondition.timeMode": 0,
        "newAlarmWhenAcknowledged": true,
        "refreshRate": 300000,
        "action[0].message": "${TC}",
        "alarmName": "New alarm 1",
        "disabled": false,
        "alarmPriority": 0,
        "triggerCondition.triggeredDevicesRatioLimitPercent": 0,
        "triggerCondition.delayTriggeringValueInMinutes": 120,
        "triggerCondition.meaningCategories": [
            0
        ]
    }
}

If the specified alarm does not exist, this method returns random HTML code.

14.03 Delete an alarm

To delete an alarm, use the method deleteAlarmDefinition available at /api/alarmmanagement.

Arguments
id (required) Alarm identifier

Delete the alarm DevicesUpdateTimeRatioTriggersGenerator

import requests

payload = {
    'id': 'DevicesUpdateTimeRatioTriggersGenerator',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/deleteAlarmDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "status": "OK",
    "errorCode": "0",
    "errorCodeLabel": null,
    "value": null,
    "message": null,
    "statusOk": true,
    "statusError": false
}

14.04 Retrieve all alarm parameters available by alarm type and action

Alarm parameters that can be specified in updateAlarmDefinition vary by alarm type. The method getVirtualSingleActionAlarmDefinitionEditablePropertyDescritors available at /api/alarmmanagement allows clients to retrieve all alarm parameters available for a given combination of alarm type and action.

The reponse is a long list of objects. Each object has at least a name which should be used as the parameter propertyName in updateAlarmDefinition. For alarm parameters that only accept specific values, the corresponding object in the response will contain another object enumValues which lists all acceptable values.

Arguments
triggerConditionImplClassName (required) Alarm type
alarmStateChangeActionImplClassName (required) Alarm action
geoZoneId GeoZone identifier

Retrieve all alarm parameters available for the alarm type Controller alarm: no data received and the action Notify by eMail

import requests

payload = {
    'triggerConditionImplClassName': 'com.slv.alarming.trigger.ControllerUpdateTimeAlarm',
    'alarmStateChangeActionImplClassName': 'com.slv.alarming.action.SendEMailAction',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/getVirtualSingleActionAlarmDefinitionEditablePropertyDescritors", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "dataFormat": {
            "mainGroup": "common",
            "mainGroup.labelKey": "dataformat.alarmbundle.group.common.label",
            "min": "0",
            "max": "9",
            "mainGroup.label": "General"
        },
        "enumValues": null,
        "format": "min=0&max=9",
        "label": "Priority",
        "labelKey": "alarmbundle.property.alarmPriority.label",
        "name": "alarmPriority",
        "type": "integer"
    },
    ...
]

If the specified alarm type or action does not exist, this method returns an SLVResult object with a status of ERROR and the error code 500.

Sample response when the specified alarm action does not exist

[
    {
        "status": "ERROR",
        "errorCode": "500",
        "errorCodeLabel": "Internal error",
        "value": "java.lang.ClassNotFoundException: com.slv.alarming.action.SendEMailAction_nonexistent",
        "message": "com.slv.alarming.action.SendEMailAction_nonexistent",
        "statusOk": false,
        "statusError": true
    }
]

14.05 Retrieve all alarm parameters available for an existing alarm

Alarm parameters that can be specified in updateAlarmDefinition vary by alarm type. The method getAlarmDefinitionEditablePropertyDescriptors available at /api/alarmmanagement allows clients to retrieve all alarm parameters available for a given alarm

The reponse is a long list of objects. Each object has at least a name which should be used as the parameter propertyName in updateAlarmDefinition. For alarm parameters that only accept specific values, the corresponding object in the response will contain another object enumValues which lists all acceptable values.

Arguments
id (required) Alarm identifier

Retrieve all alarm parameters available for the alarm ID DevicesUpdateTimeRatioTriggersGenerator

import requests

payload = {
    'id': 'DevicesUpdateTimeRatioTriggersGenerator',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/getAlarmDefinitionEditablePropertyDescriptors", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "dataFormat": {
            "mainGroup": "common",
            "mainGroup.labelKey": "dataformat.alarmbundle.group.common.label",
            "min": "0",
            "max": "9",
            "mainGroup.label": "General"
        },
        "enumValues": null,
        "format": "min=0&max=9",
        "label": "Priority",
        "labelKey": "alarmbundle.property.alarmPriority.label",
        "name": "alarmPriority",
        "type": "integer"
    },
    ...
]

If the specified alarm does not exist, this method returns an SLVResult object with a status of ERROR and the error code 613.

Sample response when the specified alarm does not exist

{
    "status": "ERROR",
    "errorCode": "613",
    "errorCodeLabel": "Item not found",
    "value": "streetlight.util.ItemNotFoundException: Item 'InexistentAlarm' not found as 'class com.slv.alarming.AlarmBundle'!",
    "message": "Item 'InexistentAlarm'' not found as 'class com.slv.alarming.AlarmBundle'!",
    "statusOk": false,
    "statusError": true
}

14.06 Retrieve an alarm

To retrieve an alarm , use the method getAlarmDefinition available at /api/alarmmanagement. It returns the corresponding alarm object.

Arguments
id (required) Alarm identifier

Retrieve the alarm ID DevicesUpdateTimeRatioTriggersGenerator

import requests

payload = {
    'id': 'DevicesUpdateTimeRatioTriggersGenerator',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/getAlarmDefinition", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "alarmStateChangeActionImplClassNames": [
            "com.slv.alarming.action.SendEMailAction"
        ],
        "id": "DevicesUpdateTimeRatioTriggersGenerator",
        "name": "My alarm 1",
        "geoZoneId": 1,
        "triggerConditionImplClassName": "com.slv.alarming.trigger.DevicesUpdateTimeRatioTriggersGenerator",
        "propertyValues": {
            "disabled": false
        }
    }
]

If the specified alarm does not exist, this method returns an SLVResult object with a status of ERROR and the error code 613.

Sample response when the specified alarm does not exist

{
    "status": "ERROR",
    "errorCode": "613",
    "errorCodeLabel": "Item not found",
    "value": "streetlight.util.ItemNotFoundException: Item 'InexistentAlarm' not found as 'class com.slv.alarming.AlarmBundle'!",
    "message": "Item 'InexistentAlarm'' not found as 'class com.slv.alarming.AlarmBundle'!",
    "statusOk": false,
    "statusError": true
}

14.07 Retrieve all alarms

To retrieve all alarms , use the method getAllAlarmDefinitions available at /api/alarmmanagement. It returns all alarm objects visible to the current user.

Arguments
propertyDescriptors Set to true to obtain alarm properties. When it is set to false, only the common basic alarm attributes are provided in the response. Defaults to false

Retrieve all alarms

import requests

payload = {
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/getAllAlarmDefinitions", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "alarmStateChangeActionImplClassNames": [
        "com.slv.alarming.action.SendEMailAction"
    ],
    "id": "DevicesUpdateTimeRatioTriggersGenerator",
    "name": "My alarm 1",
    "geoZoneId": 1,
    "triggerConditionImplClassName": "com.slv.alarming.trigger.DevicesUpdateTimeRatioTriggersGenerator",
    "propertyValues": {
        "triggerCondition.deviceIds": [
            1807
        ],
        "triggerCondition.timeMode": 0,
        "newAlarmWhenAcknowledged": false,
        "action[0].from": "slv@mycompany.com",
        "alarmName": "My alarm 1",
        "alarmPriority": 0,
        "action[0].subject": "My alarm 1",
        "triggerCondition.triggeredDevicesRatioLimitPercent": 10,
        "autoAcknowledge": true,
        "refreshRate": 3600000,
        "action[0].to": [
            "john.doe@mycompany.com"
        ],
        "action[0].message": "My alarm 1 is currently active",
        "disabled": false,
        "triggerCondition.delayTriggeringValueInMinutes": 120,
        "triggerCondition.meaningCategories": [
            0
        ]
    }
}

14.08 Retrieve all possible master alarms

To retrieve all alarms that can be used as master alarms, use the method getAlarmsForNotificationTrigger available at /api/alarmmanagement. It does not take any argument.

To define a master alarm for an alarm to suppress its email notifications, set the property action[0].dependsOnAlarm to value of the desired master alarm, as returned by this method.

Retrieve all possible master alarms

import requests

payload = {
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarmmanagement/getAlarmsForNotificationTrigger", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "value": "DevicesUpdateTimeRatioTriggersGenerator",
        "properties": null,
        "label": "My alarm 1 Geozone: GeoZones",
        "dependentFields": null
    }
]

15. Alarm instances

The alarm instance

An alarm instance corresponds to an alarm as visible in the Alarms application in the SLV UI.

Attributes Description
id Alarm instance ID (int)
generator Identifier of the alarm that generated the alarm instance
name Name of the alarm that generated the alarm instance
groupId Identifier of the GeoZone where the alarm instance was generated
groupName Name of the GeoZone where the alarm instance was generated
creationTime Creation date of the alarm instance
lastStateChangeTime Date of the last alarm state change
lastStateChangeInfo Last acknowledgement message
lastStateChangeSrc User responsible for the last ackknowledgement
priority Alarm priority
stateKey State of the alarm, TRIGGERED or ACKNOWLEGED
changes Unused
description Unused

15.01 Retrieve alarm instances by GeoZone

To retrieve all alarm instances by GeoZone, use the method getGeoZoneAlarms available at /api/alarm. It returns a list of alarm instances.

Arguments
geoZoneId (required) GeoZone identifier (int)
recurse Set to true to include alarm instances belonging to sub-geozones. Defaults to false
priorityMin Filters the results to include only alarms that have a priority higher than the specified value. Defaults to 0
includeAcknowledgedAlarms Set to true to include alarms that have been acknowledged. Defaults to false
includeLastTrigger Unused

Retrieve the alarms instances at the root GeoZone

import requests

payload = {
    'geoZoneId': '1',
    'includeLastTrigger': 'true',
    'ser': 'json'
}

r = my_session.get(SLV_URL + "/api/alarm/getGeoZoneAlarms", params=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

[
    {
        "creationTime": "2020-04-02 09:00:16",
        "description": null,
        "generator": "DevicesUpdateTimeRatioTriggersGenerator",
        "groupId": 1,
        "groupName": "GeoZones",
        "id": 1,
        "lastStateChangeInfo": null,
        "lastStateChangeSrc": "-",
        "lastStateChangeTime": "2020-04-02 14:05:52",
        "name": "My alarm 1",
        "priority": 0,
        "stateKey": "TRIGGERED",
        "changes": null
    }
]

If no GeoZone is specified, this method returns an SLVResult object with a status of ERROR and the error code 500. If an inexistent GeoZone is specified, this method returns an SLVResult object with a status of ERROR and the error code 630.

15.02 Acknowledge an alarm instance

To manually acknowledge an alarm instance, use the method acknowledgeAlarms available at /api/alarm. It returns an SLVResult object with the specified alarm instance with its updated properties inside value.

Arguments
id (required) Alarm instance ID
comment Acknowledgement message

Acknowledge the alarm instance 1 with the message Ok

import requests

payload = {
    'id': '1',
    'comment': 'Ok',
    'ser': 'json'
}

r = my_session.post(SLV_URL + "/api/alarm/getGeoZoneAlarms", data=payload, auth=('USERNAME', 'PASSWORD'), headers=token_header)

Sample response

{
    "status": "OK",
    "errorCode": "0",
    "errorCodeLabel": null,
    "value": [
        {
            "creationTime": "2020-04-02 09:00:16",
            "description": null,
            "generator": "DevicesUpdateTimeRatioTriggersGenerator",
            "groupId": 1,
            "groupName": "GeoZones",
            "id": 1,
            "lastStateChangeInfo": "Ok",
            "lastStateChangeSrc": "admin",
            "lastStateChangeTime": "2020-04-02 15:21:22",
            "name": "My alarm 1",
            "priority": 0,
            "stateKey": "ACKNOWLEGED",
            "changes": null
        }
    ],
    "message": null,
    "statusOk": true,
    "statusError": false
}

If an inexistent GeoZone is specified, this method returns an SLVResult object with a status of ERROR and the error code 613.