When I installed Templater, I really liked the developer’s demo of using wttr.in to insert an icon-based day’s weather forecast into a daily note. I wanted to do something similar, but being a bit of a weather geek, I wanted a little more detail in mine. Fortunately, my favorite US weather source (the National Weather Service) has an API that lets one pull just about any element of current conditions or forecast data one could want. So I built a daily note template/process around that and thought I would share for any others interested in doing something similar.
tl;dr — daily cron job → URI scheme → automatic daily note creation → Templater function → custom curl command to get appropriate NWS API JSON document → insertion of extracted forecast text into daily note.
NWS API info
A good place to start learning about the NWS API is their API Github page. There’s a wealth of info there. The main info of relevance to this effort is in the General FAQs page, which steps you through the process of getting the forecast for your location through the API. All you need to start is your location in latitude/longitude. Querying the API using that, you’ll get a JSON document back that includes the link for pulling your forecast. For example, it reveals that mine is https://api.weather.gov/gridpoints/PSR/172,49/forecast.
Within the forecast JSON, you’ll see a “periods” section with several numbered periods beneath it. Those, as you’ll notice, are the different forecast periods (“tonight,” “Friday,” “Friday Night,” etc.). That will be relevant later.
Templater setup
To pull the weather data, I created a user-defined Templater function that runs the following shell command:
curl -s https://api.weather.gov/gridpoints/PSR/172,49/forecast | /usr/local/bin/fx-macos .properties.periods[1].detailedForecast
It has two parts. The part before the pipe uses cURL to retrieve the JSON document. The part after the pipe passes the document to a macOS-compatible binary of the FX tool (available as “fx-macos” here under the “releases” subfolder) to efficiently extract the text I want (from the “detailedForecast” field under the “periods” section labeled “1”).
Auto-creating the daily note
Since the period containing the day’s forecast changes with time (and goes away altogether once the day is ending), just counting on myself to manually create the note at the right time each day was a non-starter. I needed a way to automatically create the daily note at the same time each day. To do this, I brought four tools together to join forces: Obsidian’s URI scheme, the Obsidian Advanced URI plugin, AppleScript, and macOS’s trusty crontab. Here’s what they each bring to the table:
- URI scheme: provides a way to execute actions in Obsidian from outside the app
- Advanced Obsidian URI plugin: lets me use a URI to open the daily note
- AppleScript: provides a way to open/run a URI
- crontab: lets me schedule the triggering of an AppleScript command
Here’s the command I call from the cron job:
58 04 * * * osascript -e 'open location "obsidian://advanced-uri?vault=ObsidianBeta&daily=true"'
What this does: at 4:58am every day, that URI runs on my main computer (which is always on), causing Obsidian to go to the current daily note. Since that note doesn’t exist yet, it creates it, at which point Templater does its thing, getting the text from the NWS forecast and inserting it into my daily note. (It gets the text from period 1 instead of period 0 since at 4:58am period 0 is still the overnight forecast.) Here’s what today’s looked like, for example:
Mostly sunny. High near 100, with temperatures falling to around 97 in the afternoon. South wind 5 to 10 mph.
Whew! It took a bit of effort to get that text flowing, but it now works like a charm. Whenever I get around to opening my daily note that day, the forecast is right there at the top, concisely capturing the forecast for easy reference throughout the day and for posterity’s enjoyment for as long as the note lives.
Anyhow, hopefully this proves helpful to someone—or at least spurs some other Obsidian automation ideas using these components.
EDIT (07 December 2022)
Thanks to some tips from the Templater folks, I’ve refined the use of the template a bit. Instead of creating a custom user function in Templater’s settings, I now use the following code right in the body of the template MD file:
<%*
try {
const forecast = await fetch("https://api.weather.gov/gridpoints/GRR/45,15/forecast").then(res => res.json())
const detailedForecast = forecast.properties.periods[1].detailedForecast
tR += detailedForecast
} catch (err) {
new Notice("Error: \n" + err , 2000);
tR += "Data access error :("
}
%>
That effectively does the same thing as before but handles data errors such as 500 and 503 errors (which are annoyingly common with the NWS API, it seems) gracefully rather than halting the processing of the template. If the right data comes back, it inserts it. If not, it prints an alternative message to let me know what happened.