I have two python scripts, flickSwitch.py & measureTemp.py, the first calls the second when a button is pressed. All works fine when run directly from /home/pi.
I put the first script into crontab -e
:
@reboot sudo python3 /home/pi/flickSwitch.py &
I can see it launches on reboot by a LED on a tower light flashing red.
But pressing the button now doesn't seem to launch the second script "measureTemp.py".
Any ideas?
Below are the two scripts: flickSwitch.py
#!/usr/bin/python3
import automationhat
import time
import subprocess, os
import signal
#import measureTemp
def towerlight_cleanup():
automationhat.output.one.off()
automationhat.output.two.off()
automationhat.output.three.off()
automationhat.relay.one.off()
automationhat.output.one.on()
time.sleep(2)
automationhat.output.one.off()
try:
run = 0
while True:
if automationhat.input[0].read() == 1 and run == 0:
print('switch flicked on')
print('starting measureTemp.py script')
run_script = 'python3 /home/pi/measureTemp.py'
p=subprocess.Popen(run_script, shell=True, preexec_fn=os.setsid)
run=1
while automationhat.input[0].read() == 1:
time.sleep(0.01)
if automationhat.input[0].read() == 0 and run == 1:
print('switch flicked off')
print('killing script...')
run = 0
towerlight_cleanup()
os.killpg(p.pid, signal.SIGTERM)
while automationhat.input[0].read() == 0:
time.sleep(0.01)
except KeyboardInterrupt:
towerlight_cleanup()
print('keyboard interrupt')
measureTemp.py
#!/usr/bin/python3
# programme to measure temp of raspberryPi and turn on appropriate LED on tower light.
import os
from time import sleep
import paho.mqtt.client as mqtt
import paho.mqtt.publish as publish
from gpiozero import OutputDevice
import automationhat
# DEFINE VARIABLES #
# Light Tower output pins (BCM pin numbering )
redPin = automationhat.output.one
greenPin = automationhat.output.two
yellowPin = automationhat.output.three
buzPin = automationhat.relay
def measure_temp():
temp = os.popen("vcgencmd measure_temp").readline() # reads output of command
temp, celsius = temp.replace("temp=","").split("'") # takes the output and slipts it at ' and returns a list of two
return (temp)
def POT():
print('commencing POT...')
leds = [redPin, yellowPin, greenPin]
for x in range(3):
for led in leds:
led.on()
sleep(0.1)
led.off()
print('POT complete...')
def blink_tower_led(led):
led.on()
sleep(2)
led.off()
def main():
# test all leds in tower light are working:
POT()
sleep(2)
print('tower lights all tested...proceeding to main programme...')
while True:
temp = float(measure_temp())
if temp >= 46:
print("it's getting hot in here...{}C".format(temp))
blink_tower_led(redPin)
elif temp >= 35 <= 45:
print("it's getting rather warm...{}C".format(temp))
blink_tower_led(yellowPin)
else:
print("it's nice and cool {}C if you don't mind".format(temp))
blink_tower_led(greenPin)
sleep(5)
if __name__ == '__main__':
main()
1 Answer 1
Nice puzzle... You should work toward discovering some more information to narrow this down:
You've stated, "All works fine when run directly from /home/pi". From that statement, it would seem that something is different when
cron
starts your job instead of you (your user id). And indeed it is. Among other things, theenvironment
is different. Once you've read this tutorial, you will begin to wonder... ifcron
'sPATH
variable is different than thePATH
set for me as my user id, perhaps the reason things don't work is that the system doesn't know where the programs I'm calling are located. For example, doescron
'senvironment
tell the system where the programssudo
andpython3
are located?Knowing how to discover what
cron
'senvironment
is will help you answer this first question. Here's one way to discovercron
'senvironment
variables, and therefore itsPATH
.If you discover a program you're telling
cron
to start is not incron
'sPATH
, you could correct that easily by adding the full file specification to the line in yourcrontab
.Why have you put the
&
at the end of yourflickSwitch.py
program? AFAIK, all jobs run bycron
are run in the "background", and so this appears to be redundant - at best. Have you tried eliminating the&
to see if it makes any difference?Related to the
environment
is the question, "Where does my output go?" And for that matter, where does the system send error messages and get its input? These are calledstdin
,stdout
andstderr
(See 1 & 2 for details: 1, 2). If you launched your program from the command line, the system would know to send any error messages to your terminal. But, ifcron
starts your job, where are those error messages sent?There is a shell trick you could use to make sure you are informed of any exceptions encountered when
cron
starts your job. You could redirect thestderr
output to a file. In this way, you won't miss any exceptions thrown whencron
tries to start your job. Here's one way to accomplish this redirection:
@reboot /home/pi/myjob >> /home/pi/myjob_errorlog.txt 2>&1
There are some more things we could try, but this information will help narrow things down. You can edit your question & add anything useful you learn from 1 - 3 above.
sudo chmod +x /home/pi/measureTemp.py
,which python3
:/usr/bin/python3 /home/pi/measureTemp.py
,Popen("bash -c python3 /home/pi/measureTemp.py", ...)
have you try this ?@reboot sudo python3 /home/pi/flickSwitch.py &>/home/pi/myscript.log &
... after started , what is the content of this file ? (may contain your error)