diff --git a/README.md b/README.md index b4efdce..6cfdcec 100644 --- a/README.md +++ b/README.md @@ -170,22 +170,6 @@ cd PVM && git pull sudo reboot ``` -## Logs - -All logs for each time each RPI is stored in the log folder. - -Name convention for each file is `{:%Y-%m-%d %H:%M:%S}.log` - -All output from the console is synchronized to the file in real-time. - -```bash -2022-10-31 13:34:21;INFO;Received command: file -2022-10-31 13:34:21;INFO;Received value: jellyfish720p.mp4 -2022-10-31 13:34:21;INFO;File set: /home/pi/Videos/jellyfish720p.mp4 -``` - -If you close the program and then reopen it, a new log file will be created. - ## Examples Navigate to the `examples` folder and open the `examples.maxproj` file. @@ -218,5 +202,26 @@ The (proof of concept) resync system, on the top right portion of the patch, inc Also don't forget to checkout our [wiki](https://github.com/omarcostahamido/PVM/wiki)! It contains instructions on various topics like [_setting up remote access to the Raspberry Pi_](https://github.com/omarcostahamido/PVM/wiki/How-to-connect-to-a-Raspberry-Pi-remotely) and how to run the examples. +## Development + +### Logs + +All logs for each time each RPI is stored in the `log` folder in the current directory. If it doesn't exist yet, a new directory named `log` would be created. + +Name convention for each file is `{:%Y-%m-%d %H:%M:%S}.log` + +All output from the console is synchronized to the file in real-time. + +```bash +2022-10-31 13:34:21;INFO;Received command: file +2022-10-31 13:34:21;INFO;Received value: jellyfish720p.mp4 +2022-10-31 13:34:21;INFO;File set: /home/pi/Videos/jellyfish720p.mp4 +``` + +If you close the program and then reopen it, a new log file will be created. + +## Run the test + +You could write tests for your combination of commands in the `test.py` file. Simply run `python3 test.py` from the console will run it. When the test script is started, it will first **kill any existing `pvm.py` processes**, and then spawn a new one to test the commands, and end it again after test is finished. ## Known limitations diff --git a/pvm.py b/pvm.py index 545e1ab..ed25c3f 100644 --- a/pvm.py +++ b/pvm.py @@ -11,7 +11,11 @@ def _init_logger(): logger = logging.getLogger("PVM") logger.setLevel(logging.INFO) handler = logging.StreamHandler(sys.stderr) - fileHandler = TimedRotatingFileHandler('./log/{:%Y-%m-%d %H:%M:%S}.log'.format(datetime.now()), when='midnight') + # Check if the `log` directory exists, create one if not. + log_path = "./log/{:%Y-%m-%d %H:%M:%S}.log" + if not os.path.exists(log_path): + os.makedirs(log_path) + fileHandler = TimedRotatingFileHandler(log_path.format(datetime.now()), when='midnight') handler.setLevel(logging.INFO) formatter = logging.Formatter("%(asctime)s;%(levelname)s;%(message)s", "%Y-%m-%d %H:%M:%S") @@ -42,48 +46,51 @@ def parse_commands(*args): _logger.info("Received command: %s", str(value)) pass # TODO: Create another python file to control two display - if command=="file": - _logger.info("File set: %s", PEFIX_PATH + value) - IS_FILE_SET = True - media = OMXPlayer(PEFIX_PATH + value, dbus_name='org.mpris.MediaPlayer2.omxplayer', args=['--loop']) - media.pause() - VIDEO_PATH = value - return + try: + if command=="file": + _logger.info("File set: %s", PEFIX_PATH + value) + IS_FILE_SET = True + media = OMXPlayer(PEFIX_PATH + value, dbus_name='org.mpris.MediaPlayer2.omxplayer', args=['--loop']) + media.pause() + VIDEO_PATH = value + return - if not IS_FILE_SET: - _logger.info("Command %s failed because of the file is unset.", command) - return + if not IS_FILE_SET: + _logger.info("Command %s failed because of the file is unset.", command) + return - if command=="start": - if media.can_play(): - media.play() + if command=="start": + if media.can_play(): + media.play() + _logger.info("%s command success.", command) + else: + _logger.info("%s command failed.", command) + elif command=="stop": + if media.can_quit(): + media.stop() + IS_FILE_SET = False + _logger.info("%s command success and file has been unset.", command) + else: + _logger.info("%s command failed.", command) + elif command=="set_position": + media.set_position(float(value)) _logger.info("%s command success.", command) - else: - _logger.info("%s command failed.", command) - elif command=="stop": - if media.can_quit(): - media.stop() - IS_FILE_SET = False - _logger.info("%s command success and file has been unset.", command) - else: - _logger.info("%s command failed.", command) - elif command=="set_position": - media.set_position(float(value)) - _logger.info("%s command success.", command) - elif command=="set_rate": - fps = str(30 * float(value)) - media = OMXPlayer(PEFIX_PATH + VIDEO_PATH, dbus_name='org.mpris.MediaPlayer2.omxplayer', args=['--loop','--force-fps', fps]) - media.pause() - _logger.info("%s command success.", command) - elif command=="pause": - if media.can_pause(): + elif command=="set_rate": + fps = str(30 * float(value)) + media = OMXPlayer(PEFIX_PATH + VIDEO_PATH, dbus_name='org.mpris.MediaPlayer2.omxplayer', args=['--loop','--force-fps', fps]) media.pause() _logger.info("%s command success.", command) + elif command=="pause": + if media.can_pause(): + media.pause() + _logger.info("%s command success.", command) + else: + _logger.info("%s command failed.", command) else: - _logger.info("%s command failed.", command) - else: - _logger.info("%s unknown.", command) - + _logger.info("%s unknown.", command) + except Exception as e: + # `logger#exception method prints the stack trace` + _logger.exception("Function: parse_commands failed! %s" % (e)) def main(RECEIVE_PORT): #OSC server diff --git a/test.py b/test.py new file mode 100644 index 0000000..34a7c97 --- /dev/null +++ b/test.py @@ -0,0 +1,43 @@ +import os +from subprocess import CalledProcessError, check_output +import subprocess +import time +from pythonosc.udp_client import SimpleUDPClient + +def killPvm(): + try: + ret = check_output(["pgrep", "-f", "python pvm.py"]) + pid = int(ret.decode("utf-8").strip()) + os.kill(pid, 9) + print("killed", pid) + except CalledProcessError as ce: + print("No pvm.py running") +def sendCommand(): + port = 8001 + ip = "0.0.0.0" + client = SimpleUDPClient(ip, port) # Create client + + client.send_message("/PVM", ["file", "jellyfish720.mp4"]) + time.sleep(1) + client.send_message("/PVM", "start") + time.sleep(1) + client.send_message("/PVM", "stop") + time.sleep(1) + client.send_message("/PVM", "stop") + +def test(): + killPvm() + cmd = ["python", "pvm.py"] + popen = subprocess.Popen(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True) + time.sleep(2) + sendCommand() + killPvm() + out, err = popen.communicate() + # ret = err.readlines() + print("***err", err) + print("***out", out) + if "error" in err.lower() or "exception" in err.lower(): + print("Exceptions or errors detected, test failed.") + else: + print("Test finished successfully.") +test() \ No newline at end of file