For Christmas this year I received a few nerdy toys; One of them being a digital power meter (Amazon Link) that allows you to see your energy consumption.

I mainly asked for it so that I could start tracking energy usage around the house. Mostly for fun and only partially for the data.

After watching a number of videos on YouTube all about Tesla PowerWalls and the app that comes with it, I got inspired to build a similar kind of app / utility monitor to allow me to see how much power the house consumes and when are my peak energy consumption times.

This post primarily focuses on getting the data from the Modbus power meter into a RaspberryPi. Separate posts will include building services to publish this data.

There are two options to buy the power meter; A lcd display unit that gives you a quick read out and a unit that converts its signals into Modbus RS485 which can then be plugged into a bigger system – in my case a RaspberryPi. (Clicking on the images takes you to Amazon, it’s not an affiliate link. I’m just being helpful if you want to copy my setup).

Power Meter with LCD Screen

This power meter gives you an instant read out of energy consumed.

This power meter outputs its energy readings using the Modbus RS485 Protocol

This power meter outputs its energy readings using the Modbus RS485 Protocol

The reason that I chose to use the Modbus power meter rather than the LCD was that I wanted to measure power coming into the house from my circuit breaker and while its great to quickly wire the LCD unit into the setup, running around the house and then back to the circuit breaker would have just been too boring.. plus code!

Here’s a simple setup digram for how I wired the power meter into my house electrical system.

Electrical Wiring Diagram

Both the live and neutral are wired into the power meter and then the inductor is placed to encapsulate the live wire.

!* ⚠️ Warning! ⚠️ *!
Electricity is VERY dangerous, please take every precaution you can to be safe. If in doubt consult a qualified electrician who can do the work for you.

Depending on the setup and country your going to get a few outputs of power.
In the US, power is 110/220AC at 60Hz, in the UK its 240AC at 50Hz, in Europe its 230AC at 50Hz. Again, please consult a qualified electrician for your region, the last thing anyone needs is to short a wire and burn your house down.

 

Once you have the power meter wired up you can begin to take some measurements. The unit maker PeaceFair have released a windows version to read the values quickly. You can find a link here; however it requires an AliExpress login. If you’re using windows and don’t need anything more a viewer this is probably going to be perfect for you.

 

In my setup I’ve plugged the USB connector into a RaspberryPi, the Pi using the latest version of Raspbian Buster Lite. Buster Lite is a variant of Ubuntu and so you can run ubuntu commands.

First thing to do is to update the Pi’s software.

sudo apt-get update -y && sudo apt-get upgrade -y

 

This updates all the installed software on the Pi and allows us to start with a fresh up-to-date image.

In the user Pi home directory create a new folder called powerMeter.

cd ~ && mkdir powerMeter && cd powerMeter

This command will create the folder and navigate to it.

 
Once here, we need to setup a Python script to communicate with the power meter.

The power meter uses a protocol called ‘Modbus‘ which was invented in the late 1970’s and uses two wires to communicate between a master and multiple slave devices on the same 2 wire network. Its protocol is very similar to RS232 only with less device handshaking.

Due to the open nature of Modbus, a number of tools and scripts exist to communicate with a Modbus device.

For Python, I’m going to be using the ‘MinimalModbus library which will do a lot of the heavy lifting for us.

 

To get started create a script called ‘powerMeter.py‘ using your preferred text editor. Im using nano, but feel free to use vim or anything else.

nano powerMeter.py

 

Once in the text editor add the python3 shebang (The shebang line in any script determines the script’s ability to be executed like a standalone executable)

#!/usr/bin/env python3

Then import the needed libraries.

import minimalmodbus
import serial

in this script the needed libraries are minimalmodbus and serial.

 

Once we have setup the script we can start to define our powerMeter, adding in the needed credentials to make a connection via RS485/Modbus.



powerMeter = minimalmodbus.Instrument('/dev/ttyUSB0', 1)
powerMeter.serial.baudrate = 9600
powerMeter.serial.bytesize = 8
powerMeter.serial.parity = serial.PARITY_NONE
powerMeter.serial.stopbits = 1
powerMeter.mode = minimalmodbus.MODE_RTU
print('Details of the power meter are:')
print(powerMeter)

 

Let’s unpack what’s going on here; powerMeter is the object that’s been created to act as the connection via the USB socket (‘ttyUSB0’), the 9600 refers to the speed of communication. At the end the RTU mode sets up the specific protocol that the service will use. Modbus actually has a few different ones, so we need to implicitly define one.

At the end, the powerMeter is printed to show what values have been assigned.

 
Now that the powerMeter has been created, a function can be created to read the data values from it.


def readPowerMeter():
print("Attempting to read power meter")
try:
voltageReading = powerMeter.read_register(0, 0, 4)
ampsReading = powerMeter.read_register(1, 0, 4)
wattsReading = powerMeter.read_register(3, 0, 4)
frequencyReading = powerMeter.read_register(7, 0, 4)
print("Voltage", voltageReading/10)
print("Amps", ampsReading/10)
print("Watts", wattsReading/10)
print("Frequency", frequencyReading/10)
except IOError:
print("Failed to read from instrument")

