Skip to content

Commit 561b42a

Browse files
committed
Publish robot USB status to MQTT
Follows the status LED Uses enum names for the status
1 parent dc7f2e3 commit 561b42a

File tree

1 file changed

+19
-8
lines changed

1 file changed

+19
-8
lines changed

runusb/__main__.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@
4848
# This will be populated if we have the config file
4949
# url format: mqtt[s]://[<username>[:<password>]@]<host>[:<port>]/<topic_root>
5050
MQTT_URL = None
51+
MQTT_TOPIC_ROOT = ''
52+
MQTT_CLIENT = None
5153
MQTT_CONFIG_FILE = '/etc/sbot/mqtt.conf'
5254

5355

@@ -134,6 +136,15 @@ def set_status(self, value: LedStatus) -> None:
134136
GPIO.output(self.LEDs.STATUS_GREEN, GPIO.HIGH if value.value[1] else GPIO.LOW)
135137
GPIO.output(self.LEDs.STATUS_BLUE, GPIO.HIGH if value.value[2] else GPIO.LOW)
136138

139+
# Also send the status over MQTT
140+
if MQTT_CLIENT is not None:
141+
MQTT_CLIENT.publish(
142+
f'{MQTT_TOPIC_ROOT}/state',
143+
json.dumps({"state": value.name}),
144+
qos=1,
145+
retain=True,
146+
)
147+
137148

138149
LED_CONTROLLER = LEDController()
139150

@@ -216,6 +227,7 @@ def __init__(self, mountpoint_path: str) -> None:
216227
self._setup_logging(mountpoint_path)
217228
LED_CONTROLLER.set_code(True)
218229
LED_CONTROLLER.set_status(LedStatus.Running)
230+
219231
env = dict(os.environ)
220232
env["SBOT_METADATA_PATH"] = MOUNTPOINT_DIR
221233
if MQTT_URL is not None:
@@ -248,7 +260,6 @@ def cleanup(self) -> None:
248260
except subprocess.TimeoutExpired:
249261
# The process did not exit after 5 seconds, so kill it.
250262
self._send_signal(signal.SIGKILL)
251-
self._set_leds()
252263

253264
def close(self) -> None:
254265
self.cleanup()
@@ -267,8 +278,10 @@ def _watch_process(self) -> None:
267278
self.process.wait()
268279
if self.process.returncode != 0:
269280
USERCODE_LOGGER.warning(f"Process exited with code {self.process.returncode}")
281+
LED_CONTROLLER.set_status(LedStatus.Crashed)
270282
else:
271283
USERCODE_LOGGER.info("Your code finished successfully.")
284+
LED_CONTROLLER.set_status(LedStatus.Finished)
272285

273286
process_lifetime = time.time() - self.process_start_time
274287

@@ -306,12 +319,6 @@ def _log_output(self, pipe: IO[str]) -> None:
306319
USERCODE_LOGGER.log(USERCODE_LEVEL, line.rstrip('\n'))
307320
LOGGER.info('Process output finished')
308321

309-
def _set_leds(self) -> None:
310-
if self.process.returncode == 0:
311-
LED_CONTROLLER.set_status(LedStatus.Finished)
312-
else:
313-
LED_CONTROLLER.set_status(LedStatus.Crashed)
314-
315322
def _rotate_old_logs(self, log_dir: str) -> None:
316323
"""
317324
Add a suffix to the old log file, if it exists.
@@ -438,7 +445,7 @@ def read_mqtt_config_file() -> MQTTVariables | None:
438445

439446

440447
def setup_usercode_logging() -> None:
441-
global REL_TIME_FILTER
448+
global REL_TIME_FILTER, MQTT_CLIENT, MQTT_TOPIC_ROOT
442449
REL_TIME_FILTER = RelativeTimeFilter()
443450
USERCODE_LOGGER.addFilter(REL_TIME_FILTER)
444451
USERCODE_LOGGER.setLevel(logging.DEBUG)
@@ -459,6 +466,8 @@ def setup_usercode_logging() -> None:
459466
connected_callback=lambda: LED_CONTROLLER.set_wifi(True),
460467
disconnected_callback=lambda: LED_CONTROLLER.set_wifi(False),
461468
)
469+
MQTT_CLIENT = handler.mqtt
470+
MQTT_TOPIC_ROOT = mqtt_config.topic_prefix
462471

463472
handler.setLevel(logging.INFO)
464473
handler.setFormatter(TieredFormatter(
@@ -479,6 +488,8 @@ def main():
479488
registry = AutorunProcessRegistry()
480489

481490
LED_CONTROLLER.mark_start()
491+
LED_CONTROLLER.set_status(LedStatus.NoUSB)
492+
482493
# Initial pass (in case an autorun FS is already mounted)
483494
registry.update_filesystems(fstab_reader.read())
484495

0 commit comments

Comments
 (0)