When we started shopping for solar generation installations, how much electricity we can consume was a challenging question. We were replacing our HVAC system, so “look at the last 12 months of electric bills” wasn’t an approach that would yield valid data. What we needed was a way to see electrical consumption for the next two or three weeks once our new HVAC system was installed.
We purchased several AeonLabs Home Energy Meters (HEM) and have been using them to track our power consumption for almost six months now. The HEM’s are set up in SmartThings & have a SmartApp-HEMLogger “SmartApp” attached to them that posts data to a MySQL table on our server via a web form (myURL needs to be … well, your URL).
Install a quick MySQL server (does not need to be Internet accessible) and a web server / programming language of your choice combination (*does* need to be Internet accessible – we are using Apache and PHP).
Create the database and a table to hold your energy data:
mysql> describe EnergyMonitors; +-----------+-------------+------+-----+-------------------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+-------------+------+-----+-------------------+----------------+ | keyID | int(11) | NO | PRI | NULL | auto_increment | | monitorID | varchar(50) | YES | | NULL | | | clampID | varchar(50) | YES | | NULL | | | eventTime | timestamp | NO | | CURRENT_TIMESTAMP | | | kwatts | double | YES | | NULL | | | kwhours | double | YES | | NULL | | +-----------+-------------+------+-----+-------------------+----------------+ 6 rows in set (0.00 sec)
Create an ID within your database that has read/write permission to this table. I create another ID that has read-only access (pages displaying data use this ID, the page to post data uses the read/write ID).
We also track temperature — ideally, we’d be able to compare power consumption based on temperature *and* sunlight (we use a lot less power on a cold sunny day than I expect … just don’t know how much less) … but I’m not there yet. Currently, the weather database only holds temperature:
mysql> describe weather; +--------------+-----------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +--------------+-----------+------+-----+-------------------+-----------------------------+ | recordedTime | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | | temperature | int(11) | YES | | NULL | | | id | int(11) | NO | PRI | NULL | auto_increment | +--------------+-----------+------+-----+-------------------+-----------------------------+ 3 rows in set (0.01 sec)
Since we brought our Bloomsky online, I use the Bloomsky API to record temperature. Prior to that, I was parsing the XML from NWS’s closest reporting station’s – for Cleveland, that is http://w1.weather.gov/xml/current_obs/KCLE.xml … there’s probably one near you. I grabbed both observation_time_rfc822 and temp_f in case observations were not updated regularly – the observation time was stored as the recordedTime. The temperature recording script is in cron as an hourly task.
You also need a small web page where SmartThings can post data — in PHP, I have
<?php if(!$_POST["monitorID"] || !$_POST["clampID"] ){ echo "<html><body>\n"; echo "<form action=\""; echo $_SERVER['PHP_SELF']; echo "\" method=\"post\">\n"; echo "Monitor ID: <input type=\"text\" name=\"monitorID\"><br>\n"; echo "Clamp ID: <input type=\"text\" name=\"clampID\"><br>\n"; echo "KW Value: <input type=\"text\" name=\"kwatts\"><br>\n"; echo "KWH Value: <input type=\"text\" name=\"kWHours\"><br>\n"; echo "<input type=\"submit\">\n"; echo "</form>\n"; echo "</body></html>\n"; } else{ $strMeter = $_POST["monitorID"]; $strClamp = $_POST["clampID"]; $strKWValue = $_POST["kwatts"]; $strKWHValue = $_POST["kWHours"]; print "<pre>Meter: $strMeter\nClamp: $strClamp\nKW: $strKWValue\nKWH: $strKWHValue\n</pre>\n"; $servername = "DatabaseHostname"; $username = "MySQLUID"; $password = 'MySQLPassword'; $dbname = "HomeAutomation"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } if($strKWHValue && $$strKWValue){ $sql = "INSERT INTO EnergyMonitors (monitorID, clampID, kwatts, kwhours) VALUES ('$strMeter', '$strClamp', '$strKWValue', '$strKWHValue')"; } elseif($strKWHValue){ $sql = "INSERT INTO EnergyMonitors (monitorID, clampID, kwhours) VALUES ('$strMeter', '$strClamp', '$strKWHValue')"; } else{ $sql = "INSERT INTO EnergyMonitors (monitorID, clampID, kwatts) VALUES ('$strMeter', '$strClamp', '$strKWValue')"; } if ($conn->query($sql) === TRUE) { echo "New record created successfully"; } else { echo "Error: " . $sql . "<br>" . $conn->error; } $conn->close(); } ?>
DatabaseHostname, MySQLUID and MySQLPassword need to be yours too. Since posted data is meant to come from a trusted source (a source where I’ve supplied the URL) and in a known good format, these are quick INSERT statements *not* the safest.
Check in your database that you are getting data, then let it run for a few hours. Once you have a little bit of history, you can start viewing your energy usage. Link it into Excel/Access using MyODBC for ad-hoc reporting, write your own code to do exactly what you want, use a generic charting package capable of reading MySQL data …
I am using pChart to display data – the chart I use most frequently is the stacked bar chart for kWH and a line chart for temperature. Here is the PHP code which generates this PNG: energyUsage-StackedBarChart-Flat – again, DatabaseHostname, MySQLUID, and MySQLPassword need to be yours.
We no longer have our heat pump, air handler, and heat strips being monitored – but for periods where there is data from the other sources, we had several segments to our energy usage report (“other” is the report from the HEM on our mains MINUS all of the other reporting segments). You can yank all of the non-mains segments (or change them to be whatever sub-segments you are monitoring. The monitor ID comes from the HEM name in SmartThings – since those are user-configured, I have the names hard coded. You *could* hard code the Mains and then use “select distinct” to get a list of all the others and make the code more flexible.).
Short term charts (past 24 hours or so) can render out real-time, but longer term views take a long time to load. Since we’re looking more for trends and totals – being up to the second isn’t critical. I’ve got cron tasks that generate out PNG files of the charts.
Two enhancements for a nothing-doing rainy day – adding authentication to the HEM Logger (SmartThings posts from multiple netblocks, so there isn’t a good way to IP source restrict access to the post data page. Anyone with your URL could post rogue energy usage info into your database – or more likely try to hack your servers.) and add lumen to the weather data / graph displays.