There's a million different ways of handling alarms to make sure you get up in the morning. Some people turn on the radio. Others need the lights to turn on bright. Still others need literal klaxons blaring in their ears. For me none of those options will work because usually I'm getting up early before my spouse to go for a run. So anything loud won't work. A pretty good solution for me is using SleepAsAndroid tied to my Garmin watch so when my alarm goes off it first vibrates my watch. If I don't turn the alarm off in ~2 minutes for some reason then it starts up with the progressively increasing in volume alarm sound.
Since I run, there are days when I don't want to run such as when it's too cold or pouring rain. I try to look at the weather forecast but sometimes the rain is scattered or it turns out not to be as cold as forecasted. So I wanted a way to automatically turn my early alarm off and turn on a later alarm, allowing me to sleep in. I also just wanted a way to adjust my alarm without having to pull out my phone, and with the recent COVID-19 outbreak adjust my alarm on the fly depending on my work schedule has proven useful.
There are 3 basic parts to this: 1) the ability to toggle an individual days alarm on/off, as well as the next day's alarm, and then turn on a standard "sleep in" alarm, 2) the ability to turn off the next day's alarm and set a custom alarm time, 3) the ability to turn on "vacation mode" and disable all the alarms and turn on an extra-late sleep in alarm (just in case!).
The below solution works for me and could probably be adjusted to work for you fairly easily. So far it's been fairly bulletproof with some minor tweaks, but I would strongly suggest you test it carefully before you become 100% reliant on it.
Things we need (other than HomeAssistant and NodeRed):
1) Join - similar to apps like Pushbullet, this one is made by the same dev as Tasker. As a result, it has a unique feature we'll need which is the ability to call Tasker activities remotely.
2) Tasker - a super handy app for any Android user. If you don't have it, it's worth the few dollars as it can pretty much do....anything. And the dev is always adding new features. This is Android only; sorry iOS users.
3) SleepAsAndroid(any alarm app should work, so long as it supports some way of being controlled by Tasker, such as via intents)
HomeAssistant is relatively simple and requires a number of input_booleans, input_numbers, and a template sensor (optional). Below is the code you can copy in your configuration.yaml.
The sensor is optional because I only use it to visually display my alarm time in Lovelace (see below). I use a custom card called Multiple Entity Row and I think it's nice but not necessary for the core functionality we'll discuss. Similarly optional, the "Pandemic Mode" is my COVID-19 addition that automatically turns off my early alarm at 8pm the day before. Eventually it will be converted to a "work from home" mode.
Here's my Lovelace code, if you want to copy it as well:
That's pretty much it for HomeAssistant, except for one more piece, which is Join.
As mentioned above, Join is a Pushbullet-like service that is very useful for this situation mainly for the Tasker calls. Since this post is already going to be incredibly long I'm not going to go through all the details of setting up Join on your phone. I would suggest checking out the dev's website here as I think it's fairly self explanatory.
Once it's set up on your phone, we'll need to get things working with HomeAssistant. Check out the integration page here. Again, I think the docs are fairly self-explanatory here. The key things you need to find are your Join API key and device id. I would suggest just using a single device_id instead of the device_ids or device_names options. Here's the relevant portion of my configuration.yaml:
Once you reboot HomeAssistant, you should have a bunch of new services. The key one we'll need is joaoapps_join.YOUR_DEVICE_NAME_send_tasker. More on this later.
If you haven't used Tasker before, it's really an amazing Android app that can do all kinds of things. Tasker has a bit of a learning curve, and setting it up is again outside the scope of this post. Just check out the subreddit or one of thesearticles for help.
Instead of copying the code into this post, see this gist. You shouldn't need to make any changes to the code as it's very generic, so long as you're using SleepAsAndroid. If you're using a different alarm app you'll need to change the tasks to match your alarm app. You should still be able to use the trigger from Join without much change. Here's what it should like when copied in.
Now what does this all do? Let's just take the Normal Alarm Toggle profile as an example. When Join receives the Tasker Command "Alarm" along with the variables of alarmday and alarmtoggle (which we'll get to/will come from NodeRed) it will then use a shell command to toggle the alarm on a specific day on/off. See the SleepAsAndroid API documentation for how I figured this part out. Don't worry if you don't understand any of that, again you shouldn't have to do anything other than import the xml file. How to import? Open up Tasker, long press on the bottom edge and then click "Import Project." Find where you saved the xml file and import it. Here's a walk through if that doesn't make sense.
For SleepAsAndroid you'll need 2 alarms for every day: "mon" and another called "monsleep," "tue" and "tuesleep" (note the name is important to work with the Tasker code above so follow this naming convention). You'll also want to create an alarm called "Vacation." Set the alarm times to whatever you want, that's entirely up to you! Again not going into the finer details of setting up SleepAsAndroid here.
You also may need to enable Tasker in the SleepAsAndroid app. Go to Settings->Services and look for Tasker. I can't remember if this is a requirement (I don't think it is) so you can try without it first and then enable later if things aren't working for you.
Now finally the fun part! This one could probably be simplified a bit on the NodeRed end but it works for me so it's one of those "if it ain't broke don't fix it" deals. Basically what it does is whenever an alarm input_boolean changes, it runs through a bunch of checks and changes the data/payloads using some templates to get the data correct and then sends the Tasker command via Join. You may wonder why there are some rate limiting nodes: after some testing I discovered that Join/Tasker can't handle a flood of requests all at once (most notably when turning vacation mode on/off) so some alarms weren't being turned on/off correctly. Putting in the rate limits fixed those problems. So this isn't instantaneous but it shouldn't impact anything.
You will need to modify a few of the nodes to call the correct Join service. Everything else should be plug-n-play. The part in the bottom left corner is the reset that restores the normal alarm at a preset time of 11am. I picked this time kind of arbitrarily. My thought process was that if I used an earlier time I might inadvertently reset my alarm so it triggers again (ie I wake up earlier than normal I don't want my alarm to go off twice!).
The NodeRed code is at the bottom of the post.
Phew. It may seem complicated (and let me tell you it was a pain to figure out all the bits and pieces, most notably the Tasker/Join bits), but you really should be able to use the code without much modification. The end result is a simple to control morning alarm system that you can use various automations (such as based on special calendar events/holidays, or other triggers) to easily modify your alarm schedule.
Hope you enjoyed. Feel free to message me over on Reddit (/u/FuzzyMistborn) if you have questions or run into issues!