Get your smart electric, water and gas meter scm readings into home assistant with a RTL-SDR

For the life of me, I can’t figure out what I am doing wrong. I have a Pi3B+ running HAOS and a Pi0W running amridm2mqtt. I’m able to see my water meter fine (R900) when running rtl_tcp and rtlamr in two different terminals, but the data isn’t be passed to my MQTT Broker running in HA. I’m using MQTT Explorer to monitor the broker and its not showing anything. My MQTT Broker is setup and running fine.

I read through most of this thread and used some of the bug fixes and modifications @biochemguy and @adamg posted. I have hit a wall and would appreciate any help.

Below are the “amridm2mqtt.service”, “amrscm2mqtt.py” and “settings.py” files.

amridm2mqtt.service

[Unit]
Description=AMR IDM to MQTT
After=network.target

[Service]
ExecStart=/usr/bin/python3 /opt/amridm2mqtt/amrscm2mqtt.py
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=amridm2mqtt

[Install]
WantedBy=multi-user.target

amrscm2mqtt.py

#!/usr/bin/env python3
'''
Runs rtlamr to watch for IDM broadcasts from power meter. If meter id
is in the list, usage is sent to 'readings/{meter id}/meter_reading'
topic on the MQTT broker specified in settings.

WATCHED_METERS = A Python list indicating those meter IDs to record and post.
MQTT_HOST = String containing the MQTT server address.
MQTT_PORT = An int containing the port the MQTT server is active on.

'''
import subprocess
import signal
import sys
import time
import paho.mqtt.publish as publish
import settings

# uses signal to shutdown and hard kill opened processes and self
def shutdown(signum, frame):
    subprocess.call('/usr/bin/pkill -9 rtlamr', shell=True)
    subprocess.call('/usr/bin/pkill -9 rtl_tcp', shell=True)
    subprocess.call('/usr/bin/pkill -9 amridm2mqtt', shell=True)
    sys.exit(0)

signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)

auth = None

if len(settings.MQTT_USER) and len(settings.MQTT_PASSWORD):
        auth = {'username':settings.MQTT_USER, 'password':settings.MQTT_PASSWORD}

def send_mqtt(topic, payload,):
    try:
        publish.single(topic, payload=payload, qos=1, hostname=settings.MQTT_HOST, port=settings.MQTT_PORT, auth=auth)
    except Exception as ex:
        print("MQTT Publish Failed: " + str(ex))

time.sleep(30)

# start the rtl_tcp program
rtltcp = subprocess.Popen([settings.RTL_TCP + " > /dev/null 2>&1 &"], shell=True,
    stdin=None, stdout=None, stderr=None, close_fds=True)

time.sleep(5)

# start the rtlamr program.
rtlamr = subprocess.Popen([settings.RTLAMR,
    '-msgtype=r900',
    '-format=csv'], stdout=subprocess.PIPE)
#changes msgtype from "scm" to "r900"
while True:

    try:
        # rtlamr's readline returns byte list, remove whitespace and convert to string
        amrline = rtlamr.stdout.readline().strip().decode()
        # split string on commas
        flds = amrline.split(',')

        if len(flds) != 9:

            # proper SCM results have 9 fields. If SCM+ have more fields, you can adjust this number.
            # proper R900 results have 9 fields.
            continue

        # make sure the meter id is one we want - Change this if the meter ID is in another field.
        #R900 meter ID is in field 2
        meter_id = int(flds[2])
        if len(settings.WATCHED_METERS) and meter_id not in settings.WATCHED_METERS:
            continue

        # get some required info: current meter reading, current interval id, most recent interval - SCM+ Change this if there is more fields in the data
        #R900 consumption data is in field 6
        read_waterusage = int(flds[6])
        #R900 doesn't display decimle, converting to show tenth
        #changed "current_reading_in_kwh" to "current_reading_in_wholenumber"
        #changed multiplier to .1 to show tenth
        current_reading_in_wholenumber = (read_waterusage * settings.WH_MULTIPLIER) / .1

        #changed "current_reading_in_kwh" to "current_reading_in_wholenumber" to match above
        send_mqtt(
            'readings/' + str(meter_id) + '/meter_reading',
            '%s' % (current_reading_in_wholenumber)
        )

    except:
        time.sleep(2)

settings.py

# List of the Meter IDs to watch
# Use empty brackets to read all meters - []
# List may contain only one entry - [12345678]
# or multiple entries - [12345678, 98765432, 12340123]
WATCHED_METERS = [1564077862]

# multiplier to get reading to Watt Hours (Wh)
# examples:
#   for meter providing readings in kWh
#      MULTIPLIER = 1000
#   for meter providing readings in kWh
#   with 2 extra digits of precision
#      MULTIPLIER = 10
# MULTIPLIER needs to be a number
WH_MULTIPLIER = .1

# number of IDM intervals per hour reported by the meter
# examples:
#   for meter providing readings every 5 minutes
#   or 12 times every hour
#     READINGS_PER_HOUR = 12
#   for meter providing readings every 15 minutes
#   or 12 times every hour
#     READINGS_PER_HOUR = 4
READINGS_PER_HOUR = 12

