HomeTaskerTasker: Weather Alarm Clock

Tasker: Weather Alarm Clock

This is the coolest alarm profile you will ever make!

One of the latest MIUI updates to my Xiaomi Mi 11 (review) introduced a new alarm setting: Weather Alarm. A “cool-on-paper” concept except Xiaomi’s implementation doesn’t let you control alarm sounds or weather patterns. That’s ok, as my Tasker Weather Alarm takes care of all that for you!

Weather influenced alarms

Imagine waking up to your usual alarm tune prefixed with custom weather effects. Getting up on a rainy morning starts with raindrops on your phone gently blending into the alarm sound to ease you into the day. On a sunny day, raindrops are replaced with chirping birds and if a deadly meteor shower is threatening human existence on that particular morning, you’ll get a theme tune from “Armageddon” to kick start your planet-saving efforts.

My Tasker Weather Alarm project checks for a weather forecast around the time you need to wake up and selects the best matching alarm ringtone to the weather situation outside. In my case, I opted out for weather ambient effects, but nothing stops you from replacing these with sounds or songs to combat the elements or complement a beautiful day outside.

Either way, you’ll learn the following in this tutorial:

  • how to use OpenWeather API in Tasker
  • how to find data in JSON structured variables
  • how to query alarms on Android devices
  • how to substitute files
  • bonus: how to mix sounds

I made Tasker Weather Alarm during my LiveCoding sessions on YouTube, so if you want to see all unfiltered experiences with all mistakes and workarounds – you can follow these in part 1 & part 2.

Before we start, bear in mind that Tasker Weather Alarm comes with some limitations. I used the Google Clock app for alarms, as it didn’t cache the ringtone, other apps (like the default Xiaomi Clock app caches the tune, and it can’t be replaced without root-access).

Tasker Weather Alarm Project

The entire project is split into 3 tasks. Every day Tasker obtains the weather forecast for the next 4 days and checks the alarms on your phone. If the alarm is set, the forecast is being matched against the alarm, and Tasker replaces your default alarm sound with the forecast-adjusted version.

I will follow my project naming convention, so if you feel like your projects are all over the (Tasker) place, have a read and organise your projects better.

The project checks for alarms and updates the weather at midnight every day, by executing these tasks in a logical order by the main task. If your schedule is more hectic, you can change the pattern or increase the frequency of the alarm queries.

Tasker Profile: WA Check Alarms
    Profile: WA Check Alarms
    	Time: From 12:00am Till 12:01am

    Enter Task: WA Apply Alarm
    
    A1: Perform Task [
         Name: WA Get Weather
         Priority: %priority
         Structure Output (JSON, etc): On ]
    
    A2: Perform Task [
         Name: WA Next Alarm
         Priority: %priority
         Structure Output (JSON, etc): On ]
    
    A3: Perform Task [
         Name: WA Find Forecast
         Priority: %priority
         Structure Output (JSON, etc): On ]
        If  [ %WAnextAlarm !~ none ]

Tasker: OpenWeather.org API

It’s not the first time I used this API to get the weather data. I covered this in the past in a dedicated weather forecast notification, so this time around I will be brief and outline the major changes. Since the introduction of the JSON structured data in Tasker (more about JSON), working with API that serves it, is easier.

Register the account and generate the API Key which will be used to obtain the weather report in your location. You can substitute fixed coordinates, zip code, city name or use Tasker Get Location to obtain your location. As I used a location-based query, the URL will require a REST call which looks like this:

api.openweathermap.org/data/2.5/forecast?lat=your_latitude&lon=your_longitude&appid=API_key&units=metric

You can either hardcode these values into the URL or pass these as variables. The response is saved in %WAcurrentWeather.

