11import json
22import logging
3+ from re import I
34import meshtastic
45import meshtastic .serial_interface
56import meshtastic .tcp_interface
2021logger .setLevel (logging .DEBUG )
2122
2223
24+ class CustomTCPInterface (meshtastic .tcp_interface .TCPInterface ):
25+ def __init__ (self , hostname , device_name ):
26+ self .device_name = device_name
27+ self .hostname = hostname
28+ super (CustomTCPInterface , self ).__init__ (hostname )
29+
30+
2331def onReceive (packet , interface ): # called when a packet arrives
32+ nodeInfo = interface .getMyNodeInfo ()
2433
2534 for pipeline , pipeline_plugins in bridge_config ["pipelines" ].items ():
2635 logger .debug (f"Pipeline { pipeline } initiated" )
@@ -29,6 +38,9 @@ def onReceive(packet, interface): # called when a packet arrives
2938 pipeline_packet = p .do_action (packet )
3039
3140 for plugin in pipeline_plugins :
41+ if not pipeline_packet :
42+ continue
43+
3244 for plugin_key , plugin_config in plugin .items ():
3345
3446 logger .debug (f"Processing plugin: { pipeline } /{ plugin_key } " )
@@ -57,8 +69,17 @@ def onConnection(
5769 )
5870
5971
72+ def onLost (interface ):
73+ logger .debug (f"Connecting to { interface .hostname } ..." )
74+ devices [interface .device_name ] = CustomTCPInterface (
75+ hostname = interface .hostname , device_name = interface .device_name
76+ )
77+ logger .debug (f"Connected to { interface .hostname } " )
78+
79+
6080pub .subscribe (onReceive , "meshtastic.receive" )
6181pub .subscribe (onConnection , "meshtastic.connection.established" )
82+ pub .subscribe (onLost , "meshtastic.connection.lost" )
6283
6384with open ("config.yaml" ) as f :
6485 bridge_config = yaml .load (f , Loader = SafeLoader )
@@ -75,99 +96,109 @@ def onConnection(
7596 devPath = device ["serial" ]
7697 )
7798 elif "tcp" in device :
78- devices [device ["name" ]] = meshtastic .tcp_interface .TCPInterface (
79- hostname = device ["tcp" ]
99+ logger .debug (f"Connecting to { device ['tcp' ]} ..." )
100+ devices [device ["name" ]] = CustomTCPInterface (
101+ hostname = device ["tcp" ], device_name = device ["name" ]
80102 )
103+ logger .debug (f"Connected to { device ['tcp' ]} " )
81104 else :
82105 devices [device ["name" ]] = meshtastic .serial_interface .SerialInterface ()
83106
84- for config in bridge_config ["mqtt_servers" ]:
85- required_options = [
86- "name" ,
87- "server" ,
88- "port" ,
89- ]
107+ if "mqtt_servers" in bridge_config :
108+ for config in bridge_config ["mqtt_servers" ]:
109+ required_options = [
110+ "name" ,
111+ "server" ,
112+ "port" ,
113+ ]
90114
91- for option in required_options :
92- if option not in config :
93- logger .warning ("Missing config: {option}" )
115+ for option in required_options :
116+ if option not in config :
117+ logger .warning ("Missing config: {option}" )
94118
95- client_id = config ["client_id" ] if "client_id" in config else None
96- username = config ["username" ] if "username" in config else None
97- password = config ["password" ] if "password" in config else None
119+ client_id = config ["client_id" ] if "client_id" in config else None
120+ username = config ["username" ] if "username" in config else None
121+ password = config ["password" ] if "password" in config else None
98122
99- if client_id :
100- mqttc = mqtt .Client (client_id )
101- else :
102- mqttc = mqtt .Client ()
123+ if client_id :
124+ mqttc = mqtt .Client (client_id )
125+ else :
126+ mqttc = mqtt .Client ()
103127
104- if username and password :
105- mqttc .username_pw_set (username , password )
128+ if username and password :
129+ mqttc .username_pw_set (username , password )
106130
107- mqtt_servers [config ["name" ]] = mqttc
131+ mqtt_servers [config ["name" ]] = mqttc
108132
109- def on_connect (mqttc , obj , flags , rc ):
110- logger .debug (f"Connected to MQTT { config ['name' ]} " )
133+ def on_connect (mqttc , obj , flags , rc ):
134+ logger .debug (f"Connected to MQTT { config ['name' ]} " )
111135
112- def on_message (mqttc , obj , msg ):
113- packet = msg .payload .decode ()
136+ def on_message (mqttc , obj , msg ):
137+ orig_packet = msg .payload .decode ()
114138
115- logger .debug (f"MQTT { config ['name' ]} : on_message" )
139+ logger .debug (f"MQTT { config ['name' ]} : on_message" )
116140
117- if "pipelines" not in config :
118- logger .warning (f"MQTT { config ['name' ]} : no pipeline" )
119- return
141+ if "pipelines" not in config :
142+ logger .warning (f"MQTT { config ['name' ]} : no pipeline" )
143+ return
120144
121- for pipeline , pipeline_plugins in config ["pipelines" ].items ():
145+ for pipeline , pipeline_plugins in config ["pipelines" ].items ():
122146
123- logger .debug (f"MQTT { config ['name' ]} pipeline { pipeline } started" )
124- if not packet :
125- continue
147+ packet = orig_packet
126148
127- for plugin in pipeline_plugins :
128- for plugin_key , plugin_config in plugin .items ():
129- if plugin_key not in plugins :
130- logger .error (f"No such plugin: { plugin_key } . Skipping" )
149+ logger .debug (f"MQTT { config ['name' ]} pipeline { pipeline } started" )
150+ if not packet :
151+ continue
152+
153+ for plugin in pipeline_plugins :
154+ if not packet :
131155 continue
132156
133- p = plugins [plugin_key ]
134- p .configure (devices , mqtt_servers , plugin_config )
157+ for plugin_key , plugin_config in plugin .items ():
158+ if plugin_key not in plugins :
159+ logger .error (f"No such plugin: { plugin_key } . Skipping" )
160+ continue
161+
162+ p = plugins [plugin_key ]
163+ p .configure (devices , mqtt_servers , plugin_config )
135164
136- try :
137- packet = p .do_action (packet )
138- except Exception as e :
139- logger .error (f"Hit an error: { e } " , exc_info = True )
140- logger .debug (f"MQTT { config ['name' ]} pipeline { pipeline } finished" )
165+ try :
166+ packet = p .do_action (packet )
167+ except Exception as e :
168+ logger .error (f"Hit an error: { e } " , exc_info = True )
169+ logger .debug (f"MQTT { config ['name' ]} pipeline { pipeline } finished" )
141170
142- def on_publish (mqttc , obj , mid ):
143- logger .debug (f"MQTT { config ['name' ]} : on_publish: { mid } " )
171+ def on_publish (mqttc , obj , mid ):
172+ logger .debug (f"MQTT { config ['name' ]} : on_publish: { mid } " )
144173
145- def on_subscribe (mqttc , obj , mid , granted_qos ):
146- logger .debug (f"MQTT { config ['name' ]} : on_subscribe: { mid } " )
174+ def on_subscribe (mqttc , obj , mid , granted_qos ):
175+ logger .debug (f"MQTT { config ['name' ]} : on_subscribe: { mid } " )
147176
148- mqttc .on_message = on_message
149- mqttc .on_connect = on_connect
150- mqttc .on_publish = on_publish
151- mqttc .on_subscribe = on_subscribe
177+ mqttc .on_message = on_message
178+ mqttc .on_connect = on_connect
179+ mqttc .on_publish = on_publish
180+ mqttc .on_subscribe = on_subscribe
152181
153- import ssl
182+ import ssl
154183
155- if "insecure" in config and config ["insecure" ]:
156- mqttc .tls_set (cert_reqs = ssl .CERT_NONE )
157- mqttc .tls_insecure_set (True )
184+ if "insecure" in config and config ["insecure" ]:
185+ mqttc .tls_set (cert_reqs = ssl .CERT_NONE )
186+ mqttc .tls_insecure_set (True )
158187
159- mqttc .connect (config ["server" ], config ["port" ], 60 )
188+ mqttc .connect (config ["server" ], config ["port" ], 60 )
160189
161- if "topic" in config :
162- mqttc .subscribe (config ["topic" ], 0 )
190+ if "topic" in config :
191+ mqttc .subscribe (config ["topic" ], 0 )
163192
164- mqttc .loop_start ()
193+ mqttc .loop_start ()
165194
166195while True :
167196 time .sleep (1000 )
168197
169- for device , instance in devices .items ():
170- instance .close ()
198+ if devices :
199+ for device , instance in devices .items ():
200+ instance .close ()
171201
172- for server , instance in mqtt_servers .items ():
173- instance .disconnect ()
202+ if mqtt_servers :
203+ for server , instance in mqtt_servers .items ():
204+ instance .disconnect ()
0 commit comments