# MQTT Server settings
# MQTT_HOST needs to be a string
# MQTT_PORT needs to be an int
# MQTT_USER needs to be a string
# MQTT_PASSWORD needs to be a string
# If no authentication, leave MQTT_USER and MQTT_PASSWORD empty
MQTT_HOST = '#######'
MQTT_PORT = 1883
MQTT_USER = '#######'
MQTT_PASSWORD = '#######'

# path to rtlamr
RTLAMR = '/usr/local/bin/rtlamr'

# path to rtl_tcp
RTL_TCP = '/usr/bin/rtl_tcp'

Home Assistant Config

mqtt:
  sensor:
    - name: "Water Meter"
      unique_id: "1564077862"
      state_topic: "readings/1564077862/meter_reading"
      unit_of_measurement: G

I have since migrated to the rtlamr2mqtt Add On. It works the same, but is much easier to use

Are you talking about the “AMR2MQTT” addon or is there a different add-on? My Pi3B+ doesn’t seem to be able to handle HAOS and that addon. It keeps crashing due to low memory.

Therefore, I was running this on my extra Pi0W.

EDIT: I found the add-on you were talking about. Got it setup and everything is working perfectly!

Thanks

I’m not sure if this is a HW issue or a software issue - but having 0 luck with the googles, so thought i’d start here to see if anyone as thoughts i’d greatly appreciate some input.

Seems like it is randomly crashing dying with the following error:

Sep 27 02:40:37 raspberrypi4 amridm2mqtt[2664]: 02:40:37.674301 main.go:124: GainCount: 29
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]: 05:23:18.741129 main.go:343: Receiver context cancelled.
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]: 05:23:18.741690 main.go:320: read tcp 127.0.0.1:42734->127.0.0.1:1234: i/o timeout
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]: io.ReadFull
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]: main.(*Receiver).Run.func2
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]:         /srv/go/pkg/mod/github.com/bemasher/[email protected]/main.go:181
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]: runtime.goexit
Sep 27 05:23:18 raspberrypi4 amridm2mqtt[2664]:         /usr/lib/go-1.18/src/runtime/asm_arm64.s:1259
lsusb -s 001:006
Bus 001 Device 006: ID 0bda:2838 Realtek Semiconductor Corp. RTL2838 DVB-T
root@raspberrypi4:/srv/HA/amridm2mqtt# git pull
Already up to date.

root@raspberrypi4:/srv/HA/amridm2mqtt# dpkg -l | egrep -i sdr
ii  librtlsdr0:arm64                0.6.0-4                                 arm64        Software defined radio receiver for Realtek RTL2832U (library)
ii  rtl-sdr                         0.6.0-4                                 arm64        Software defined radio receiver for Realtek RTL2832U (tools)

root@raspberrypi4:/srv/HA/amridm2mqtt# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.1 LTS
Release:	22.04
Codename:	jammy

Syslog is a little interesting

Sep 27 05:23:13 raspberrypi4 kernel: [ 9870.476308] usb 1-1.1: USB disconnect, device number 3
Sep 27 05:23:14 raspberrypi4 kernel: [ 9870.699267] usb 1-1.1: new high-speed USB device number 6 using xhci_hcd
Sep 27 05:23:14 raspberrypi4 kernel: [ 9870.811112] usb 1-1.1: New USB device found, idVendor=0bda, idProduct=2838, bcdDevice= 1.00
Sep 27 05:23:14 raspberrypi4 kernel: [ 9870.811138] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
Sep 27 05:23:14 raspberrypi4 kernel: [ 9870.811147] usb 1-1.1: Product: RTL2838UHIDIR
Sep 27 05:23:14 raspberrypi4 kernel: [ 9870.811154] usb 1-1.1: Manufacturer: Realtek
Sep 27 05:23:14 raspberrypi4 kernel: [ 9870.811160] usb 1-1.1: SerialNumber: 00000001

If anyone has any thoughts

I’m experiencing the same issue. I did a lot of digging online and found the same issue documented here. It is more than likely a dead or dying unit and should be replaced. Luckily mine was still within the return window on Amazon so I have filed a return and am waiting for the new unit.

I also went ahead and bought a different antenna dongle from here. I’ve read that their dongles have a better life expectancy.

The final thing you could try is to run the usb dongle via a powered usb hub as discussed here. I tried it with the exact model he used but I still experienced the same issue.

I have tried this on a RPi3, RPi4, and a Proxmox HA VM. I’ll try to post an update once my new antennas come in :slight_smile:

I’ve been trying to get the rtl_tcp and rtlamr packages running on my RPi 3B+ (with a NooElec NESDR Mini), but it never finds anything for the smart reader (CS20D). It just sits there scanning. I was also getting a lot of “ll+ ###” outputs and read it was a power thing maybe, but the RPi is getting plenty of juice. I tried plugging the NooElec into my UnRAID server where I run HA, and installed the amr2mqtt add-on, and it too also shows in the log lots of “ll+ ###” entries. Can’t be a power thing on that machine. It’s currently scanning for msgtype=all hoping I’d be finding the signal and could narrow it down later but nothing is found.

