{"id":456,"date":"2009-02-07T22:09:00","date_gmt":"2009-02-07T22:09:00","guid":{"rendered":"http:\/\/dalelane.co.uk\/blog\/?p=456"},"modified":"2009-02-18T12:50:59","modified_gmt":"2009-02-18T12:50:59","slug":"getting-data-from-the-currentcost-cc128","status":"publish","type":"post","link":"https:\/\/dalelane.co.uk\/blog\/?p=456","title":{"rendered":"Getting data from the CurrentCost CC128"},"content":{"rendered":"<p>I really need to stop <a href=\"http:\/\/dalelane.co.uk\/blog\/?tag=currentcost\">blogging about CurrentCost<\/a> stuff, this is starting to look like an obsession \ud83d\ude42<\/p>\n<p>But before I do that, I thought I&#8217;d share my experiences in writing a new CurrentCost parser. <\/p>\n<p><strong>What is this all about?<\/strong><br \/>\nOn the off-chance that anyone following me hasn&#8217;t already heard about <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=265\">CurrentCost<\/a> a million times already, CurrentCost meters are domestic electricity monitors that tell you how much electricity your household is using. And they have a connection underneath that lets you grab the data from them.<\/p>\n<p>As well as getting your current electricity usage, you can also get historical usage totals out of the serial port, which I&#8217;ve used in a variety of ways, such as in <a href=\"http:\/\/code.google.com\/p\/currentcostgui\/\" target=\"_blank\">my Python CurrentCost software<\/a>.<\/p>\n<p>CurrentCost have now brought out a new model of their monitor &#8211; <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=389\">the CC128<\/a>. The data format is different to the current models, so I wanted to try and write a new parser that could handle both the existing model and the new CC128 data.<\/p>\n<p><!--more--><strong>Connecting<\/strong><br \/>\nFirst things first, connecting to the meter. <\/p>\n<p>I used to do this in Python to get data from the meter:<\/p>\n<pre><code>ser = serial.Serial(port='COM20', timeout=5)\r\nline = ser.readline()<\/code><\/pre>\n<p>With the CC128, I need to use:<\/p>\n<pre><code>ser = serial.Serial(port='COM20', \r\n                    baudrate=57600,\r\n                    bytesize=serial.EIGHTBITS,\r\n                    parity=serial.PARITY_NONE,\r\n                    stopbits=serial.STOPBITS_ONE,\r\n                    timeout=3)\r\nline = ser.readline()<\/code><\/pre>\n<p><strong>Getting history data &#8211; how it used to work<\/strong><br \/>\nMy old CurrentCost meter outputs <a href=\"http:\/\/cumbers.wordpress.com\/2008\/05\/07\/breakdown-of-currentcost-xml-output\/\" target=\"_blank\">a line of XML<\/a> every six seconds or so. Most of the time it includes history data, but not always. But it was good enough for my app to keep reading updates from the meter until it gets one with history data &#8211; at worst, the user waits for about 15 seconds until the app has the data it needs.<\/p>\n<p><strong>Getting history data &#8211; how it works now<\/strong><br \/>\nThe CC128 doesn&#8217;t include history data in every (or nearly every) update. The <a target=\"_blank\" href=\"http:\/\/www.currentcost.com\/cc128\/xml.htm\">draft doc on the CurrentCost website<\/a> says: <\/p>\n<blockquote><p>&#8220;History messages are output starting at 1 minute past every odd hour, ie 17:01, 19:01 etc&#8221;<\/p><\/blockquote>\n<p> so you can potentially have to wait quite a while to get history update (or be connected at the right time!). <\/p>\n<p>Alternatively, you can force the meter to output the history data by <\/p>\n<blockquote><p>&#8220;pressing and holding the Down and OK buttons together until the LED flashes&#8221;<\/p><\/blockquote>\n<p> The LCD display changes to just displaying a single number, flashing 1 to 9 repeatedly until it has finished outputting the history. <\/p>\n<p>This is a bit of a pain for me with <a href=\"http:\/\/code.google.com\/p\/currentcostgui\/\" target=\"_blank\">my app<\/a>, as I get the data from the meter remotely so needing to be near enough to the meter to press the buttons is less than ideal. <\/p>\n<p><strong>How it works now &#8211; what it looks like<\/strong><br \/>\nI&#8217;ve already blogged about <a href=\"http:\/\/dalelane.co.uk\/blog\/?p=389\">what history data you can get from the CC128<\/a>, and the <a href=\"http:\/\/www.currentcost.com\/cc128\/xml.htm\" target=\"_blank\">draft doc for the CC128 XML<\/a> gives a specification of the data. <\/p>\n<p>What I didn&#8217;t realise from reading it was that you don&#8217;t get a single line of XML with the whole history data in it. You get a series of XML updates, each of which contains a sliding, overlapping window into the history data.<\/p>\n<p>First you get two-hourly history, then daily history, then monthly history data. Each set of history data is returned in chronological order &#8211; from the oldest data to the most recent.<\/p>\n<p>For example, my meter has been running for 14 days since I last reset it. So the oldest two-hourly history data is <code>h324<\/code> &#8211; the electricity used from 326 hours to 324 hours ago.<\/p>\n<p>So the first line of two-history data contains the two-hourly history data:<br \/>\n<code>h324, h322, h320, h318, ... h230, h228, h226<\/code><br \/>\nThe second line of history data received contains the two-hourly history data:<br \/>\n<code>h322, h320, h318, h316, ... h228, h226, h224<\/code><br \/>\nThe third line of history data received contains two-hourly history data:<br \/>\n<code>h320, h318, h316, h314, ... h226, h224, h222<\/code><\/p>\n<p>And so on, until the end of the two-hourly history data:<br \/>\n<code>h102, h100, h098, h096, ... h008, h006, h004<\/code><\/p>\n<p>And then the daily history data:<br \/>\n<code>d014, d013, d012, d011, d010, ... d003, d002, d001<\/code><\/p>\n<p>I would then receive monthly data, except my meter hasn&#8217;t been running for a month since last reset, so there isn&#8217;t any monthly history data yet. <\/p>\n<p>Notice that you only receive XML for the data you have &#8211; unlike the old meter which receives the full XML in every history update, with zeroes for data not yet available.<\/p>\n<p>If you want to see an example, <a href=\"http:\/\/dalelane.co.uk\/blog\/post-images\/cc128history.xml.zip\">here is my history data<\/a> for the last couple of weeks.<\/p>\n<p><strong>How do you use the CC128 history data<\/strong><br \/>\nThe history data is big. Very big. <\/p>\n<p>This explains why we don&#8217;t get history data every 6 seconds!<\/p>\n<p>Getting just fourteen days of history data (i.e. 112 updates of two-hourly history, 1 update of daily data, 0 updates of monthly data) takes about <strike>a minute<\/strike> ten minutes to be output, and produces about 1MB of XML.<\/p>\n<p>For my interactive app which displays a progress bar while it&#8217;s waiting to receive a complete copy of the history, this means that once the meter history is full, downloading history data could take <strike>a few minutes<\/strike> quarter-of-an-hour or longer. <\/p>\n<p>Still, there are benefits to this approach. The overlap in the history data means that we can handle losing a few updates without losing any data. And in some ways it makes more sense to output a new copy of the history after it has changed &#8211; outputting months of history data every 6 seconds is a little redundant.<\/p>\n<p><strong>Parsing the data<\/strong><br \/>\nI&#8217;ve updated my Python parser so that it now can handle receiving XML from either the old or the new CurrentCost meters. It can be downloaded from <a target=\"_blank\" href=\"http:\/\/code.google.com\/p\/currentcost\/\">http:\/\/code.google.com\/p\/currentcost\/<\/a>.<\/p>\n<p>.<br \/>\n<strong>Update (10th Feb):<\/strong> I massively underestimated the time it takes to download the history. I was going by the timestamps contained in the XML I was downloading &#8211; but it turns out that <a target=\"_blank\" href=\"http:\/\/twitter.com\/MartinDix\/status\/1191572493\">the CurrentCost meter&#8217;s clock stops while it is outputting history data<\/a>. What I said took only a minute took more like ten minutes. It also resulted in my CurrentCost clock being ten minutes slow(er) once this was complete &#8211; every time I downloaded the history.<\/p>\n<p><strong>Update (18th Feb):<\/strong> I got a new CC128 <a href=\"http:\/\/eightbar.co.uk\/2009\/02\/12\/mad-scientists\/\" target=\"_blank\">last week<\/a> and now it&#8217;s been running for a week, I took a look at <a href=\"http:\/\/currentcost.googlecode.com\/files\/cc128_sample.xml\" target=\"_blank\">the XML<\/a>. The new CC128 has a later software version (0.11) than the one I was using when I wrote this post (0.09). The XML produced by the newer version is a little different. There are a couple of new items included in there, for example, there is now a &lt;dsw&gt; (<a target=\"_blank\" href=\"http:\/\/twitter.com\/MartinDix\/status\/1202378756\">days-since-wipe<\/a>) item in addition to the previous &lt;dsb&gt;. More importantly though, it looks like <a href=\"http:\/\/currentcost.googlecode.com\/files\/cc128_sample.xml\" target=\"_blank\">v0.11<\/a> doesn&#8217;t overlap the history data in the way that <a href=\"http:\/\/dalelane.co.uk\/blog\/post-images\/cc128history.xml.zip\">0.09<\/a> did. This is great to see. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>I really need to stop blogging about CurrentCost stuff, this is starting to look like an obsession \ud83d\ude42 But before I do that, I thought I&#8217;d share my experiences in writing a new CurrentCost parser. What is this all about? On the off-chance that anyone following me hasn&#8217;t already heard about CurrentCost a million times [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[194,212],"class_list":["post-456","post","type-post","status-publish","format-standard","hentry","category-code","tag-currentcost","tag-python"],"_links":{"self":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=456"}],"version-history":[{"count":0,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=\/wp\/v2\/posts\/456\/revisions"}],"wp:attachment":[{"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dalelane.co.uk\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}