1

I am getting some really strange behavior when trying to run a python script at start up using an sh script in crontab.

Here is the python script (it controls wifi lights in my house):

#IMPORTS
from lifxlan import BLUE, GREEN, LifxLAN #for lights

#INITIALIZE THE LAN
lan = LifxLAN(6) #LAN Object of all the lights on the LAN from lifx - 6 lights on the system
lights = lan.get_devices_by_group('Living Room')  #Object of lights on the LAN


print('Trying to turn the lights on...')
if True:
    lights.set_power(power = 'on', duration = 10) #turns on the lights for all the lights on the LAN
    print('If you see this text, the lights should be on')

Here is the sh script:

#!/bin/sh
#launcher.sh
#navigate to the home directory, then to python directory, then back to home
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games

cd /
. /home/pi/python/python-virtual-env/lights/bin/activate
cd home/pi/Desktop
python3 test.py
deactivate
cd /

Here is the line in sudo crontab -e:

@reboot sh /home/pi/Desktop/test.sh > /home/pi/Desktop/test_log 2>&1

I know the file is running because the output of cat Desktop/test_log is:

Trying to turn the lights on...
If you see this text, the lights should be on

But the lights don't turn on.

So:
1) cron is running the .sh script
2) shell is launching the python script
3) I am receiving no errors and the logs are printing the indented code chunk, meaning that it executed the line: lights.set_power(power = 'on', duration = 10) and didn't meet package problems.
4) But the lights don't turn on.

Notably the lights turn on if i do any of:
1) sudo sh home/pi/Desktop/test.sh
2) if I paste the lines one by one from the test.sh script into the terminal - including activating the virtual environment.
3) if I run the lines of python code one by one in the python shell

So something is making the LiFX code not run when the test.sh script is launched by crontab.

Extra information: I got the PATH variable for the test.sh script from by activating the virtual environment and typing echo $PATH. I assume this is correct. I also did sudo pip install lifxlan while in the virtual environment to install that module (https://github.com/mclarkk/lifxlan).

I am stumped at this point. I assume something isn't loading in the virtual environment via cron, but there are no errors and everything works if i run the code from within the virtual environment.

Adding extra information after following the instructions from @Ingo. I tried running this using systemd, and things worked initially, but then stopped after i updated the .py script.

  1. The full path of the script I am trying to run is: /home/pi/python/lights/lightsV4.py
  2. Script is not executable, but since i call it with /usr/bin/python3 in the .service script i assume it doesn't need to be.
  3. /usr/bin/python3 /home/pi/python/lights/lightsV4.py at the command line effectively executes the script (does not need sudo)
  4. print() statements in the .py script only call text.
  5. It does not need wifi (its running a PiR sensor that was triggered by the wifi module) but does need eth0 - its plugged in.
  6. No remote sources, its the only file running.
  7. The .py script requires a number of packages to load:

    import RPi.GPIO as GPIO import time from datetime import datetime, timedelta from lifxlan import BLUE, GREEN, LifxLAN import requests import pytz

  8. The script runs on a while loop. As such i changed the .service script such that Type=simple, rather than Type = oneshot. Worked fine initially.

I really appreciate the help. Let me know what I could be missing to cause the

2
  • Did you check it by Systemd method? raspberrypi.stackexchange.com/a/109561/44221 Commented Mar 31, 2020 at 7:46
  • Maybe the Pi hasn’t connected to your Wi-Fi network yet? Does the lifx library throw an error if it can’t see a light? Try adding a 30 second delay as a test.
    – CoderMike
    Commented Mar 31, 2020 at 7:58

1 Answer 1

3

There are some things with output redirection, path environment variable, directory back and forth, which make things a bit confusing. In addition it isn't defined when the cron job is executed. It is possible that it already runs when the WiFi isn't available. To manage all this in a clean way you should use systemd. You can create a new service for it with an Unit file. Try it with:

rpi ~$ sudo systemctl --force --full edit switch-light.service

In the empty editor insert these statements, save them and quit the editor:

[Unit]
Description=Switch lights on
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=/home/pi/python/python-virtual-env/lights/bin/activate
ExecStart=/usr/bin/python3 /home/pi/Desktop/test.py
ExecStartPost=/home/pi/python/python-virtual-env/lights/bin/deactivate

[Install]
WantedBy=multi-user.target

This is straight forward. I don't know what activate and deactivate do. Seems it is using a virtual environment. You should not use it in a productive environment, in particular if you want to run it on startup. There you have to use the real environment to get the status of the network. Make only /usr/bin/python3 /home/pi/Desktop/test.py running from the commandline. Then it is always possible to also run it as service. Enable and monitor the new service with:

rpi ~$ sudo systemctl enable switch-light.service
rpi ~$ systemctl status switch-light.service

The output of the print() functions you will find in the journal with

rpi ~$ journalctl -b -e
6
  • Thanks very much for this. I will try and set this up using systemd tonight. Quick question regarding virtual environments. I can try and set this up in the real environment, but there seems to be a lot of python documentation detailing the need for virtual environments to avoid package conflicts. Can you clarify for me. For example what would i do if i wanted two python scripts to run on the pi that required different versions of the same package without throwing errors (docs.python.org/3/tutorial/venv.html). If this should be a separate questions let me know.
    – MorrisseyJ
    Commented Mar 31, 2020 at 17:39
  • @MorrisseyJ I'm not so familiar with python but as far as I know the trouble with environments is mostly respected to downstream compatibility with old scripts and versions. If you start with new scripts using python3 you should find recommendations to handle it properly. I suggest to make first your script only running on the RasPi. Tell me, if it doesn't work. If then afterwards problems coming up with other python scripts you should ask a new question, but better on stackoverflow.com about the conflicts.
    – Ingo
    Commented Mar 31, 2020 at 18:49
  • thanks for all your help on this. I got this all up and running - using both your the test.py script and the full py script. I subsequently had to update that .py script and things broke. I tried running the test.py setup again, and no luck. Once again, if I stop and then sudo systemctl start lights.service things work, however if i enable and reboot the script doesn't execute correctly. Notably, status shows that the indented code chunk ran. So systemd seems to be running the service script, but for some reason the lights code is not working. The network elements are unchanged
    – MorrisseyJ
    Commented Apr 2, 2020 at 3:24
  • @MorrisseyJ What's the name of the productive script? Does it run on the command line with: /full/path/to/productive.py? What's the complete command to run it with parameter? Do you need sudo? What environment is needed to run it? WiFi must running? Only text output with print() or graphical output? Access to remote sources/files? Other important things? Please add this to the question.
    – Ingo
    Commented Apr 2, 2020 at 10:05
  • updated the question. Hopefully this is useful. I assume the problem is about getting the network up using eth0 rather than wifi.
    – MorrisseyJ
    Commented Apr 2, 2020 at 15:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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