
This post was last updated:
This post shows how you can use Power Automate to control your Honeywell Evohome or Round Thermostats by using Honeywell’s Total Connect Comfort API. You can get temperature readings for each of your room thermostats and control or set the temperature for any room. I have also included a fully working demo that logs temperature readings to a SharePoint List.
Contents
- Getting Started
- What is Evohome?
- How to access the Web API Help Page
- Using the Total Connect Comfort API
- This is the Flow we will build
- The Base URL Path
- Initialise three variables
- API calls for logging into the system (Authentication)
- Get the sessionId
- Get the userId
- API call to Get your locationID
- Get the locationID
- API call to Get Devices (Thermostats)
- Get Devices (Thermostats) information
- Example: Setting the Heat Point of the Kitchen zone to 12.5℃
- Summary
- Notes
- A Working Demo
1. Getting Started
This post shows you how to access the Total Connect Comfort RESTful API using Power Automate. You’ll need to have signed up for an account at http://www.mytotalconnect.com.
The Total Connect Comfort API provides support for Evohome and the Round Thermostat. API seems to support only EU/EMEA-based systems. Apparently American Evohome systems use a different or similar API?
In this post I use Power Automate to obtain temperature readings from all thermostats (zones) which can then be saved to an Excel file or a SharePoint List for example. The flow uses the HTTP connector which is a premium connector. This means that you will need a premium license in order to use this connector and this usually requires a subscription. Please check with your MS 365 or Power Platform administrator.
2. What is Evohome?
Honeywell Evohome is a smart thermostat that lets you setup a thermostat for each room (or zone) and then control the temperature in each room independently.
For Evohome reviews see:
- Honeywell Evohome review
- Honeywell evohome long term review
- Honeywell Home evohome review: The “Sonos of heating” for your home
3. How to access the Web API Help Page
The Web API Help Page and documentation can be found here:
https://mytotalconnectcomfort.com/WebApi/Help/Reference
Use the following application ID to login:
91db1612-73fd-4500-91b2-e63b069b185c

The Help menu will now be displayed:

The API provides a number of device functions. Click API Reference from the menu, then select Devices:
4. Using the Total Connect Comfort API
This is an overview of how I will use the Total Connect Comfort API with Power Automate and obtain temperature readings from all the thermostats (zones) at my location:

The diagram below is the same as above but shows some of the properties we send and obtain from the API response:

sessionResponse
properties from the three API calls: (1) Authenticate, (2) Get Locations and, (3) Get Devices.5. This is the Flow we will build
This is the structure of the flow that we will build:

5.1 The Base URL Path
The base URL address for all API calls is the following fully qualified path:
https://mytotalconnectcomfort.com/WebApi
Initialise a variable of type String to store the Base URL:

5.2 Initialise three variables
We also need to use three other important pieces of information in the flow. the sessionId
, userId
and the locationID
. Initialise three variables of type String. These properties are explained later in the flow:

5.3 API calls for logging into the system (Authentication)
All Web API calls must use authentication.
Before using any other API calls, the user must be logged in and a sessionId
needs to be obtained. This is done using the API call POST api/Session
.
If the login action is successful, the API call will return the sessionResponse
object, and within the sessionResponse
object we will find the sessionId
. We will also need the userId
and this can also be found within the sessionResponse
.

sessionResponse
) contains the sessionId
and userId
.The sessionId
value will be used all in subsequent API calls:

We will now build the Authentication part of the flow. The sample flow below uses a Scope block. The Scope doesn’t do anything other than to help us organise the Flow a little better:

We will login to the Honeywell system using the Power Automate HTTP action. If the HTTP action is successful, the API call will return a sessionResponse
object, and within the sessionResponse
object we will find the sessionId
and the userId
.
In order to login to the system we need to supply the following details in the HTTP action:
METHOD:
POST
URI:
<baseURL>/api/Session
HEADERS:
accept : application/json
content-length : 126
content-type : application/json
BODY:
{
"username": <email-address>,
"password": <password>,
"applicationId": "91db1612-73fd-4500-91b2-e63b069b185c"
}

If you enter your username or password directly into the Body of the HTTP action, these must be enclosed within quotes, for example “username”: “AlexW@someEmailAddress.com” and “password” : “P@ssw0rd1”.
5.4 Get the sessionId
Next set the sessionId
variable using the following expression:
body('HTTP')?['sessionId']
This expression selects the sessionId
from the sessionResponse
object. The sessionResponse
object is contained within body(‘HTTP’):

If you need help understanding how to query JSON data please refer to the following post:
According to the web api documentation, the sessionId
can be used for up to 15 minutes, in other words the sessionId
has a lifetime of up to 15 minutes:
[🚫This doesn’t work!🚫] Session ID is valid for 15 minutes. Each call with previously obtained Session ID resets timeout interval.
However, this information does not seem to be correct, at least for my implementation. I paused my flow for about 10 minutes, but I was not able to re-use the same sessionId
. Therefore, before making another API call, I had to login again (re-authenticate) to obtain a new sessionId
:

