On a raspberry pi how to launch a python script via crontab as we would do in SSH? - cron

I have a python script that uses the 'os' library to find the screen size. This script works fine when I run it in SSH but it crashes if I try to run it with crontab.
my python script :
import os
screen_resolution = os.popen("xrandr | grep '*' | awk '{print $1}'").read().strip().split("x")
screen_width = int(screen_resolution[0])
screen_height = int(screen_resolution[1])
print("Screen Resolution : ", screen_width, "x", screen_height)
crontab :
#reboot python /home/pi/Documents/run.py > /home/pi/log.log 2>&1t
or
#reboot env DISPLAY=:0 XAUTHORITY=~/.Xauthority python /home/pi/Documents/run.py > /home/pi/log.log 2>&1
error log :
Can't open display
Traceback (most recent call last):
File "/home/pi/Documents/run.py", line 4, in <module>
screen_width = int(screen_resolution[0])
ValueError: invalid literal for int() with base 10: ''
Is there a way to run this kind of script once the whole system has booted ?
Because I have the impression that by going through cron some of the environment variables have not yet been configured
I tried to pass it variables display and Xauthority in crontab but without success.
I would like to execute this script automatically when you launch by hand via SSH

I think you can more easily determine the resolution of the attached monitor using this command:
/usr/bin/tvservice -s
state 0xa [HDMI DMT (87) RGB full 15:9], 1024x600 # 60.00Hz, progressive
That doesn't require an X11 server to be running, or any authorisation or DISPLAY setting.
You may want to extract just the resolution like this:
/usr/bin/tvservice -s | grep -Po '(?<=,\s)\d+x\d+'
1024x600
Another option is:
/usr/bin/vcgencmd get_lcd_info
1024 600 24

I solved my problem by using the autostart file
nano ~/.config/lxsession/LXDE-pi/autostart
thanks

Related

Python script not working when run via a CRON job

I am fairly new to python so please bear with me.
I have a certain script in python which performs the following steps:
Calls another python script to generate a file (called logfile.txt which contains a lot of text around 25kb which might take upto a couple of mins).
after this file generation is complete, it parses the file and looks for a certain text (assume 'power=XXX'), and saves the xxx in a variable.
performs a db call and saves this value xxx in a mysql table.
All of this is working fine when the script is executed standalone like this:
sudo python3 Parser.py
Now I have to do the same in every 15 mins.
So I made an entry in the crontab sudo crontab -e
*/2 * * * * sudo python3 /home/pi/Parser.py >> /home/pi/cronlogs.txt
now this cron job is running fine and generating the cronlogs, where I can see the logs from the python script, but the logfile is not generated, and therefore the parsing is failing(giving 0 as expected when the file is not found)
Things I have tried:
I thought it could be a user issue so I printed the user in the logs in teh start of the script and both scenarios the user is root (as expected)
Added a file availability check before calling the parsing code:
print("file found:",os.path.isfile(fileName))
This resulted in a true!! (even when I can see there is no file in the location)
When i printed the first line of the file it printed empty.
Please help.
OS: Rasbian (Rapberry pi)
Update [Added code snippet which creates the file]:
libDir="/home/pi/SIDLMSIntegration/Gurux.DLMS.Library.python/"
dlmsCmd = " sudo python3 " + libDir + "main.py "
dlmsCmd += " -S /dev/ttyUSB0:9600:8None1 -c 32 -s 3 -a Low -P ABCD0001 -sn 1 -v 0.0.40.0.0.255 -t Verbose > /home/pi/SIDLMSIntegration/logFile.txt "
print("dlmsCommand is:",dlmsCmd)
try:
os.system(dlmsCmd)
signedPow=0.0
activeEnergy=0
print("Exception did not occur")
except Exception as err:
print("Exception Occured:",err)
pass
parseFile("Unit.ACTIVE_POWER")

bash script to auto run on boot, make screen, execute a command and detach

