Watering my (digital) plant with Emacs timers
Christopher Howard (he/him) - IRC: lispmacs, http://gem.librehacker.com, christopher@librehacker.com
The following image shows where the talk is in the schedule for Sat 2024-12-07. Solid lines show talks with Q&A via BigBlueButton. Dashed lines show talks with Q&A via IRC or Etherpad.
Format: 14-min talk ; Q&A: IRC https://chat.emacsconf.org/?join=emacsconf,emacsconf-gen Etherpad: https://pad.emacsconf.org/2024-water
Etherpad: https://pad.emacsconf.org/2024-water
Discuss on IRC: #emacsconf-gen
Status: Q&A open for participation
Saturday, Dec 7 2024, ~11:30 AM - 11:45 AM MST (US/Mountain)
Saturday, Dec 7 2024, ~10:30 AM - 10:45 AM PST (US/Pacific)
Saturday, Dec 7 2024, ~6:30 PM - 6:45 PM UTC
Saturday, Dec 7 2024, ~7:30 PM - 7:45 PM CET (Europe/Paris)
Saturday, Dec 7 2024, ~8:30 PM - 8:45 PM EET (Europe/Athens)
Sunday, Dec 8 2024, ~12:00 AM - 12:15 AM IST (Asia/Kolkata)
Sunday, Dec 8 2024, ~2:30 AM - 2:45 AM +08 (Asia/Singapore)
Sunday, Dec 8 2024, ~3:30 AM - 3:45 AM JST (Asia/Tokyo)
Duration: 13:50 minutes00:02.679 Introduction 00:28.823 What is Astrobotany? 00:48.914 What is Gemini? 01:25.337 How do you play Astrobotany? 03:37.000 Timers 06:37.792 The code 09:05.724 Managing the plant 13:09.560 Conclusion
Description
This talk gives a brief introduction to Emacs timer functionality. I explain how I used Emacs timers to water and harvest my flower on the gemini Astrobotany service.
About the speaker:
Christopher Howard is a simulator technican and free software ethusiast living in Fairbanks, Alaska. Christopher explains how he uses Emacs timers to automatically water and harvest his flower on the Astrobotany gemini service.
See also these other talks by the same speaker:
- EmacsConf - 2024 - talks - Emacs as a Shell
- EmacsConf - 2023 - talks - Org-Mode Workflow: Informal Reference Tracking
Transcript
[00:00:02.679] Introduction
Welcome to Watering My Digital Plant with Emacs Timers, a talk by Christopher Howard for Emacs Conference 2024. The goal of this talk is to give a brief introduction to Emacs timers using the illustration of how I created a bot for the Astrobotany service.
[00:00:28.823] What is Astrobotany?
What is Astrobotany? Let me jump to the home page. Astrobotany is a botany game or a simulation that is played using the Gemini protocol and gemtext documents.
[00:00:48.914] What is Gemini?
What is Gemini? The Gemini protocol is a small web protocol, similar to the HyperText Transfer Protocol, but with differing goals of simplicity, non-extensibility, and protecting privacy. Gemtext is a simple hyperlinking document format, the analog of the HyperText Markup Language, or HTML. Much more could be said about the design and goals of the Gemini project, but that is not the focus of this talk.
[00:01:25.337] How do you play Astrobotany?
And how do you play Astrobotany? First, you need to get a Gemini client or what you might call a browser. Many clients are available, but I am using Elpher, a Gemini client for Emacs. Once you have your client running, navigate to the home page for Astrobotany, which is shown in this window. You'll see the URL for the home page displayed at the top of the window. On your first visit to Astrobotany, you will need to create a client certificate, which will be used instead of a password. Your Gemini client will help you to create the certificate. Then you will go to the Visit Your Plant page in order to view your plant, to water it, and to collect things from it, including money. So here you see the plant that I'm currently growing in glorious ASCII graphics. There's also a color version available from this page. Back at the home page, you can do other things like go to the item shop, to buy items like badges, fertilizer, or post on the message board. In Astrobotany, gardener bots are fully legal. And to do an action on your plant, like watering the plant, all your bot needs to do is to access the appropriate Gemini URL or page while presenting the appropriate certificate for your plant.
[00:03:37.000] Timers
And this brings us to Emacs timers. So the main function of interest to us is the run-at-time function. Here is the help documentation, which is available in any recent Emacs installation. As you see, the purpose of the function is to perform an action at a specific time to repeat it after a specific number of seconds. And so basically, all you have to do is pass in a function to run-at-time, telling Emacs how soon you want to run the function, and then how often you want to run the function after that. The function has a variety of options for specifying the time parameter, that is, how soon you want the function to run. For our application, in which we'll be running our functions once or twice a day at specific times, it is most useful to specify the number of seconds until the event. This does, however, require calculating the number of seconds until a specific time of day. I will provide code for this shortly. The run-at-time function does allow you to specify the time parameter as a string, representing the hours and minutes. For example, 05:40. However, there is an oddity in the design of run-at-time, such that if the specified time of day has already passed, then the timer will run immediately, rather than in the future, as you might expect. This can be problematic, for example, if run-at-time is being called from your init file, since the timer will run immediately every time you restart Emacs for any reason. I noticed recently that run-at-time also allows you to pass in a value from encode-time, which maybe does what we want, but I never bothered with testing that. Actually, I have a vague memory of once looking into it and it didn't seem to do what I wanted, but honestly I can't clearly remember, so you may want to look into that yourself. What I ended up using was just passing in a number of seconds.
[00:06:37.792] The code
So now we'll move over to the code. So I'll skip down here first to the code that I wrote for calculating the number of seconds. It's a function that calculates the number of seconds until a particular time of day in the future. You can see that you pass in the hour as a number from 0 to 23 and the minutes as a number from 0 to 59. And here's the code, which will also be available later. I wrote another function, secs-until-weekly, which we do not need for this talk, but which is useful if you're running events which need to happen once per week. This function also requires a target hour and a target minute, but also requires passing in a target day. And while we're on the subject of timers specifically, I should mention that Emacs has a very useful function called list-timers. So if I call the interactive function list-timers, it will give me a list of all the timers currently running. This page shows not only which timers exist, but also how long it will be until they run again, along with the periodic repeat value that you specified. Furthermore, any timer can be canceled by moving point over the timer and running timer-list-cancel, which on my system is bound to the letter c by default. This is very helpful while you are developing some timer function. So I could cancel the timer that I already have running for shaking the plant, as well as the one for watering the plant. and back to the code.
[00:09:05.724] Managing the plant
So now we'll talk about the actual code for managing the plant. So you see I have a variable set up here that specifies where the certificate file, the public certificate file, as well as the secret key file is located. This is where it is in my system. Of course, depending on your specific Gemini client, it may be in a different space and will likely have a different name. And here is the code for watering the plant, which I can call interactively. And the core of it here is that it uses the gmni utility, a command line utility to call a particular URL while also loading up or presenting the required certificate. So in this case, you can see it is the URL that is required for watering the plant. This idea is very simple and the gmni client or gmni command line program makes this very simple to do. Here's another function for shaking the plant. Again it is almost identical except that we use a different URL, one for shaking the plant instead of watering it. And again we want to shake the plant in order to get money to fall off of it. You need to water your plant at least once per day or it'll die. I usually water mine twice and just in case something happens where Emacs was turned off because of power outage or something like that that I'm more likely to get it watered, and I shake it once per day because there isn't any purpose to shaking it more than that. If you try to shake it more than that, then money no more money will fall off, or not much. So you see down here, I have the code that actually calls run-at-time. I left here commented my original forms of this which used the just specify directly the time of day. As I mentioned the problem with that was that it would... these functions would also get called whenever I restarted Emacs for any reason and that was kind of annoying. So instead we have here the functions down here which uses secs-until-daily to water the plant and then secs-until-daily to shake the plant. You see, I've specified the plant to get watered at 4 in the morning and then the function is run again after that, every 43,200 seconds, which translates to every 12 hours, and then I shake the plants, shake the plant every morning at 4.15 a.m. and once every [24] hours. With a little bit more sophistication, a little bit more work on the code, I could actually have multiple plants be watering and shaking multiple plants with multiple certificates, but I never got around to that. Didn't seem worth the bother to me.
[00:13:09.560] Conclusion
So thank you for watching my video, Watering My Digital Plant with Emacs Timers. You'll see at the bottom of this page links to the code for this talk as well as other things that I mentioned like the source code for the Elpher Gemini client, the URL for the Astrobotany capsule, as well as a link to more information about Project Gemini and my own personal Gemini capsule that's being run off my own server at home. Thank you very much.
Questions or comments? Please e-mail christopher@librehacker.com