I got temperature, pressure, and altitude readings on my PI using a sensor:
The problem is, to see the results, I have to execute the code.py every time by myself. I am trying to automate it somehow so it will keep running itself for the time I want.
Once that is automated, would like to save the results and analyze the output after some time.
Is there a way I can write code for both the tasks?
Thank you.
There are two things required here. First a script i.e code.py to log the functional behavior like temperature, pressure, and altitude readings along with error/response during the process. Another is the script executions logs i.e a success or failure during the scheduled time and other system logs.
For first job, you have to do by your self but ensure to have a logger module in place to log the process flow.
For Second job, you can use OS provided scheduler crontab for Linux based os. For example to execute script every minutes
* * * * * python /home/script/code.py > /home/script/code.log 2>&1
For more about scheduler jobs, you can refer here
The time module is your friend here. You can set up an infinite loop with while True: and use time.sleep(secs) at the end of the loop (after output).
I'd use additional controller script like this:
import subprocess;
import time;
import sys;
x = True;
while x:
while exit_code!=0:
try:
exit_code = subprocess.check_call(['python', 'collect_data.py', '-cli_args_if_needed']);
except:
print(sys.exec_info()[1]);
print('Relaunching in 5 seconds');
time.sleep(5)
Related
is there any way I can run python code in this way:
main code will run all the time ,
once every 5 min will run another function while running the main code.
my code is reading gps signal and send it to my server every 5 seconds.
I have to run another code that check the device cpu\file\temp every 5 min (this part take around 30 seconds )
can both of them run at the same time while still getting gps?
I have the GPS code ready and also the Check code ready - how do I combine them (if it's possiable)
Thanks ,
This might answer your question: Running Two Script at Once Using Bash
Based on the answer here, all you'd have to run is:
python script1.py &
python script2.py &
You can use the threading module, to do this task: it allows you to run functions as different processes seperate from the main program. Threading Documentation
I think you should get what you want with the following code:
import threading
def gpsJob():
threading.Timer(300.0, gpsJob).start()
# Here goes your GPS-code
gpsJob()
if __name__ == '__main__':
# main code
I am using my raspberry Pi3 to create timelapse videos. I have a cron that runs a python script every minute that decides how many photos to take and then imports a function from another python script that takes the actual photos. The problem is that after running for about 4 hours the camera stops taking photos- if I try and take one manually it says it is out of memory, and top confirms this. If I watch top while the timelapse is running the memory usage steadily climbs.
I think I have narrowed the problem down to the python script that takes the photos. I can run this on its own, and if I start up the pi and run it a few times I see that the memory used climbs by about 10MB the first run and about 1MB every subsequent run (screenshot at the bottom of the post). This is the script
import time
import picamera
import os
def ShutterTS(dirname):
with picamera.PiCamera() as cam:
cam.resolution=(1920,1440)
cam.rotation=180
cam.hflip=True
# camera warm up time
time.sleep(2)
FNfmt = "%4d%02d%02d_%02d:%02d:%02d.JPG"
Fname = FNfmt % time.localtime()[0:6]
framename = os.path.join(dirname, Fname)
cam.capture(framename)
return
def main():
dirname = [insert path here, my path hidden]
ShutterTS(dirname)
return
if __name__ == '__main__':
import sys
sys.exit(main())
I'm not a good coder, I basically cobble stuff together from bits I find on the internet so I'm hoping this is something really simple that I've missed. The with is the raspberry pi recommended way of calling the camera. I know this should close the camera instance on exit but I'm guessing something is hanging around in memory? I tried adding close.cam() at the end of the function and it made no difference (didn't think it would). I've tried del on all the variables at the end of the function and it made no difference. I think the return at the end of the function is redundant but adding it made no difference.
This website https://www.linuxatemyram.com/ suggests that top showing the memory climbing is normal and free -m is a better gauge, and that shows plenty available- but the fact remains the camera stops working, saying it is out of memory. Any clues would be much appreciated!
This is the cron script (some other imports cropped)
from ShutterTimestamp import ShutterTS
from makedirectory import testmakedir
from SunTimesA import gettimes
def Timer(dirname,FRAMES_PER_MINUTE):
# I take a picture first and then loop so the program isn't
# sleeping pointlessly to the end of the minute
start = time.time()
ShutterTS(dirname)
if FRAMES_PER_MINUTE>1:
for frame in range(FRAMES_PER_MINUTE-1):
time.sleep(int(60 / FRAMES_PER_MINUTE) - (time.time() - start))
start = time.time()
ShutterTS(dirname)
return
def main():
dirfmt = []
dirname = dirfmt % time.localtime()[0:3]
FPM=gettimes()
if FPM > 0:
testmakedir(dirname)
Timer(dirname,FPM)
return
if __name__ == '__main__':
sys.exit(main())
Screenshot of memory use
I suppose you have a wrapping python script which import the script you provide in the question and call ShutterTS in a loop. This function does not return any output to main script (just return).
If you can observe a memory leak it probably is located in the picamera module.
A workaround it to call this script as a sub-process, not as a function call in the main process. It can be done in a shell script or in the python script using subprocess module.
Thus the memory will be released after each capture.
Looked at all the similar questions but unable to get the syntax correct. I have a python script that runs a single command at the moment. What I need to do is have this command repeat itself over and over...indefinitely...at certain intervals. Here is my script:
#! /usr/bin/env python
import sys
from scapy.all import sr1,IP,ICMP,UDP,send,DNS,DNSQR
p=send(IP(dst="192.168.1.128")/UDP()/DNS(rd=1,qd=DNSQR(qname="domain.com")), count=100 )
if p:
p.show()
This runs fine from the command line. However I need it to repeat every 30 seconds or 1 minute. How would I tell it to do that inside the script? I know I can probably set this up as a cron job but I'd like to know how to script it. Thanks!
You can use the time module's sleep() method inside a while True loop.
#! /usr/bin/env python
import sys
import time
from scapy.all import sr1,IP,ICMP,UDP,send,DNS,DNSQR
while True:
p=send(IP(dst="192.168.1.128")/UDP()/DNS(rd=1,qd=DNSQR(qname="domain.com")), count=100)
if p:
p.show()
time.sleep(60) # sleep for one minute
you can put a infinite while loop and add sleep of 30 seconds in every iteration. The other option could be set the script into cron job.
The advisable option is cronjob as in case python script exit due to any exception or error, cron can re-run it in next cycle.
Create a while loop. True is always True, so the loop keeps running. After the commands wait a while.
#! /usr/bin/env python
import sys, time
interval = 60 #1 minute
from scapy.all import sr1,IP,ICMP,UDP,send,DNS,DNSQR
while True:
p=send(IP(dst="192.168.1.128")/UDP()/DNS(rd=1,qd=DNSQR(qname="domain.com")), count=100 )
if p:
p.show()
time.sleep(interval)
The infinite loop with the sleep as mentioned in the above answers is the simplest way to do what you want. However, if you do that, your program becomes a daemon which you have to monitor and make sure is running. This has some costs that you should be aware of up front.
I would prefer to use cron to run it every n minutes or something similar. Yet another way, which is similar to the inifinite loop is to the use the python sched module to run a mini cron like system inside your program.
I need to write a python script that autostarts on boot and is executed every 5 minutes on a raspberry pi. How can this be done? in particular, how can I avoid having a script locking up the cpu running a infine loop waiting for the 5 minutes to be over?
You can easily use cron for this task (schedule to run Python script). ;)
How to setup cron
I suppose that you have cron installed already; if not, then install some (vixie-cron for an example).
Create a new file /etc/cron.d/<any-name>.cron with the following content:
# run script every 5 minutes
*/5 * * * * myuser python /path/to/script.py
# run script after system (re)boot
#reboot myuser python /path/to/script.py
where myuser is the user to run the script (it shouldn’t be root if possible, for security reasons). If this doesn’t work, then try to append the content to /etc/crontab instead.
You might want to redirect stdout/stderr of the script to file, so you can check if everything works fine. This is same as in shell, just add something like >>/var/log/<any-name>-info.log 2>>/var/log/<any-name>-error.log after the script path.
Use schedule
wrap the scrip in a function
import schedule
import time
def func():
print("this is python")
schedule.every(5).minutes.do(func)
while True:
schedule.run_pending()
time.sleep(1)
You can use time.sleep
count = -1
while(not abort):
count = (count+1) % 100
if count == 0:
print('hello world!')
time.sleep(3)
I am considering your code takes less than 5 minutes, but the execution time for each run is not constant.
import time
while True:
t= time.time()
# your code goes here
................
........
t= time.time()-t
time.sleep(300-t)
I'm working on a python script that needs to run between two given times. I'm required to use the build in sched module as this script needs to be able to run directly on any machine that has python 2.7 as to reduce configuration time. (SO CRON IS NOT AN OPTION)
A few variables define the settings for the time to run, here set_timer_start=0600 and set_timer_end=0900 are written in HHMM. I'm able to stop the script at the right time.
I don't know exactly how sched works (the python doc page doesn't make to much sense to me), but as far as I understand It runs at a date/time (epoch) while I only want it to run at a given time (HHMM).
Can anyone give me an example (or link) on how to use the scheduler and perhaps calculate the next run date/time?
If I got your requirements right, what you need is probably a loop, that will re-enter a task in the queue every time it will be executed. Something along the lines of:
# This code assumes you have created a function called "func"
# that returns the time at which the next execution should happen.
s = sched.scheduler(time.time, time.sleep)
while True:
if not s.queue(): # Return True if there are no events scheduled
time_next_run = func()
s.enterabs(time_next_run, 1, <task_to_schedule_here>, <args_for_the_task>)
else:
time.sleep(1800) # Minimum interval between task executions
However, using the scheduler is - IMO - overkilling. Using datetime objects could suffice, for example a basic implementation would look like:
from datetime import datetime as dt
while True:
if dt.now().hour in range(start, stop): #start, stop are integers (eg: 6, 9)
# call to your scheduled task goes here
time.sleep(60) # Minimum interval between task executions
else:
time.sleep(10) # The else clause is not necessary but would prevent the program to keep the CPU busy.
HTH!