Running a tkinter GUI using crontab - python

I have a simple GUI (created using tkinter) that I want to run at a specific time of day on a Raspberry pi 3. Bellow is the code snippet I used in crontab. I invoked the crontab manager using sudo crontab -e.
0 18 * * * cd /home/pi/gui && python3 gui.py
For the moment, I can execute the GUI by invoking it directly via the Pi's command line. However, it doesn't work when I try to do it using cron. I also tried to switch to a basic python script (writing to a file) and that worked. Is there a specific weird interaction that I need to be aware of?
My setup: raspberry pi 3, python 3, raspi-screen, tkinter (latest version as far as I know)

The sudo will run without a tty and display that is why you command won't work.
Try having xvfb installed and use
0 18 * * * cd /home/pi/gui && xvfb-run python3 gui.py
Update-1: 22-Jun-18
If you want to use your actual display then you need to make sure that you use below command
XAUTHORITY=/home/<user>/.Xauthority DISPLAY=:0 python3 gui.py
And also make sure the cron is for your user. The default DISPLAY is :0.
When you have a XServer (GUI display), you cannot just connect to it without an authorization. When system start it creates a file and that location is stored in environment variable XAUTHORITY.
When you run a cron, you have limited environment variables. There is no existing XAUTHORITY or DISPLAY defined
to be able to connect to display you need. So you need to define every environment variable that would be required by your program
So you define DISPLAY=:0 to select the default display and you need to set XAUTHORITY=/home/<user>/.Xauthority to prove that you are authorized to connect to the display

Raspbian 10 (buster): the only missing part - in my case - was to inform the cron-job using gtk, which display it has to use, by inserting
DISPLAY=:0. I used a bash-script to start the python script using tk; This could be a python script as well.
#reboot DISPLAY=:0 /home/pi/path/to/my/script.sh start
Useful for debugging:
#reboot DISPLAY=:0 /home/pi/path/to/my/script.sh start >> home/pi/Desktop/cron.log (in one line)
Using cron as user pi (not as root), it was necessary to place the cron.log file in some /home/pi/... folder to give writing access for the log-files.
Maybe Raspbian needs some time to setup everything before an applicaiton can be started; I used:
#reboot sleep 10 && DISPLAY=:0 /home/pi/path/to/my/script.sh start
In place of #reboot the usual cron settings can be used, e.g.:
*/5 * * * *(rest of line see above)
for every 5 minutes to start.

Related

Unable to run python script with cron

