-1day when calculating time difference. python - python

I'm trying to create an uptime command for the bot e.g "the bot has been online for 10 hours 15 minutes 10 seconds"
It works the way as indented up until it hits 12am, I think it might be to do with the calculation but I'm unsure on why it would add -1day when its formatted in hours minutes seconds.
This is what I have at the moment. Any help would be appreciated :)
from datetime import datetime
import os
import time
folder = r"C:\Users\Ryan Mclaughlin\PycharmProjects\Snappingbot-V2\SnappingbotV2\text files"
filename = "uptime.txt"
fp = os.path.join(folder, filename)
with open(fp, "w") as f:
f.writelines(datetime.now().time().strftime('%H:%M:%S')) # on startup of bot write the time in a file
file = open(fp)
startup_time = (file.readline()) # reads the startup time
print(startup_time)
time.sleep(10)
time_now = datetime.now().time().strftime('%H:%M:%S') # finds time now
print(time_now)
FMT = '%H:%M:%S'
tdelta = datetime.strptime(time_now, FMT) - datetime.strptime(startup_time,FMT) # calculates the difference between the startup time and now
print(tdelta)

Related

Strange failure while logging CPU-Temp with Python to a .csv-File (Rasbperri-Pi)

i Try to set up my Raspberry pi with a fan. It should log the Temperature every 5 minutes and write it to a .csv-file with a Python Script. If the Temperature is hotter than 52 Degrees Celsius, it shoud turn on a USB-Hub, and turn it of if it is below that value. For now, i created a little website, to see my logged data. And here is my question: as you can see in the screenshot, it tells me sometimes [HOT] and sometimes [OK] for the same Values? Also it is not sepperating the Data like a want it to seperate (over/under 52 Degrees Celsius).
Screenshot from my little website (This only displays my .csv-File)
My .py-code:
from gpiozero import CPUTemperature
from time import sleep, strftime, time
from datetime import datetime, timedelta
from threading import Timer
import matplotlib.pyplot as plt
v=datetime.today()
w = v.replace(day=v.day, hour=1, minute=0, second=0, microsecond=0) + timedelta(days=1)
delta_t=w-v
secs=delta_t.total_seconds()
cpu = CPUTemperature()
plt.ion()
x = []
y = []
def write_tempHot(temp):
with open("/var/www/html/cpuTemp.csv", "a") as log:
log.write("{0}{1}\n".format(strftime("%Y-%m-%d %H:%M:%S = [HOT] "),str(temp)))
def write_tempLow(temp):
with open("/var/www/html/cpuTemp.csv", "a") as log:
log.write("{0}{1}\n".format(strftime("%Y-%m-%d %H:%M:%S = [OK] "),str(temp)))
def clearTemp():
filename = "/var/www/html/cpuTemp.csv"
# opening the file with w+ mode truncates the file
f = open(filename, "w+")
f.close()
while True:
temp = cpu.temperature
if temp > 52:
temp = cpu.temperature
write_tempHot(temp)
plt.pause(300)
t = Timer(secs, clearTemp)
t.start()
else:
temp = cpu.temperature
write_tempLow(temp)
plt.pause(300)
t = Timer(secs, clearTemp)
t.start()
(Also dont mind for the clearTemp()-function, i want to clear the .csv-file once a day)
Does anybody have n idea, why the results are that kind of strange?
Greetings & Thanks a lot!
Your comparison is
if temp > 52
when it should be
if temp >= 52.0
because otherwise your temperature Hi will only match if it is 53C or above.
I'd also use time.sleep() instead of plt.pause().
For your logfile, you've got two functions to write to your logfile, I'd use one instead:
def write_log(temp):
fmt = """{when} = [{option}] {temp}"""
datefmt = """%Y-%m-%d %H:%M:%S"""
option = "OK"
with open("/var/www/html/cpuTemp.csv", "a") as log:
when = datetime.now().strftime(datefmt)
if temp >= 52.0:
option = "HOT"
log.write(fmt.format(when=when, option=option, temp=temp))
Finally, I do not understand why you want to truncate your logfile every 5 minutes.

How can I make my Python script run after 2 hours?

