For the last couple of years I have been working on software projects to improve my life. These have been small and large and mostly they remind me of this one XKCD about automating tasks. It might very well be that the total amount spent on this did not actually offset the time saved. However I had fun and learned lots, so I thought I could share some lessons and ideas learned along the way.
The Three Giants
The main way I think about all the automation is that it consists of actions and commands. Both are small packages of logic which execute when I need them to. An action is logic that is executed on a regular basis. It will run in the background without effort from me. A command is logic that is triggered, when I want it to. For both of these I created a software project. Zeus, the god of order, handles the actions and determines every 15 minutes which actions to run and runs them. Ares, a chatbot, handles the commands for me. Zeus is located on a server that I own, that lives under the desk of my apartment. This server is called Samaritan and besides Zeus hosts some other software as well.
There are many small tasks that I want to run every 15 minutes. It is very similar to cron, a Linux service, which runs commands every x minutes/hours/days. I thought of using it, however I have some specific features that I added on top of cron to make it easier for me to work with. When something breaks, I want to know. The task that might be broken might be important and I don’t review my logs that often, so when a task fails Zeus will notify me on Telegram, a popular messaging service, that something is wrong. However getting messages every time something breaks overloads you with messages. There are 2 main ways I solved this problem of message overload. First, it will only start sending me messages after the 4th successive error. Sometimes a service is down for half an hour or just randomly fails. I don’t need to know about things which will resolve themselves automatically. Secondly, if a task is actually broken, I might be working on other things, have no time to fix it or it is not important enough. So I want to run an action less often. To achieve that, each action has a linked property called NextRunTime. If an actions fails, it’s next runtime will be the current time plus two to the power of the number of errors it has had in minutes. For the third error this will be 2³ = 8 minutes after the current time. However, as we run Zeus every 15 minutes, it will not exclude it on its next run. Only after the fourth error (2⁴ = 16 minutes) will it start excluding the action. After 11 failures, this will result in the task being postponed for more than a full day. Another cool thing is that we can “abuse” this to implement scheduling. If an action is very resource intensive and doesn’t change much, the action can also set its own NextRunTime to be next week instead of in 15 min.
Ares is a Telegram chat bot that I use to control much of the systems that I built. Ares is comprised of commands, each with its own keyword. For instance, the most simple command is
\ping, which tells me if the bot is working. A previous version can be found here. I recently rebuilt it from the ground up to use Microsoft's bot framework. It enables me to quickly write and implement new commands. It is run in the cloud, so it is always online. Both of these projects are largely using ApiLibs, a library I wrote that is used to communicate with any service that I use that has an API. On Telegram, you can talk to it via @Laurentia_Bot
I need a place to host software I have running all the time. To do that, I have a server called Samaritan, after an AI in the Person Of Interest tv series, which hosts everything. However, I sometimes want to perform actions on this server from either Ares, Zeus or my phone. To do this, I have created an REST-API for Samaritan. This in turn is able to contact software or change configuration files on the server.
In the rest of the article, I will be discussing everything that I’ve built on top of these projects and some more. These sections are not dependent on each other, so you can read them in a random order or skip some.
I watch a lot of videos and oh boy, have I created a lot of software that hooks into this one way or the other. Below I will detail more about this.
Plex is one of the main software products in my life. Plex is a media server which runs on Samaritan. It is a way to store all your (video) files and make them available over the web. This enables me to watch everything wherever I am in the world and also doesn’t require me to have the hard disk of my laptop full with files. As another benefit, it tries to automatically find subtitles for me.
Another advantage of Plex is that it has integration with Trakt, which is a website where you can track things you have seen. This enables me to determine that I have spent around 184 days, 7 hours and 13 mins of my life watching TV shows.
Many people have asked me, if I could download a video for them. However, this usually took some time. Furthermore, I wanted to give people I trust a way to download stuff onto my server without me having to do anything (I’m lazy). So to make it easier, I gave Ares the ability to download videos. First, someone asks Ares to download something. This will trigger Ares to activate an Azure function running in America. To make sure they find the correct video, I ask 6 sources to return me results. We then sort each answer and return the top result back to Ares.
Then the user can choose and pick the video they want to download. After this, Ares contacts SamaritanApi and tells it to download it.
Sometimes you might want to take these files with you. You might be going to a place without WiFi or need to make sure that a video plays. Plex is nice, but to stream in 1080p you need an internet connection, which is able to handle 8mbps, which is too much for a lot of places. Therefore, I needed a way to download shows. The way I implemented it, is that I use Ares to pick the file I want to download and generate a download link. Then using SamaritanApi I download the file straight from the server. Using some magic I also add a code to the back to keep it somewhat secure, so that not everyone has easy access to the files on my server.
Now I am lazy. I don’t want to wake up one day and realize my entire hard drive is full and that I need to spend time to remove videos. To solve this problem, I keep a list of everything that was downloaded and when they are scheduled to be deleted. By default this time is 2 years. There are 3 ways I change the date. The first is pretty easy. I keep a list of all videos that were automatically downloaded. These will be set to be deleted 3 months in the future. After some testing, I figured out that for 99% of these I will have either watched them or probably never will look at. The second way is that when downloading shows from Ares, I ask you how long the torrent should stay and if you answer this, I will adhere to this time. Lastly, I am able to search for and change deletion dates from Ares. This enables me to look for outliers and delete anything I have seen.
One of the more cute examples of my own code is Wallsetter. This is a small app which I built to set a new lock screen and wallpaper every two hours. It gets new images from Unsplash, an amazing website to find free to use images. Wallsetter is then able to apply all sorts of effects to it.
The cool thing is that for the lock screen is that it is able to check my Trakt and look at which TV show airs today or if there are any shows from yesterday that I have not watched yet. Then it will grab an image of that show and set it as my lock screen or wallpaper.
However, that is not my setup currently I use it to download an image, set it as my wallpaper and set a black and white version of that as my lock screen image. It is gorgeous and I am very happy with it.
Spotify is a really nice service to listen to your favourite music. However, because I use it a lot, I have found some small issues that I can solve with automation.
Sort by Loudness
To aid you in finding new music, Spotify presents you with two auto-generated personalized playlists. A Discover Weekly playlist with new music from new artists and a Release Radar playlist which contains music released this week. Both are very nice, but have one problem, they jump from very loud energetic to peaceful piano music. This is very jarring if you are listening. To solve this, Zeus gets all songs from the playlist and gets the features of the songs. These features are provided by Spotify and contain things like energy, danceability, liveness and loudness. I order all songs by loudness and put them in a new playlist for me. This way I can listen to my music from very loud to very peaceful.
Once you have features of songs, you can think bigger. Spotify can extract features from all of my saved music. From that you can generate playlists. However to do that, you would need to find the perfect settings to create a nice playlist. To do this, I created Playlister, a universal Windows app, which enables me to play with all the features you see on the right of the image below.
Using Playlister, I have created playlists named Summer, Winter, Piano and Energy. Every week, Zeus downloads all my saved songs from Spotify and runs it through each of the finely tuned filters for my playlists and updates each with new songs I’ve added and removes songs I no longer like. So if I want to listen to music that gets me hyped, I listen to the Energy playlist, which consists of songs I like that following my tweaks, can be considered full of energy.
Last 4 weeks
I spend a lot of time biking and travelling by train. I also don’t have a mobile data plan. This leads to the fact that I need Spotify to download a lot of music. However, I also have a lot of new music that I want to bring with me. I could download all my music, but my phone does not have enough storage for that.To solve this problem, Zeus will make a playlist every night with songs I added in the last 4 weeks. I then tell Spotify to keep this playlist downloaded at all times. This leads to an almost always updated playlist with my newest songs.
In the previous paragraph I explained that I can’t download every songs to my phone. However, I might want to listen to a random selection of music every once in a while. Music not in one of my automatically generated playlist or in any other list. Furthermore, even if I have internet, I sometimes feel like the shuffle is not completely random. To solve these problems, every night Zeus takes all my saved music, picks 50 random songs and adds it to a playlist sorted by loudness, so I can always listen to some random music I like.
Full Release Radar
Spotify has a feature called Release Radar, where each week, you can listen to music that came out that week. And new music from artists you might not listen to. This is great and I’ve gotten a lot of new music from it, however it might miss artists that I like and if an artist released an entire album, it will only display one, which I can definitely understand, but I don’t want. So I created an action on Zeus, which every Friday checks all the artists I follow. If they released any new music in the last week and it puts the songs into a playlist called “Full release radar”, so that I do have this overview.
I follow a lot of sources. Many of them support a nice protocol called RSS. It enables a common format to get updates on your favourite news. Using this, I follow updates on GitHub, Factorio, Todoist, TV-show reviews and more. In total there are 28 sources I keep track of. If there is a new article, I put it into a service called Instapaper. This is an online service I use to keep track of articles. It strips the article down to the bare contents, which makes it easier to read.
I, like everyone else, need to do shopping. My preferred supermarket where I do my shopping is called Albert Heijn. When I go shopping, I need a grocery list. For my grocery list I use an old todo service called Wunderlist. There is no specific reason for using it, except that I have been using it for that for a while now and I like it. There are three ways in which I create my grocery list. The most normal way is to just to add new items onto the grocery list (4).
Next up, there is a Trigger List (2). This is a list, originating from the Getting Things Done methodology, which contains items that might be relevant and “trigger” your thinking. In this case it is a list of groceries I don’t buy often, but need every once in a while, like toilet paper. This is very useful and I go over it every week and every time I realise that I forgot to put something on my grocery list. If I need an item, I will check it off. Zeus then unchecks it and puts it on my grocery list.
The Albert Heijn also has products labeled as “bonus” (1), which are all products with a discount. You can get these from their website. Combining this with a file of products I might want to buy, I get a list of products that I want to buy and are discounted. I put them in my Wunderlist and just like the Trigger List, if I need an item, I will mark it as completed and Zeus will come along, uncheck it and put it on my grocery list.
Lastly, I have a command in Ares that enables me to get a recipe of the Allerhande (3), a website by the Albert Heijn which contains very good recipes for food. Using Ares, I scale by the amount of people that will eat with us and then put those items on the grocery list.
Because of all these things, I have a pretty good idea of what I need to buy when I walk into the supermarket and won’t forget anything.
There are often times when I go shopping and pay things for my roommates (common food, cleaning supplies, etc.) or friends (dinner, presents, etc.). To keep things balanced, we use a service called WieBetaaltWat. This service enables you do add expenses to a shared ledger and then after a while settle it. This is very useful, as it is never a hassle who’s turn it is to pay, as it will balance out in the end anyway.
Now, Albert Heijn stores the items you last bought. Zeus is able to extract this list using web scraping and then sends me a message when some new item is found. Then I can use Ares to select which things I bought for which group of people and Ares automatically adds it to the correct WieBetaaltWat group. This saves me a lot of hassle and this enables my friends to see exactly what I bought.
I use a todo system in my daily life. I don’t need it, but it does help me a lot in not forgetting stupid things I should do. In the future, I would like to have one system for all my tasks. The idea would be that this system functions as an overview for me, so that I don’t enforce one way of working to me or other people. Right now my eyes are set on Todoist to do this for me. It is incredibly powerful and very important, it has a nice API.
As I want Todoist to be the center of all my tasks, I need to figure out a way for the relevant tasks to be in there. This is why I have been working on synchronization between many of the services that I use. Any issue that is opened on GitHub now shows up in my todo system. This is the same for GitLab. Furthermore, for any email that you send me is a task is automatically made that I need to handle this in 2 weeks or it will start reminding me. This makes sure that I keep on top of things.
As some might know, every Friday, I try to clean my room. This is very nice, as I will come back to a clean room and during the week I don’t have to think about keeping everything clean, as on Friday I will clean it anyways, nor do I have to force it in sometime during the week. Cleaning, just like grocery shopping, uses a Trigger List. There might be things that I do not have to clean or do right now, but might be needed to do in the future. Furthermore, usually it is the case that after cleaning I go home to my parents. Therefore it does not make sense to show these tasks when I am at my parents, as there is no way for me to do them and I will not do them in the next few days. Only on Friday, when everything starts again. This is the fundamental idea of temporary projects, where some only appear for a certain timespan in a week or day, when they are relevant. It uses TaskPaper, a simplistic way of writing down tasks, to create all projects, tasks and visibility time. These configuration files are stored in my OneDrive, so I can edit, delete or add any new list at any time or any place.
An idea for the future might be to allow Ares to toggle projects as well, for the projects that do occur more than once but not on a predictable rhythm.
After I put all tasks in one place and have everything, which we need to do on a day, we need to actually do some of the tasks. To help me with that, I created another universal windows app called DailyTodo, which helps me with picking out the tasks I want to do on a given day. I can search for them, filter by project or label. Once I have picked the task, it will add the @today label to it. This tells my system that I want to do this task today. It will then also make a notification in my windows action center and forces it to stay at the top. So if at any point of the day I wonder what I should do, I can simply open it and quickly pick my next task. As you can also see in the images below, with these notifications I can also quickly complete or remove them from my day.
Next, there are two other labels to help me with this system. If I am preparing for the next day or find something I want to do tomorrow, I can give it the label
@tomorrow. Every night at 12, Zeus will change all tasks with
@today. To start fresh every morning. All tasks that had an
@today label will be changed to
@yesterday. It might be that tasks, which were important yesterday, are no longer important today, but I should decide that manually and the
@yesterday enables me to keep track of those todo's.
All of my friends know that I send a calendar invite for every dinner/meeting/meetup I have. I have found that this enables everyone to have the same basic truth and then there can be no doubt when a meeting event is. So I make a lot of them. Recently I have made a telegram command for this, so that I can specify with natural language a meeting and it will do the rest for me.
In Outlook, you can also store where a person lives. When I have a meeting at a friends place and their address is in my system, I only have to write the name of the person in the location field of the event and Zeus will add the exact address of that person.
Just like every other person on this planet, I am terrible at remembering birthdays. To make sure I don’t forget to buy presents, I get a reminder a week ahead of a persons birthday and then on the day itself to make sure to wish them a happy birthday.
I use inbox zero which results me moving email which I completed or are no longer relevant to an archive folder. To remove this small OCD thing that there might be unread email in that folder, it just marks everything in that folder as read.
To keep into shape I (try to) swim every week at a student association called DSZ-Wave. To be able to swim, you have to sign up. However, the sign up form only opens on the day itself and I have often forgotten to sign up until it was too late. So I needed to over engineer this. Every day, Zeus looks at which swim-practices are available. Next, it looks at my calendar and sees if there is an event called “Swimming” at the same time. If thats the case, it will automatically enroll me for that practice. This checking of my calendar is especially useful for the case, where I have something else on the time that I would usually swim. In that case I delete the event ahead of time and don’t take up the space of someone that does want to swim.
Since the second year I have been studying in Delft, every Thursday me and a group of friends have met up to eat together. Since that time, every week I have sent an invite with the date and who is supposed to be hosting that week. As making that invite every week is a bit annoying and I sometimes very awkwardly would forget someone or use the wrong email adress, I made this a command I can trigger with Ares.
I have 5 lights in a row in my room. As a present, these lights were upgraded to TradFri smart bulbs. This is the smart lighting solution from IKEA. Of course I could not let the opportunity slide to automate some nice things with it.
Waking up is hard for almost everyone in the world. For me too. To make it a bit easier, I have made it that just before I need to wake up, Zeus will slowly start to turn on the lights. When 15 minutes later my alarm goes off, I wake up with a little bit more light.
In the Spotify section I talked about how I can get the energy and loudness of a song. But that is not all we can extract from a song. You can also extract the beats of a given song. This means that you can get the tempo of a song. With Spotify, we can also see which song is playing and where we are in the song. Next, by contacting the smart bulbs, we can toggle the lights on the beat of a song. Right now, I have a pattern where all lights are off, except one. On the next beat the light will turn off and the one on the right of it will turn on. This will make it seem like the lights are going from left to right. It is amazing to experience and very fun to show off to visitors of your room.
I have been using software like F.lux and more recently the built in Night Light from Windows for a long time. Besides the fact it should help you sleep better, it feels like it does not burn your eyes at night. However, I realised this does not happen for the lights in my room. So I made them to that. Every afternoon, Zeus calculates when the sun is going down. Then in around 40 minutes, it will start dimming the lights to a level where it still is bright enough to see, but clearly darkened. I have found that this actually works really well, as it will feel like the sun is going under in the room, making me more sleepy. The most amazing thing is that this transition is so slow that you don’t notice it.
These were the highlights of all the automation I use. I hope you found them interesting or inspiring to go build some yourself.