1

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()
  • How do you know? The script will not be connected to a display so any screen output will be dumped. – joan Dec 11 '19 at 12:44
  • @joan The second script turns on/off LEDs in the towerlight and they do not turn on/off hence my assumption that the script does not run. – Tullio_IRL Dec 11 '19 at 14:45
  • @joan plus doing a ps -aux | grep measureTemp.py returns nothing. – Tullio_IRL Dec 11 '19 at 14:57
  • 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 ? – Ephemeral Dec 11 '19 at 16:00
  • @reboot sudo python3 /home/pi/flickSwitch.py &>/home/pi/myscript.log & ... after started , what is the content of this file ? (may contain your error) – Ephemeral Dec 11 '19 at 16:06
1

Nice puzzle... You should work toward discovering some more information to narrow this down:

  1. 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, the environment is different. Once you've read this tutorial, you will begin to wonder... if cron's PATH variable is different than the PATH 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, does cron's environment tell the system where the programs sudo and python3 are located?

    Knowing how to discover what cron's environment is will help you answer this first question. Here's one way to discover cron's environment variables, and therefore its PATH.

    If you discover a program you're telling cron to start is not in cron's PATH, you could correct that easily by adding the full file specification to the line in your crontab.

  2. Why have you put the & at the end of your flickSwitch.py program? AFAIK, all jobs run by cron 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?

  3. 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 called stdin, stdout and stderr (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, if cron 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 the stderr output to a file. In this way, you won't miss any exceptions thrown when cron 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.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.