NAV Navbar
Logo
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

6.1.1 (current)

Authentication

Authentication to the API is performed via either HTTP Basic Auth or Form-based 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.

Basic

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 the username 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

Form

To authenticate against an SLV CMS using Form-based Auth, use the following code:

import urllib.request
import urllib.parse
import json

def login():
  # Make a first request to auth.json to get a cookie from the CMS
  urllib.request.urlopen(SLV_URL + "/auth.json")

  # Send the credentials to the CMS
  credentials = urllib.parse.urlencode({'j_username':USERNAME,'j_password':PASSWORD})
  try:
    urllib.request.urlopen(SLV_URL + "/j_security_check", data=credentials.encode("utf-8"))
  except urllib.error.HTTPError as err:
    print ("Unable to log in: {0}".format(err))

def is_authenticated():
  authenticated = False
  response = urllib.request.urlopen(SLV_URL + "/auth.json").read().decode("utf-8")
  try:
    jsonresponse = json.loads(response)
  except ValueError:
    return False
  if jsonresponse["authenticated"] == "true" :
    authenticated = True
  return authenticated

# Enable cookie saving
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor)
urllib.request.install_opener(opener)

login()
if is_authenticated() == False:
  print("Wrong crendentials")
  quit()
else:
  print("Logged in sucessfully")
# Replace SLV_URL by the full URL of the SLV CMS
curl -c cookie.txt "SLV_URL/auth.json" 
curl -b cookie.txt -c cookie.txt -d "j_username=USERNAME" -d "j_password=PASSWORD" "SLV_URL/j_security_check"
curl -b cookie.txt -c cookie.txt "SLV_URL/auth.json"

# Use the same cookie in all subsequent requests
curl -b cookie.txt "api_endpoint_here"

In Form-based Auth, you have to specify the full URL of the SLV CMS, e.g. http://mydomain.com:8080/reports. This is represented by the parameter SLV_URL in the code examples.

There are three steps to form-based auth: 1. Make a first request to SLV_URL/auth.json. This allows you to get a cookie from the SLV CMS 2. Make a request to SLV_URL/j_security_check along with your credentials 3. Make a second request to SLV_URL/auth.json. When authenticated successfully, it will return {"authenticated":"true"}

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 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.05 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.05 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.06 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.