From 44a94827d427605f51e026f24aa25154d1971f7d Mon Sep 17 00:00:00 2001 From: Limao Chang <80520563+LimaoC@users.noreply.github.com> Date: Fri, 4 Oct 2024 11:40:46 +1000 Subject: [PATCH] feat: add overlord_lord.py, update camera_overlord.py to be compatible --- client/drivers/camera_overlord.py | 59 ++++++++++++++++++++----------- client/overlord_overlord.py | 47 ++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 21 deletions(-) create mode 100644 client/overlord_overlord.py diff --git a/client/drivers/camera_overlord.py b/client/drivers/camera_overlord.py index 8632046..4ec2d5f 100644 --- a/client/drivers/camera_overlord.py +++ b/client/drivers/camera_overlord.py @@ -1,31 +1,48 @@ -# This script periodically takes photos and saves them to -# a temporary file on ram. This allows multiple programs to -# access the camera feed at once. +""" +This script periodically takes photos and saves them to a temporary file on ram. This +allows multiple programs to access the camera feed at once. -from picamera2 import Picamera2 +Exits gracefully with status INTERRUPTED and closes the camera if a sigint is received. +""" + +import logging import os +import signal import time +from enum import Enum + +from picamera2 import Picamera2 + + +class ExitCode(Enum): + INTERRUPTED = 1 + -if __name__ == '__main__': +logger = logging.getLogger(__name__) + + +def handle_quit(signo, frame): + logger.info("Received SIGINT, quitting") + picam2.close() + quit(ExitCode.INTERRUPTED.value) + + +if __name__ == "__main__": picam2 = Picamera2() - config = picam2.create_still_configuration({'size':(640,480)}) + config = picam2.create_still_configuration({"size": (640, 480)}) picam2.configure(config) picam2.start() - picam2.options['quality'] = 80 + picam2.options["quality"] = 80 + + signal.signal(signal.SIGINT, handle_quit) try: - f = open('/tmp/snapshot.jpg','x') + f = open("/tmp/snapshot.jpg", "x") f.close() - except: - print('Snapshot already exists') - - try: - while True: - picam2.capture_file("/tmp/snapshot2.jpg") - os.replace("/tmp/snapshot2.jpg", "/tmp/snapshot.jpg") - time.sleep(0.5) - - except KeyboardInterrupt: - picam2.close() - print('Closed nicely') - quit() + except FileExistsError: + print("Snapshot already exists") + + while True: + picam2.capture_file("/tmp/snapshot2.jpg") + os.replace("/tmp/snapshot2.jpg", "/tmp/snapshot.jpg") + time.sleep(0.5) diff --git a/client/overlord_overlord.py b/client/overlord_overlord.py new file mode 100644 index 0000000..6dea833 --- /dev/null +++ b/client/overlord_overlord.py @@ -0,0 +1,47 @@ +""" +One overlord to rule them all... +""" + +import logging +import multiprocessing +import os +import signal +import subprocess + +PYTHON_DEFAULT = "python3.10" +PYTHON_CAMERA = "python3.11" + + +def spawn_camera_overlord(): + subprocess.run([PYTHON_CAMERA, "drivers/camera_overlord.py"]) + + +def spawn_pi_overlord(): + subprocess.run([PYTHON_DEFAULT, "drivers/main.py"]) + + +def main(): + logger = logging.getLogger(__name__) + + camera_overlord = multiprocessing.Process(target=spawn_camera_overlord, args=()) + logger.info("Starting camera overlord") + camera_overlord.start() + + pi_overlord = multiprocessing.Process(target=spawn_pi_overlord, args=()) + logger.info("Starting pi overlord") + pi_overlord.start() + + _, pi_overlord_wait_status = os.waitpid(pi_overlord.pid, 0) + pi_overlord_exit_code = os.waitstatus_to_exit_code(pi_overlord_wait_status) + logger.info(f"Reaped pi overlord with exit code {pi_overlord_exit_code}") + + os.kill(camera_overlord.camerad, signal.SIGINT) + _, camera_overlord_wait_status = os.waitcamerad(camera_overlord.camerad, 0) + camera_overlord_exit_code = os.waitstatus_to_exit_code(camera_overlord_wait_status) + logger.info(f"Reaped camera overlord with exit code {camera_overlord_exit_code}") + + logger.info("Exiting") + + +if __name__ == "__main__": + main()