Skip to content

Commit

Permalink
Merge pull request #69 from allangood/dev
Browse files Browse the repository at this point in the history
Changes for version 1.5.4
  • Loading branch information
allangood authored Jan 12, 2022
2 parents bf463e6 + b5bcded commit d3a3cda
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 57 deletions.
132 changes: 88 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
@@ -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/
Expand All @@ -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.<meter_name>
cycle: hourly
daily_water:
source: sensor.<meter_name>
cycle: daily
monthly_water:
source: sensor.<meter_name>
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
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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.
Expand All @@ -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:
Expand All @@ -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.<meter_name>
cycle: hourly
daily_water:
source: sensor.<meter_name>
cycle: daily
monthly_water:
source: sensor.<meter_name>
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
Expand Down
14 changes: 9 additions & 5 deletions rtlamr2mqtt-addon/config.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -23,7 +23,8 @@
"options": {
"general": {
"sleep_for": 300,
"verbosity": "debug"
"verbosity": "debug",
"tickle_rtl_tcp": false
},
"mqtt": {
"host": "hassio.local",
Expand All @@ -44,14 +45,16 @@
"name": "gas_meter",
"format": "####.###",
"unit_of_measurement": "",
"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?",
Expand All @@ -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)?"
}
]
}
Expand Down
19 changes: 11 additions & 8 deletions rtlamr2mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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'
Expand Down Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions rtlamr2mqtt.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
general:
sleep_for: 0
verbosity: debug
tickle_rtl_tcp: false

mqtt:
host: 127.0.0.1
Expand Down

0 comments on commit d3a3cda

Please sign in to comment.