Is it possible to automatically check time then execute certain codes?
timer = os.date('%H:%M:%S', os.time() - 13 * 60 * 60 )
if timer == "18:04:40" then
print("hello")
end
I am trying to print hello on "18:04:40" everyday (os.date's time) without setting up a timer (which counts how much time past since the program's initiation) as I can't run the program 24 hours non-stop...
Thanks for reading.
This may not be the best solution but, when using a library like love2d for example you could run something like this:
function love.update(dt)
timer = os.date('%H:%M:%S', os.time() - 13 * 60 * 60 )
if timer >= value then
--stuff here
end
end
Or if you wanna make it so you have a whole number something like
tick = 0
function love.update(dt)
tick = tick + dt
if tick > 1 then
timer = os.date('%H:%M:%S', os.time() - 13 * 60 * 60 )
if timer >= value then
--stuff here
end
end
end
Lua has to check the time in some way.
Without a loop that can be realized with debug.sethook().
Example with Lua 5.1 typed in an interactive Lua (lua -i)...
> print(_VERSION)
Lua 5.1
> debug.sethook() -- This clears a defined hook
> -- Next set up a hook function that fires on 'line' events
> debug.sethook(function() local hour, min, sec = 23, 59, 59 print(os.date('%H:%M:%S', os.time({year = 2021, month = 12, day = 11, hour = hour, min = min, sec = sec}))) end, 'l')
-- just hit return/enter or do other things
23:59:59
5.9 - The Debug Library
https://www.lua.org/manual/5.1/manual.html#5.9
Related
Using Micropython for the ESP32 microcontroller, flashed with the latest firmware at time of writing (v1.18)
I'm making an alarm (sort-of) system where I get multiple time values ("13:15" for example) from my website, and then I have to ring an alarm bell at those times.
I've done the website and I can do the ring stuff, but I don't know how to actually create time objects from the previously mentioned strings ("13:15"), and then check if any of the times inputted match the current time, the date is irrelevant.
From reading the documentation, im getting the sense that this cant be done, since ive looked through the micropython module github, and you apparently cant get datetime in micropython, and i know that in regular python my problem can be solved with datetime.
import ntptime
import time
import network
# Set esp as a wifi station
station = network.WLAN(network.STA_IF)
# Activate wifi station
station.active(True)
# Connect to wifi ap
station.connect(ssid,passwd)
while station.isconnected() == False:
print('.')
time.sleep(1)
print(station.ifconfig())
try:
print("Local time before synchronization: %s" %str(time.localtime()))
ntptime.settime()
print("Local time after synchronization: %s" %str(time.localtime()))
except:
print("Error syncing time, exiting...")
this is the shortened code from my project, with only the time parts, now comes into play the time comparison thing I don't know how to do.
Using ntptime to get time from server. I use "time.google.com", to get the time. Then, I transform it into seconds (st) to be more accurate. And set my targets hour in seconds 1 hour = 3600 s.
import utime
import ntptime
def server_time():
try:
# Ask to time.google.com server the current time.
ntptime.host = "time.google.com"
ntptime.settime()
t = time.localtime()
# print(t)
# transform tuple time 't' to seconds value. 1 hour =
st = t[3]*3600 + t[4]*60 + t[5]
return st
except:
# print('no time')
st = -1
return st
while True:
# Returns an increasing millisecond counter since the Board reset.
now = utime.ticks_ms()
# Check current time every 5000 ms (5s) without going to sleep or stop any other process.
if now >= period + 5000:
period += 5000
# call your servertime function
st = server_time()
if ((st > 0) and (st < 39600)) or (st > 82800): # Turn On 17:00 Mexico Time.
# something will be On between 17:00 - 06:00
elif ((st <82800) and (st > 39600)): # Turn Off 6:00.
# something will be Off between 06:00 - 17:00
else:
pass
After running ntptime.settime() you can do the following to retrieve the time, keep in mind this is in UTC:
rtc = machine.RTC()
hour = rtc.datetime()[4] if (rtc.datetime()[4]) > 9 else "0%s" % rtc.datetime()[4]
minute = rtc.datetime()[5] if rtc.datetime()[5] > 9 else "0%s" % rtc.datetime()[5]
The if else statement makes sure that numbers lower or equal to 9 are padded with a zero.
Is there a way to delay or offset a scheduled command from the proposed frequency options?
e.g:
$schedule->command('GetX')->everyTenMinutes(); --> run at 9:10, 9:20, 9:30
$schedule->command('GetY')->everyTenMinutes(); --> run at 9:15, 9:25, 9:35
There are no delay function when scheduling tasks.
But when method can be used to schedule a task every 10 minutes, delay 5 minutes:
// this command is scheduled to run if minute is 05, 15, 25, 35, 45, 55
// the truth test is checked every minute
$schedule->command('foo:bar')->everyMinute()->when(function () {
return date('m') - 5 % 10 == 0;
});
Follow this rule, you can schedule a task every x minutes, delay y minutes
$schedule->command('foo:bar')->everyMinute()->when(function () {
return date('m') - y % x == 0;
});
If it gets difficult, the direct way you can simply write a custom Cron schedule. It is the easier way to understand without getting headache when you read the code later.
$schedule->command('foo:bar')->cron('05,15,25,35,45,55 * * * *');
There is the following task: I need to get minutes between one time and another one: for example, between "8:15" and "7:45". I have the following code:
(Time.parse("8:15") - Time.parse("7:45")).minute
But I get result as "108000.0 seconds".
How can I fix it?
The result you get back is a float of the number of seconds not a Time object. So to get the number of minutes and seconds between the two times:
require 'time'
t1 = Time.parse("8:15")
t2 = Time.parse("7:45")
total_seconds = (t1 - t2) # => 1800.0
minutes = (total_seconds / 60).floor # => 30
seconds = total_seconds.to_i % 60 # => 0
puts "difference is #{minutes} minute(s) and #{seconds} second(s)"
Using floor and modulus (%) allows you to split up the minutes and seconds so it's more human readable, rather than having '6.57 minutes'
You can avoid weird time parsing gotchas (Daylight Saving, running the code around midnight) by simply doing some math on the hours and minutes instead of parsing them into Time objects. Something along these lines (I'd verify the math with tests):
one = "8:15"
two = "7:45"
h1, m1 = one.split(":").map(&:to_i)
h2, m2 = two.split(":").map(&:to_i)
puts (h1 - h2) * 60 + m1 - m2
If you do want to take Daylight Saving into account (e.g. you sometimes want an extra hour added or subtracted depending on today's date) then you will need to involve Time, of course.
Time subtraction returns the value in seconds. So divide by 60 to get the answer in minutes:
=> (Time.parse("8:15") - Time.parse("7:45")) / 60
#> 30.0
I want to trigger a notification for all my users at a specific time in their time zone. I want to compute the delay the server should wait before firing the notification. I can compute the time at the users Time Zone using Time.now.in_time_zone(person.time_zone)
I can strip out the hours, minutes and seconds from that time and find out the seconds remaining to the specific time. However, I was wondering if there's a more elegant method where I could set 9:00 AM on today and tomorrow in a timezone and compare it with Time.now.in_time_zone(person.time_zone) and just find out the number of seconds using arithmetic operations in the ruby Time Class.
Or in short my question is: (was: before the downvote!)
How do I compute the number of seconds to the next 9:00 AM in New York?
What about this
next9am = Time.now.in_time_zone(person.time_zone).seconds_until_end_of_day + 3600 * 9
next9am -= 24 * 60 * 60 if Time.now.in_time_zone(person.time_zone).hour < 9
NOTIFICATION_HOUR = 9
local_time = Time.now.in_time_zone(person.time_zone)
desired_time = local_time.hour >= NOTIFICATION_HOUR ? local_time + 1.day : local_time
desired_time = Time.new(desired_time.year, desired_time.month, desired_time.day, NOTIFICATION_HOUR, 0, 0, desired_time.utc_offset)
return desired_time - local_time
I am trying to have a check fire off every second for 30 seconds. I haven't found a clear way to do this with Ruby yet. Trying something like this currently:
until counter == 30
sleep 1
if condition
do something
break
else
counter +=1
end
Problem with something like that is it has to use sleep, which stops the thread in its tracks for a full second. Is there another way to achieve something similar to the above without the use of sleep? Is there a way to have something cycle though on a time based interval?
You can approximate what you're looking for with something along these lines:
now = Time.now
counter = 1
loop do
if Time.now < now + counter
next
else
puts "counting another second ..."
end
counter += 1
break if counter > 30
end
You could do something simple like..
max_runtime = 10.seconds.from_now
puts 'whatever' until Time.now > max_runtime
you can try this it allows for interval controls
counter == 30
interval = 5 # Check every 5 seconds
interval_timer = 1 # must start at 1
now = Time.now
while Time.now - now < counter
if interval_timer % interval == 0 #Every 5 attempts the activity will process
if condition
stuff
end
end
process_timer = process_timer + 1
end
This will happen under a guaranteed 30 seconds the interval can be set to any value 1 or greater. Some things process via milliseconds this will give you an option that will save you cycles on processing. Works well in graphics processing.