Raspberry Pi: terminate raspistill command from python - python

I'm trying to use a PHP file on a server to transmit some variables into a Python script which will in turn start a raspistill timelapse on my Raspberry Pi.
I've so far managed to start taking pictures but I'd now like to have a button to kill the timelapse - i've tried many methods including .kill() and .terminate() but cant get it working.
Here is my current python code:
import sys, os, time, datetime
import subprocess
import signal
from time import sleep
tlfreq = int(sys.argv[1])
tltime = int(sys.argv[2])
dir = '/var/www/timelapse/' + sys.argv[3]
if not os.path.exists(dir):
os.makedirs(dir)
cmd = ('raspistill -t ' + str(tltime) + " -tl " + str(tlfreq) + " -o " + dir + "/photo_%04d.jpg")
pro = subprocess.Popen(cmd, stdout=subprocess.PIPE,
shell=True, preexec_fn=os.setsid)
print "Pictures are now being taken every" , tlfreq/1000 , "second/s for a total of", tltime/3600000 , "hours. These are being stored in", dir
Perhaps I need an "if variable = 1 then kill" command and then send the variable to python.
Any help would be greatly appreciated!
Many thanks,
Dan

You can create new python script kill_raspystill.py with this code
import os
os.system("pkill raspistill")
and call that script when you press a button.

I would suggest the signal library: http://docs.python.org/2/library/signal.html

Related

subprocess output data word recognition

may be this question was asked already but i cant find answer what works for me so please need your help . I try write script what automaticly will start another script if service down, in my case apache2 , i write small script but i cant make it work its not recognize output , please your help , here the script :
import os
import subprocess
service = "apache2"
p = subprocess.Popen(["systemctl", "is-active", service], stdout=subprocess.PIPE)
(output, err) = p.communicate()
output = output.decode('utf-8')
print 'APA Serv :',(output)
if output == "inactive":
print '\x1b[31;1m' + ' Attention!' + '\x1b[0m'
os.system('sudo python baz.py')
time.sleep(2)
p.stdout.close()

Python script reading terminal every period of time

I need to create script that do a few things:
Pass a command to the Linux shell, that starts a process.
Read every (for example) 1s the terminal conent, and clear terminal to get only the new lines.
Close the process and the terminal.
I tried to emulate this, by simplifying the task by just writing a command and reading it two times, but it does not seem to work. Do you have any idea how to solve this problem? Is it possible to do this this way or maybe is there more clever way to handle it?
from subprocess import Popen, PIPE, STDOUT
import pty
import os
master, slave = pty.openpty()
p = Popen('ls', shell=True, stdout=slave, stdin=PIPE, stderr=slave, close_fds=True)
stdin_handle = p.stdin
stdou_handle = os.fdopen(master)
stdin_handle.write('cd /')
stdin_handle.write('ls')
print stdout_handle.readline()
stdin_handle.write('clear')
stdin_handle.write('cd /home')
stdin_handle.write('ls')
print stdout_handle.readline()
stdin_handle.write('exit')
I think you should do something like the code shown below:
import os
import time
while True:
start_time = time.time()
# can check if you are in correct working directory: os.getcwd()
os.chdir('/')
os.listdir()
print(f'\33c\e[3J')
os.chdir('/home')
os.listdir()
print(f'\33c\e[3J')
time.sleep(1 - ((time.time() - start_time) % 1))
# exit due to some conditional for example: if datetime.now().hour == 9:
exit()

Using digicamcontrol to control Nikon camera using Python?

Has anyone been successful in doing this on windows? I'm trying to command a DSLR camera to take photos with Python over USB on a Windows machine. Or do you have a better solution (I am unable to switch to Linux).
Here's a working solution, using Python 3.5 (installed via Anaconda), BTW.
The parameters for the ISO and shutter are hardwired, but this should get you going if you ever need it.
import sys
import os
import subprocess
import datetime
def func_TakeNikonPicture(input_filename):
camera_command = 'C:\Program Files (x86)\digiCamControl\CameraControlCmd.exe'
camera_command_details = '/filename ./' + input_filename + ' /capture /iso 500 /shutter 1/30 /aperture 1.8'
print('camera details = ',camera_command_details)
full_command=camera_command + ' ' + camera_command_details
p = subprocess.Popen(full_command, stdout=subprocess.PIPE, universal_newlines=True, shell=False)
(output, err) = p.communicate()
#This makes the wait possible
p_status = p.wait(1)
# print(p.stdout.readline())
#This will give you the output of the command being executed
print('Command output: ' + str(output))
print('Command err: ' + str(err))
print('done')
if(len(sys.argv) < 2):
rawimagename = 'test.jpg'
else:
# sys.argv[0] is the program name, sys.argv[1] is the first file, etc.
# need to shift this over
files = sys.argv[1:len(sys.argv)]
# Read the image
rawimagename = files[0]
if(os.path.isfile(rawimagename) is True):
print("File exists...not overwriting.")
sys.exit()
# Store date/time for file uniqueness
current_dt=datetime.datetime.now().strftime('%Y%m%d_%H%M%S')
print("Current date time = " + current_dt)
rawimagename=current_dt + '_' + rawimagename
print('Name of raw image will be: ', rawimagename)
# take picture
func_TakeNikonPicture(rawimagename)
Digicamcontrol have a remote utility which can control the application almost all aspects, the utility can be run in command prompt or execute using subprocess.call in Python
For more info about utility command line arguments check this link http://digicamcontrol.com/doc/userguide/remoteutil