I am using Centos 7 and on boot I would like to:
Make a screen
Execute a command: osrm-routed --algorithm=MLD
~/osrm-backend/profiles/australia-latest.osrm
Detatch from screen (possibly not needed, just as long as I can
access it myself after its running in future)
Here is something I have thought about, although not correct and wont work
filename: mapstart.sh
Contents of file:
#!/bin/bash
/usr/bin/screen -dmS mapapi osrm-routed --algorithm=MLD ~/osrm-backend/profiles/australia-latest.osrm
With your help with the script. I am not sure the best way to run that on boot with centos 7.
Appreciate your help and input.
For those who would like to know. The issue was with OSRM and centos. I was able to get it running using the full paths of everything and the following in crontab -e
To get the full path of osrm-backend i ran the command of:
which osrm-routed
It returned the result of:
/usr/local/bin/osrm-routed
That then enabled me to add the full path of the command I was trying to run from crontab -e which is required. From there it worked running the below in crontab -e
#reboot /usr/bin/screen -dm -S pistartup /usr/local/bin/osrm-routed --algorithm=MLD ~/osrm-backend/profiles/australia-latest.osrm
break down of all the above:
runs command at reboot only:
#reboot
full path to screen command:
/usr/bin/screen
create screen with name of pistartup and detach:
-dm -S pistartup
my particular command i wanted to run inside the screen:
/usr/local/bin/osrm-routed --algorithm=MLD ~/osrm-backend/profiles/australia-latest.osrm
Now when ever the machine is rebooted. it has created a screen and run my command. To resume the screen manually If i ever wanted to, i could issue the command of:
screen -r pistartup

How to verify scheduled run in linux

I am following this post. I want to run a python script, in the background, after logging out of ssh, witht the output stored into a specific file. Namely, I wish to use the following bash command:
nohup python3 main.py --dataset CorrSR/testTraining/small --train --input_height=256 --output_height=256 --epoch=2 | at 1:25 PM Mon > logs/background_run_small.txt &
I am not sure regarding the order of the command. is | before >? The command runs with no errors, though a process is immediately opened with
4285 pts/5 Sl 0:02 /usr/bin/python3 -u /usr/lib/python3/dist-packages/spyderlib/widgets/externalshell/start_ipython_kernel.p
and also the output file is immediately created. Is that normal? how do I know the program waits for the designated time to run?
Your command line executes main.py immediately.
What you probably want is:
echo 'nohup python3 main.py --dataset CorrSR/testTraining/small --train --input_height=256 --output_height=256 --epoch=2 > logs/background_run_small.txt' | at "1:25 PM Mon"

Python selenium script does not open a browser on default display from the crontab

I would like to open a web page in a browser on raspberry by running a python selenium script every n hours from the crontab.
Its a pretty standard script that works if I run it locally on that machine.
So if i connect a keyboard to the raspberry and run
python /home/pi/ww/open_dashboard.py >> /home/pi/ww/selenium_output.txt
it will open the browser and do the selenium commands that I need.
Now I can also ssh into the raspberry and run
export DISPLAY=:0 && python /home/pi/ww/open_dashboard.py >> /home/pi/ww/selenium_output.txt
and I can see a browser open and do what I need on the monitor connected to the raspberry.
Now when I add this line to the cron.
57 9 * * * export DISPLAY=:0 && python /home/pi/ww/open_dashboard.py >> /home/pi/ww/selenium_output.txt
I can see that cron executed the command if I check grep CRON /var/log/syslog
Jul 18 09:57:01 raspberrypi CRON[2971]: (pi) CMD (export DISPLAY=:0 && python /home/pi/ww/open_dashboard.py >> /home/pi/ww/selenium_output.txt)
But browser did not open on the monitor connected to the raspberry. What could I be doing wrong here? :)

linux can't access screens on crontab

I have created a bash file that executes a python script on an existing screen called 'cronscreen'. The bash file contains the following line:
screen -S cronscreen -X stuff "python test.py$(printf \\r)"
When I run the file from the command line, it works fine, and I see the output is printed when I attach my 'cronscreen'. However, I would like it to run in cron, so I have set up crontab as follows:
* * * * * myuser /home/myuser/myscript.sh > /home/ec2-user/agg.log
The cron is executed because I can see that the file agg.log is regenerated every minute, but when I attach 'cronscreen', I see no output printed there (and agg.log is empty). Why is that? Thanks.
Update:
I also tried changing the script to this(re-attaching the screen), but no change:
screen -r cronscreen
screen -S cronscreen -X stuff "python test.py$(printf \\r)"
screen needs an tty active to create a session which is not what is available under cron.
You need to split this into two parts , the first is to run screen and make it detach - screen -dmS cronscreen and then in your cronjob attach to the screen session with -r cronscreen

Resources