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.