If I plug the NooElec into a laptop and use something like CubicSDR, I can find signals at the 927MHz range (the meter is 902-927) which appear about every 30secs. If I run rtl_tcp on its own and connect to it, the same range does not show anything happening. Bizarre.

I may have to give up and do something else with the NooElec, and pay for the box the electricity company offers (a Powerley device), assuming I can get what I need out of that into HA … maybe the connection to the meter is locked down.

@biochemguy quick question. I have successfully scanned and found several ERT readings around my house. I assumed one of them will be my gas reader. Unfortunately non of them matches my actual meter dial status. Would you know if the “consumption_data” are somehow encrypted?

{
  "time": "2023-02-12 14:45:10",
  "model": "ERT-SCM",
  "id": 12661550,
  "physical_tamper": 1,
  "ert_type": 12,
  "encoder_tamper": 0,
  "consumption_data": 368495,
  "mic": "CRC"
}

So has anybody gotten a nicor meter in the suburbs of chicago working yet? long thread and just wanted to check if i missed it.

1 Like

I have been looking and looking. I believe that the nicor meters only broadcast as a response from a nicor signal

1 Like

I had a project with Sensus water meters a few years ago. Because of the 20 year warranty, the sealed battery unit in their radio only broadcasts reads once every 4 hours. The data packet is technically 4 one hour reads, but is sent once every 4 hours.

I have an iTron OpenWay (AMI7) meter. I am in Pittsburgh, PA and have Duquesne Light Company for my power. I see some people getting RTLAMR readings from OpenWay meters, but all of my reading says it is not possible. Can you provide any details about how you are doing it?

Can you explain some more on on how you were able to connect?

I was using the Sensus’ cloud monitoring software during the project buildout since I was part of the engineering team on the project. Sensus registers a licensed FCC frequency for each system, technically I think they have a small bank of registered frequencies that they draw from to help insure minimal overlap for that locale. It is kind of difficult sorting through the FCC inventory to find the frequency for your particular system, but it should show the owner as Sensus since it is subscription based. Hope that helps.

I too am with Nicor, in the Chicago suburbs, and have a Sensus Flexnet 100GM-B. Checking in to see if there’s been any progress.

[SOLVED]: I was close. Protocol needed to be SCM, not SCM+. Receiving messages now.

Looking for help with initial setup for rtlamr2mqtt for my gas meter.

  • add-on is installed and configured
  • gas meter ID added to config (Itron 100G DLS)
  • logs show nooelec USB detected and up
  • mosquito mqtt is installed

I am unsure of next steps, but I’ve not seen any other MQTT device detected, and if I go to the MQTT config and set listening mode to “debug”, nothing happens.

I have my power readings coming through the Xcel2MQTT add-on without issue.

general:
  sleep_for: 300
  verbosity: debug
  listen_only: false
  tickle_rtl_tcp: false
  device_id: single
mqtt:
  ha_autodiscovery: true
  ha_autodiscovery_topic: homeassistant
  base_topic: rtlamr
  tls_enabled: false
custom_parameters:
  rtltcp: "-s 2048000"
  rtlamr: "-unique=true"
meters:
  - id: 51344808
    protocol: scm+
    name: gas_meter
    format: "####.###"
    unit_of_measurement: m³
    icon: mdi:gas_canister
    device_class: gas

image

@simps Are you a Nicor customer?

@tempeduck No, this is for Xcel. I have my electric meter connected via local wifi, gas connected via RTL-SDR. Water was upgraded to a cellular-based system, so unless I can scrape consumption from their website, that one looks like I won’t be able to get it integrated

x-posting here to maybe raise visibility… trying to solve an issue with AMR2MQTT:

https://community.home-assistant.io/t/home-assistant-add-on-amr2mqtt/378196/59

Everything was working until earlier today. Now it’s not able to read data. This is due to my configuration not being right, but as a HASS noob I’m having trouble finding how to solve the issue.

Does anyone have any tips/suggestions?

OK I think I solved it. I watched this video: https://www.youtube.com/watch?v=8uB-vFmEuD0 and ended up creating an mqtt.yaml and included that in configuration.yaml. This is what my mqtt.yaml looks like for those that may see this later:

sensor:
  - name: "XCel Gas Meter Reading"
    state_topic: "rtlamr/$IDHERE"
    unit_of_measurement: "CCF"
    force_update: true
    value_template: "{{ value_json.Consumption }}"
    unique_id: "amr2mqtt_$IDHERE_consumption"
    device_class: "gas"
    state_class: "total"
1 Like

I have just set up my water meter and I’m curious about the internal leak flags.
R900:{ID:14819****** Unkn1:0xA1 NoUse: 0 BackFlow:0 Consumption: 1419**** Unkn3:0x00 Leak:15 LeakNow:3}}

I have also seen others that have the Leak:15 and LeakNow:3 values. What do these mean?