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