API/Development

Getting Started with the GlamoxHeating API

The GlamoxHeating API provides a standard http-based interface for control of Glamox thermostats. Software developers will be able to query status and send commands to their thermostat(s). GlamoxHeating aims to follow the general rules of API compatibility and will protect implementations from breaking when bug fixes and new features are implemented. The API also strives to be self-documenting, easy to understand and use.

Remote Client API User Guide

Overview

GlamoxHeating API is provided as a REST service and that allows you to:

  • Get your rooms target and current temperatures,
  • Change your rooms heating target temperatures.

Getting Started

For using GlamoxHeating API you will need an authentication token for secure access and some REST services usage knowledge. The API is provided at the https://
api-1.glamoxheating.com/client-api/ address. The services description can be accessed at the https://api-1.glamoxheating.com/client-api/openapi in an OpenAPI format. You
could also use the provided Python and Java samples as a starting point.

Obtaining Authentication Credentials Required for GlamoxHeating API

Using the GlamoxHeating WiFi application you can create and get the authentication token used for accessing the GlamoxHeating API. You should use at least the GlamoxHeating WiFi
app version 3.5.1. The authentication token can be accessed following those steps:

  1. Navigate to Account Tab,
  2. Select “Remote user client API”
  3. Select “Add Credential”
  4. Give some name to the created credential and copy the generated password.

Using GlamoxHeating API

The API provides 3 end points:

  1. /auth/ for authentication to the REST service.
  2. /rest/v1/control/ for controlling your rooms
  3. /rest/v1/content/ for getting rooms statuses.

Control and status endpoins accepts and returns json documents.

Code Samples

Python Sample

# install dependencies with: pip install requests sanction

import requests
import sanction
 
CLIENT_ID     = "112395" # replace with your client ID (see Glamox Heating app, Account Section)
CLIENT_SECRET = "6imtpX63D5WoRyKh" # replace with your client ID (see Glamox Heating app, Account Section)
API_URL       = "https://api-1.glamoxheating.com/client-api"

def get_token():
    # Authenticate and obtain JWT token
    oauthClinet = sanction.Client(token_endpoint = API_URL + '/auth/token')
    oauthClinet.request_token(grant_type = 'password', username = CLIENT_ID, password = CLIENT_SECRET)
    return oauthClinet.access_token

def set_room_target_temperature(roomId, temperature, token):
    # Sets target temperature of the room
    headers = { "Authorization": "Bearer " + token }
    json = { 'rooms': [{ 'id': roomId, 'targetTemperature': str(temperature) }] }
    requests.post(API_URL + '/rest/v1/control/', json = json, headers = headers)
 
def get_homes_info(token):
    headers = { "Authorization": "Bearer " + token }
    response = requests.get(API_URL + "/rest/v1/content/", headers = headers)
    
    json = response.json()
    
    for room in json['rooms']:
        roomName = room['name']
        targetTemperature = room['targetTemperature'] / 100.0
        currentTemperature = 0
    
    if ('temperature' in room):
        currentTemperature = room['temperature'] / 100.0
    
    print("Room: %15s, Target: %5.2fC, Temperature: %5.2fC, id: %5d" % (roomName, targetTemperature, currentTemperature, room['id']))

token = get_token()
                                                 # Change the temperature to 24 C in the room with an Id of 196342
set_room_target_temperature(196342, 2400, token) # Replace the 196342 with the room id from the get_homes_info output
get_homes_info(token)
 

Java Sample

/**
 * Add com.github.scribejava/scribejava-apis 
 * and org.json/json dependencies
 */
 
package no.glamox.heating.client.api;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.stream.Collectors;
import javax.net.ssl.HttpsURLConnection;
import org.json.JSONArray;
import org.json.JSONObject;
import com.github.scribejava.apis.openid.OpenIdJsonTokenExtractor;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.builder.api.DefaultApi20;
import com.github.scribejava.core.extractors.TokenExtractor;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.oauth.OAuth20Service;
 
public class ClientDemo
{
    private String apiUrl = "https://api-1.glamoxheating.com/client-api";
    private String clientId = "112395"; // replace with your client ID (see Glamox Heating app, Account Section)
    private String clientSecret = "6imtpX63D5WoRyKh"; // replace with your client ID (see Glamox Heating app, Account Section)
 
    public static void main(String[] args) throws Exception
    {
        ClientDemo client = new ClientDemo();
 
        String token = client.getToken();
 
        // Change the temperature to 24 C in the room with an Id of 196342
        // Replace the 196342 with the room id from the getHomesInfo output
        client.setRoomTargetTemperature(196342, 2400, token);
        client.getHomesInfo(token);
    }
 
    /**
     * Sets target temperature of the room
     *
     * @throws IOException
     */
    private void setRoomTargetTemperature(int roomId, int temperature, String token) throws Exception
    {
        String postData = "{ \"rooms\": [{ \"id\": " + roomId + ", \"targetTemperature\": " + temperature + " }] }";
 
        HttpsURLConnection connection = (HttpsURLConnection)(new URL(apiUrl + "/rest/v1/control/").openConnection());
        connection.setRequestProperty("Authorization", "Bearer " + token);
        connection.setDoOutput(true);
        connection.setRequestMethod("POST");
        connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        connection.setRequestProperty("Accept", "application/json");
 
        byte[] input = postData.getBytes("utf-8");
        connection.setFixedLengthStreamingMode(input.length);
 
        connection.connect();
        connection.getOutputStream().write(input);
        connection.getOutputStream().close();
 
        String response = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
        connection.getInputStream().close();
        System.out.println(response);
    }
 
    private void getHomesInfo(String token) throws Exception
    {
        HttpsURLConnection connection = (HttpsURLConnection)(new URL(apiUrl + "/rest/v1/content/").openConnection());
 
        connection.setRequestProperty("Authorization", "Bearer " + token);
        connection.setDoOutput(true);
        connection.setRequestMethod("GET");
        connection.connect();
 
        String response = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)).lines().collect(Collectors.joining("\n"));
        connection.getInputStream().close();
 
        JSONObject jsonObject = new JSONObject(response);
        JSONArray jsonArray = jsonObject.getJSONArray("rooms");
 
        for (int i = 0; i < jsonArray.length(); i++)
        {
            JSONObject roomData = jsonArray.getJSONObject(i);
 
            String roomName = roomData.getString("name");
            int roomId = roomData.getInt("id");
            int targetTemperature = roomData.getInt("targetTemperature") / 100;
            int currentTemperature = 0;
 
            if (!roomData.isNull("temperature"))
            {
                currentTemperature = roomData.getInt("temperature") / 100;
            }
 
            System.out.println(String.format("Room: %15s, Target: %5d, Temperature: %5d, id: %5d", roomName, targetTemperature, currentTemperature, roomId));
        }
    }
 
    /**
     * Authenticate and obtain JWT token
     */
    private String getToken() throws Exception
    {
        DefaultApi20 api = new DefaultApi20()
        {
            public String getAccessTokenEndpoint()
            {
                return apiUrl + "/auth/token";
            }
 
            public TokenExtractor getAccessTokenExtractor()
            {
                return OpenIdJsonTokenExtractor.instance();
            }
 
            protected String getAuthorizationBaseUrl()
            {
                throw new UnsupportedOperationException();
            }
 
            public String getRevokeTokenEndpoint()
            {
                throw new UnsupportedOperationException();
            }
        };
 
        OAuth20Service service = new ServiceBuilder(this.clientId).apiSecret(this.clientSecret).build(api);
 
        return service.getAccessTokenPasswordGrant(this.clientId, this.clientSecret).getAccessToken();
    }
}