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.
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:
[php]
<?php
// 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
ORDER BY time DESC
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
) VALUES (
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
$prepare->execute($vals);
}
}
[/php]
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.
Results
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:
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.
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.
Resources
GitHub – https://github.com/SorX14/Projects/tree/master/HomeHub5
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.
http://www.alistairmills.com/datatables/up.php
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