48
48
# This will be populated if we have the config file
49
49
# url format: mqtt[s]://[<username>[:<password>]@]<host>[:<port>]/<topic_root>
50
50
MQTT_URL = None
51
+ MQTT_TOPIC_ROOT = ''
52
+ MQTT_CLIENT = None
51
53
MQTT_CONFIG_FILE = '/etc/sbot/mqtt.conf'
52
54
53
55
@@ -216,6 +218,9 @@ def __init__(self, mountpoint_path: str) -> None:
216
218
self ._setup_logging (mountpoint_path )
217
219
LED_CONTROLLER .set_code (True )
218
220
LED_CONTROLLER .set_status (LedStatus .Running )
221
+ if MQTT_CLIENT is not None :
222
+ MQTT_CLIENT .publish (f'{ MQTT_TOPIC_ROOT } /state' , '{"state": "running"}' , qos = 1 , retain = True )
223
+
219
224
env = dict (os .environ )
220
225
env ["SBOT_METADATA_PATH" ] = MOUNTPOINT_DIR
221
226
if MQTT_URL is not None :
@@ -256,6 +261,9 @@ def close(self) -> None:
256
261
LED_CONTROLLER .set_code (False )
257
262
USERCODE_LOGGER .removeHandler (self .handler )
258
263
264
+ if MQTT_CLIENT is not None :
265
+ MQTT_CLIENT .publish (f'{ MQTT_TOPIC_ROOT } /state' , '{"state": "no USB"}' , qos = 1 , retain = True )
266
+
259
267
def _send_signal (self , sig : int ) -> None :
260
268
if self .process .poll () is not None :
261
269
# Process has already exited, so the kill() call would fail.
@@ -267,8 +275,13 @@ def _watch_process(self) -> None:
267
275
self .process .wait ()
268
276
if self .process .returncode != 0 :
269
277
USERCODE_LOGGER .warning (f"Process exited with code { self .process .returncode } " )
278
+ new_state = 'crashed'
270
279
else :
271
280
USERCODE_LOGGER .info ("Your code finished successfully." )
281
+ new_state = 'finished'
282
+
283
+ if MQTT_CLIENT is not None :
284
+ MQTT_CLIENT .publish (f'{ MQTT_TOPIC_ROOT } /state' , json .dumps ({"state" : new_state }), qos = 1 , retain = True )
272
285
273
286
process_lifetime = time .time () - self .process_start_time
274
287
@@ -438,7 +451,7 @@ def read_mqtt_config_file() -> MQTTVariables | None:
438
451
439
452
440
453
def setup_usercode_logging () -> None :
441
- global REL_TIME_FILTER
454
+ global REL_TIME_FILTER , MQTT_CLIENT , MQTT_TOPIC_ROOT
442
455
REL_TIME_FILTER = RelativeTimeFilter ()
443
456
USERCODE_LOGGER .addFilter (REL_TIME_FILTER )
444
457
USERCODE_LOGGER .setLevel (logging .DEBUG )
@@ -459,6 +472,8 @@ def setup_usercode_logging() -> None:
459
472
connected_callback = lambda : LED_CONTROLLER .set_wifi (True ),
460
473
disconnected_callback = lambda : LED_CONTROLLER .set_wifi (False ),
461
474
)
475
+ MQTT_CLIENT = handler .mqtt
476
+ MQTT_TOPIC_ROOT = mqtt_config .topic_prefix
462
477
463
478
handler .setLevel (logging .INFO )
464
479
handler .setFormatter (TieredFormatter (
@@ -479,6 +494,10 @@ def main():
479
494
registry = AutorunProcessRegistry ()
480
495
481
496
LED_CONTROLLER .mark_start ()
497
+
498
+ if MQTT_CLIENT is not None :
499
+ MQTT_CLIENT .publish (f'{ MQTT_TOPIC_ROOT } /state' , '{"state": "no USB"}' , qos = 1 , retain = True )
500
+
482
501
# Initial pass (in case an autorun FS is already mounted)
483
502
registry .update_filesystems (fstab_reader .read ())
484
503
0 commit comments