I am trying to run a simple python script with cron and I cannot for the life of me get it to work. I am running Ubuntu 18.04.
I know there are many questions (and answers) on this. I have looked at a number of them and I still cannot get it to work.
My python script is:
#!/usr/bin/env python
from tkinter import messagebox
messagebox.showinfo('MessageBox','Hello world!')
I have followed Unable to Run Python Script In Cron and changed the permissions as follows:
chmod +x /home/brb/bugs/projects/cron/hello.py
I can successfully run this from the command line as follows:
brb#bishop:~$ /home/brb/bugs/projects/cron/hello.py
Inside crontab I have tried to execute the script in 2 different ways as follows (every 2 or 3 minutes to try and pin down which one works...)
*/2 * * * * /home/brb/bugs/projects/cron/hello.py
*/3 * * * * /usr/bin/env python /home/brb/bugs/projects/cron/hello.py
Nothing happens.
I followed http://www.jessicayung.com/automate-running-a-script-using-crontab/ and tried to inspect the error file as follows:
cd ../..
cd var/mail
nano $brb
and I observe a message in nano that says
[ Directory '.' is not writable ]
I am not sure which directory '.' is, perhaps it is var/mail. In any case, not sure how to make it writable. I will google chmod some more to get this writable I guess, but that still doesn't solve why cron is not working when it looks like all the examples I've seen...
EDIT:
I followed How to run an X program from outside the X session (e.g. from the console or SSH) as per the comment from triplee and, not really knowing what I am doing, I attempted to change my display permissions as follows:
brb#bishop:~$ export XAUTHORITY=/home/brb/.Xauthority
brb#bishop:~$ export DISPLAY=':0'
My cron job is still not work...
Your problem is twofold:
cronjob has does not know where it could be displaying a graphical app (which X server or DISPLAY to use.
This can be addressed by making sure DISPLAY is set in the environment of you script. Run echo $DISPLAY in a terminal running in your X session. :0 is a very likely it.
Even if it knows the correct DISPLAY, it does (should) not have access to it. If you are running the cronjob under the same user as the one running your target X session. If it is a different user, and it has access to your user's home, you could reuse it's authority file by setting XAUTHORITY to point to it.
You can also export necessary information from your running session (renewed with each session), type this into a terminal there: xauth list $DISPLAY and add it for your cron running user: xauth add displayname protocolname hexkey (using those three values as returned by xauth list.

Cronjob on Ubuntu Mate for Raspberry stops right after execution

I use a RaspberryPi 3 with UbuntuMate 16.04. On it, I want to start a little Python (3.5) program every midnight. For that I call a little shell script, so that I can change into the wanted directory comfortably.
crontab:
5 0 * * * /path/to/script/start.sh
start.sh (yes, it's executable):
#!/bin/bash
cd /path/to/wanted/workingDir/
python3.5 ControllerQueue.py
#also tried: python3.5 ControllerQueue.py &
Now if I execute the programm or script from the terminal, everything runs fine. But if I use the crontab it starts the script and stops right after. I also tried running the programm directly but get the same outcome. The paths are correct as I copied the workingDir path from the crontab-file and started it via the terminal.
Is there something I overlook?
As stofvl suggested, I saved the error output of my shell script. It turns out that I needed to add a display. My programm is divided into two scripts. One which provides a GUI and the other main application. The script only starts the main application, without the GUI, but it seems that this didn't matter.
This discussion helped me solve the problem.

Schedule script in python

I am looking to schedule a code on my raspberry pi zero. The task would be to run a .py script to a pet feeder 3 times a day on specific times based on the system clock. I have tried to search it on the internet but the results kept on coming back for windows 7 task scheduler, however I need to run it on Raspbian.
Any suggestion will be appreciated.
Thanks
Try the schedule package:
https://pypi.python.org/pypi/schedule
It had worked for me in raspberry pi.
cron works well to schedule the python script to run at certain times. It's much simpler than using the python schedule package.
Firstly, make sure your python script starts with a shebang
#!/usr/bin/env python
and is executable
$sudo chmod 755 ./my-python-script.py
Then, in command line on the pi. Open a new cron tab
$sudo crontab -e
(you may also need to select an editor, nano is the easiest)
and schedule your script to run by adding the follow to the last line of the crontab (this will run every 8 hours)
0 */8 * * * /path/to/my-python-script.py
or if you would like to log the output, use
0 */8 * * * /path/to/my-python-script.py > /home/pi/Desktop/my_script_log.txt
Lastly, save and exit from nano (cntl + x) and restart your Pi.
If you are having issues, check the cron sys log
$grep cron /var/log/syslog
Use this site for working out the crontab interval syntax - https://crontab.guru/
Okay so Rc.local didnt work, Ive tried everything, however Cron worked to autostart the launcher.sh.
Now, I need a second thing, where the scrip runs everyday 3 times in specific times, however the schedule 0.5.0 does not seem to work.
I have pip version 10.0.0 then I have managed to install schedule in the terminal, but when I try to run my script it comes back with an error, that the import schedule cant be found.
Do anyone know a solution for this?
import schedule error
link
Thanks

Starting a Python script on a raspberry via plink (not responding crontab)

I have written a script.py, which opens a tk window and draws with turtle in the canvas the window contains. I want to start this script via a plink using:
plink.exe -pw raspberry pi#pi-fisch00 python /home/pi/script.py
But I always receive an error:
script.py line 32, in <module> root = Tk()
no display name and no $DISPLAY environment variable
I think the same error is causing that the crontab is not executing the script.py.
My entry in the crontab:
*/1 * * * * python /home/pi/script.py
The syntax should be right, because other scripts are working and if I put python /home/pi/script.py in the cmd manually everything is fine. The script.py gets executed. How can I fix this and let the crontab execute the script.py? Why can't I execute the script.py via plink?
Look at the error message you are getting:
no display name and no $DISPLAY environment variable
You are attempting to run something that requires an X11 display, which isn't going to be available from within cron's context (and likely not via plink either, unless you are running an X11 display server locally and have enabled X11 forwarding).
Typically, if you have something that needs access to the display you need to run it from within an existing desktop session. There are ways to work around this; for some thoughts on that topic see:
https://unix.stackexchange.com/questions/25684/how-to-access-x-display-from-a-cron-job-when-using-gdm3
https://unix.stackexchange.com/questions/10121/open-a-window-on-a-remote-x-display-why-cannot-open-display

Raspberry Pi Auto Starting a program

So I have a python game (PyGame) running on a raspberry Pi.
I have followed the instructions found on many sites for getting the Raspberry Pi to auto login (those all work), auto run startx, but I'm stuck on getting my program to run once the GUI loads.
Many people (here on StackOverflow and other places) point to this presentation here:
http://www.slideshare.net/SeggySegaran/raspberry-pi-autostarting-a-python-program
I've tried both ways of doing it (putting the desktop file in autostart or putting the command in rc.local
I have opened up a Terminal window and copy / pasted the command to verify there are no typos and the code will run......
sudo python /home/pi/valley.py
and it will run. Is there a way to see a log to find out WHY the program doesn't launch? Is there a better way to get done what I want to get done?
I've got my python script to run at startup doing this:
sudo nano /etc/xdg/lxsession/LXDE/autostart
This will allow you to add an element to run when the LXDE desktop session begins (the raspian default GUI if setup to do from raspi-config)
It will probably have entries like these:
#lxpanel --profile LXDE
#pcmanfm --desktop --profile LXDE
#xscreensaver -no-splash
It's just a matter of adding your script there as well
#lxpanel --profile LXDE
#pcmanfm --desktop --profile LXDE
#xscreensaver -no-splash
#python /home/pi/yourAwesomePyScriptHere.py
If your python script uses GPIO, you need to run that as root (using sudo):
#sudo python /home/pi/yourGPIOScript.py
One thing I do want to point out: always test your script before hand.
I mean, run with the absolute path, make sure it still works, try to break it, make sure it's as robust as it can be. If there are errors in your script and you place it at start up you won't see those in a terminal window, but you will hog the cpu with python stuck in a loop at startup.
Also check out this answer on the RPi exchange
You can achieve this in two ways:
1). Using LXDE autostart.
2). As a service via init.d.
If you are starting X with "startx", you can also just stick your game in your .xinitrc. If your game binary is called "game" and is in your path, just do this:
echo "game" >> ~/.xinitrc
This works for other commands. Add a "&" if you want the command to keep running in the background.
This is how I start my window manager, load my wallpaper, start a compositor, etc. It is stupid simple, easy to change later, and can do anything you can do at a terminal prompt.
You can run your script automatically on startup of raspberry by using crontab.
Crontab is table that list all command to perform on scheduled time.
First, you need to edit crontab by using:
sudo crontab -e
And after this, add following line:
#reboot python path-of-your-script & (& should be at the end of line that means command will execute in background).
Save your script and reboot your system. When your system will start, your script will run automatically.

Categories