Skip to content

Commit 638dff1

Browse files
committed
examples: Add ability for mqtt_relay to use a config file
This commit adds the ability to read config values from rtl_433_mqtt_relay.yaml (overriding defaults). This read is skipped if the yaml module can't be loaded or the config file can't be read, so those without PyYAML or a config file see no change. Those with a config file can set parameters for address/port to listen for json-in-sylog, MQTT credentials, whether to post individual values, a json dictionary, or both. While rudimentary, this is a huge functional improvement, allowing those using TLS and broker passwords (as arguably all should be) to use the script without modifying it.
1 parent ea7e732 commit 638dff1

File tree

1 file changed

+54
-21
lines changed

1 file changed

+54
-21
lines changed

examples/rtl_433_mqtt_relay.py

+54-21
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,52 @@
2424
import json
2525
import paho.mqtt.client as mqtt
2626

27-
# Syslog socket configuration
28-
UDP_IP = "127.0.0.1"
29-
UDP_PORT = 1433
30-
31-
# MQTT broker configuration
32-
MQTT_HOST = "127.0.0.1"
33-
MQTT_PORT = 1883
34-
MQTT_USERNAME = None
35-
MQTT_PASSWORD = None
36-
MQTT_TLS = False
37-
MQTT_PREFIX = "sensor/rtl_433"
38-
MQTT_INDIVIDUAL_TOPICS = True
39-
MQTT_JSON_TOPIC = True
27+
# The config class represents a config object. The constructor takes
28+
# an optional pathname, and will switch on the suffix (.yaml for now)
29+
# and read a dictionary.
30+
class rtlconfig(object):
31+
32+
# Initialize with default values.
33+
c = {
34+
# Syslog socket configuration
35+
'UDP_IP': "127.0.0.1",
36+
'UDP_PORT': 1433,
37+
38+
# MQTT broker configuration
39+
'MQTT_HOST': "127.0.0.1",
40+
'MQTT_PORT': 1883,
41+
'MQTT_USERNAME': None,
42+
'MQTT_PASSWORD': None,
43+
'MQTT_TLS': False,
44+
'MQTT_PREFIX': "sensor/rtl_433",
45+
'MQTT_INDIVIDUAL_TOPICS': True,
46+
'MQTT_JSON_TOPIC': True,
47+
}
48+
49+
def __init__(self, f=None):
50+
fdict = None
51+
52+
# Try to read a dictionary from f.
53+
if f:
54+
try:
55+
# Assume yaml. \todo Check and support other formats
56+
import yaml
57+
with open(f) as fh:
58+
fdict = yaml.safe_load(fh)
59+
except:
60+
print('Did not read {f} (no yaml, not found, bad?).'.format(f=f))
61+
62+
# Merge fdict into configdict.
63+
if fdict:
64+
for (k, v) in fdict.items():
65+
self.c[k] = v
66+
67+
# Support c['name'] references.
68+
def __getitem__(self, k):
69+
return self.c[k]
70+
71+
# Create a config object, defaults modified by the config file if present.
72+
c = rtlconfig("rtl_433_mqtt_relay.yaml")
4073

4174
def mqtt_connect(client, userdata, flags, rc):
4275
"""Handle MQTT connection callback."""
@@ -50,7 +83,7 @@ def mqtt_disconnect(client, userdata, rc):
5083

5184
# Create listener for incoming json string packets.
5285
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
53-
sock.bind((UDP_IP, UDP_PORT))
86+
sock.bind((c['UDP_IP'], c['UDP_PORT']))
5487

5588

5689
# Map characters that will cause problems or be confusing in mqtt
@@ -70,15 +103,15 @@ def publish_sensor_to_mqtt(mqttc, data, line):
70103
# Construct a topic from the information that identifies which
71104
# device this frame is from.
72105
# NB: id is only used if channel is not present.
73-
path = MQTT_PREFIX
106+
path = c['MQTT_PREFIX']
74107
if "model" in data:
75108
path += "/" + sanitize(data["model"])
76109
if "channel" in data:
77110
path += "/" + str(data["channel"])
78111
if "id" in data:
79112
path += "/" + str(data["id"])
80113

81-
if MQTT_INDIVIDUAL_TOPICS:
114+
if c['MQTT_INDIVIDUAL_TOPICS']:
82115
# Publish some specific items on subtopics.
83116
if "battery_ok" in data:
84117
mqttc.publish(path + "/battery", data["battery_ok"])
@@ -92,7 +125,7 @@ def publish_sensor_to_mqtt(mqttc, data, line):
92125
if "depth_cm" in data:
93126
mqttc.publish(path + "/depth", data["depth_cm"])
94127

95-
if MQTT_JSON_TOPIC:
128+
if c['MQTT_JSON_TOPIC']:
96129
# Publish the entire json string on the main topic.
97130
mqttc.publish(path, line)
98131

@@ -120,11 +153,11 @@ def rtl_433_probe():
120153
mqttc = mqtt.Client()
121154
mqttc.on_connect = mqtt_connect
122155
mqttc.on_disconnect = mqtt_disconnect
123-
if MQTT_USERNAME != None:
124-
mqttc.username_pw_set(MQTT_USERNAME, password=MQTT_PASSWORD)
125-
if MQTT_TLS:
156+
if c['MQTT_USERNAME'] != None:
157+
mqttc.username_pw_set(c['MQTT_USERNAME'], password=c['MQTT_PASSWORD'])
158+
if c['MQTT_TLS']:
126159
mqttc.tls_set()
127-
mqttc.connect_async(MQTT_HOST, MQTT_PORT, 60)
160+
mqttc.connect_async(c['MQTT_HOST'], c['MQTT_PORT'], 60)
128161
mqttc.loop_start()
129162

130163
## Receive UDP datagrams, extract json, and publish.

0 commit comments

Comments
 (0)