WEBVTT captioned by sachac
NOTE Introduction
00:00:02.679 --> 00:00:06.782
Welcome to Watering My Digital Plant with Emacs Timers,
00:00:07.503 --> 00:00:11.384
a talk by Christopher Howard for Emacs Conference 2024.
00:00:11.385 --> 00:00:16.989
The goal of this talk is to give
00:00:17.010 --> 00:00:19.431
a brief introduction to Emacs timers
00:00:20.892 --> 00:00:23.334
using the illustration of how I created
00:00:23.394 --> 00:00:25.676
a bot for the Astrobotany service.
NOTE What is Astrobotany?
00:00:28.823 --> 00:00:30.004
What is Astrobotany?
00:00:30.924 --> 00:00:32.384
Let me jump to the home page.
00:00:38.649 --> 00:00:42.411
Astrobotany is a botany game or a simulation
00:00:42.611 --> 00:00:45.072
that is played using the Gemini protocol
00:00:45.893 --> 00:00:47.234
and gemtext documents.
NOTE What is Gemini?
00:00:48.914 --> 00:00:49.615
What is Gemini?
00:00:50.700 --> 00:00:53.563
The Gemini protocol is a small web protocol,
00:00:54.263 --> 00:00:57.246
similar to the HyperText Transfer Protocol,
00:00:58.047 --> 00:01:00.109
but with differing goals of simplicity,
00:01:00.789 --> 00:01:03.712
non-extensibility, and protecting privacy.
00:01:05.453 --> 00:01:09.057
Gemtext is a simple hyperlinking document format,
00:01:09.557 --> 00:01:14.242
the analog of the HyperText Markup Language, or HTML.
00:01:16.095 --> 00:01:17.075
Much more could be said
00:01:17.135 --> 00:01:18.516
about the design and goals
00:01:18.576 --> 00:01:19.756
of the Gemini project,
00:01:20.236 --> 00:01:22.096
but that is not the focus of this talk.
NOTE How do you play Astrobotany?
00:01:25.337 --> 00:01:27.057
And how do you play Astrobotany?
00:01:28.418 --> 00:01:30.518
First, you need to get a Gemini client
00:01:31.138 --> 00:01:32.838
or what you might call a browser.
00:01:34.079 --> 00:01:35.599
Many clients are available,
00:01:36.259 --> 00:01:39.860
but I am using Elpher, a Gemini client for Emacs.
00:01:41.340 --> 00:01:43.161
Once you have your client running,
00:01:43.801 --> 00:01:46.361
navigate to the home page for Astrobotany,
00:01:46.782 --> 00:01:48.842
which is shown in this window.
00:01:50.783 --> 00:01:53.023
You'll see the URL for the home page
00:01:53.103 --> 00:01:54.704
displayed at the top of the window.
00:01:57.865 --> 00:01:59.625
On your first visit to Astrobotany,
00:02:00.406 --> 00:02:02.586
you will need to create a client certificate,
00:02:03.426 --> 00:02:05.507
which will be used instead of a password.
00:02:06.067 --> 00:02:07.548
Your Gemini client will help you
00:02:07.588 --> 00:02:08.768
to create the certificate.
00:02:12.102 --> 00:02:16.306
Then you will go to the Visit Your Plant page
00:02:22.472 --> 00:02:24.553
in order to view your plant,
00:02:28.297 --> 00:02:32.781
to water it, and to collect things from it,
00:02:33.141 --> 00:02:37.928
including money. So here you see
00:02:37.968 --> 00:02:39.429
the plant that I'm currently growing
00:02:40.229 --> 00:02:41.910
in glorious ASCII graphics.
00:02:43.070 --> 00:02:46.691
There's also a color version available from this page.
00:02:56.895 --> 00:02:57.935
Back at the home page,
00:02:59.536 --> 00:03:00.836
you can do other things
00:03:02.537 --> 00:03:05.358
like go to the item shop,
00:03:07.165 --> 00:03:10.247
to buy items like badges, fertilizer,
00:03:11.607 --> 00:03:13.348
or post on the message board.
00:03:15.849 --> 00:03:18.991
In Astrobotany, gardener bots are fully legal.
00:03:20.852 --> 00:03:23.153
And to do an action on your plant,
00:03:23.693 --> 00:03:24.814
like watering the plant,
00:03:25.454 --> 00:03:26.915
all your bot needs to do is
00:03:27.035 --> 00:03:30.917
to access the appropriate Gemini URL or page
00:03:31.537 --> 00:03:33.998
while presenting the appropriate certificate
00:03:34.419 --> 00:03:34.999
for your plant.
NOTE Timers
00:03:37.000 --> 00:03:39.862
And this brings us to Emacs timers.
00:03:42.904 --> 00:03:45.906
So the main function of interest to us
00:03:46.626 --> 00:03:49.288
is the run-at-time function.
00:04:00.714 --> 00:04:03.235
Here is the help documentation,
00:04:03.395 --> 00:04:07.036
which is available in any recent Emacs installation.
00:04:10.157 --> 00:04:13.277
As you see, the purpose of the function
00:04:13.498 --> 00:04:16.718
is to perform an action at a specific time
00:04:20.920 --> 00:04:25.801
to repeat it after a specific number of seconds.
00:04:29.770 --> 00:04:32.573
And so basically, all you have to do is
00:04:32.673 --> 00:04:35.795
pass in a function to run-at-time,
00:04:36.436 --> 00:04:39.058
telling Emacs how soon you want to run the function,
00:04:39.999 --> 00:04:41.541
and then how often you want to run the
00:04:41.581 --> 00:04:42.461
function after that.
00:04:44.403 --> 00:04:46.605
The function has a variety of options for
00:04:46.645 --> 00:04:48.887
specifying the time parameter,
00:04:49.347 --> 00:04:52.030
that is, how soon you want the function to run.
00:04:55.307 --> 00:04:57.428
For our application, in which we'll be
00:04:57.508 --> 00:04:58.409
running our functions
00:04:58.649 --> 00:05:01.030
once or twice a day at specific times,
00:05:03.152 --> 00:05:04.513
it is most useful to
00:05:04.553 --> 00:05:06.954
specify the number of seconds until the event.
00:05:08.515 --> 00:05:09.876
This does, however, require
00:05:10.436 --> 00:05:11.977
calculating the number of seconds
00:05:12.097 --> 00:05:15.399
until a specific time of day. I will
00:05:15.419 --> 00:05:16.800
provide code for this shortly.
00:05:18.860 --> 00:05:20.803
The run-at-time function does allow you to
00:05:20.864 --> 00:05:23.308
specify the time parameter as a string,
00:05:24.029 --> 00:05:25.672
representing the hours and minutes.
00:05:26.413 --> 00:05:32.149
For example, 05:40.
00:05:32.150 --> 00:05:34.051
However, there is an oddity in the
00:05:34.091 --> 00:05:35.392
design of run-at-time,
00:05:36.372 --> 00:05:41.395
such that if the specified time of day has
00:05:41.455 --> 00:05:42.216
already passed,
00:05:43.196 --> 00:05:44.877
then the timer will run immediately,
00:05:45.578 --> 00:05:46.638
rather than in the future,
00:05:46.958 --> 00:05:47.839
as you might expect.
00:05:49.280 --> 00:05:51.441
This can be problematic, for example,
00:05:51.661 --> 00:05:54.663
if run-at-time is being called from your init file,
00:05:55.583 --> 00:05:57.624
since the timer will run immediately
00:05:58.245 --> 00:06:00.426
every time you restart Emacs for any reason.
00:06:02.526 --> 00:06:04.691
I noticed recently that run-at-time
00:06:04.791 --> 00:06:07.217
also allows you to pass in a value
00:06:07.317 --> 00:06:17.657
from encode-time, which maybe does what we want,
00:06:18.378 --> 00:06:20.760
but I never bothered with testing that.
00:06:21.340 --> 00:06:23.041
Actually, I have a vague memory of
00:06:23.181 --> 00:06:25.743
once looking into it and it didn't seem to do what I
00:06:25.783 --> 00:06:29.286
wanted, but honestly I can't clearly remember,
00:06:29.946 --> 00:06:31.667
so you may want to look into that yourself.
00:06:32.728 --> 00:06:34.209
What I ended up using was just
00:06:34.309 --> 00:06:35.750
passing in a number of seconds.
NOTE The code
00:06:37.792 --> 00:06:39.413
So now we'll move over to the code.
00:06:46.764 --> 00:06:49.426
So I'll skip down here first
00:06:49.966 --> 00:06:52.447
to the code that I wrote for calculating the number of
00:06:52.527 --> 00:06:52.887
seconds.
00:06:54.408 --> 00:06:57.790
It's a function that calculates the number of seconds
00:06:58.050 --> 00:07:01.012
until a particular time of day in the future.
00:07:04.214 --> 00:07:09.277
You can see that you pass in the hour as a number from
00:07:09.278 --> 00:07:19.137
0 to 23 and the minutes as a number from 0 to 59. And
00:07:20.078 --> 00:07:22.539
here's the code, which will also be available later.
00:07:25.700 --> 00:07:29.202
I wrote another function, secs-until-weekly,
00:07:29.522 --> 00:07:32.464
which we do not need for this talk,
00:07:32.604 --> 00:07:34.685
but which is useful if you're running
00:07:34.745 --> 00:07:36.746
events which need to happen once per week.
00:07:39.264 --> 00:07:44.025
This function also requires a target hour
00:07:44.085 --> 00:07:48.926
and a target minute, but also requires passing in a
00:07:48.966 --> 00:08:00.548
target day. And while we're on the subject of timers
00:08:00.568 --> 00:08:02.588
specifically, I should mention that
00:08:02.648 --> 00:08:05.929
Emacs has a very useful function called list-timers.
00:08:07.577 --> 00:08:09.959
So if I call the interactive function list-timers,
00:08:11.560 --> 00:08:14.542
it will give me a list of all the timers
00:08:14.842 --> 00:08:15.542
currently running.
00:08:16.723 --> 00:08:19.625
This page shows not only which timers exist,
00:08:20.186 --> 00:08:22.807
but also how long it will be until they run again,
00:08:23.848 --> 00:08:26.750
along with the periodic repeat value that you
00:08:26.770 --> 00:08:27.390
specified.
00:08:29.992 --> 00:08:33.034
Furthermore, any timer can be canceled by moving point
00:08:33.514 --> 00:08:38.515
over the timer and running timer-list-cancel,
00:08:38.696 --> 00:08:42.556
which on my system is bound to the letter c by default.
00:08:43.537 --> 00:08:45.417
This is very helpful while you are developing
00:08:45.497 --> 00:08:46.537
some timer function.
00:08:48.438 --> 00:08:52.158
So I could cancel the timer that I already have running
00:08:53.779 --> 00:08:55.059
for shaking the plant,
00:08:57.420 --> 00:08:59.360
as well as the one for watering the plant.
00:09:02.842 --> 00:09:03.843
and back to the code.
NOTE Managing the plant
00:09:05.724 --> 00:09:08.566
So now we'll talk about the actual code for
00:09:08.646 --> 00:09:09.567
managing the plant.
00:09:14.210 --> 00:09:16.031
So you see I have a variable set up here
00:09:16.471 --> 00:09:19.353
that specifies where the certificate file,
00:09:20.994 --> 00:09:23.836
the public certificate file, as well as
00:09:23.936 --> 00:09:26.458
the secret key file is located.
00:09:27.918 --> 00:09:29.459
This is where it is in my system.
00:09:30.119 --> 00:09:33.181
Of course, depending on your specific Gemini client,
00:09:33.481 --> 00:09:36.722
it may be in a different space and will likely have a
00:09:36.762 --> 00:09:37.303
different name.
00:09:41.045 --> 00:09:43.486
And here is the code for watering the plant,
00:09:44.526 --> 00:09:45.967
which I can call interactively.
00:09:49.412 --> 00:09:52.334
And the core of it here is that it uses the
00:09:52.834 --> 00:09:57.937
gmni utility, a command line utility to
00:10:00.998 --> 00:10:06.982
call a particular URL while also loading up
00:10:07.702 --> 00:10:10.564
or presenting the required certificate.
00:10:12.505 --> 00:10:16.447
So in this case, you can see it is the URL that is
00:10:16.567 --> 00:10:18.088
required for watering the plant.
00:10:19.827 --> 00:10:24.952
This idea is very simple and the gmni client
00:10:26.353 --> 00:10:30.097
or gmni command line program
00:10:30.758 --> 00:10:31.999
makes this very simple to do.
00:10:34.554 --> 00:10:36.535
Here's another function for shaking the plant.
00:10:37.696 --> 00:10:40.758
Again it is almost identical except that we
00:10:40.958 --> 00:10:43.300
use a different URL,
00:10:44.180 --> 00:10:46.982
one for shaking the plant instead of watering it.
00:10:47.562 --> 00:10:49.183
And again we want to shake the plant
00:10:50.044 --> 00:10:51.745
in order to get money to fall off of it.
00:10:55.847 --> 00:10:59.290
You need to water your plant at least once per day or
00:11:00.791 --> 00:11:01.251
it'll die.
00:11:02.930 --> 00:11:09.953
I usually water mine twice and just in case something
00:11:10.013 --> 00:11:13.314
happens where Emacs was turned off because of
00:11:13.414 --> 00:11:15.035
power outage or something like that
00:11:15.595 --> 00:11:17.196
that I'm more likely to get it watered,
00:11:19.036 --> 00:11:21.957
and I shake it once per day because there isn't
00:11:23.398 --> 00:11:25.339
any purpose to shaking it more than that.
00:11:25.619 --> 00:11:27.240
If you try to shake it more than that,
00:11:27.420 --> 00:11:29.560
then money no more money will fall off,
00:11:30.321 --> 00:11:30.821
or not much.
00:11:37.242 --> 00:11:39.526
So you see down here, I have the code that
00:11:39.627 --> 00:11:41.209
actually calls run-at-time.
00:11:42.560 --> 00:11:45.141
I left here commented my original forms of this
00:11:45.661 --> 00:11:50.024
which used the just specify directly the time of day.
00:11:50.644 --> 00:11:52.225
As I mentioned the problem with that
00:11:53.505 --> 00:11:54.466
was that it would...
00:11:54.786 --> 00:11:57.187
these functions would also get called
00:11:59.208 --> 00:12:02.649
whenever I restarted Emacs for any
00:12:02.709 --> 00:12:04.250
reason and that was kind of annoying.
00:12:05.011 --> 00:12:07.352
So instead we have here the functions down here
00:12:07.452 --> 00:12:09.533
which uses secs-until-daily
00:12:10.913 --> 00:12:11.754
to water the plant
00:12:12.294 --> 00:12:14.756
and then secs-until-daily to shake the plant.
00:12:16.057 --> 00:12:20.821
You see, I've specified the plant to get watered
00:12:21.181 --> 00:12:26.025
at 4 in the morning and then the function is run again
00:12:26.125 --> 00:12:31.269
after that, every 43,200 seconds, which translates to
00:12:31.389 --> 00:12:32.270
every 12 hours,
00:12:33.711 --> 00:12:36.353
and then I shake the plants, shake the plant
00:12:38.760 --> 00:12:43.341
every morning at 4.15 a.m. and once every [24] hours.
00:12:45.742 --> 00:12:46.802
With a little bit more
00:12:46.902 --> 00:12:49.483
sophistication, a little bit more work on the code,
00:12:50.143 --> 00:12:53.964
I could actually have multiple plants be watering and
00:12:54.264 --> 00:12:57.985
shaking multiple plants with multiple certificates,
00:12:58.105 --> 00:12:59.885
but I never got around to that.
00:13:00.946 --> 00:13:02.246
Didn't seem worth the bother to me.
NOTE Conclusion
00:13:09.560 --> 00:13:12.964
So thank you for watching my video,
00:13:13.825 --> 00:13:16.227
Watering My Digital Plant with Emacs Timers.
00:13:16.628 --> 00:13:18.189
You'll see at the bottom of this page
00:13:19.491 --> 00:13:21.613
links to the code for this talk
00:13:22.354 --> 00:13:24.096
as well as other things that I mentioned
00:13:24.677 --> 00:13:27.819
like the source code for the
00:13:27.979 --> 00:13:30.100
Elpher Gemini client,
00:13:30.801 --> 00:13:33.282
the URL for the Astrobotany capsule,
00:13:34.203 --> 00:13:36.865
as well as a link to more information about
00:13:36.925 --> 00:13:41.407
Project Gemini and my own personal Gemini capsule
00:13:42.808 --> 00:13:45.129
that's being run off my own server at home.
00:13:46.790 --> 00:13:47.471
Thank you very much.