@@ -152,6 +152,8 @@ def on_connect(
152
152
retain = True ,
153
153
)
154
154
self .subscribe (self .configuration ["subscribe_topic" ])
155
+ if self .configuration ["enable_multi_gtw_sync" ]:
156
+ self .subscribe (self .configuration ["trackersync_topic" ])
155
157
else :
156
158
logger .error (
157
159
"Failed to connect to MQTT broker %s:%d reason code: %s" ,
@@ -227,28 +229,52 @@ def subscribe(self, sub_topic: str) -> None:
227
229
"""Subscribe to MQTT topic <sub_topic>."""
228
230
229
231
def on_message (client , userdata , msg ) -> None : # noqa: ANN001,ARG001
230
- logger .info (
231
- "Received `%s` from `%s` topic" ,
232
- msg .payload .decode (),
233
- msg .topic ,
234
- )
235
- try :
236
- msg_json = json .loads (msg .payload .decode ())
237
- except (json .JSONDecodeError , UnicodeDecodeError ) as exception :
238
- logger .warning (
239
- "Invalid JSON message %s: %s" , msg .payload .decode (), exception
240
- )
241
- return
232
+ # Evaluate trackersync messages
233
+ if (
234
+ msg .topic == self .configuration ["trackersync_topic" ]
235
+ and self .configuration ["enable_multi_gtw_sync" ]
236
+ ):
237
+ msg_json = json .loads (msg .payload )
238
+ logger .debug ("trackersync message: %s" , msg_json )
242
239
243
- try :
244
- msg_json ["id" ] = self .rpa2id (msg_json ["id" ])
245
- except KeyError :
246
- logger .warning (
247
- "JSON message %s doesn't contain id" , msg .payload .decode ()
240
+ if (
241
+ msg_json ["gatewayid" ] != self .configuration ["gateway_id" ]
242
+ and msg_json ["trackerid" ] in self .discovered_trackers
243
+ and self .discovered_trackers [msg_json ["trackerid" ]].time != 0
244
+ ):
245
+ self .discovered_trackers [msg_json ["trackerid" ]].time = 0
246
+ logger .debug (
247
+ "Tracker %s disassociated by gateway %s" ,
248
+ msg_json ["trackerid" ],
249
+ msg_json ["gatewayid" ],
250
+ )
251
+
252
+ logger .debug (
253
+ "[DIS] Discovered Trackers: %s" , self .discovered_trackers
254
+ )
255
+ else :
256
+ logger .info (
257
+ "Received `%s` from `%s` topic" ,
258
+ msg .payload .decode (),
259
+ msg .topic ,
248
260
)
249
- return
261
+ try :
262
+ msg_json = json .loads (msg .payload .decode ())
263
+ except (json .JSONDecodeError , UnicodeDecodeError ) as exception :
264
+ logger .warning (
265
+ "Invalid JSON message %s: %s" , msg .payload .decode (), exception
266
+ )
267
+ return
268
+
269
+ try :
270
+ msg_json ["id" ] = self .rpa2id (msg_json ["id" ])
271
+ except KeyError :
272
+ logger .warning (
273
+ "JSON message %s doesn't contain id" , msg .payload .decode ()
274
+ )
275
+ return
250
276
251
- self .decode_advertisement (msg_json )
277
+ self .decode_advertisement (msg_json )
252
278
253
279
self .client .subscribe (sub_topic )
254
280
self .client .on_message = on_message
@@ -370,14 +396,11 @@ def check_tracker_timeout(self) -> None:
370
396
if (
371
397
round (time ()) - time_model .time >= self .configuration ["tracker_timeout" ]
372
398
and time_model .time != 0
373
- and (
374
- self .configuration ["discovery" ]
375
- or self .configuration ["general_presence" ]
376
- )
377
399
):
378
400
if (
379
401
time_model .model_id in ("APPLEWATCH" , "APPLEDEVICE" )
380
402
and not self .configuration ["discovery" ]
403
+ and self .configuration ["general_presence" ]
381
404
):
382
405
message = json .dumps (
383
406
{"id" : address , "presence" : "absent" , "unlocked" : False }
@@ -391,9 +414,12 @@ def check_tracker_timeout(self) -> None:
391
414
+ "/"
392
415
+ address .replace (":" , "" ),
393
416
)
417
+
394
418
time_model .time = 0
395
419
self .discovered_trackers [address ] = time_model
396
- logger .debug ("Discovered Trackers: %s" , self .discovered_trackers )
420
+
421
+ logger .info ("Tracker %s timed out" , address )
422
+ logger .debug ("[TO] Discovered Trackers: %s" , self .discovered_trackers )
397
423
398
424
async def ble_scan_loop (self ) -> None :
399
425
"""Scan for BLE devices."""
@@ -440,6 +466,10 @@ async def ble_scan_loop(self) -> None:
440
466
"Sent %s messages to MQTT" ,
441
467
self .published_messages ,
442
468
)
469
+
470
+ # Check tracker timeouts
471
+ self .check_tracker_timeout ()
472
+
443
473
await asyncio .sleep (
444
474
self .configuration ["ble_time_between_scans" ],
445
475
)
@@ -611,11 +641,26 @@ def publish_json(
611
641
+ "/"
612
642
+ get_address (data_json ).replace (":" , "" ),
613
643
)
644
+
645
+ # Update tracker last received time
614
646
self .discovered_trackers [str (data_json ["id" ])] = TnM (
615
647
round (time ()),
616
648
str (data_json ["model_id" ]),
617
649
)
618
- logger .debug ("Discovered Trackers: %s" , self .discovered_trackers )
650
+ # Publish trackersync message
651
+ if self .configuration ["enable_multi_gtw_sync" ]:
652
+ message = json .dumps (
653
+ {
654
+ "gatewayid" : self .configuration ["gateway_id" ],
655
+ "trackerid" : data_json ["id" ],
656
+ }
657
+ )
658
+ self .publish (
659
+ message ,
660
+ self .configuration ["trackersync_topic" ],
661
+ )
662
+
663
+ logger .debug ("[GP] Discovered Trackers: %s" , self .discovered_trackers )
619
664
620
665
# Remove "track" if PUBLISH_ADVDATA is 0
621
666
if not self .configuration ["publish_advdata" ] and "track" in data_json :
0 commit comments