Python running synchronously? Running one executable at a time

Trying to use python to control numerous compiled executables, but running into timeline issues! I need to be able to run two executables simultaneously, and also be able to 'wait' until an executable has finished prior to starting another one. Also, some of them require superuser. Here is what I have so far:
import os
sudoPassword = "PASS"
executable1 = "EXEC1"
executable2 = "EXEC2"
executable3 = "EXEC3"
filename = "~/Desktop/folder/"
commandA = filename+executable1
commandB = filename+executable2
commandC = filename+executable3
os.system('echo %s | sudo %s; %s' % (sudoPassword, commandA, commandB))
os.system('echo %s | sudo %s' % (sudoPassword, commandC))
print ('DONESIES')
Assuming that os.system() waits for the executable to finish prior to moving to the next line, this should run EXEC1 and EXEC2 simultaneously, and after they finish run EXEC3...
But it doesn't. Actually, it even prints 'DONESIES' in the shell before commandB even finishes...
Please help!
Your script will still execute all 3 commands sequentially. In shell scripts, the semicolon is just a way to put more than one command on one line. It doesn't do anything special, it just runs them one after the other.
If you want to run external programs in parallel from a Python program, use the subprocess module: https://docs.python.org/2/library/subprocess.html
Use subprocess.Popen to run multiple commands in the background. If you just want the program's stdout/err to go to the screen (or get dumped completely) its pretty straight forward. If you want to process the output of the commands... that gets more complicated. You'd likely start a thread per command.
But here is the case that matches your example:
import os
import subprocess as subp
sudoPassword = "PASS"
executable1 = "EXEC1"
executable2 = "EXEC2"
executable3 = "EXEC3"
filename = os.path.expanduser("~/Desktop/folder/")
commandA = os.path.join(filename, executable1)
commandB = os.path.join(filename, executable2)
commandC = os.path.join(filename, executable3)
def sudo_cmd(cmd, password):
p = subp.Popen(['sudo', '-S'] + cmd, stdin=subp.PIPE)
p.stdin.write(password + '\n')
p.stdin.close()
return p
# run A and B in parallel
exec_A = sudo_cmd([commandA], sudoPassword)
exec_B = sudo_cmd([commandB], sudoPassword)
# wait for A before starting C
exec_A.wait()
exec_C = sudo_cmd([commandC], sudoPassword)
# wait for the stragglers
exec_B.wait()
exec_C.wait()
print ('DONESIES')

Script execution stops at os.execlpe()

I am a bit of a newbie on Python, but was was testing some things I learned on Ubuntu.
Basically, this script is supposed to set your TCP/IP config, then restart the networking daemon and display the changes.
This is the whole script:
#!/usr/bin/env python
import commands
import os
import sys
euid = os.geteuid()
if euid != 0:
print "Script not started as root. Running sudo.."
args = ['sudo', sys.executable] + sys.argv + [os.environ]
# the next line replaces the currently-running process with the sudo
os.execlpe('sudo', *args)
print 'Running. Your euid is', euid
print "IP"
IP = raw_input(">>")
print "Gateway"
PE = raw_input(">>")
ifconfig = commands.getoutput("ifconfig")
interfaz = ifconfig[0:5]
ArchivoInterfaces = open("/etc/network/interfaces", "w")
ArchivoInterfaces.write("#auto lo\n#iface lo inet loopback\nauto %s\niface %sinet static\naddress %s\ngateway %s\nnetmask 255.255.255.0"%(interfaz, interfaz, IP, PE))
ArchivoInterfaces.close()
ArchivoResolv = open("/etc/resolv.conf", "w")
ArchivoResolv.write("# Generated by NetworkManager\ndomain localdomain\nsearch localdomain\nnameserver 8.8.8.8\nnameserver 8.8.4.4")
ArchivoResolv.close()
os.execlpe('/etc/init.d/networking', "test","restart", os.environ)
print "Todo esta correcto, su IP ahora es %s" %(IP)
fin = raw_input("write d and press enter to show the changes, or press enter to exit.")
if fin == "d":
ArchivoResolv = open("/etc/resolv.conf")
ArchivoInterfaces = open("/etc/network/interfaces")
ifconfig2 = commands.getoutput("ifconfig")
print "ARCHIVO resolv.conf\n"+ArchivoResolv.read()+"\n\n"+"ARCHIVO interfaces\n"+ArchivoInterfaces.read()+"\n\n"+"RESULTADO DE \"ifconfig\"\n"+ifconfig2
fin = raw_input("Presiona ENTER para salir.")
Unfortunately, it keeps stopping on this line - and I'm not sure why:
os.execlpe('/etc/init.d/networking', "test","restart", os.environ)
After reaching this spot, the script runs the restart, and then just exits.
I would love to get it to run the last part of the script so I can see what changed, but I'm unable. Any ideas?
Because all of the exec family of functions work by replacing the current process with the one you execute.
If you just want to run an external command, use the spawn functions instead. (In this case, os.spawnlpe is very nearly a drop-in replacement.)
os.execlpe (and the similar os.exec* functions) replace the current process:
These functions all execute a new program, replacing the current process; they do not return.

Categories