ESP8266 Power Monitor
Energy Monitoring using ESP8266
Last month we have been using air-conditioning for more than usual. And when I received the bill, the bill was 46 USD but previously the bill never gone up above 20 USD. When analysed the bill and found there was a revision in the tariff. Here is the tariff.
All the tariffs were for the Bi-Monthly consumption.
Consumption | Slab | Charges Per Unit (USD) | Fixed Charges for 2 months |
---|---|---|---|
Upto 100 Units | 0-100 units | 0.016 | 0.31 |
Upto 200 Units | 0-200 units | 0.02 | 0.31 |
Upto 500 Units | 0-200 units | 0.03 | 0.47 |
201-500 units | 0.05 | 0.47 | |
Above 500 Units | 0-200 units | 0.06 | 0.63 |
201-500 units | 0.07 | 0.63 | |
Above 501 units | 0.10 | 0.63 |
All the tariffs were for the Bi-Monthly consumption I have consumed 630 Units of electricity for the month of April and May of 2015
So the calculation follows to tarrif Above 500 Units
200 * 0.06 = 12 USD
300 * 0.07 = 21 USD
130 * 0.10 = 13 USD
For Total 630 Units = 46 USD
If we use energy bellow 500 units for 60 days the bill would be
200 * 0.03 = 6 USD
299 * 0.05 = 14.95 USD
For 499 Units = 20.95 USD
Conceive of the Project
If we need to utlize energy bellow 499 units for Bi-monthly (60 days) we need to monitor the energy usage instantaniously and log the datas.
Materials laying around
1. Raspberry PI (I already had raspberry PI running rasbian for home automation)
2. ESP8266 (ESP-12)
3. L14G2 (Photo Transistor)
4. 2600Mah Power Bank
5. 5V Charger (For charging Power bank)
How.
I had a analogue old type meter with spinning wheel . With no LED’s or pulse output .
So I had to install a watt-hour meter with LED pulse output after the main meter. The newly installed meter has output of 3200 pulse per kilowatt (3200 Pulses/Unit) through Red color LED.
So the simple logic is to capture the pulse count for every 60 seconds from wathour meter LED with L14G2 Photo Transistor and update to the raspberry PI web-server on scheduled every minute through ESP8266 with interrupt and timer function.
In the web-server part Raspberry PI running rasbian with apache2, PHP and MySQL. have a simple PHP script to receive the values and save it to MySQL database. The script will be called by ESP8266 on every minute to post the collected pulses. Raspberry web-server script also has the reports for the usage of power.
Well, we have some backup policies in the ESP8266 and some Bugs.
When the connection with ESP8266 and Raspberry web-server was not established on the updated schedule due do any reasons, The logged pulse for the current minute will be accumulated to the next until the success full connection establishment and update.
The Bug is Interrupt was not working after 40-50 minutes of continues operation. So to overcome that the ESP8266 Programmed to reset every 30 minutes. (simple but efficient)
Here is the video of the project testing in progress with the computer processing LED istead of watthour LED
Attached the images
ESP8266 Stack with PowerBank
ESP8266 Stack with stack able board and pull down resistor connected to GPIO13
ESP8266 Stack with stacakble board and connector for L14G2
ESP8266 Stack with Power-bank and L14G2 wired
Installed the L14G2 with the masking tape facing the pulse output LED of watt-hour meter.
Cheap and neat enclosure from ESP Stack
Screwed the enclosure and powered the power-bank from the 5V mobile charger. and ESP Stack with output from power-bank
Reports Front Page
Logged Pulses and Watts from every minute
MinuteWise Pulses /Watts Consumed
DayWise Power Consumption Graph
Attached the images ESP8266 Stack with PowerBank
Access the live reports @ https://www.oakdock.com
Code of ESP8266 Stack (NodeMCU)
powermon.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
gpio2 =7 count = 0 avg=0 watts=0 accu=1 loged = 0 print("Esp8266 Power Monitor\n") function debounce (func) local last = 0 local delay = 2000 return function (...) local now = tmr.now() if now - last < delay then return end last = now return func(...) end end function resetnode() node.reset() loged = 0 end function upload() conn = net.createConnection(net.TCP, 0) conn:on("receive", function(conn, payload) success = true print(payload) end) conn:on("disconnection", function(conn, payload) print('\nDisconnected') if loged >= 60 then resetnode() end end) conn:on("connection", function(conn, payload) print('\nConnected') conn:send("GET /putrows.php?" .."what=xxxxxxxx&devid=1&pulse="..count .."&power="..watts .." HTTP/1.1\r\n" .."Host: oakdock.com\r\n" .."Connection: keep-alive\r\n" .."Accept: */*\r\n" .."User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n" .."\r\n") count=0 avg=0 watts=0 accu=1 end) print("Opening port") accu = accu + 1 loged = loged + 1 print("Accu "..accu.."\n") conn:connect(80,'oakdock.com') end function onChange () count=count+1 print("Int"..count.."\n") end gpio.mode(gpio2, gpio.INT) gpio.trig(gpio2, 'up', debounce(onChange)) tmr.alarm(0,60000, 1, function() if (count > 0 ) then avg = (accu * 60) / count watts = (( 3600 / avg ) / 3200 ) * 1000 end print("Count "..count.."\n") print("Average "..avg.."\n") print("Watts "..watts.."\n") print("Accu "..accu.."\n") upload() end) |
Note : xxxxxxxx is the secret code in your php script . and make sure to change oakdock.com to your raspberry IP
init.lua
1 2 3 4 |
wifi.setmode(wifi.STATION) wifi.sta.config("user","pass") wifi.sta.connect() dofile ("powermon.lua") |
Note : user and pass is your wifi credentials and make sure to change it.
PHP Code for Raspberry PI
putrows.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?php include_once './DbConnect.php'; function putrows() { // echo $_GET["what"]; if ($_GET["what"] == "xxxxxxxx") { $response = array(); $devid = $_GET["devid"]; $pulse = $_GET["pulse"]; $power = $_GET["power"]; $db = new DbConnect(); $query = "INSERT INTO `powermon`.`powerlog` (`devid`, `logdate`, `pulsecount`, `watts`) VALUES ('$devid',now(),'$pulse','$power')"; $result = mysql_query($query) or die(mysql_error()); if ($result) { $response["error"] = false; $response["message"] = "OK"; } else { $response["error"] = true; $response["message"] = "Failed"; } } else { $response["error"] = true; $response["message"] = "Invalid Login!"; } // echo json response echo json_encode($response); } putrows(); ?> |
Note : xxxxxxxx is the secret code should match to the code in powermon.lua script
DbConnect.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?php /** * Connecting / disconnecting Database * * @author Mohan */ class DbConnect { private $conn; // constructor function __construct() { // connecting to database $this->connect(); } // destructor function __destruct() { // closing db connection $this->close(); } /** * Establishing database connection * @return database handler */ function connect() { include_once dirname(__FILE__) . './Config.php'; // Connecting to mysql database $this->conn = mysql_connect('localhost', 'user', 'pass') or die(mysql_error()); // Selecting database mysql_select_db('powermon') or die(mysql_error()); // returing connection resource return $this->conn; } /** * Closing database connection */ function close() { // closing db connection mysql_close($this->conn); } } ?> |
Note : user and pass is the login details for the mysql database server the database name we used is powermon
getdata.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php include_once './DbConnect.php'; function ShowLogs(){ $db = new DbConnect(); $response = array(); $response["pmon"] = array(); $result = mysql_query("SELECT * FROM powerlog order by logdate DESC limit 60"); while($row = mysql_fetch_array($result)){ echo $row['logdate'] . ' | ' . $row['pulsecount'] . ' Pulse | ' .$row['watts'] . " Watts<br>"; } } ShowLogs(); ?> |
Note :These files should be on the Raspberry Pi Server var//www/ Directory
SQL Structure
Database name : powermon
Table name : powerlog
|
Create table script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
-- -- Database: `powermon` -- -- -------------------------------------------------------- -- -- Table structure for table `powerlog` -- CREATE TABLE IF NOT EXISTS `powerlog` ( `id` int(11) NOT NULL AUTO_INCREMENT, `devid` int(11) NOT NULL DEFAULT '0' COMMENT 'Device ID', `logdate` datetime NOT NULL, `pulsecount` int(11) NOT NULL DEFAULT '0', `watts` float NOT NULL DEFAULT '0' COMMENT 'Watts', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; |
If everything is correctly configured you can see the powerlog table filled with new low on every minute. from the esp8266.
and you can make your own reports from the data available. and charts can be done using amcharts.
Happy coding..