Monitoring BT Home Hub 5 usage

I’ve been working on collecting BT Home Hub 5A usage by connecting with PHP + cURL and extracting data from the status page. The last piece of the puzzle is figuring out the roll-over point of the data counter; it resets when it reaches a high enough level.

BT Home Hub 5A helpdesk screen
BT Home Hub 5A helpdesk screen

I collected data every second for a few hours while repeatedly downloading linux torrents (I have unlimited usage) and here are my results.

Getting data

I ended up using the class I wrote previously (linked at the bottom) and added a few more functions to help with data extraction. I use the class with Restler to create an API, now I can access the data with /homehub/status within my local network. This makes collection much easier, and I used the following code to add the data to my database:


// We’ll connect to the API from the inside
$result = file_get_contents(RESTLER_URL);

if (isset($result)) {
$decode = json_decode($result);
if ($decode->return_code == 100) {
// Get the variables we’ll be inserting
$uptime = $decode->uptime;
$raw = $decode->data_usage->raw;
$received_mb = $decode->data_usage->received_mb;
$sent_mb = $decode->data_usage->sent_mb;
$version = $decode->version->version;
$last_update = date(‘Y-m-d’, strtotime($decode->version->update_date));

// Connect to the database
$database = new Database();
$db = $database->getDBObject();

// We need to get the last entry in the table so we can compare
try {
$stmt = $db->query("SELECT
time, uptime, data_received, data_sent, total_received, total_sent
FROM router
LIMIT 1");

$result = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
// We failed to get the previous stats, but its not required later on
$result = false;

// Now calculate the difference between the previous reading and the current reading
$diff_received = $received_mb – $result[‘data_received’];
$diff_sent = $sent_mb – $result[‘data_sent’];

// Add the difference to the total counts
$total_received = $result[‘total_received’] + $diff_received;
$total_sent = $result[‘total_sent’] + $diff_sent;

// Insert the data
$prepare = $db->prepare("INSERT INTO router (
time, uptime, data_received, data_sent,
diff_sent, diff_received, total_received,
total_sent, raw, version, last_update
NOW(), :uptime, :received, :sent,
:diff_sent, :diff_received, :total_received,
:total_sent, :raw, :version, :last_update

$vals = array (
‘:uptime’ => $uptime,
‘:received’ => $received_mb,
‘:sent’ => $sent_mb,
‘:diff_sent’ => $diff_sent,
‘:diff_received’ => $diff_received,
‘:total_received’ => $total_received,
‘:total_sent’ => $total_sent,
‘:raw’ => $raw,
‘:version’ => $version,
‘:last_update’ => $last_update

// Execute the query

I ran this script with a while(true) loop with sleep(1) to limit the load on the Home Hub and to prevent my database from being filled with duplicate entries.


Roll-over point at 4.3GB
Roll-over point at 4.3GB

I was surprised at the roll-over point, it seemed to be 4.3 GB which seems arbitrary – you would’ve thought 5 GB or similar. However, depending on the operating system underneath, the data counter may be an unsigned long to count bytes which has a maximum value of 4,294,967,295 (reference). If we divide it down by 1000 (KB) and 1000 (MB) again, we get ~ 4295 which is close enough for rounding to have given us 4.3. Regardless of why the roll-over point is what it is, we just need to know the exact time that it occurs so we can accurately configure the collector to deal with it correctly.

I modified my original script which returns megabytes to use 1000 instead of 1024 when converting from GB to MB. There is confusion over which is the correct to use, and technically if you use 1024 you should write MiB instead of MB. As non-unlimited data transfer contracts exist, I would assume BT would callously pick 1000 instead of 1024. In fact, I managed to capture the change-over point from showing MB to GB which pretty much conclusively shows the units BT are using:

Transition from MB to GB
Transition from MB to GB

WGET –limit-rate

I figured the best way to test the Home Hubs counter would be to remove all devices from the network apart from my server, and run WGET with the --limit-rate argument to only download at half a megabyte (--limit-rate=500k). By taking a measurement every second, I would be able to see how accurate the counter was compared to a known data rate.

500k transfer vs Home Hub usage reporting
500k transfer vs Home Hub usage reporting

As you can see above, the Home Hub reports an increase of ~0.6MB each second, which means that either WGET is transferring faster than it should be, there is a large amount of overhead involved in transferring the data, or the Home Hub is just plain wrong. There doesn’t seem to be an easy link between the amount of data a program uses and the figures that the hub reports, but, it is consistent so we can at least work with a known error.

The Hub reported the following at a constant 1MB/s WGET:

Segment number Time Name Time difference
#1 20:52:49 4.0GB -> 4.1GB transition
#2 20:54:21 4.1GB -> 4.2GB transition 1m 32s
#3 20:55:54 4.2GB -> 4.3GB transition 1m 33s
#4 20:56:36 4.3GB roll-over 42s

Taking the 4295 MB roll-over point discussed above, it almost matches what we’re seeing…

Segment #1 is likely to start at 4050 MB (rounded up, its the first time we get 4.1 GB), so segment #2 would start at 4150 MB and so on. Taking a look at the time difference, we can make an assumption as to the roll-over amount. It takes ~93 seconds to transfer 100 MB, or 1.075 MB/s, so 42 seconds would shift about 45 MB. Add 45 to 4250 and we get – you guessed it – 4295; our magical predicted unsigned long limit.

With that I’m calling it case closed, it’ll be a simple case of adding in compensation for this roll-over point and my project is done.


GitHub –

Join the conversation


  1. Hello

    I have downloaded and executed your BT Home Hub code. Well done. It works!

    However, I am not sure about how to implement the code example on this page. It feels to me that there are some details missing about how to configure RESTLER_URL and the local database.

    I have written quite a lot of monitors for things which interest me, and one which monitors my BT Home Hub would be very useful. For example, the following reports the status of my home computers and web sites.

    1. Indeed, there is some missing code. I used Restler to output the results of the github code, but you don’t need to use that at all. All you need is the example.php file, and you’ll be able to consume the data in any way that you see fit. You could make it output JSON for example, or XML.

      Hope that makes sense

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.