0

This i what I have so far...

from gpiozero import MotionSensor
import subprocess 
import threading
import time

pir = MotionSensor(4)

while True:
   pir.wait_for_motion()
print("Start Playing Music")
subprocess.call(['mplayer', '-vo', 'null', '-ao', 'alsa', '-playlist', 'myplaylist', '-shuffle'])

The music playing part works great, but as for the timing, I've tried threading and time, but all seem to do is pause the code for a given amount of time. I want to run the subprocess for a given amount of time, then return to wait on motion. I'm still learning. Thanks for your help.

TrcyPrkr
  • 52
  • 5
  • it seems that `mplayer` has option to stop after specific time [playing a specific interval of a video in mplayer using command line option](https://stackoverflow.com/questions/9878138/playing-a-specific-interval-of-a-video-in-mplayer-using-command-line-option) – furas Nov 29 '19 at 02:17
  • You can use `threading` with `subprocess.Popen()` – karolch Nov 29 '19 at 10:12

1 Answers1

0

Python 2.7 - 3.x

Create your subprocess command. I have chosen Popen.

Popen doesn't block, allowing you to interact with the process while it's running, or continue with other things in your Python program. The call to Popen returns a Popen object.

You can read the difference between subprocess.Popen and subprocess.call here

You can use shlex module to split your string command - very comfortable.

After that, you can call your command in the thread. From this moment, you can manage your task called in a thread. There is a simple example, how to do it:

Example of code:

import logging
import shlex
import subprocess
import sys
import threading

logging.basicConfig(filename='log.log',
                    filemode='a',
                    format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
                    datefmt='%H:%M:%S',
                    level=logging.INFO)

log = logging.getLogger(__name__)


def exec_cmd(command):
    try:
        cmd = subprocess.Popen(shlex.split(command),  # nosec
                               shell=False,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               universal_newlines=True)
        _thread_command(cmd)
        out, err = cmd.communicate()
        log.error(err) if err else log.info(out)

    except subprocess.CalledProcessError as su_err:
        log.error('Calledprocerr: %s', su_err)

    except OSError as os_error:
        log.error('Could not execute command: %s', os_error)


def _thread_command(task, timeout=5):
    """
    Thread. If task is longer than <timeout> - kill.
    :param task: task to execute.
    """
    task_thread = threading.Thread(target=task.wait)
    task_thread.start()
    task_thread.join(timeout)
    if task_thread.is_alive():  # do whatever you want with your task, for example, kill:
        task.kill()
        logging.error('Timeout! Executed time is more than: %s', timeout)
        sys.exit(1)


if __name__ == '__main__':
    exec_cmd('sleep 10')  # put your string command here

Tested on Centos:

[kchojnowski@zabbix4-worker1 ~]$ cat log.log
11:31:48,348 root ERROR Timeout! Executed time is more than: 5
karolch
  • 184
  • 4
  • 19