24
24
import json
25
25
import paho .mqtt .client as mqtt
26
26
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" )
40
73
41
74
def mqtt_connect (client , userdata , flags , rc ):
42
75
"""Handle MQTT connection callback."""
@@ -50,7 +83,7 @@ def mqtt_disconnect(client, userdata, rc):
50
83
51
84
# Create listener for incoming json string packets.
52
85
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' ] ))
54
87
55
88
56
89
# Map characters that will cause problems or be confusing in mqtt
@@ -70,15 +103,15 @@ def publish_sensor_to_mqtt(mqttc, data, line):
70
103
# Construct a topic from the information that identifies which
71
104
# device this frame is from.
72
105
# NB: id is only used if channel is not present.
73
- path = MQTT_PREFIX
106
+ path = c [ ' MQTT_PREFIX' ]
74
107
if "model" in data :
75
108
path += "/" + sanitize (data ["model" ])
76
109
if "channel" in data :
77
110
path += "/" + str (data ["channel" ])
78
111
if "id" in data :
79
112
path += "/" + str (data ["id" ])
80
113
81
- if MQTT_INDIVIDUAL_TOPICS :
114
+ if c [ ' MQTT_INDIVIDUAL_TOPICS' ] :
82
115
# Publish some specific items on subtopics.
83
116
if "battery_ok" in data :
84
117
mqttc .publish (path + "/battery" , data ["battery_ok" ])
@@ -92,7 +125,7 @@ def publish_sensor_to_mqtt(mqttc, data, line):
92
125
if "depth_cm" in data :
93
126
mqttc .publish (path + "/depth" , data ["depth_cm" ])
94
127
95
- if MQTT_JSON_TOPIC :
128
+ if c [ ' MQTT_JSON_TOPIC' ] :
96
129
# Publish the entire json string on the main topic.
97
130
mqttc .publish (path , line )
98
131
@@ -120,11 +153,11 @@ def rtl_433_probe():
120
153
mqttc = mqtt .Client ()
121
154
mqttc .on_connect = mqtt_connect
122
155
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' ] :
126
159
mqttc .tls_set ()
127
- mqttc .connect_async (MQTT_HOST , MQTT_PORT , 60 )
160
+ mqttc .connect_async (c [ ' MQTT_HOST' ], c [ ' MQTT_PORT' ] , 60 )
128
161
mqttc .loop_start ()
129
162
130
163
## Receive UDP datagrams, extract json, and publish.
0 commit comments