Whether you want to maximize self-consumption of your solar power, receive alerts about power usage, or simply collect statistics on your consumption or production profile, there are many good reasons to make your power meter data available to automation scripts.
Over the past few months, I’ve built
gonrg to make this easy.
gonrg reads OBIS data — such as total consumption or
production in kilowatt-hours, or instantaneous power in watts — from
your digital energy meter. To do this, your meter must provide an
optical D0 interface.
Optical D0 interface
Most modern energy meters are equipped with an optical D0 interface, usually recognizable by two small holes on the front of the meter that house an optical sender and receiver. You can easily purchase an optical D0 head online and attach it to the meter using its built-in magnet.
gonrg works with D0 heads connected to your computer via
USB or UART, but any serial connection should work.
Setting up your (Linux) meter-reading box
You’ll need a computer located close to your energy meter so you can connect the optical D0 head to it — typically via USB. A common and convenient choice is a Raspberry Pi running the Debian-based Raspberry Pi OS.
Once you connect the D0 head, it will usually appear as a serial
device such as /dev/ttyUSB0.
Installing gonrg on Linux
gonrg is available as a prebuilt binary on GitHub. To
download the latest release, run:
curl -L https://github.com/lnobach/gonrg/releases/latest/download/gonrg-linux-arm64-8 -o gonrg && chmod 755 gonrg
This command downloads gonrg-linux-arm64-8, which is
suitable for Raspberry Pi 4 and 5. For Raspberry Pi 1–3, use
gonrg-linux-arm-6 instead. If you’re running on an Intel or
AMD system, download gonrg-linux-amd64.
A Windows build of gonrg is also available on GitHub.
This guide focuses on Linux, but most commands are directly applicable
on Windows as well.
Testing gonrg with your meter
Run ./gonrg --help to see an overview of the available
options.
Before integrating gonrg into your setup, you should
verify that it can successfully read your meter. Check the meter
compatibility page to see whether your meter is supported, which
parameters are recommended, and whether alternative baud rates or other
quirks are required. If your meter is not listed, you’ll need to
experiment with different parameters.
First, determine whether your meter uses plain OBIS or SML. For SML
meters, add the --sml flag:
./gonrg -d /dev/ttyUSB0 --sml
For plain OBIS meters, run:
./gonrg -d /dev/ttyUSB0
If everything is set up correctly, gonrg will read the
meter and display the values in a neatly formatted table. If you don’t
obtain all desired OBIS values, check if you need to enter a PIN into
your meter first, which you can obtain from your grid operator upon
request.
Running gonrg as a server
gonrg can also run as a server, allowing other devices
on your network to access meter readings.
Create a configuration file (for example,
servertest.yaml) with your preferred editor:
listenaddr: 0.0.0.0:8080
meters:
- name: power
device:
device: /dev/ttyUSB0
cron: "0/10 * * * * ?"For more advanced configuration options, refer to the example server configuration on GitHub.
Start the server with:
./gonrg server -C servertest.yaml
Once running, the server will expose your meter readings on the
network. Open http://<my-server>:8080/meter/power in
your browser to view the data.
Example openHAB integration
If you’re using openHAB, you don’t need a specific plugin to use the data from gonrg, instead, you can simply use the HTTP binding. If you use the example below, ensure to adapt it to the OBIS values you actually obtain from your meter.
Example Things configuration for a power meter:
Thing http:url:garagemeter "Garage Meter" [
baseURL="http://your-gonrg-host-ip:8080/meter/power",
refresh=60] {
Channels:
Type number : energy "Energy" [ stateTransformation="JSONPATH:$.list[?(@.simplifiedKey == \"1.8.0\")].valueFloat" ]
Type number : power "Power" [ stateTransformation="JSONPATH:$.list[?(@.simplifiedKey == \"16.7.0\")].valueFloat" ]
Type number : power_l1 "Power L1" [ stateTransformation="JSONPATH:$.list[?(@.simplifiedKey == \"36.7.0\")].valueFloat" ]
Type number : power_l2 "Power L2" [ stateTransformation="JSONPATH:$.list[?(@.simplifiedKey == \"56.7.0\")].valueFloat" ]
Type number : power_l3 "Power L3" [ stateTransformation="JSONPATH:$.list[?(@.simplifiedKey == \"76.7.0\")].valueFloat" ]
}
Correspondig Items configuration:
Number Meter_Grid_Garage "Meter Grid Garage [%d kWh]" <Energy> (Garage) ["Energy", "Measurement"] {
channel="http:url:garagemeter:energy"
}
Number Power_Garage "Power Garage [%d W]" <Power> (Garage) ["Power", "Measurement"] {
channel="http:url:garagemeter:power"
}
Number Power_Garage_L1 "Power Garage L1 [%d W]" <Power> (Garage) ["Power", "Measurement"] {
channel="http:url:garagemeter:power_l1"
}
Number Power_Garage_L2 "Power Garage L2 [%d W]" <Power> (Garage) ["Power", "Measurement"] {
channel="http:url:garagemeter:power_l2"
}
Number Power_Garage_L3 "Power Garage L3 [%d W]" <Power> (Garage) ["Power", "Measurement"] {
channel="http:url:garagemeter:power_l3"
}
