Recently I spoke at an event where we did a hands-on exercise to create a simple Power Automate Flow, which sends a daily weather summary to my inbox at 6am every day. Afterwards, I made some enhancements to the layout and thought I would share this with you.
At high-level, the Flow is very simple: Get the weather and send the details to my inbox. Under the bonnet I had to draw on some relatively complex expressions to ensure the output was exactly as I needed. I will go into those complexities at the end. As part of this blog, I'm giving you a simple script to copy/paste into your flow which will handle all of those complexities!
This is a preview of what you will get:
The Flow has a trigger, and two actions.
Trigger: Run on a schedule.
Action: Get the Weather from MSN Weather.
Action: Send me an email with the daily forecast.
Let's Make it!
Follow these simple steps, and you'll have this up and running in about 5 minutes!
Go to https://make.powerautomate.com and sign in with your Work or School account.
Trigger
Search for Recurrence in the connectors & actions box.
Set this for whatever time you want. I opted for 6am daily.
Get My Weather
Search for the MSN Weather connector and choose the Get forecast for today action. You can see all of the available outputs at this site.
In the location, put something specific enough like Locality, City, Country.
Choose Metric (Celcius, Kilometres) or Imperial (Fahrenheit, Miles) as you prefer.
Rename this action to Get My Weather. It's important as the code I shared below needs that exact name.
Send an Email
Search for Send an email (V2) action which is part of the Office 365 Outlook connector.
The first time you do this, you'll need to log into your account. This will be used as the sender of the email. You can use a different account if you have access to one, like support@yourcompany.com
Put your email address and preferred subject in the To and Subject boxes.
In the body part, select the </> icon and switch to Code View, paste in the below and the email will be nicely formatted for you.
There are some parts of the code you will need to customise, they are highlighted in red in the code below
Your name in the greeting
The To timezone. Choose yours from the Timezone column at this website.
Save & test. You are done! Did you get the email?
The Email body code. Copy Paste this in the Send an Email step above. But make sure to change the red parts first.
<p><span style="font-size: 18px; font-family:Helvetica;color: rgb(44,130,201)"><strong>Hi Ben, here's your daily weather summary</strong></span></p>
<span style="font-size: 14px; font-family:Helvetica">
<ul>
<li>Location: @{outputs('Get_My_Weather')?['body/responses/source/location']}</li>
<li>Temp: @{outputs('Get_My_Weather')?['body/responses/daily/tempLo']}-@{outputs('Get_My_Weather')?['body/responses/daily/tempHi']} @{outputs('Get_My_Weather')?['body/units/temperature']}</li>
<li>Sunrise/set: @{formatDateTime(convertTimeZone(outputs('Get_My_Weather')['body/responses/almanac/sunrise'],'UTC','GMT Standard Time'),'HH:mm')}/@{formatDateTime(convertTimeZone(outputs('Get_My_Weather')['body/responses/almanac/sunset'],'UTC','GMT Standard Time'),'HH:mm')}</li>
<li>UV Index: @{outputs('Get_My_Weather')?['body/responses/daily/uv']} (@{outputs('Get_My_Weather')?['body/responses/daily/uvDesc']})
<li>☀️ Day</li>
<ul>
<li>@{outputs('Get_My_Weather')?['body/responses/daily/day/summary']}</li>
<li>@{outputs('Get_My_Weather')?['body/responses/daily/day/precip']}% chance rain</li>
<li>Wind: @{outputs('Get_My_Weather')?['body/responses/daily/day/windSpd']} @{outputs('Get_My_Weather')?['body/units/speed']} in @{createArray('Northerly','North Easterly','Easterly','South Easterly','Southerly','South Westerly','Westerly','North Westerly','Northerly')[sub(int(formatNumber(div(add(22.5,outputs('Get_My_Weather')?['body/responses/daily/night/windSpd']),45),'#0')),1)]} direction</li>
<li>Humidity: @{outputs('Get_My_Weather')?['body/responses/daily/rhLo']}-@{outputs('Get_My_Weather')?['body/responses/daily/rhHi']}% </li>
</ul>
</li>
<li>⭐ Evening
<ul>
<li>@{outputs('Get_My_Weather')?['body/responses/daily/night/summary']}</li>
<li>@{outputs('Get_My_Weather')?['body/responses/daily/night/precip']}% chance rain</li>
<li>Wind: @{outputs('Get_My_Weather')?['body/responses/daily/night/windSpd']} @{outputs('Get_My_Weather')?['body/units/speed']} in @{createArray('Northerly','North Easterly','Easterly','South Easterly','Southerly','South Westerly','Westerly','North Westerly','Northerly')[sub(int(formatNumber(div(add(22.5,outputs('Get_My_Weather')?['body/responses/daily/night/windSpd']),45),'#0')),1)]} direction</li>
</ul>
</li>
<li>🌙 Moon
<ul>
<li>@{outputs('Get_My_Weather')?['body/responses/almanac/moonPhase']}</li>
<li>Moonrise/set: @{formatDateTime(convertTimeZone(outputs('Get_My_Weather')?['body/responses/almanac/moonrise'],'UTC','GMT Standard Time'),'HH:mm')}/@{formatDateTime(convertTimeZone(outputs('Get_My_Weather')?['body/responses/almanac/moonset'],'UTC','GMT Standard Time'),'HH:mm')}</li>
</ul>
</li>
</ul>
</span>
<span style="font-size: 12px; font-family:Helvetica; font-style: italic">
</i>Your daily forecast data was derived at @{formatDateTime(convertTimeZone(outputs('Get_My_Weather')['body/responses/daily/created'],'UTC','GMT Standard Time'),'dd/MM/yyyy HH:mm')}</i>
</span>
Complexities: Let's explore expressions.
The steps above should only take 3-5 minutes. If this is your first Power Automate Flow and are looking to learn a little more of the programming side of things, then read on.
Normally, if you want to use the output of a previous step, you can grab it from the Dynamic content window which pops up, see the red circle/arrow below? If you need to manipulate that content, then you need to switch to an Expression, where you can edit/transform/adjust the data as you need. See the blue circle/arrow below?
In the code I shared, you will see I've used some expressions to format the data the way I need it. Expressions allow you to perform actions that aren't necessarily available in the drag/drop manner. There is much more you can do with Power Automate, if you learn the coding side of things.
You can see all of the available expressions at this site.
Format dates & switch time zone
The Sun & Moon rise/set times come in a full date & time like 2023-07-05 05:15:35, and furthermore it's in the UTC time zone. My goal is to show these in the email as my local time zone and just the clock time, like 05:15.
Here are the steps, which you can see in the code highlighted in blue in the code snippet above.
Get the Sunrise time from the step with this expression: outputs('Get_My_Weather')['body/responses/almanac/sunrise']
Convert that time to my time zone the convertTimeZone expression.
Format the time to HH:MM using the formatDateTime expression.
The final result is long, but if you break it down, you can see what it's doing
formatDateTime(convertTimeZone(outputs('Get_My_Weather')['body/responses/almanac/sunrise'],'UTC','GMT Standard Time'),'HH:mm')
Format the Wind direction
The wind direction given in the MSN Weather connector is in degrees from 0 to 359. I'd prefer a more relatable label, like Northerly, North Easterly, Easterly, etc. This one involved a little bit of maths and an array to change a number to a label.
With the 8 directions I wanted to use, I need to switch the degrees value from the MSN Weather connector, to a number between 1 & 8, then map that to an array I created containing the 8 wind directions (four for Nth/Sth/Est/West and the four mid-points between)
Given zero represents North, then from 0-22.5 and from 337.5-359 all represent North. From 22.5 to 67.5 represents North Easterly, and so on.
Let's look at it visually:
The logic I used goes like this:
A. Create an array with the 8 directions in the correct order. I need Northerly at the beginning and the end, as it numerically exists at the beginning range (0-22.5) and the end range (337.5-350). Therefore, it's actually 9 items we need.
createArray('Northerly','North Easterly','Easterly','South Easterly','Southerly','South Westerly','Westerly','North Westerly','Northerly')
B. Now I need to turn the 0-359 number into a relative position in the array, to grab the correct value.
First I need to offset the value by 22.5. This is because North doesn't represent 0-45 degrees, it's the range left and right of the natural 0,45,90,etc.
add(22.5,outputs('Get_My_Weather')?['body/responses/daily/night/windSpd'])
C. Divide that number by 45, to get a number between 1-9 giving *almost* the ordinal position in the array to get the label.
div(B,45)
D. The number from step C is a decimal number, so I need to round it down and subtract 1 to get the correct ordinal position
sub(int(C),1)
E. We piece it together and get the Nth (from step D) item in the array from step A in the format array[position], or A[D] which explodes out to the full script of:
createArray(
'Northerly','North Easterly','Easterly',
'South Easterly','Southerly','South Westerly',
'Westerly','North Westerly','Northerly')
[sub(
int(
formatNumber(
div(
add(22.5,outputs('Get_My_Weather')?['body/responses/daily/night/windSpd']),
45),
'#0'))
,1)
]
Phew! This was actually a little more complicated than I normally need to dive into with Power Automate, so don't let it frighten you off learning the code.
Links
MSN Weather output
Power Automate Expression Reference
Windows Default Time zones
Comments