Skip to content

Commit 2f36840

Browse files
authored
Merge pull request #77 from sourcebots/mqtt-publish-state
Publish robot USB status to MQTT
2 parents 2091a3b + 561b42a commit 2f36840

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

@@ -156,6 +158,15 @@ def set_status(self, value: LedStatus) -> None:
156158
GPIO.output(self.LEDs.STATUS_GREEN, GPIO.HIGH if value.value[1] else GPIO.LOW)
157159
GPIO.output(self.LEDs.STATUS_BLUE, GPIO.HIGH if value.value[2] else GPIO.LOW)
158160

161+
# Also send the status over MQTT
162+
if MQTT_CLIENT is not None:
163+
MQTT_CLIENT.publish(
164+
f'{MQTT_TOPIC_ROOT}/state',
165+
json.dumps({"state": value.name}),
166+
qos=1,
167+
retain=True,
168+
)
169+
159170

160171
LED_CONTROLLER = LEDController()
161172

@@ -238,6 +249,7 @@ def __init__(self, mountpoint_path: str) -> None:
238249
self._setup_logging(mountpoint_path)
239250
LED_CONTROLLER.set_code(True)
240251
LED_CONTROLLER.set_status(LedStatus.Running)
252+
241253
env = dict(os.environ)
242254
env["SBOT_METADATA_PATH"] = MOUNTPOINT_DIR
243255
if MQTT_URL is not None:
@@ -270,7 +282,6 @@ def cleanup(self) -> None:
270282
except subprocess.TimeoutExpired:
271283
# The process did not exit after 5 seconds, so kill it.
272284
self._send_signal(signal.SIGKILL)
273-
self._set_leds()
274285

275286
def close(self) -> None:
276287
self.cleanup()
@@ -289,8 +300,10 @@ def _watch_process(self) -> None:
289300
self.process.wait()
290301
if self.process.returncode != 0:
291302
USERCODE_LOGGER.warning(f"Process exited with code {self.process.returncode}")
303+
LED_CONTROLLER.set_status(LedStatus.Crashed)
292304
else:
293305
USERCODE_LOGGER.info("Your code finished successfully.")
306+
LED_CONTROLLER.set_status(LedStatus.Finished)
294307

295308
process_lifetime = time.time() - self.process_start_time
296309

@@ -328,12 +341,6 @@ def _log_output(self, pipe: IO[str]) -> None:
328341
USERCODE_LOGGER.log(USERCODE_LEVEL, line.rstrip('\n'))
329342
LOGGER.info('Process output finished')
330343

331-
def _set_leds(self) -> None:
332-
if self.process.returncode == 0:
333-
LED_CONTROLLER.set_status(LedStatus.Finished)
334-
else:
335-
LED_CONTROLLER.set_status(LedStatus.Crashed)
336-
337344
def _rotate_old_logs(self, log_dir: str) -> None:
338345
"""
339346
Add a suffix to the old log file, if it exists.
@@ -460,7 +467,7 @@ def read_mqtt_config_file() -> MQTTVariables | None:
460467

461468

462469
def setup_usercode_logging() -> None:
463-
global REL_TIME_FILTER
470+
global REL_TIME_FILTER, MQTT_CLIENT, MQTT_TOPIC_ROOT
464471
REL_TIME_FILTER = RelativeTimeFilter()
465472
USERCODE_LOGGER.addFilter(REL_TIME_FILTER)
466473
USERCODE_LOGGER.setLevel(logging.DEBUG)
@@ -481,6 +488,8 @@ def setup_usercode_logging() -> None:
481488
connected_callback=lambda: LED_CONTROLLER.set_wifi(True),
482489
disconnected_callback=lambda: LED_CONTROLLER.set_wifi(False),
483490
)
491+
MQTT_CLIENT = handler.mqtt
492+
MQTT_TOPIC_ROOT = mqtt_config.topic_prefix
484493

485494
handler.setLevel(logging.INFO)
486495
handler.setFormatter(TieredFormatter(
@@ -501,6 +510,8 @@ def main():
501510
registry = AutorunProcessRegistry()
502511

503512
LED_CONTROLLER.mark_start()
513+
LED_CONTROLLER.set_status(LedStatus.NoUSB)
514+
504515
# Initial pass (in case an autorun FS is already mounted)
505516
registry.update_filesystems(fstab_reader.read())
506517

0 commit comments

Comments
 (0)