Therefore, if there is going to be a delay of several minutes between API calls, you may need to login again (re-authenticate) to obtain a new sessionId
.
5.5 Get the userId
Next set the userId
variable using the following expression:
body('HTTP')?['userInfo']?['userId']
This expression selects the userId
from the sessionResponse
object. The sessionResponse
object is contained within body(‘HTTP’):

The userId
will be used to get your location information (i.e. the location(s) where Evohome devices have been installed). Once we have the location information, we can then get all the devices installed at that location.
5.6 API call to Get your locationID
We will now build the Get Locations part of the flow. The sample flow below uses a Scope block. The Scope doesn’t do anything other than to help us organise the Flow a little better:

In order to get the Location information, we need to supply the following details in the HTTP action:
METHOD:
GET
URI:
<baseURL>/api/locations
HEADERS:
sessionId: variables('sessionId')
accept: application/json
QUERIES:
userId: variables('userId')
allData: true

5.7 Get the locationID
Next set the locationID
variable using the following expression:
body('HTTP_Get_Locations')?[0]?['locationID']
This expression selects the first locationID
from the sessionResponse
object. The sessionResponse
object is contained within body(‘HTTP_Get_Locations’). If you have more than one location registered with Honeywell Evohome webservices, then you need to change the array index. For example, to get the second location, the expression would be body(‘HTTP_Get_Locations’)?[1]?[‘locationID’].

5.8 API call to Get Devices (Thermostats)
We will now build the Get Devices part of the flow. The sample flow below uses a Scope block. The Scope doesn’t do anything other than to help us organise the Flow a little better:

In order to get the device information (temperature information) for our selected location, we need to supply the following details in the HTTP action:
METHOD:
GET
URI:
<baseURL>/api/devices
HEADERS:
sessionId: variables('sessionId')
accept: application/json
QUERIES:
locationId: variables('locationID')
allData: true

5.9. Get Devices (Thermostats) information
For each device or thermostat, the HTTP Get Devices sessionResponse
object will return a JSON object similar to the extract shown below, which show the device data for Bedroom 1:
{
"gatewayId": 19175352,
"deviceID": 90792089,
"thermostatModelType": "EMEA_ZONE",
"deviceType": 96,
"name": "Bedroom 1",
"scheduleCapable": false,
"holdUntilCapable": false,
"thermostat": {
"units": "Celsius",
"indoorTemperature": 19.3,
"outdoorTemperature": 128,
"outdoorTemperatureAvailable": false,
"outdoorHumidity": 128,
"outdootHumidityAvailable": false,
"indoorHumidity": 128,
"indoorTemperatureStatus": "Measured",
"indoorHumidityStatus": "NotAvailable",
"outdoorTemperatureStatus": "NotAvailable",
"outdoorHumidityStatus": "NotAvailable",
"isCommercial": false,
"allowedModes": [
"Heat",
"Off"
],
"deadband": 0,
"minHeatSetpoint": 12,
"maxHeatSetpoint": 22,
"minCoolSetpoint": 50,
"maxCoolSetpoint": 90,
"changeableValues": {
"mode": "Off",
"heatSetpoint": {
"value": 16.5,
"status": "Scheduled"
},
"vacationHoldDays": 0
},
"scheduleCapable": false,
"vacationHoldChangeable": false,
"vacationHoldCancelable": false,
"scheduleHeatSp": 0,
"scheduleCoolSp": 0
},
"alertSettings": {
"deviceID": 2079403,
"tempHigherThanActive": true,
"tempHigherThan": 30,
"tempHigherThanMinutes": 0,
"tempLowerThanActive": true,
"tempLowerThan": 5,
"tempLowerThanMinutes": 0,
"faultConditionExistsActive": false,
"faultConditionExistsHours": 0,
"normalConditionsActive": true,
"communicationLostActive": false,
"communicationLostHours": 0,
"communicationFailureActive": true,
"communicationFailureMinutes": 15,
"deviceLostActive": false,
"deviceLostHours": 0
},
"isUpgrading": false,
"isAlive": true,
"thermostatVersion": "03.00.10.06",
"macID": "FFD02F5FFFF0",
"locationID": 326242,
"domainID": 14352,
"instance": 1
}
From the sample data above, we see that the name of the thermostat is Bedroom 1 (line 6), the measured temperature is 19.3 (line 11) degrees Celsius (line 10). The temperature is set to 16.5 degrees Celsius (line 34). The thermostat is following a program (line 35), “Scheduled”. We can use a Select action to select these and other properties from the sessionResponse
object:

The sessionResponse
object is contained within body(‘HTTP_Get_Devices’).
The expressions for the Select action are:
Room:
item()?['name']
Temperature:
item()?['thermostat']?['indoorTemperature']
Temperature Status:
item()?['thermostat']?['indoorTemperatureStatus']
Heat Setpoint:
item()?['thermostat']?['changeableValues']?['heatSetpoint']?['value']
Mode:
item()?['thermostat']?['changeableValues']?['heatSetpoint']?['status']
Here is some sample runtime output:
{
"body": [
{
"Room": "Bedroom 3",
"Temperature": 19.95,
"Temperature Status": "Measured",
"Heat Setpoint": 20,
"Mode": "Scheduled"
},
{
"Room": "Bedroom 2",
"Temperature": 20.03,
"Temperature Status": "Measured",
"Heat Setpoint": 15.5,
"Mode": "Scheduled"
},
{
"Room": "Bedroom 1",
"Temperature": 19.3,
"Temperature Status": "Measured",
"Heat Setpoint": 16.5,
"Mode": "Scheduled"
},
{
"Room": "Kitchen",
"Temperature": 16.25,
"Temperature Status": "Measured",
"Heat Setpoint": 12,
"Mode": "Scheduled"
},
{
"Room": "Living room",
"Temperature": 19.95,
"Temperature Status": "Measured",
"Heat Setpoint": 16,
"Mode": "Scheduled"
},
...
]
}
Here are the temperature readings saved to a SharePoint List:

Example: Setting the Heat Point of the Kitchen zone to 12.5℃
Here is an example of setting the heat point of the Kitchen thermostat (DeviceID = 2084943) to 12.5℃ degrees until 2022-12-05 10:00:


Here is the link to the API documentation: https://mytotalconnectcomfort.com/WebApi/Help/Api/PUT-api-devices-deviceId-thermostat-changeableValues-heatSetpoint_changeTag
Hopefully this post should be enough to help explore the Honeywell API further, and perhaps even write an Evohome PowerApp?

6. Summary
The post outlined the steps to access the Total Connect Comfort RESTful API using Power Automate. The API is used to support the Evohome and Round Thermostat systems in the EU/EMEA region. To use the API, you need to have a premium Power Automate license and have signed up for an account at mytotalconnect.com. The demo flow built in the post uses the HTTP connector and includes three API calls: Authenticate, Get Locations, and Get Devices. The flow was used to obtain temperature readings from all thermostats and these readings can be saved to an Excel file or SharePoint List. The base URL for all API calls is https://mytotalconnectcomfort.com/WebApi and authentication is required for all Web API calls. A session ID was obtained by logging into the system and was used for all subsequent API requests.
7. Notes
- Honeywell Web API Reference: https://mytotalconnectcomfort.com/WebApi/Help/Reference
- Python Evohome Client: https://github.com/watchforstock/evohome-client
- Evohome Python Client documentation: https://evohome-client.readthedocs.io/en/latest/#evohome-client
- How to query JSON data using JSON notation with Power Automate❔❔❓ – This post illustrates through examples, JSON notation that often confuses beginners.
8. A Working Demo
This is the SharePoint List where the temperature readings saved to:

SharePoint Columns:

SharePoint Columns showing their Display names and internal names:
Column Display Name | Internal Name |
---|---|
Title | Title |
Time | Time |
Temperature | Temperature |
Heat Setpoint | HeatSetpoint |
Mode | Mode |
Weather Conditions | WeatherConditions |
Outside Temperature °C | OutsideTemperature |
Outside Humidity | OutsideHumidity |
Date | Date |
Temperature Column Formatting
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "[$Temperature]",
"style": {
"color": "=if((@currentField <= ([$HeatSetpoint] + 0.5)) && (@currentField >= ([$HeatSetpoint] - 0.5)),'green', if(@currentField < [$HeatSetpoint],'blue', if(@currentField >[$HeatSetpoint],'orange', 'green')))"
}
}
Outside Temperature Column Formatting
{
"$schema": "https://developer.microsoft.com/json-schemas/sp/v2/column-formatting.schema.json",
"elmType": "div",
"txtContent": "[$OutsideTemperature]",
"style": {
"color": "=if(@currentField < 10, 'blue', 'black')"
}
}
Outside Humidity Column Formatting using Conditional Formatting

These are the conditional formatting rules:

A Working Flow

Trigger with Concurrency Control set to 1
Initialize Variables
convertFromUtc(utcNow(), 'GMT Standard Time', 'yyyy-MM-ddTHH:mm')
Scope Authentication
Scope Location
Scope Devices
Scope Log Data
The expressions for the Select action are:
Room:
item()?['name']
Temperature:
item()?['thermostat']?['indoorTemperature']
Temperature Status:
item()?['thermostat']?['indoorTemperatureStatus']
Heat Setpoint:
item()?['thermostat']?['changeableValues']?['heatSetpoint']?['value']
Mode:
item()?['thermostat']?['changeableValues']?['heatSetpoint']?['status']
The expressions for the Create Item are:
Title: items('Apply_to_each')?['name']
Time: variables('currentTime')
Temperature: item()?['thermostat']?['indoorTemperature']
Heat Setpoint: items('Apply_to_each')?['thermostat']?['changeableValues']?['heatSetpoint']?['value']
Mode: items('Apply_to_each')?['thermostat']?['changeableValues']?['heatSetpoint']?['status']
Date: formatDateTime(variables('currentTime'),'yyyy-MM-dd')
Leave a Reply