For Christmas this year I received a few nerdy toys; One of them being a digital power meter
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).
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.
!* ⚠️ 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!
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!.