home
github icon rss icon

Easy Meter Integration with rtlamr + Home Assistant

September 12, 2019

Last year my city began installing Neptune E-Coder smart water meters with R900 meter interface units. I was excited because I had a spare software-defined radio that I could put to use. I was also excited because I’m a nerd.

neptune e-coder water meter

I wasn’t a Home Assistant user at the time. I set up rtlamr, inserted readings into InfluxDB, set up graphs in Grafana, and called it a day.

Well, I recently started using Home Assistant, so I’ve been searching for a way to integrate my meter. I’m going to cover two easy methods of getting rtlamr output into Home Assistant. I’m working with a water meter but these should be adaptable to gas and electric smart meters as well.

Requirements

Install dependencies

You need rtl-sdr, golang, git, and jq. You will find these in your package manager on Linux or Homebrew on macOS.

Find your meter interface unit ID

You need to locate your water meter’s 10-digit MIU ID. Your SDR will also pick up your neighbors meters and you will use your ID to filter them out. My MIU ID is printed on a label affixed to the R900 unit outside.

If you are unable to find your ID take a manual reading, run rtlamr without a filter, and get the ID from a transmission with a matching consumption value.

jq to the rescue

Here is a sample of rtlamr’s JSON output:

{
    "Time": "2019-09-12T10:04:40.940874822-05:00",
    "Offset": 0,
    "Length": 0,
    "Type": "R900",
    "Message": {
        "ID": 1499285123,
        "Unkn1": 163,
        "NoUse": 32,
        "BackFlow": 0,
        "Consumption": 915521,
        "Unkn3": 0,
        "Leak": 0,
        "LeakNow": 0
    }
}

Unfortunately Home Assistant can only extract top level json_attributes from a sensor. If your JSON includes children then you have to create template sensors to access these values.

You can avoid template sensors by piping the JSON through jq to move all of the Message elements to the top level:

jq '. |= del(.Message) + .Message'

Option 1: Command line sensor

If you connected your SDR to your Home Assistant machine, and you are not running Home Assistant with Docker, then you can set up a command line sensor.

Download rtlamr and start rtl_tcp:

GOPATH=${HOME} go get github.com/bemasher/rtlamr
sudo rtl_tcp &

Add the sensor to your Home Assistant configuration, making sure you plug in your MIU ID:

sensor:
  - platform: command_line
    name: neptune
    command: ${HOME}/bin/rtlamr -msgtype=r900 -format=json -single -duration=1m -filterid=YOUR_MIU_ID | jq -c '. |= del(.Message) + .Message'
    command_timeout: 45
    value_template:
      '{{ value_json.Consumption | float / 10 }}'
    unit_of_measurement: 'gal'
    json_attributes:
      - Time
      - BackFlow
      - Consumption
      - Leak
      - LeakNow

Your water meter emits readings periodically, and rtlamr will block until it gets one. Your Home Assistant log is going to fill up with warnings that this sensor is taking longer than 10 seconds.

Option 2: RESTful sensor

If your SDR is not connected to your Home Assistant machine, or you are running Home Assistant with Docker, then you can use stdout_httpd with a RESTful sensor. stdout_httpd is a simple program I wrote to serve the last line of standard output over HTTP.

Start rtl_tcp, rtlamr, and stdout_httpd, making sure you plug in your MIU ID:

sudo rtl_tcp &
GOPATH=$(pwd) go get \
  github.com/bemasher/rtlamr \
  github.com/abaker/stdout_httpd
bin/rtlamr -msgtype=r900 -format=json -filterid=YOUR_MIU_ID |
  jq --unbuffered -c '. |= del(.Message) + .Message' |
  bin/stdout_httpd -port 8080

Add the sensor to your Home Assistant configuration:

sensor:
  - platform: rest
    name: neptune
    resource: http://your-sdr-host:8080
    force_update: true
    value_template:
      '{{ value_json.Consumption | float / 10 }}'
    unit_of_measurement: 'gal'
    json_attributes:
      - Time
      - BackFlow
      - Consumption
      - Leak
      - LeakNow

That’s it!

Restart Home Assistant to check out your new sensor. You can detect leaks and backflow using sensor attributes.

neptune e-coder sensor

If you had any trouble setting this up leave a comment below and I’ll try to help out

Up Next: Read-Only Filesystem After Ubuntu do-release-upgrade

Previous: Open a Tab in ChromeOS from Docker

comments powered by Disqus