I wrote a program that will close the hard drive with BitLocker in Windows by using libraries datetime and subprocess but I cannot get the correct result.
Here is my code:
import subprocess
import datetime
now = datetime.datetime.today()
delta = datetime.timedelta(hours=2)
time_delta = now + delta
# print(time_delta)
# print(now)
try:
if now == time_delta:
close = subprocess.check_output(['manage-bde', '-lock', 'D:', '-ForceDismount'])
close.decode('utf-8').split('\n')
print('done')
except Exception:
pass
That is because you are checking the current time now = datetime.datetime.today(), then add 2 hours to it and immediately after check, if time_delta is equal to now.
Thus the if statement always results in false and the code in it does not get executed.
You need to put something in place to wait. Something like that.
import subprocess
import datetime
import time
now = datetime.datetime.today()
delta = datetime.timedelta(hours=2)
time_delta = now + delta
while now != time_delta:
time.sleep(1) # wait for a second
now = datetime.datetime.today()
# when now == time_delta we continue here:
try:
close = subprocess.check_output(['manage-bde', '-lock', 'D:', '-ForceDismount'])
close.decode('utf-8').split('\n')
print('done')
except Exception:
pass
This is not the best way to schedule a task, but it should be working.

How to compare ctime properly?

I have a program that gets the modified date/time of directories and files. I then want to get the date/time from 30 seconds ago and compare that to the modified date/time.
If the modified time is less than 30 seconds ago, I want to trigger an alert. My code is triggering alert even if the modified time occurred more than 30 seconds ago.
Is there a way I can only trigger an alert if the modification occurred less than 30 seconds ago?
import os.path
import time, stat
import sys
share_dir = 'C:/mydir'
source_dir = r'' + share_dir + '/'
def trigger():
print("Triggered")
def check_dir():
while True:
for currentdir, dirs, files in os.walk(source_dir):
for file in files:
currentfile = os.path.join(currentdir, file)
# get modified time for files
ftime = os.stat(currentfile )[stat.ST_MTIME]
past = time.time() - 30 # last 30 seconds
if time.ctime(ftime) >= time.ctime(past):
print(time.ctime(ftime) + " > " + time.ctime(past))
print("Found modification in last 30 seconds for file =>", currentfile, time.ctime(ftime))
trigger()
sys.exit()
else:
print('No recent modifications.' + currentfile)
for folder in dirs:
currentfolder = os.path.join(currentdir, folder)
# get modified time for directories
dtime = os.stat(currentfolder)[stat.ST_MTIME]
past = time.time() - 30 # last 30 seconds
if time.ctime(dtime) >= time.ctime(past):
print(time.ctime(dtime) + " > " + time.ctime(past))
print("Found modification in last 30 seconds for folder =>", currentfolder, time.ctime(dtime))
trigger()
sys.exit()
else:
print('No recent modifications: ' + currentfolder)
time.sleep(4)
if __name__ == "__main__":
check_dir()
I'm doing this on a large scale file system. I personally use SQLite3 and round the mtime of the file (I had weird things happen using any other sort of operation and it was more consistent).
I'm also unsure why you're not just doing a pure math solution. Take the current time, take the mtime of the file, find the difference between them and if it's less than or equal to thirty, you get a hit.
I redid some of the code. I recommend trying this:
import os.path
import time, stat
import sys
def trigger():
print("Triggered")
def check_dir(source_dir):
for currentdir, dirs, files in os.walk(source_dir):
for file in files:
currentfile = os.path.join(currentdir, file)
# get modified time for files
ftime = os.path.getmtime(currentfile)
if time.time() - ftime <= 30:
print("Found modification in last 30 seconds for file =>", currentfile, time.ctime(ftime))
trigger()
exit(0)
else:
print('No recent modifications.' + currentfile)
for folder in dirs:
currentfolder = os.path.join(currentdir, folder)
# get modified time for directories
dtime = os.stat(currentfolder)[stat.ST_MTIME]
if time.time() - dtime <= 30:
print("Found modification in last 30 seconds for folder =>", currentfolder, time.ctime(dtime))
trigger()
exit(0)
else:
print('No recent modifications: ' + currentfolder)
if __name__ == "__main__":
check_dir('yourdirectoryhere')
Did some light testing on my own system and it seemed to work perfectly. Might want to add back the while loop but it should work.

Python - Alarm clock with multiple alarms

I'm trying to create an alarm clock with multiple alarms, which are set from a text file with a specific time each line, but at the moment it's only working if I set only one time. What am I doing wrong? Here is the code I have right now:
import time
from playsound import playsound
Time = time.strftime('%H:%M')
with open('alarms.txt') as f:
alarms = f.readlines()
for alarm in alarms:
while Time != alarm:
print('The time is: ' + Time)
Time = time.strftime('%H:%M')
time.sleep(1)
continue
if Time == alarm:
playsound('alarm.mp3')
And my alarms.txt is setup like HH:MM:
18:45
18:55
From the information given so far, my thought is this:
Remember that readlines() reads in lines and returns strings with the newline character still trailing.
You need to compare the Time to the lines with the newline character removed.
import time
from playsound import playsound
Time = time.strftime('%H:%M')
with open('alarms.txt') as f:
alarms = f.readlines()
for alarm in alarms:
alarm = alarm.rstrip('\n')
while Time != alarm:
print('The time is: ' + Time + '\n')
Time = time.strftime('%H:%M')
time.sleep(1)
continue
if Time == alarm:
playsound('alarm.mp3')
This also assumes, of course, that the times in the text file are in the desired chronological order.

