2

I would like to improve on my project by using cron jobs. Currently, i have a web application that allows me to control servos. However I would like to add another function on the web application where i can set the cron job to execute a script that would control the servos automatically. meaning that i can click on a button on the web specifying that i'm not at home or something and that would tell cron job to take over.

Any idea how can i do this? A link or tutorial would be good too. :)

| improve this question | | | | |
  • 1
    The way you are using "cron" does not make sense to me. cron is for adding jobs that are scheduled. But you imply you want immediate action when the button is pressed. Just have cron execute runmotors.py once an hour and your web server execute runmotors.py when you click a button. – rob Mar 28 '14 at 13:45
  • hi @rob . no as in, when i click that "cron start" button, i will set the cron to start doing things, say twice per day. the purpose here is when i'm not at home to do the controlling, the task can still be done. – yvonnezoe Mar 28 '14 at 13:55
  • so is your question "how do I add a job to cron programmatically" ? – rob Mar 28 '14 at 13:58
  • there is a great discussion about this on stackoverflow stackoverflow.com/questions/610839/… – rob Mar 28 '14 at 13:59
  • wow. thanks @rob. yeah, i think that's a better phrase for the question :) sorry, i'm quite new to this and havent try cron yet. – yvonnezoe Mar 28 '14 at 14:07
3

Is it just me or does the thought of allowing a web application to edit cron jobs give you the willies.

Here is how I would go about it: Setup a cron job to always run at the frequency you desire. Make it run the script you want. In the script the first thing you do is read a small settings file which tells it whether to continue or not, for instance

run=false

Now when you want the job to actually run you make your web application edit the settings file setting run=true and the next time the cron job is run the script will run in its entirety.

Just make sure you use absolute paths throughout.

| improve this answer | | | | |
  • +1 sounds simple enough but what do you mean by "small settings file"? can you provide more details on this? :) – yvonnezoe Mar 30 '14 at 6:49
  • The default choice is a text file containing simply the single line run=false. However depending upon the programming language being used by the web application the settings file could be a script itself for instance a python script that simply contains run = False and is imported by the application. This avoids having to open, read content and close the file but has its own set of pitfalls. – Abid H. Mujtaba Mar 30 '14 at 10:40
3

Have you looked into GO based groundcontrol daemon at https://github.com/jondot/groundcontrol? It is very light on CPU resource and has a very simple control UI with various buttons for executing simple bash commands or complex scripts.

In your case, let's say you have a cronjob entry to allow a script named, servos.sh run every 30 minutes.

crontab -l
*/30 * * * * /scripts/servos.sh > /dev/null 2>&1

If you want conditional on/off for this cron job, then you can execute sed based command to enable/disable specific cronjob, and assign these commands to ON/OFF buttons in groundcontrol app.

Relevant portion of /etc/groundcontrol.json will look like this. Check groundcontrol documentation for installing daemon and editing config file.

"controls" : {
    "servos_cron": {
      "on" : "crontab -l | sed '/servos/s/^#//' | crontab -",
      "off" : "crontab -l | sed '/^\*.*servos/s/^/#/' | crontab -"
    }
  }

PS: Upon clicking off button in groundcontrol UI, sed command will place "#" character at the beginning of running servos cronjob entry, given it begins with asterix. If your cron entry has different parameter at the beginning, edit off command accordingly.

Once you restart groundcontrol, you will get nice UI at localhost:4571 (port can be changed) allowing you to manage servos cron by pressing a button!

Hope that helps.

enter image description here

| improve this answer | | | | |
  • +1 hmm definitely worth trying when i'm not in rush to achieve it, cos i know nothing about json and i'm using python and cherrypy currently. – yvonnezoe Mar 30 '14 at 6:48
  • You do not need to know json scripting for this. Groundcontrol documentation is all you need. Here is my /etc/groundcontrol.json file for running groundcontrol as a daemon: pastebin.com/7w07CuXh Script is pretty much self-explanatory, and you can add/remove commands as per you need. Unlike other scripting, I doubt if json file respects comment character "#", and so I'd no comment lines within script. PS: I am not the groundcontrol owner but simply love that app! – Samir Mar 31 '14 at 16:14
2

Have you considered having cron always run your job and then have a flag that the script that cron starts checks to see if the script should execute or not.

This flag could be the presence of a file. If the file exists (easily checked in a shell script) the script would just exit.

Now all your web page needs to do is create the file if you want the script disabled and delete the file if you want the script to run.

Here's some python code to create and delete the flag file.

To create:

#!/usr/bin/python
import os

def touch(fname, times=None):
    with file(fname, 'a'):
        os.utime(fname, times)

# Create file called /tmp/flag_file
touch("/tmp/flag_file")

To delete:

#!/usr/bin/python
import os

myfile="/tmp/flag_file"

## if file exists, delete it ##
if os.path.isfile(myfile):
    os.remove(myfile)
else:    ## Show an error ##
    print("Error: %s file not found" % myfile)
| improve this answer | | | | |
  • +1 but i have no idea how to do that. O_o i'm currently running a python script that starts cherrypy web server at port 8080 – yvonnezoe Mar 30 '14 at 6:50
2

As far as I have understood your question and comments, what you are actually asking for is a way to access e.g. the python scripts by HeatfanJohn / edit the configuration file by Abid H. Mujtaba via your webserver.

The way I would to this is use a small PHP File. For this to work, you will need to have PHP installed. The File could look somewhat like this:

    <?php
    $path='/var/www/cron_onoff.txt';
    $text=$_GET['arg'];
    shell_exec('echo '.$text.' > '.$path);
    ?>

Save it for example as "cron_onoff.php" in your /var/www folder. Now, on your HTML Website, you add a link to enable, and another to disable:

    <html>
    <head>...</head>
    <body>
    <a href="cron_onoff.php?arg=on">Turn ON</a><br />
    <a href="cron_onoff.php?arg=off">Turn OFF</a><br />
    </body></html>

Now, when you click the first link, the text "on" (without quotes) will be written into the file you specified in the php-script, when you click the second link, the content will be replaces by "off". Whatever your cronjob runs should now open this file, and check if "on" is written there, otherwise stop executing. (See this StackOverflow question on how to do something like this with bash).

Also, if you decide to put the file cron_onoff.txt elsewhere, you might get some trouble with permissions to write. Remember, the active user for scripts executed via Webbrowser is 'www-data', so you have to grant at least some basic permissions. Also, if this doesn't work, your PHP might not have been configured to allow the execution of shell scripts.

Finally, you can, of course, use different commands in the shell_exec-Function. For example,

    shell_exec('python /var/www/script.py');

could run one of the scripts provided by HeatfanJohn. Be sure to add the executable flag for the www-data user for the script: (run in Terminal)

  cd /var/www
  sudo chown script.py www-data:www-data
  sudo chmod +x script.py
| improve this answer | | | | |
  • Thanks for the detailed explanation. I will look into this again. :D – yvonnezoe Apr 10 '14 at 4:45

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.