Finally call the function to read the values from the powerMeter function

# Run the function to read the power meter.
readPowerMeter()

 

You can run the script by typing

python3 powerMeter.py

On success the script will print out all the values it could read from the meter.

Here’s a copy of mine:

 
Attempting to read power meter
Voltage 245.7
Amps 165.8
Watts 329.3
Frequency 60.0

As you can see from the readouts, my house operates at 250AC (ish) Volts, I’m currently drawing 165 AMPS of power and consuming 329 watts of electricity.

Success!

Success!

Success!

With the basic script setup we can now make requests to the Modbus power meter and read back basic values about power being consumed in the house.
Later posts will show how you can turn this data into information I can store on a server and then recall to a UI.
Thank you!

Attributes: 

I placed a full copy of the script on GitHub. Please clone and use as you please!

Community post which contained code I used in my setup – Thanks to Bill Thomson for sharing!.

 

Over the last few months I’ve been speaking to a lot of customers (of Twilio), who need to be able to break down the spend of minutes spread over the countries that they call.

An example here would be:

ISO Country Code Minutes Used Total Price Number Of Calls
US 34 55.23 29

 

Thinking about how to solve this issue, I thought the best way to do it was to put the power into a script that you can download and run yourself.

You can find the script at: https://github.com/dotmat/TwilioCountryMonthlyReport

You will need to install Twilio helper library by running:

pip install Twilio

Once you have the helper library installed you need to edit the ‘CountryReportGenerator.py’ file to include your AccountSID and AuthKey as well as the dates you want to examine.

  • Keep in mind that the larger date range you select the longer the script will take to run.

From your terminal you can now run:

python3 ./CountryReportGenerator.py

The script will generate three reports for you.

  1. A CSV file showing containing the log of calls made in the date period. The CSV headers are: CallSID, CountryCode, NumberCalled, CallPrice, CallDuration
  2. A CSV file, this CSV file is the outcome of   and outputs: Country, MinutesUsed, TotalPrice, NumberOfCalls
  3. A JSON feed of the data so that you can use this in any server scripts you have running

Please let me know if you have any questions or issues.

TL:DR: Python3 Script that examines a date range to work out what countries have been called and in what frequency.

With the PCB now built and soldered, my attention can turn to the software that powers the BeeSafe and the cloud API that it runs on.

The software is broken down into two parts; software run locally on each BeeSafe and software run in the cloud that manages all inputs, requests, alerts and data.

This post will focus on the software, hosted locally on the Raspberry Pi – the brain of each BeeSafe.