Tasker Task: WA Get Weather
        Task: WA Get Weather    
    A1: Variable Set [
         Name: %weatherapi
         To: YOURAPI
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A2: Variable Set [
         Name: %lat
         To: YOUR_LAT
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A3: Variable Set [
         Name: %long
         To: YOUR_LONG
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A4: HTTP Request [
         Method: GET
         URL: api.openweathermap.org/data/2.5/forecast?lat=%lat&lon=%long&appid=%weatherapi&units=metric
         Timeout (Seconds): 30
         Structure Output (JSON, etc): On ]
    
    A5: Variable Set [
         Name: %WAcurrentWeather
         To: %http_data
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]

Tasker: get the next alarm

This task is reasonably straightforward (with exception of reliable alarms, which you should have enabled in Tasker already). Unless you turn these off, Tasker won’t be able to find a correct alarm. It’s because Tasker sets its own alarms in the background to keep the track of time better.

The workaround is to disable the feature for a couple of seconds, query the next alarm and enable the setting again. This way, the next alarm time (in ms from EPOCH) is the one from your alarm clock. Don’t forget to divide the time by 1000 – as timestamps in weather forecasts are in seconds not milliseconds. The result is stored in %WAnextAlarm.

Tasker Task: WA Next Alarm
           Task: WA Next Alarm    
    
    A1: Variable Set [
         Name: %WAnextAlarm
         To: none
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A2: Set Tasker Pref [
         Set: Use Reliable Alarms
         Value: Never ]
    
    A3: Wait [
         MS: 0
         Seconds: 2
         Minutes: 0
         Hours: 0
         Days: 0 ]
    
    A4: Test Next Alarm [
         Minutes Difference: 0
         Continue Task After Error:On ]
    
    A5: Set Tasker Pref [
         Set: Use Reliable Alarms
         Value: Always ]
    
    
    A6: Variable Set [
         Name: %WAnextAlarm
         To: %na_time_ms /1000 + 3600
         
         Do Maths: On
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
        If  [ %na_time_ms Set ]    

Tasker: finding forecast

I learned something new in this task. After making a blunder in a live stream and cornering myself without a solution I had to step back, re-evaluate the approach and ask questions. Joao Dias had the answer. Not one I was expecting either.

Turns out, Tasker can create “on-demand” arrays from key: value pairs in JSON objects. It means that data a JSON object like this:

[
	{
		"dt": 1643414400
		
	},
	{
		"dt": 1643425200
		
	},
	{
		"dt": 1643436000
		
	},
	{
		"dt": 1643446800
		
	}
]

can be extracted and worked on without additional actions. In my case %WAcurrentWeather.list is an array containing the forecast elements. Each element is a 3h forecast timeframe. Tasker can instantly create arrays for individual data elements in this object and use them as standard Tasker arrays.

Therefore %WAcurrentWeather.list.dt() is an array with timestamps for each forecast in the entire 4-day weather set. I can use a FOR loop to iterate through each timestamp comparing it to the time of my next alarm stored in %WAnextAlarm. The instance when the forecast timestamp is greater than my alarm time – is the NEXT forecast after the alarm goes off. To get the one before, I have to count how many times I iterated the loop, before I got to that one – and subtract one. This is the index of the %WAcurrentWeather.list(%index).weather array that corresponds with my alarm.

Tasker Task: WA Find Forecast
               Task: WA Find Forecast    
    A1: Variable Set [
         Name: %counter
         To: 0
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A2: For [
         Variable: %val
         Items: %WAcurrentWeather.list.dt()
         Structure Output (JSON, etc): On ]
    
        A3: If [ %val > %WAnextAlarm ]
    
            
            A4: Variable Set [
                 Name: %index
                 To: %counter
                 Max Rounding Digits: 3
                 Structure Output (JSON, etc): On ]
    
            A5: Goto [
                 Type: Action Label
                 Label: Loop Escape ]
    
        A6: End If
    
        A7: Variable Add [
             Name: %counter
             Value: 1
             Wrap Around: 0 ]
    
    
    A8: End For
    
    A9: Flash [
         Text: %index
         Continue Task Immediately: On
         Dismiss On Click: On ]
    
    A10: Variable Set [
          Name: %WAforecast
          To: %WAcurrentWeather.list(%index)
          Max Rounding Digits: 3
          Structure Output (JSON, etc): On ]
    
    A11: Perform Task [
          Name: WA Replace Ringtone
          Priority: %priority
          Structure Output (JSON, etc): On ]   

Making ringtones

To set custom alarm sounds, we need custom sounds. I used Zedge app to download ambient weather effects and mixed it up with my alarm ringtone in Audacity or a similar audio editing program. To make them sound nice, simply let the sounds blend together by ramping down the volume of the track gently as the other one starts.

Look up the list of weather conditions in the OpenWeather API and name your files in the same way. If the weather says “Cloudy” you must name your file Cloudy.mp3. It will make the job of picking the right track easier. Place all of them, including your default alarm choice in a separate folder. Copy the default alarm tone out of that folder and pick a directory that you are going to use to store your alarm tone.

Tasker: picking alarm ringtones

I will show you how to pick your alarm ringtones based on weather “main” events, but you can take this further and use other data like temperature or wind speed to create your own custom conditions. When the forecast is found, action Copy File searches our base folder with all ringtones for the one that matches the weather condition. If one is found, the ringtone is copied and renamed to default alarm.mp3 in the chosen by you directory. If the match is not found, the file is replaced by the default one.

Tasker Task:: WA Replace Ringtone
                 Task: WA Replace Ringtone    
    A1: Variable Set [
         Name: %filename
         To: %WAforecast.weather.main
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A2: Variable Set [
         Name: %filename
         To: %filename.mp3
         Max Rounding Digits: 3
         Structure Output (JSON, etc): On ]
    
    A3: Flash [
         Text: %filename
         Continue Task Immediately: On
         Dismiss On Click: On ]
    
    A4: List Files [
         Directory: Ringtones/WeatherAlarmSounds
         Match: %filename
         Sort Select: Alphabetic
         Variable Array: %match
         Use Global Namespace: On ]
    
    
    A5: If [ %match1 Set ]
    
        A6: Copy File [
             From: Ringtones/WeatherAlarmSounds/%filename
             To: Ringtones/default alarm.mp3
             Use Global Namespace: On ]
    
    A7: End If
    
    
    A8: If [ %match1 !Set ]
    
        A9: Perform Task [
             Name: WA Default Ringtone
             Priority: %priority
             Structure Output (JSON, etc): On ]
    
    A10: End If  
Tasker Task: WA Default Ringtone
    Task: WA Default Ringtone    
    A1: Copy File [
         From: Ringtones/WeatherAlarmSounds/default alarm.mp3
         To: Ringtones/
         Use Global Namespace: On ] 

Final Thoughts

It’s been a great adventure making this from scratch on my live stream without a previous prep. I hope you learned a thing or two from this project and you make your start of the day more awesome. Obviously feel free to replace the sounds with anything you want, like custom songs or effects or even change the trigger. The sky is your limit. Let me know if you have any questions in this Reddit thread.

Project Download

Download project files here. Bear in mind that Patreon supporters have early access to project files and videos.

PayPal

Nothing says "Thank you" better than keeping my coffee jar topped up!

Patreon

Support me on Patreon and get an early access to tutorial files and videos.

image/svg+xml

Bitcoin (BTC)

Use this QR to keep me caffeinated with BTC: 1FwFqqh71mUTENcRe9q4s9AWFgoc8BA9ZU

New to Tasker?

Tasker Quick Start – Getting started with Tasker

0
From newb to not so newbie in 10 min

Best Tasker Projects

How to use Raspberry PI as WOL (wake on lan) server

0
While you could wake up your PC from a mobile directly, having a dedicated server capable of doing so is the best solution. The reason is simple. You can hook up as many devices as you wish with a single endpoint. This is why Raspberry Pi is perfect for this.

7 awesome Bluetooth keyboard shortcuts for Android

0
7 unique Android shortcuts that you can add to any Bluetooth keyboard.

Smart overnight charging with Tasker

0
Still keeping your phone plugged in overnight? Try smarter overnight charging with this profile

How to wake on LAN computers and put it to sleep with Power Menu,...

0
How to Wake on LAN properly via Android, Alexa, Google Assistant and Web

One thing that Join app can’t do and how to fix it with Tasker

0
It's not possible to share the clipboard automatically between join accounts registered to 2 different emails. But you can fix this with tasker.

Essential Guides

Tasker: Seconds into DD:HH:MM:SS (dynamic)

0
It's time to.... ok it's a pun, but I will show you how to master time and convert seconds to DD:HH:MM:SS dynamically

4 ways to organise Tasker projects

0
Keep your Tasker tidy!

A better way to store Tasker credentials

0
The more clever way of managing credentials

Annoyed with dozens of AutoApps populating your app drawer? Here is a fix!

0
Clear your app drawer from the clutter in seconds

Putting AutoTools pie chart to a good use – SSID logger

0
Who wants a piece of the pie (chart)?