I am trying to test how long my battery runs on my raspberry pi. All i need to do is run a while loop until the battery dies. However, I need to record the time that it starts and ends. I would like to save the data into a txt file. My current code is as follows:
import time
file = open('time','w')
x=1
while x==1:
from datetime import datetime
now = datetime.now()
file.write(now)
file.close()
If I just print the results in python i will get a result, and the current code makes a file called 'file' but there is nothing saved in the txt file. Any and all help would be appreciated.
Thank you for your time
You have an infinite loop which just gets the current time over and over again ... This loop won't break (even if your battery dies ...).
At some point, you need to break the loop or the condition in the while needs to become False. e.g.
from datetime import datetime
while x == 1:
now = datetime.now()
break
or
from datetime import datetime
while x == 1:
now = datetime.now()
x += 1
Generally speaking, you'll want to look in your system logs for when the computer decided to start up and when it decided to shut down due to lack of battery power ...
I would recomend code that looks like the following:
import time
import datetime.datetime as dt
initTime = dt.now()
while True:
with open('time.txt', 'a') as f:
f.write( str(dt.now() - initTime) )
time.sleep(1)
The couple of differences. First, you always open the file in append mode. This way, the file will be flushed every time. Next, it will always update the file with the amount of time elapsed. So even if your raspberry pi shuts down, you should be able to recover it.
No need to record these times yourself. The Pi (and almost any Linux distribution) writes those events to the /var/log/wtmp file (more about that file here). The last command can retrieve those events (also see the manual entry for last). Try the following:
last -FRx | grep -e 'boot\|shutdown'
Explanation of the flags:
-F prints the full date and times - which is handy in your case, because that's what you wanted to know.
-R suppresses the hostname in the output. You don't need that.
-x shows shutdown en runlevel changes - now that's what you wanted to know.
Finally the grep statement filters out the boot or shutdown messages.
Related
Weird one. I have an applescript that calls a python file every time the laptop wakes from a sleep. The apple script opens the terminal and calls the python file. The python file has functions in it that run certain code if it is a certain time of the day. like this:
now = datetime.datetime.now().hour
if 9 <= now <= 10 :
then do python stuff...
now = datetime.datetime.now().hour
if 15<= now <= 18 :
then do python stuff...
now = datetime.datetime.now().hour
if 22<= now <= 23 :
then do python stuff...
So as you can see above there are certain times of the day that specific python functions will be executed. My problem is that i want to only run the python functions once within that timeframe. At the moment if the laptop wakes up twice within the time frames above then the python functions will be run twice.
Is there a way to solve this in the python file that i am calling?
I know there are probably many ways to attack this problem i.e applescripts, terminal commands or python files. to be honest i dont know where to start so i guessed id start with python and work backwards.
I am thinking if we could check when the python file was last executed and stopping it if it was evicted within the specified time frame already. Then this could be a way of stoping it running twice?
Save the time of the last execution to a file:
...
with open('path/to/file', 'w') as f:
f.write(str(now.timestamp()))
In the top of the script, attempt to read from said file:
try:
with open('path/to/file') as f:
last_execution_time = datetime.fromtimestamp(float(f.read()))
except FileNotFoundError: # will happen in the first execution, obviously
last_execution_time = now
# do whatever logic you want to perform with `last_execution_time` and `now`
...
I have a script which loops through the elements of a list. Each element is used to query an API. However, the API has a query limit (only 500 queries are permitted over a 24 hour period). I am currently managing this through a counter in a loop, which resets for each "chunk" of 500 elements and would pause the loop for a day. Is there a better way to do this?
counter = 0
for query in queries:
if counter < 500:
counter = counter + 1
api = ApiClient(api_key='secretkey')
data = api.get(q=query)
print(data)
safequery = ''.join(e for e in query if e.isalnum())
datafilename = "{} {}.txt".format(safequery,todaysdate)
with open(datafilename, 'w') as outfile:
json.dump(data, outfile)
else:
print('sleepy time')
time.sleep(86400)
counter = 0
time.sleep(86400) is asking for problems, and also makes your CPU work for nothing. If something happens during those 86400 seconds and the script crashes, nothing will restart it.
The much better option would be to save the current page/chunk somewhere (raw text file, json, DB, doesn't really matter), then load it before making the next requests.
Then you can put your script in an Operating System level/managed task scheduler (for example, cron for Unix or Task Scheduler for Windows) and run it daily.
time.sleep() is a good solution, but you can also make Python ask for input when you want to continue. That's primitive, I know.
if counter % 500 == 0: # make the counter start at 1
val = input("\nContinue? [y/n]: ")
if val == 'y':
pass # manually unpause the looping, whenever you want
elif val == 'n':
break # interrupt for loop
I would tackle this by creating a script that when ran will get the next 500 and then terminate. You might want to output a text file to store where you are up to in this sequence.
I would then schedule this script to run every 24 hours with windows task scheduler (on windows)
This means you are not having a process running doing nothing.
sleep()
should only be used for small time intervals.
I think you could make this code as a python script and execute in a batch file.
catch this batch file and schedule into a task manager to run every day at 2:00 pm for example...
usually i have a python script server that runs my robots and things that i need to do automatically.
An if else statement with a sleep is probably as simple as it gets; however it's not efficient since the process will still be alive and doing nothing for 86400 seconds.
You could look into creating a cron job to run your code one a day at the same time
I have been given a python script which allows me to mute the volume of my mac at a time I set so that any podcasts I'm listening to as I fall asleep won't wake me up once I am asleep.
However, it will only act once the time given happens on that day, therefore if I try to activate it before midnight, it will mute the laptop immediately, which is not ideal because if I want to use it I have to wait for midnight to pass before I go to sleep.
#!/usr/bin/env python3
import datetime as dt
import osascript
import sys
from threading import Timer
def do_the_biz():
osascript.osascript("set volume output volume 0")
print("Night night")
today = dt.datetime.now()
dateString = today.strftime('%d-%m-%Y') + " " + sys.argv[1]
newDate = today.strptime(dateString,'%d-%m-%Y %H:%M')
delay = (newDate - dt.datetime.now()).total_seconds()
Timer(delay,do_the_biz,()).start()
So, a typical execution of this script looks like this:
$./sleep.py 04:00
and the command line will return the following once it has reached 4am, and then close the program:
Night Night
What I would like is to be able to manipulate the date so that the script will operate at the next available time of, for example, 4am - so it would essentially operate almost in the exact same way an alarm would. For this I could run an entirely different script of sleep.tomorrow.
However, in an ideal world, I would like to be able to:
have the option to have another argument where I specify today or tomorrow and the program acts accordingly;
be able to cancel the process without having to close the terminal.
I am new to python and have been having a hard time understanding the differences between the various datetime functions and the documention hasn't helped, so a brief explanation and comparison between what they input and output and how they interact would be gratefully appreciated.
I want a python program that listens to USB ports and after connecting save USB path to a file:
import string
from ctypes import windll
import time
import os
def get_drives():
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
return drives
if __name__ == '__main__':
before = set(get_drives())
print ('Please wait...')
time.sleep(5)
after = set(get_drives())
drives = after - before
delta = len(drives)
if (delta):
for drive in drives:
if os.system("cd " + drive + ":") == 0:
newly_mounted = drive
print "There were %d drives added: %s. Newly mounted drive letter is %s" % (delta, drives, newly_mounted)
f = open( 'path.txt', 'w' )
f.write(newly_mounted)
f.close()
else:
print "Sorry, I couldn't find any newly mounted drives."
and after that in main file call it to:
import os
import time
while True:
os.system("python test.py")
time.sleep(1)
but it's not working correctly and when i connect USB sometimes it work and sometimes. is there any way to improve it?
There are some problems with your implementation:
Your 'main' file calling test.py invokes it once a second, but test.py waits five seconds between before and after. I can't remember if the python system call blocks the caller - so either a) if it doesn't block then test.py is being invoked again while it is still waiting to get the after, or b) if it does block then there is a one second delay in the 'main' where changes are never seen. Fix: #2 below fixes this by not having separate programs.
Because test.py determines before, waits five seconds, then determines after, THEN quits, a usb drive change could happen between a quit and a start and wouldn't be reported as a change by test.py. You need to make test.py never exit - it should set before when it starts, then check every five seconds and if after is different then update before with the new value of after, and go back to wait another five seconds. Fix: test.py should never exit - it should be 'main', or run forever in a thread.
If a device is plugged in just after before has been determined, then removed before after is determined, i.e. within up to five seconds, this is never reported by test.py. Fix: may not matter, and if using polling then you have to delay some time between checks. Only real solution is to not use polling but to hook into OS event notification of drive changes, which would also be the most robust implementation...
Anyway, assuming polling is best solution your code in test.py should look something like this (note test.py never exits otherwise you could miss a change):
before = set(get_drives())
while true:
time.sleep(5)
after = set(get_drives())
drives = after - before
delta = len(drives)
if (delta):
# ...process delta
...
# finally, after becomes the new before WITHOUT re-reading the drives, that will happen again in five seconds...
before = after
Hi i made this app using python refer drive-monitoring its a Event Based Approach to create reports about the Removable Drive History and file system events in drives.
I am trying to have my code detect when a flashdrive is plugged in and then continue the code. I am currently using "os.path.exists". When I start the code with the flashdrive plugged in, the code functions fine, however, if I start when the flashdrive is unplugged, and attempt to plug it in while the code is running, the code never checks to see if the flashdrive is plugged in and keeps forcing the code to sleep. How can I get the code to work?
import os
import sys
import datetime
from datetime import datetime
import shutil
import time
#Wait for FlashDrive to be connected
if os.path.exists("F:\"):
connected = 1
else:
connected = 0
while connected == 0:
print "..."
time.sleep(10)
#Get current date
currentdate=datetime.now().strftime("%m-%d-%Y")
print "Photos saved: " + currentdate
#Copy and rename DCIM
src = "F:/Pictures"
dst = "C:/Users/Josh/Desktop/photos/" + currentdate
shutil.copytree(src, dst)
The code is supposed to be a loop and execute every time an iPhone connects and never stop running, but I cannot get the code to work if it does not really check for the flashdrive.
Cycle with some arbitrary sleeps isn't a good idea (at all). It makes your program less responsive to the event, because it will take at least N ms to catch an event fired at the start of the iteration*. Also it wastes CPU due to a large amount of API calls.
Create a window.
Listen to WM_DEVICECHANGE message in your message loop. It will fire every time your device configuration changed, but won't tell you, how.
On such event, ask for current configuration.
You can find a tutorial here. Also, take a look at the similar answer on SO.
(*) Actually sleep will test on each next system tick if time_passed >= sleep_timeout. If so, it will return to the program. Problem is that system tick could be 1/18 of second on an old PC (56 ms), so you'll never have 10 ms delay.
Your problem is htat you set the connected variable outside the loop so it's never updated.
Try:
while not os.path.exists('F:\'):
print("...")
time.sleep(10)
--edit---
Then, wait for it to be removed at the end:
while os.path.exists('F:\'):
print("...")
time.sleep(10)
And, finally, wrap the entire thing in a big while True: so that the whole program repeats.
(Again, I do agree this is a 'hackish' and inefficent way to do this task)