Why do only the first three lines come up in my .txt file -?! Raspberry Pi - temperature humidity readings

I am a completely inexperienced A level student trying to get to grips with python to complete an assignment. I have been given a week to complete it - I have very little knowledge of what to do and have no experience with coding - I am truly stuck and will probably seem very stupid to people on his forum.
I have to create a temperature and humidity logger with a raspberry pi and DHT22 sensor. I am to write a script that produces a loop that sleeps for 10 seconds - I will run the script for two days to collect enough data to produce graphs. So far the code I have is this and it's not working - probably for some obvious reasons. The data needs to come out in two columns in a leafpad file. Nothing seems to be happening when I sudo python execute the script - no .txt file has been created in my ls (there is one with just this in it:
indoors
51.58778
-0.15944
But no error message in the LX terminal.. Am I doing something very obviously wrong?
# Assign header details to STRING variables - change manually
txt_studentid = '999'
txt_pi_location = 'indoors'
txt_pi_latitude = '51.58778'
txt_pi_longitude = '-0.15944'
import Adafruit_DHT
pin = 4
sensor = Adafruit_DHT.DHT22
# Import Time module import time
# open file to write
f = open('/home/pi/my_data.txt','w')
f.write(txt_studentid)
f.write('\n')
f.write(txt_pi_location)
f.write('\n')
f.write(txt_pi_latitude)
f.write('\n')
f.write(txt_pi_longitude)
f.write('\n')
f.close()
while True:
# store off the date and time details for this
sample num_month = time.localtime().tm_mon
num_day = time.localtime().tm_mday
num_hour = time.localtime().tm_hour
num_min = time.localtime().tm_min
num_sec = time.localtime().tm_sec
num_humidity, num_temperature = Adafruit_DHT.read_retry(sensor, pin)
txt_month = str(num_month)
txt_day = str(num_day)
txt_hour = str(num_hour)
txt_min = str(num_min)
txt_sec = str(num_sec)
txt_humidity = str(num_humidity)
txt_temperature = str(num_temperature)
f = open('/home/pi/my_data.txt','a')
f.write(txt_month)
f.write(',')
f.write(txt_day)
f.write(',')
f.write(txt_hour)
f.write(',')
f.write(txt_min)
f.write(',')
f.write(txt_sec)
f.write(',')
# write the temperature and humidity to file
f,write(txt_humidity)
f.write(',')
f,write(txt_temperature)
f.write(',')
# write new line
f.write('\n')
# close the file
f.close()
# wait for ten seconds
time.sleep(10)
You definitely want to at least include the file writing in the while loop; or keep track somehow of the readings for later saving.
I've modified your code to help you get started:
import Adafruit_DHT
import time
from datetime import datetime
pin = 4
sensor = Adafruit_DHT.DHT22
# Import Time module import time
# open file to write
f = open('/home/pi/my_data.txt','w')
f.write(txt_studentid)
f.write('\n')
f.write(txt_pi_location)
f.write('\n')
f.write(txt_pi_latitude)
f.write('\n')
f.write(txt_pi_longitude)
f.write('\n')
f.close()
f = open('/home/pi/my_data.txt','a')
begintime = datetime.now()
while True:
# store off the date and time details for this
sample_time = datetime.now()
sample num_month = time.localtime().tm_mon
num_day = time.localtime().tm_mday
num_hour = time.localtime().tm_hour
num_min = time.localtime().tm_min
num_sec = time.localtime().tm_sec
num_humidity, num_temperature = Adafruit_DHT.read_retry(sensor, pin)
txt_month = str(num_month)
txt_day = str(num_day)
txt_hour = str(num_hour)
txt_min = str(num_min)
txt_sec = str(num_sec)
txt_humidity = str(num_humidity)
txt_temperature = str(num_temperature)
f.write(txt_month)
f.write(',')
f.write(txt_day)
f.write(',')
f.write(txt_hour)
f.write(',')
f.write(txt_humidity)
f.write(',')
f.write(num_temperature)
f.write('\n')
time.sleep(10) #sleep for 10 seconds
timedelta = sample_time - begintime
if timedelta.days >= 2:
break
f.close()
I would try setting the timedelta requirement to something like 30 seconds to make sure it works as expected before going up to 2 days. You can do that by changing if timedelta.days >= 2: to if timedelta.seconds >= 30:
I guess you indentation is wrong. You'll get stuck in the while loop and will never write anything to the file. Try indenting everything from num_month = time.localtime().tm_mon to time.sleep(10)

Categories

Resources