From b5bcdeda0ce2c0b488a1976b34f3ba9ce30d58f3 Mon Sep 17 00:00:00 2001 From: Allan GooD Date: Tue, 11 Jan 2022 23:23:33 -0600 Subject: [PATCH] Changes for version 1.5.4 --- README.md | 132 ++++++++++++++++++++++------------ rtlamr2mqtt-addon/config.json | 14 ++-- rtlamr2mqtt.py | 19 ++--- rtlamr2mqtt.yaml | 1 + 4 files changed, 109 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 5175a81..ffcaf32 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,20 @@ + ### RTLAMR2MQTT [![Build Status](https://app.travis-ci.com/allangood/rtlamr2mqtt.svg?branch=main)](https://app.travis-ci.com/allangood/rtlamr2mqtt) [![Docker Pulls](https://img.shields.io/docker/pulls/allangood/rtlamr2mqtt)](https://hub.docker.com/r/allangood/rtlamr2mqtt) -This project was created to send readings made by RTLAMR to a MQTT broker. +This project was created to send readings made by RTLAMR + RTL_TCP to a MQTT broker. My user case is to integrate it with Home Assistant. ### Noteworthy Updates +*2022-01-11* + - Happy new year! :) + - Added "tickle_rtl_tcp" parameter to enable/disable the feature (explained below) + - Added date/time to the log output + - Added device_class configuration option #66 (thanks to @phidauex) + - Some clean up in the README file! + - Machine Learning to detect leaks still experimental and needs a lot of love to work properly + *2021-12-01* - Lots of changes!!!! - Using Debian bullseye instead of Alpine. Here is why: https://pythonspeed.com/articles/alpine-docker-python/ @@ -14,55 +23,41 @@ My user case is to integrate it with Home Assistant. - A new attribute "Anomaly" is available for every meter. It will return "true" if an anomaly is detected. - ***IMPORTANT*** A new volume is necessary if you want to keep your history! See the compose/docker run command for more info. +# Readme starts here -### How to run the container in LISTEN ALL METERS Mode: -If you don't know your Meter ID or the protocol to listen, you can run the container in DEBUG mode to listen for everything. +### What do I need? + **1) You need a smart meter** +First and most important, you must have a "smart" water/gas/energy meter. You can find a list of compatible meters [here](https://github.com/bemasher/rtlamr/blob/master/meters.csv) -In this mode, rtlamr2mqtt will ***not read the configuration file***, this means that nothing is going to happen other than print all meter readings on screen! -``` -docker run --rm -ti -e LISTEN_ONLY=yes -e RTL_MSGTYPE="all" --device=/dev/bus/usb:/dev/bus/usb allangood/rtlamr2mqtt -``` + **2) You need an USB RT-SDR device** +I am using this one: [NooElec NESDR Mini USB](https://www.amazon.ca/NooElec-NESDR-Mini-Compatible-Packages/dp/B009U7WZCA/ref=sr_1_1_sspa?crid=JGS4RV7RXGQQ&keywords=rtl-sdr) -### Home Assistant Utility: - -![image](https://user-images.githubusercontent.com/757086/117556120-207bd200-b02b-11eb-9149-58eaf9c6c4ea.png) +**3) You need a MQTT broker** (Like Mosquitto) +**4) Home assistant is optional, but highly recommended, because it is awesome!** -### Home Assistant configuration: -``` -utility_meter: - hourly_water: - source: sensor. - cycle: hourly - daily_water: - source: sensor. - cycle: daily - monthly_water: - source: sensor. - cycle: monthly -``` -If you have `ha_autodiscovery: false` in your configuration, you will need to manually add the sensors to your HA configuration. - -This is a sample for a water meter using the configuration from the next section: -``` -sensor: - - platform: mqtt - name: "My Utility Meter" - state_topic: rtlamr/meter_water/state - unit_of_measurement: "\u33A5" -``` -You must change `meter_water` with the name you have configured in the configuration YAML file (below) +### How it looks like? +![image](https://user-images.githubusercontent.com/757086/117556120-207bd200-b02b-11eb-9149-58eaf9c6c4ea.png) +### How to run and configure? +Docker and Docker-compose are the most indicated way. +If you are not running the add-on, you must write the **rtlamr2mqtt.yaml** configuration file. -### Configuration sample: +Create the config file on `/opt/rtlamr2mqtt/rtlamr2mqtt.yaml` for instance. +The configuration must looks like this: ``` +# -- Configuration file starts here -- # (Optional section) general: - # Sleep for this amount of seconds after one successful of every meter + # Sleep for this amount of seconds after one successful reading of every meter + # This parameter is helpful to keep CPU usage low and the temperature low as well # Set this to 0 (default) to disable it sleep_for: 300 # Set the verbosity level. It can be debug or info verbosity: debug + # Enable/disable the tickle_rtl_tcp. This is used to "shake" rtl_tcp to wake it up. + # For me, this started to cause the rtl_tcp to refuse connections and miss the readings. + tickle_rtl_tcp: false # (Required section) # MQTT configuration @@ -72,7 +67,7 @@ mqtt: # MQTT user name if you have, remove if you don't use authentication user: mqtt # MQTT user password if you use one, remove if you don't use authentication - password: my very strong password + password: my-very-strong-password # Whether to use Home Assistant auto-discovery feature or not ha_autodiscovery: true # Home Assistant auto-discovery topic @@ -86,6 +81,7 @@ custom_parameters: # Documentation for rtl_tcp: https://osmocom.org/projects/rtl-sdr/wiki/Rtl-sdr rtltcp: "-s 2048000" # Documentation for rtlamr: https://github.com/bemasher/rtlamr/wiki/Configuration + # If you want to disable the local rtl_tcp and use an external/remote one, you must add "-server=remote-ip-address:port" to the rtlamr section below. rtlamr: "-unique=true -symbollength=32" # (Required section) @@ -97,13 +93,15 @@ meters: protocol: scm+ # A nice name to show on your Home Assistant/Node Red name: meter_water - # A number format to be used for your meter + # (optional) A number format to be used for your meter format: "#####.###" - # A measurement unit to be used by Home Assistant + # (optional) A measurement unit to be used by Home Assistant # Typical values are ft³ and m³ (use the superscript) for water/gas meters # and kWh or Wh for electric meters unit_of_measurement: "\u33A5" - # An icon to be used by Home Assistant + # (optional) The device_class if you want to specify one + device_class: none + # (optional) An icon to be used by Home Assistant icon: mdi:gauge # A device_class to define what the sensor is measuring for use in the Energy panel # Typical values are "gas" or "energy". Default is blank. @@ -113,9 +111,20 @@ meters: name: meter_hydro unit_of_measurement: kWh device_class: energy +# -- End of configuration file -- ``` - -### Docker compose configuration: +#### Run with docker +If you want to run with docker alone, run this command: +``` +docker run --name rtlamr2mqtt \ + -v /opt/rtlamr2mqtt/rtlamr2mqtt.yaml:/etc/rtlamr2mqtt.yaml \ + -v /opt/rtlamr2mqtt/data:/var/lib/rtlamr2mqtt \ + -d /dev/bus/usb:/dev/bus/usb \ + --restart unless-stopped \ + allangood/rtlamr2mqtt +``` +#### Run with docker-compose +If you use docker-compose (recommended), add this to your compose file: ``` version: "3" services: @@ -126,8 +135,43 @@ services: devices: - /dev/bus/usb volumes: - - /etc/rtlamr2mqtt.yaml:/etc/rtlamr2mqtt.yaml:ro - - /var/lib/rtlamr2mqtt:/var/lib/rtlamr2mqtt + - /opt/rtlamr2mqtt/rtlamr2mqtt.yaml:/etc/rtlamr2mqtt.yaml:ro + - /opt/rtlamr2mqtt/data:/var/lib/rtlamr2mqtt +``` + +### Home Assistant configuration: +To add your meters to Home Assistant, add a section like this: +``` +utility_meter: + hourly_water: + source: sensor. + cycle: hourly + daily_water: + source: sensor. + cycle: daily + monthly_water: + source: sensor. + cycle: monthly +``` +If you have `ha_autodiscovery: false` in your configuration, you will need to manually add the sensors to your HA configuration. + +This is a sample for a water meter using the configuration from the sample configuration file: +``` +sensor: + - platform: mqtt + name: "My Utility Meter" + state_topic: rtlamr/meter_water/state + unit_of_measurement: "\u33A5" +``` +You must change `meter_water` with the name you have configured in the configuration YAML file (below) + +### I don't know my meters ID, what can I do? +**How to run the container in LISTEN ALL METERS Mode:** +If you don't know your Meter ID or the protocol to listen, you can run the container in DEBUG mode to listen for everything. + +In this mode, rtlamr2mqtt will ***not read the configuration file***, this means that nothing is going to happen other than print all meter readings on screen! +``` +docker run --rm -ti -e LISTEN_ONLY=yes -e RTL_MSGTYPE="all" --device=/dev/bus/usb:/dev/bus/usb allangood/rtlamr2mqtt ``` ### Thanks to diff --git a/rtlamr2mqtt-addon/config.json b/rtlamr2mqtt-addon/config.json index d59b2c4..9be4b32 100644 --- a/rtlamr2mqtt-addon/config.json +++ b/rtlamr2mqtt-addon/config.json @@ -1,6 +1,6 @@ { "name": "rtlamr2mqtt", - "version": "1.5.2", + "version": "1.5.4", "slug": "rtlamr2mqtt", "panel_icon": "mdi:gauge", "description": "RTLAMR to MQTT Bridge", @@ -23,7 +23,8 @@ "options": { "general": { "sleep_for": 300, - "verbosity": "debug" + "verbosity": "debug", + "tickle_rtl_tcp": false }, "mqtt": { "host": "hassio.local", @@ -44,14 +45,16 @@ "name": "gas_meter", "format": "####.###", "unit_of_measurement": "m³", - "icon": "mdi:gas_canister" + "icon": "mdi:gas_canister", + "device_class": "gas" } ] }, "schema": { "general": { "sleep_for": "int", - "verbosity": "list(debug|normal)?" + "verbosity": "list(debug|normal)?", + "tickle_rtl_tcp": "bool?" }, "mqtt": { "host": "str?", @@ -72,7 +75,8 @@ "name": "str", "format": "str?", "unit_of_measurement": "str", - "icon": "str" + "icon": "str", + "device_class": "list(none|aqi|battery|carbon_dioxide|carbon_monoxide|current|date|energy|frequency|gas|humidity|illuminance|monetary|nitrogen_dioxide|nitrogen_monoxide|nitrous_oxide|ozone|pm1|pm10|pm25|power_factor|power|pressure|signal_strength|sulphur_dioxide|temperature|timestamp|volatile_organic_compounds|voltag)?" } ] } diff --git a/rtlamr2mqtt.py b/rtlamr2mqtt.py index 9645737..9720c68 100755 --- a/rtlamr2mqtt.py +++ b/rtlamr2mqtt.py @@ -10,6 +10,7 @@ import socket from struct import pack from random import randrange +from datetime import datetime from time import sleep, time from json import dumps, loads from paho.mqtt import MQTTException @@ -19,13 +20,14 @@ import warnings from sklearn.linear_model import LinearRegression - # I have been experiencing some problems with my Radio (geeting old, maybe?) # and the number of messages fills up my HDD very quickly. # Function to log messages to STDERR def log_message(message): - print(message, file=sys.stderr) + now = datetime.now() + dt_string = now.strftime("%Y-%m-%d %H:%M:%S") + print('[{}] {}'.format(dt_string, message), file=sys.stderr) # Environment variable to help with Travis tests # Set it to True if is set to 'yes' or 'true', false otherwise @@ -257,12 +259,12 @@ def sliding_mean(series): ##################### BUILD CONFIGURATION ##################### config = load_config(sys.argv) +# Set some defaults: +sleep_for = int(config['general'].get('sleep_for', 0)) verbosity = str(config['general'].get('verbosity', 'info')).lower() -if 'general' in config: - if test_mode: - sleep_for = 0 - else: - sleep_for = int(config['general'].get('sleep_for', 0)) +use_tickle_rtl_tcp = (config['general'].get('tickle_rtl_tcp', False)) +if test_mode: + sleep_for = 0 # Build MQTT configuration availability_topic = 'rtlamr/status' @@ -350,7 +352,8 @@ def sliding_mean(series): # Is this the first time are we executing this loop? Or is rtlamr running? if 'rtlamr' not in locals() or rtlamr.poll() is not None: - tickle_rtl_tcp(rtltcp_server) + if use_tickle_rtl_tcp: + tickle_rtl_tcp(rtltcp_server) log_message('Trying to start RTLAMR: {}'.format(' '.join(rtlamr_cmd))) # start the rtlamr program. rtlamr = subprocess.Popen(rtlamr_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True, universal_newlines=True) diff --git a/rtlamr2mqtt.yaml b/rtlamr2mqtt.yaml index 63faf8f..dd3f191 100644 --- a/rtlamr2mqtt.yaml +++ b/rtlamr2mqtt.yaml @@ -1,6 +1,7 @@ general: sleep_for: 0 verbosity: debug + tickle_rtl_tcp: false mqtt: host: 127.0.0.1