Reputation: 39
Is there a better way to create a alarm clock in python than the one I'm using in my code? It is working fine but I wonder if there is something better , also I want to separate this code and make it in to a cog....
import asyncio
from datetime import datetime
from discord.ext import commands
TOKEN = 'XXX'
client = commands.Bot(command_prefix='.')
alarm_time = '23:33'#24hrs
channel_id = '51599XXXXX5036697'
@client.event
async def on_ready():
print('Bot Online.')
async def time_check():
await client.wait_until_ready()
while not client.is_closed:
now = datetime.strftime(datetime.now(), '%H:%M')
channel = client.get_channel(channel_id)
messages = ('Test')
if now == alarm_time:
await client.send_message(channel, messages)
time = 90
else:
time = 1
await asyncio.sleep(time)
client.loop.create_task(time_check())
client.run(TOKEN)
Upvotes: 1
Views: 16397
Reputation: 98
What you could do is use the sched
, for example:
import time
import sched
s = sched.scheduler(time.perf_counter, time.sleep)
s.enter(60, 1, action_function, (args))
s.run()
The code above starts a scheduler as s
, which uses time.perf_couter
to get the current time, and time.sleep
for doing the delay.
When you use the scheduler you need to pass it at least 3 arguments, the first being the daly time in seconds, the second being it's priority (scheduled events with the highest prioroty are executed first, and the third argument is the function to be executed after the delay.
There can be two more optional arguments being a tuple of arguments, or a dict of keyword arguments, both of these arguments will get passed to the function that will be executed after the delay.
I have used this same library for implementing things such as timed bans within IRC bots, so it should also be applicable to your Discord bot.
Here is an example that should work (I don't use discord and such so don't can't really test the whole code, just snippets) using your code:
import asyncio
from datetime import datetime, timedelta
from discord.ext import commands
import time
import sched
TOKEN = 'XXX'
client = commands.Bot(command_prefix='.')
alarm_time = '23:33'#24hrs
channel_id = '51599XXXXX5036697'
@client.event
async def on_ready():
print('Bot Online.')
async def time_check():
await client.wait_until_ready()
while not client.is_closed:
channel = client.get_channel(channel_id)
messages = ('Test')
f = '%H:%M'
now = datetime.strftime(datetime.now(), f)
# get the difference between the alarm time and now
diff = (datetime.strptime(alarm_time, f) - datetime.strptime(now, f)).total_seconds()
# create a scheduler
s = sched.scheduler(time.perf_counter, time.sleep)
# arguments being passed to the function being called in s.enter
args = (client.send_message(channel, message), )
# enter the command and arguments into the scheduler
s.enter(seconds, 1, client.loop.create_task, args)
s.run() # run the scheduler, will block the event loop
client.loop.create_task(time_check())
client.run(TOKEN)
Upvotes: 3