Thursday 5 October 2017

Reverse engineering the EPH Controls Ember API

I have recently had my home heating upgraded with a new gas boiler and heating controls. While looking at the controls my plumber recommended the thermostat and controller EPH Controls. I was leaning more towards a system like Hive or Honeywell but decided to give this one a go as it did tick most of the boxes I needed. It includes 2 zone system (heating and hot water) that can be controlled via the thermostat locally in the house or via an app remotely.

The missing components to the EPH Ember system were integration into other home automation systems and voice control systems (e.g. Google Assistant). I decided it would be a good learning experience to reverse engineer the API and add it to home assistant, which I use for some other home automation controls. I have completed the first half of my task, which is reverse engineering the API, and from this have created a python library which can be used to control / monitor the system. This blog post will explain the steps I used to get the API details from their app / server.

The basic steps used to do this were:
  1. Figure out how the app and server communicate
  2. Capture that traffic 
  3. Decode and examine the traffic

Figure out how the app and server communicate

The very first thing to do is to find out how the app and server communicate. To do this I installed tPacketCapture on my android phone and sniffed the network traffic on my phone. Once I had the packet capture on my phone, I transferred it to my laptop and opened it with wireshark. From this I could see a number of different connections going out from my phone. Once I eliminated the traffic going to google, I could see network traffic going from my phone to an IP 40.127.170.98 on port 443.


As 443 is the port used by HTTPs, I could be fairly confident that that is the protocol used between server and client. HTTPs meant it was secure (good for my privacy) but (slightly) harder to decipher. However, as HTTPs is widely used there are plenty of tools available to sniff the connection when you are in control of the device and network.

Capture the traffic

The tool I chose for this was Charles Proxy a HTTP(s) proxy which allows you to capture and display HTTP(s) traffic. Once installed you should configure it to do SSL Proxying, get the root certificate, and install it on your device. Some of these steps are explained here. In later steps you will need the IP address of the computer running charles and the port that it is listening on (Proxy > Proxy Settings > Port)

On your android phone, you need to edit the wifi network settings for the network that you are connected to and have an instance of charles running on to use a proxy and point it to your charles install. To do this on Android, follow these steps:
  • Open your wifi settings.
  • Long click on the wifi network name and select modify network.
  • Select Advanced Options
  • Select Proxy > Manual
  • Enter the IP address of the server running charles
  • Enter the port charles is listening on (8888)
  • Save 
Your phone should now route all HTTP(s) traffic through your charles instance. Once you launch the ember app you should see traffic going to it's server at https://ember.ephcontrols.com

Decode and examine the traffic

As mentioned earlier, this proves that the API is using HTTPS to communicate between the app and the server. Charles can show you all information about the HTTP traffic including URL, headers, data.


Looking at the hierarchy of the folders in charles shows the URLs that are used. These include URLs such as
  • api/Account/RefreshToken
  • api/Home/GetHomeById?homeId=1234
By looking at the contents of these requests I can see that the server and client communicate by sending JSON encoded messages between them. As JSON is a widely used and text based protocol it was then just a matter of reading the charles logs to decipher the full protocol.

By running various scenarios in the app (e.g. login, check temperature, boost heating) I was able to capture most API calls and have documented them on github.