Winter has arrived and since there is no Windows Phone app for managing my pellet stove, I am working on a PowerShell module so that I know exactly how much my stove consumes by fetching the relevant data from the onboard management unit.
The module I am writing allows me to turn on and off my stove, and to configure it to suit my needs.
I have also added to this module a couple of additional functions to build a relation between the activity of my home stove with the data taken from the external weather data provider (I'll talk about this in a future post).
Now I live in a region where there can be strong winds that lower the temperature, so I thought necessary to add to my module a function specifically aimed at converting the wind direction (in degrees) into something more readable, such as one of the 16 compass headings as well as into its Italianate wind name.
This is what I am going to share with you here today.
I am not going to write an entire blog post on the history of the Rose of the Winds (there's a Wikipedia article for that), but, it is interesting to note that there are three possible ways to express a wind direction:
- in degress, such as 90°, 220° etc
- through its cardinal (north, south, east, west) and ordinal (northeast, southeast, southwest and northwest) directions
- through its italianate wind name
The italianate wind names, also known as the traditional wind names, derivate from the fact that during the 13th and 14th century the Italian was the lingua franca in the whole Mediterranean region, and sailors used it to name winds in an understandable way when crossing with people from from other countries.
So basically you have the following table with the eight principal winds:
Direction Italianate Name --------- -------------- North Tramontana Northeast Grecale or Bora East Levante or Oriente Southeast Scirocco or Exaloc South Ostro or Mezzogiorno Southwest Libeccio or Garbino West Ponente or Zephyrus Northwest Maestrale or Mistral
Now since I want my function to be more precise around the wind direction, I have choosen to adopt the 16-wind compass:
Direction Italianate Name --------- -------------- North Tramontana North Northeast Tramontana-Grecale Northeast Grecale East Northeast Grecale-Levante East Levante East Southeast Levante-Scirocco Southeast Scirocco South Southeast Scirocco-Ostro South Ostro South Southwest Ostro-Libeccio Southwest Libeccio West Southwest Libeccio-Ponente West Ponente West Northwest Ponente-Mastrale Northwest Maestrale North Northwest Maestrale-Tramontana
This is the function I came up with:
function Get-WindDirection { <# .Synopsis Returns wind direction .DESCRIPTION Returns wind direction and the italianate wind name .EXAMPLE Get-WindDirection -degress 90 .NOTES happysysadm.com @sysadm2010 #> [CmdletBinding()] [OutputType([string])] Param ( # Degrees [Parameter(Mandatory=$true,ValueFromPipeline=$true)] [ValidateRange(0,360)][int]$Degree ) Begin { $WindCompassDirection = @("North","North Northeast","Northeast","East Northeast","East","East Southeast", "Southeast", "South Southeast","South","South Southwest","Southwest","West Southwest","West","West Northwest","Northwest","North Northwest","North") $WindCompassName = @('Tramontana','Tramontana-Grecale','Grecale','Grecale-Levante','Levante','Levante-Scirocco','Scirocco','Scirocco-Ostro','Ostro','Ostro-Libeccio','Libeccio','Libeccio-Ponente','Ponente','Ponente-Mastrale','Maestrale','Maestrale-Tramontana','Tramontana') } Process { $Sector = $Degree/22.5 #Divide the angle by 22.5 because 360deg/16 directions = 22.5deg/direction change Write-Verbose "$Degree is in $Sector sector." $Value = "" | Select-Object -Property Direction,Name $Value.Direction = $WindCompassDirection[$Sector] $Value.Name = $WindCompassName[$Sector] return $Value } End {} }
Let's move to see it in detail and to explain the process of converting wind directions in degrees to text words.
The first step is to divide the given wind angle by 22.5 because 360 degrees divided by 16 directions gives sectors 22.5 degrees wide. So:
PS C:\> 23/22.5 1.02222222222222
which means that a wind coming from 23° is in the first sector, after rounding.
Another example:
PS C:\> 177/22.5 7.86666666666667
which means that a wind coming from 177° is in the 7th sector.
Let's put that value into a $Sector variable:
$Sector = $Degree/22.5
Now I just have to tag each sector by creating an array containing all of them. Actually I want two arrays because I want to be able to print the cardinal and ordinal direction along the italianate wind name.
Each arrays has 17 sectors, not 16, so that I am certain to translate a value such as 359° to North:
$WindCompassDirection = @("North","North Northeast","Northeast","East Northeast","East","East Southeast", "Southeast", "South Southeast","South","South Southwest","Southwest","West Southwest","West","West Northwest","Northwest","North Northwest","North") $ItalianateWindName = @('Tramontana','Tramontana-Grecale','Grecale','Grecale-Levante','Levante','Levante-Scirocco','Scirocco','Scirocco-Ostro','Ostro','Ostro-Libeccio','Libeccio','Libeccio-Ponente','Ponente','Ponente-Mastrale','Maestrale','Maestrale-Tramontana','Tramontana')
Now you already know for sure that you can echo back the value of an item (such as number 4) in a indexed PowerShell array with the following code:
$array[4]
This is the technique I use to access the value inside the array composed of wind names:
$value.Direction = $WindCompassDirection[$Sector] $value.ItalianateName = $ItalianateWindName[$Sector]
It is worth noticing that when $Sector is a Double, such in the case
PS C:\> 177/22.5 7.86666666666667
it is automatically converted to an integer when used as index for a value inside an array:
PS C:\> $WindCompassDirection[7.86666666666667] South
For sure we have to accept here the banker's rounding mechanism, which I have already explained in a previous post.
Stay tuned for more functions from my PowerShell module to manage a pellet stove in those cold times.
Happy new year, readers, and happy coding.
Fun article. I hadn't ever heard of italianate names before. Thanks for sharing!
ReplyDeletenice
ReplyDelete