The focus of Raspberry Pi is to help teach people (children) the basics via Python (for more information visit: http://www.raspberrypi.org), so that is the language I have chosen to use on the Pi.

While the BeeSafe PCB has a variety of sensors (Temperature, GPS, Trip Switch and Accelerometer) the main one this post will focus on is temperature. On the board itself I have included a ds18b20 temperature sensor which uses the 1-wire thermal probe. Information on this can be found at: http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/ and http://learn.adafruit.com/adafruits-raspberry-pi-lesson-11-ds18b20-temperature-sensing/hardware

Once we have a powered and working Pi, we need to activate the 1-Wire probes, in the command line of your Pi type in :

sudo modprobe w1-gpio

then

sudo modprobe w1-therm

then

cd /sys/bus/w1/devices/

ls

On the page now you should have something that looks like:

w1_bus_master1 and another that looks like “28-000004bb8e9b“. The “28-000004bb8e9b” will be the serial number of the thermal probe, if you have more than one then, they should all be presented alongside each other.

You can directly interface with the thermal probe by typing in

cd /28-000004bb8e9b

and then

cat w1_slave

This will present you with a 2 line read out of data from the thermal probe, it should look something like:

19 01 4b 46 7f ff 07 10 eb : crc=eb YES

19 01 4b 46 7f ff 07 10 eb t=17562

From the output you can see a value called t=17562 which is the temperature but presented raw format, The actual value here is 17.562C. What we need is some code to read this temperature device and give us a useful temperature value.

The code found on the tutorial page at Cambridge (http://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/temperature/) is a perfect starting point for building out with. A copy of the code is below:

# Open the file that we viewed earlier so that python can see what is in it. Replace the serial number as before.
tfile = open(“/sys/bus/w1/devices/YOURW1PROBE/w1_slave”)
# Read all of the text in the file.
text = tfile.read()
# Close the file now that the text has been read.
tfile.close()
# Split the text with new lines (\n) and select the second line.
secondline = text.split(“\n”)[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temperaturedata = secondline.split(” “)[9]
# The first two characters are “t=”, so get rid of those and convert the temperature from a string to a number.
temperature = float(temperaturedata[2:])
# Put the decimal point in the right place and display it.
temperature = temperature / 1000
print temperature

Change to your user directory folder by:

cd ~

and open a new file by typing in:

sudo nano read_temp.py

Copy and paste the above code into the nano editor and be sure to change YOURW1PROBE to the serial number of your probe. If you saved this file as read_temp.py you can run it by typing in:

sudo python ./read_temp.py

it will read the thermal probe for data and print out the temperature in the correct format.. i.e. 17.562C not 17562

Now we can read real world temperature into our software! The next step is to install the libraries to allow us to send this data in an SMS message to our phones!

In your command line update APT using the following commands:

sudo apt-get update

sudo apt-get upgrade

Next we need to install PIP, this is done by:

sudo apt-get install python-pip python-dev build-essential
sudo pip install –upgrade pip
sudo pip install –upgrade virtualenv

and then

sudo pip install twilio

Twilio is a global voice and SMS API provider, they allow you to make & receive voice and SMS (as well as MMS) messages to and from phones to and web services. For this post we are particularly interested in the Sending SMS API which will allow us to send SMS messages from our local device to a cloud service to our mobile phone.

Twilio can be found online at: http://www.twilio.com

If you haven’t already done so, sign up for a trial account. You get $30 of credit to play with the Twilio system. Once you have signed up, you will need to buy a number (these cost $1 per calendar month, but will come out from the trial credit) and verify a phone number that you currently have (such as your mobile).

Once your signed up, in your account page you will need to note down your account SID and auth token. These can be found on the top of:  https://www.twilio.com/user/account

Now we need to start to form a more complex python code, fortunately we can build onto of the code we have written before! To maintain a logical evolution of our files we are going to make a copy of read_temp.py by typing in:

sudo cp ./read_temp.py ./send_sms_temp.py

This will make a copy of our read temp file and save it as send_sms_temp.py

Open up your text editor by typing:

sudo nano send_sms_temp.py

You should see an identical copy of the code we have written before; now we are going to modify this file so that it can assemble an SMS message from our temperature data.

Start by adding:

from twilio.rest import TwilioRestClient

to the top of the page, this will call the Twilio REST API client when the file loads.

Underneath the temperature code, we need to add the following lines:

account_sid = "ACXXXXXXXXXXXXXXXXX"
auth_token = "YYYYYYYYYYYYYYYYYY"
client = TwilioRestClient(account_sid, auth_token)
message = client.messages.create(to="+12316851234", from_="+15555555555",
body="Hello there! The temperature is: " + srt(temperature) + "c")
Substitute the account SID and auth tokens with the ones you wrote down from your user account page: https://www.twilio.com/user/account, then you will need to adjust the ‘to’ value to be a number you wish to SMS. Twilio uses international number standards, so a number in the United States would be ‘+14155555555’ and one from the UK would be ‘+447971234567’.
You will also have to adjust the ‘from’ variable to be the number you have provisioned when you signed up for your trial account. A word of warning, not all numbers from Twilio support SMS messages, particularly SMS messages across geographic locations.
To check which counties can receive messages from which number, check out: https://www.twilio.com/international – when you have signed up test your number works by sending yourself a message from your account portal  (https://www.twilio.com/user/account/developer-tools/api-explorer#POST/2010-04-01/Accounts/{AccountSid}/SMS/Messages.{format})
The srt(temperature) is us telling python to convert the numerical value of temperature into a string value so that it can be added to our outgoing SMS message. Strings and Strings go together, Numbers and Numbers go together, Strings and Numbers do not.
By now your code should look something like this:

from twilio.rest import TwilioRestClient

# Open the file that we viewed earlier so that python can see what is in it. Replace the serial number as before.
tfile = open(“/sys/bus/w1/devices/YOURW1PROBE/w1_slave”)
# Read all of the text in the file.
text = tfile.read()
# Close the file now that the text has been read.
tfile.close()
# Split the text with new lines (\n) and select the second line.
secondline = text.split(“\n”)[1]
# Split the line into words, referring to the spaces, and select the 10th word (counting from 0).
temperaturedata = secondline.split(” “)[9]
# The first two characters are “t=”, so get rid of those and convert the temperature from a string to a number.
temperature = float(temperaturedata[2:])
# Put the decimal point in the right place and display it.
temperature = temperature / 1000
print temperature

account_sid = “ACXXXXXXXXXXXXXXXXX” #Replace this with your account SID
auth_token = “YYYYYYYYYYYYYYYYYY” # Replace this with your auth token
client = TwilioRestClient(account_sid, auth_token)

message = client.messages.create(to=”+12316851234″, from_=”+15555555555″,
body=”Hello there! The temperature is: ” + srt(temperature) + “c”)

This is our complete SMS temperature application!

You should now be able to send yourself a temperature based SMS message by typing in:

sudo python ./send_sms_temp.py

Tada! If all has gone according to plan you should have sent yourself an SMS with the temperature your Raspberry Pi has read from the thermal probe.

How. Cool. Is. That!

Now that you have the basics, the world is your oyster. Imagine being sent a text message when your house is getting too cold. Or a morning message of the temperature outside before you leave the house. Or sending data from an SMS device into a database.. But thats another post..