Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for weerlive.ps

(view source code of weerlive.ps as plain text)

  1. <#
  2. .SYNOPSIS
  3. NL: Toon actuele KNMI weergegevens
  4. EN: Show live Dutch weather data from the Dutch KNMI weather institute
  5.  
  6. .DESCRIPTION
  7. NL:
  8.  
  9. Dit script toont actuele KNMI weergegevens m.b.v. de Weerlive API.
  10. De Weerlive API stelt elke 10 minuten actuele weergegevens beschikbaar.
  11. Alle opgehaalde gegevens worden door dit script in het console venster weergegeven.
  12. Daarnaast wordt de afgeronde waarde van de actuele temperatuur in een pictogram in de "System Tray" getoond.
  13. Door te klikken op dit pictogram, wordt het console venster verborgen of juist weer hersteld.
  14. Om van de Weerlive API gebruik te mogen maken, hebt u een API key nodig (gratis voor persoonlijk en educatief gebruik), die u bij Weerlive.nl kunt aanvragen (zie link).
  15. Deze API key en de lokatie waarvoor de gegevens worden opgevraagd, dient u op te geven op de commandoregel of in te vullen bij na starten van het script of op te slaan in een tekstbestand "weerlive.cfg" dat zich in de zelfde map moet bevinden als dit script.
  16. Het bestand "weerlive.cfg" bevat 2 regels tekst:
  17.  
  18. key=uw_persoonlijke_api_key
  19. loc=gewenste_lokatie
  20.  
  21. Het script kan netjes afgesloten worden door een willekeurige toetsaanslag in het console venster.
  22.  
  23. EN:
  24.  
  25. This script shows live Dutch weather data from the Dutch KNMI weather institute, using the Weerlive live weather API.
  26. This API makes live weather data available once every 10 minutes.
  27. All data will be displayed in this script's console window.
  28. The rounded actual temperature will also be shown in the System Tray a.k.a. Notification Area.
  29. By clicking the icon in the Notification Area, this script's console window will be hidden or restored again.
  30. Use of the Weerlive API requires an API key (free for personal or educational use), which you can request at Weerlive.nl (see link).
  31. This API key and the location for which the data will be fetched, must either be specified on the command line or entered in a popup window when the script is started or be saved in a plain text file named "weerlive.cfg", located in the script's parent folder.
  32. The file "weerlive,cfg" contains only 2 lines of text:
  33.  
  34. key=your_personal_api_key
  35. loc=your_location
  36.  
  37. The script can be terminated gracefully by pressing any key in the console window.
  38.  
  39. Note that a basic knowledge of the Dutch language is required to get this script working with your own API key.
  40.  
  41. .PARAMETER Location
  42. NL: De plaatsnaam voor de weersgegevens. Indien zowel op de commandoregel als in een configuratiebestand een lokatie wordt opgegeven, prevaleert de commandoregel. Indien er geen plaatsnaam is opgegeven op de commandoregel en ook niet in een configuratiebestand, dan wordt een invulscherm geopend om deze alsnog in te voeren. Als APIKey en Location beide op de opdrachtregel worden meegegeven, en het configuratiebestand weerlive.cfg bestaat nog niet, dan wordt dit bestand aangemaakt.
  43. EN: De location used for the weather query. If the location is specified both on the command line sa well as in a configuration file, the command line prevails. If no location is specified on the command line and neither in a configuration file, a popup window will appear where the locatien can be specified. If both APIKey and Location are specified on the command line, and the configuration file weerlive.cfg does not exist, it will be created..
  44.  
  45. .PARAMETER APIKey
  46. NL: De API key voor het opvragen van de weersgegevens. Indien zowel op de commandoregel als in een configuratiebestand een API key wordt opgegeven, prevaleert de commandoregel. Indien er geen API key is opgegeven op de commandoregel en ook niet in een configuratiebestand, dan wordt een invulscherm geopend om deze alsnog in te voeren. Als APIKey en Location beide op de opdrachtregel worden meegegeven, en het configuratiebestand weerlive.cfg bestaat nog niet, dan wordt dit bestand aangemaakt.
  47. EN: De API key required for the weather query. If an API key is specified both on the command line as well as in a configuration file, the command line prevails. If no API key is specified on the command line and neither in a configuration file, a popup window will appear where an API key can be specified. If both APIKey and Location are specified on the command line, and the configuration file weerlive.cfg does not exist, it will be created.
  48.  
  49. .PARAMETER NoSave
  50. NL: Voorkomt dat de waarden van APIKey en Location die op de opdrachtregel worden meegegeven, bij opslaan een bestaand configuratiebestand overschrijven.
  51. EN: Prevent APIKey and Location values on the command line from overwriting an existing configuration file.
  52.  
  53. .PARAMETER Edit
  54. NL: Opent het invulvenster voor API key en plaatsnaam bij opstarten van het script. Dit invulvenster verschijnt ook als API key of plaatsnaam niet opgegeven zijn.
  55. EN: Opens the configuration window to enter an API key and location at startup of this script. This window will also be opened if API key or location aren't specified.
  56.  
  57. .PARAMETER Hide
  58. NL: Verberg het console venster direct na opstarten van het script. Klik op het icoon in de "System Tray" om het console venster te herstellen.
  59. EN: Hide this script's console immediately after starting the script. Clicking the icon in the Notification area will restore the console again.
  60.  
  61. .PARAMETER Help
  62. NL: Toon deze uitleg.
  63. EN: Show this help text.
  64.  
  65. .PARAMETER Version
  66. NL: Toon de versie van dit script. Gecombineerd met de -Verbose parameter worden daarnaast ook het volledige pad en de laatste wijzigings- of publikatiedatum van het script getoond.
  67. EN: Show this script's version. If combined with the -Verbose switch, the script's full path and last modified or release date will be shown as well.
  68.  
  69. .PARAMETER Verbose
  70. NL: Toon uitgebreidere versie-informatie bij gebruik van de -Version parameter.
  71. EN: Show verbose version information when using the -Version switch.
  72.  
  73. .LINK
  74. NL:                                              EN:
  75.  
  76. .LINK
  77. Script geschreven door Rob van der Woude:        Script written by Rob van der Woude:
  78. https://www.robvanderwoude.com/                  https://www.robvanderwoude.com/
  79.  
  80. .LINK
  81. KNMI Weergegevens via Weerlive.nl API:           Dutch KNMI weather data by Weerlive.nl API:
  82. http://weerlive.nl/delen.php                     http://weerlive.nl/delen.php
  83.  
  84. .LINK
  85. Weerlive API key aanvragen:                      Request Weerlive API key:
  86. http://weerlive.nl/api/toegang/index.php         http://weerlive.nl/api/toegang/index.php
  87.  
  88. .LINK
  89. Tabel met alle geldige plaatsnamen:              Table of valid location names:
  90. http://weerlive.nl/plaatsnamen.php               http://weerlive.nl/plaatsnamen.php
  91. #>
  92.  
  93. param (
  94. 	[string]$Location,
  95. 	[string]$APIKey,
  96. 	[switch]$NoSave,
  97. 	[switch]$Edit,
  98. 	[switch]$Hide,
  99. 	[switch]$Help,
  100. 	[switch]$Version,
  101. 	[switch]$Verbose
  102. )
  103.  
  104. $progver = "1.00"
  105.  
  106. Add-Type -AssemblyName System.Drawing
  107. Add-Type -AssemblyName System.Text.RegularExpressions
  108. Add-Type -AssemblyName System.Windows.Forms
  109.  
  110. Clear-Host
  111.  
  112. if ( $Version ) {
  113. 	if ( $Verbose ) {
  114. 		$lastmod = ( [System.IO.File]::GetLastWriteTime( $PSCommandPath ) )
  115. 		if ( $lastmod.ToString( "h.mm" ) -eq $progver ) {
  116. 			"`"{0}`", Version {1}, release date {2}" -f $PSCommandPath, $progver, $lastmod.ToString( "yyyy-MM-dd" )
  117. 		} else {
  118. 			# if last modified time is not equal to program version, the script has been tampered with
  119. 			"`"{0}`", Version {1}, last modified date {2}" -f $PSCommandPath, $progver, $lastmod.ToString( "yyyy-MM-dd" )
  120. 		}
  121. 	} else {
  122. 		$progver
  123. 	}
  124. 	exit 0
  125. }
  126.  
  127. if ( $Help -or ( [System.Environment]::CommandLine -match "[/\?]" ) ) {
  128. 	Get-Help $PSCommandPath -Full
  129. 	exit 1
  130. }
  131.  
  132. $configfile = ( Join-Path $PSScriptRoot 'weerlive.cfg' )
  133. $cachefile = ( Join-Path $PSScriptRoot 'weerlive.dat' )
  134. if ( ![string]::IsNullOrWhiteSpace( $APIKey ) -and ![string]::IsNullOrWhiteSpace( $Location ) ) {
  135. 	Remove-Item -Path $cachefile -Force
  136. 	# Write command line APIKey and Location values to configuration file if that does not yet exist, unless NoSave switch was used
  137. 	if ( !$NoSave -and !( Test-Path -Path $configfile -PathType Leaf ) ) {
  138. 		( "key={0}`nloc={1}" -f $APIKey, $Location ) | Out-File -FilePath $configfile -Force -Encoding 'ASCII'
  139. 	}
  140. }
  141.  
  142. function Get-Locations( ) {
  143. 	$url = "http://weerlive.nl/plaatsnamen.php"
  144. 	$ProgressPreference = 'SilentlyContinue'
  145. 	$html = ( Invoke-WebRequest -Uri $url -TimeoutSec 10 ).Content
  146. 	$ProgressPreference = 'Continue'
  147. 	$pattern = '<tr><td><b><a href=\"weer.php\?plaatsnaam=([^\"]+)\"'
  148. 	$matches = [System.Text.RegularExpressions.Regex]::Matches( $html, $pattern )
  149. 	@( $matches | ForEach-Object { $_.Groups[1].Value } )
  150. }
  151.  
  152. function Read-Config( ) {
  153. 	if ( Test-Path -Path $configfile -PathType Leaf ) {
  154. 		# APIKey and Location from configuration file, if it exists
  155. 		$configtext = ( Get-Content -Path $configfile -ErrorAction Stop )
  156. 		$Global:APIKey = ( $configtext | Select-String -Pattern 'key=([^\n]+)' ).Matches[0].Groups[1].Value
  157. 		$Global:Location = ( $configtext | Select-String -Pattern 'loc=([^\n]+)' ).Matches[0].Groups[1].Value
  158. 	} else {
  159. 		# use a popup window to retrieve APIKey and Location interactively
  160. 		Edit-Config
  161. 	}
  162. }
  163.  
  164. function Edit-Config( ) {
  165. 	$FormWeerliveConfig = New-Object -TypeName System.Windows.Forms.Form
  166. 	[System.Windows.Forms.Label]$labelAPIKey = $null
  167. 	[System.Windows.Forms.Label]$labelLocation = $null
  168. 	[System.Windows.Forms.ComboBox]$comboboxLocation = $null
  169. 	[System.Windows.Forms.TextBox]$textboxAPIKey = $null
  170. 	[System.Windows.Forms.Button]$buttonRequestAPIKey = $null
  171. 	[System.Windows.Forms.Button]$buttonSave = $null
  172. 	[System.Windows.Forms.Button]$buttonCancel = $null
  173.  
  174. 	$labelAPIKey = ( New-Object -TypeName System.Windows.Forms.Label )
  175. 	$labelLocation = ( New-Object -TypeName System.Windows.Forms.Label )
  176. 	$comboboxLocation = ( New-Object -TypeName System.Windows.Forms.ComboBox )
  177. 	$textboxAPIKey = ( New-Object -TypeName System.Windows.Forms.TextBox )
  178. 	$buttonRequestAPIKey = ( New-Object -TypeName System.Windows.Forms.Button )
  179. 	$buttonSave = ( New-Object -TypeName System.Windows.Forms.Button )
  180. 	$buttonCancel = ( New-Object -TypeName System.Windows.Forms.Button )
  181. 	$FormWeerliveConfig.SuspendLayout( )
  182. 	#
  183. 	#labelAPIKey
  184. 	#
  185. 	$labelAPIKey.AutoSize = $true
  186. 	$labelAPIKey.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]25, [System.Int32]29 ) )
  187. 	$labelAPIKey.Name = [System.String]'labelAPIKey'
  188. 	$labelAPIKey.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]114, [System.Int32]17 ) )
  189. 	$labelAPIKey.TabIndex = [System.Int32]5
  190. 	$labelAPIKey.Text = [System.String]'Weerlive API key'
  191. 	#
  192. 	#labelLocation
  193. 	#
  194. 	$labelLocation.AutoSize = $true
  195. 	$labelLocation.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]25, [System.Int32]73 ) )
  196. 	$labelLocation.Name = [System.String]'labelLocation'
  197. 	$labelLocation.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]82, [System.Int32]17 ) )
  198. 	$labelLocation.TabIndex = [System.Int32]6
  199. 	$labelLocation.Text = [System.String]'Plaatsnaam'
  200. 	#
  201. 	#comboboxLocation
  202. 	#
  203. 	$comboboxLocation.FormattingEnabled = $true
  204. 	$comboboxLocation.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]157, [System.Int32]70 ) )
  205. 	$comboboxLocation.Name = [System.String]'comboboxLocation'
  206. 	$comboboxLocation.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]121, [System.Int32]24 ) )
  207. 	$comboboxLocation.TabIndex = [System.Int32]1
  208. 	$comboboxLocation.DisplayMember = 'Value'
  209. 	$comboboxLocation.ValueMember = 'Value'
  210. 	$comboboxLocation.Datasource = ( Get-Locations )
  211. 	$comboboxLocation.SelectedValue = $Location
  212. 	#
  213. 	#textboxAPIKey
  214. 	#
  215. 	$textboxAPIKey.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]157, [System.Int32]29 ) )
  216. 	$textboxAPIKey.Name = [System.String]'textboxAPIKey'
  217. 	$textboxAPIKey.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]121, [System.Int32]23 ) )
  218. 	$textboxAPIKey.TabIndex = [System.Int32]0
  219. 	$textboxAPIKey.Text = $APIKey
  220. 	#
  221. 	#buttonRequestAPIKey
  222. 	#
  223. 	$buttonRequestAPIKey.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]303, [System.Int32]25 ) )
  224. 	$buttonRequestAPIKey.Name = [System.String]'buttonRequestAPIKey'
  225. 	$buttonRequestAPIKey.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]140, [System.Int32]30 ) )
  226. 	$buttonRequestAPIKey.TabIndex = [System.Int32]4
  227. 	$buttonRequestAPIKey.Text = [System.String]'Nieuwe aanvragen'
  228. 	$buttonRequestAPIKey.UseVisualStyleBackColor = $true
  229. 	$buttonRequestAPIKey.add_Click( $buttonRequestAPIKey_Click )
  230. 	#
  231. 	#buttonSave
  232. 	#
  233. 	$buttonSave.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]28, [System.Int32]131 ) )
  234. 	$buttonSave.Name = [System.String]'buttonSave'
  235. 	$buttonSave.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]140, [System.Int32]30 ) )
  236. 	$buttonSave.TabIndex = [System.Int32]2
  237. 	$buttonSave.Text = [System.String]'Opslaan'
  238. 	$buttonSave.DialogResult = [System.Windows.Forms.DialogResult]::OK
  239. 	$buttonSave.UseVisualStyleBackColor = $true
  240. 	$buttonSave.add_Click( $buttonSave_Click )
  241. 	#
  242. 	#buttonCancel
  243. 	#
  244. 	$buttonCancel.Location = ( New-Object -TypeName System.Drawing.Point -ArgumentList @( [System.Int32]303, [System.Int32]131 ) )
  245. 	$buttonCancel.Name = [System.String]'buttonCancel'
  246. 	$buttonCancel.Size = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]140, [System.Int32]30 ) )
  247. 	$buttonCancel.TabIndex = [System.Int32]3
  248. 	$buttonCancel.Text = [System.String]'Annuleren'
  249. 	$buttonCancel.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
  250. 	$buttonCancel.UseVisualStyleBackColor = $true
  251. 	$buttonCancel.add_Click( $buttonCancel_Click )
  252. 	#
  253. 	#FormWeerliveConfig
  254. 	#
  255. 	$FormWeerliveConfig.ClientSize = ( New-Object -TypeName System.Drawing.Size -ArgumentList @( [System.Int32]485, [System.Int32]200 ) )
  256. 	$FormWeerliveConfig.Controls.Add( $buttonCancel )
  257. 	$FormWeerliveConfig.Controls.Add( $buttonSave )
  258. 	$FormWeerliveConfig.Controls.Add( $buttonRequestAPIKey )
  259. 	$FormWeerliveConfig.Controls.Add( $textboxAPIKey )
  260. 	$FormWeerliveConfig.Controls.Add( $comboboxLocation )
  261. 	$FormWeerliveConfig.Controls.Add( $labelLocation )
  262. 	$FormWeerliveConfig.Controls.Add( $labelAPIKey )
  263. 	$FormWeerliveConfig.Font = ( New-Object -TypeName System.Drawing.Font -ArgumentList @( [System.String]'Microsoft Sans Serif', [System.Single]10, [System.Drawing.FontStyle]::Regular, [System.Drawing.GraphicsUnit]::Point,([System.Byte][System.Byte]0 ) ) )
  264. 	$FormWeerliveConfig.Name = [System.String]'FormWeerliveConfig'
  265. 	$FormWeerliveConfig.Text = [System.String]'Weerlive configuratie'
  266. 	$FormWeerliveConfig.AcceptButton = $buttonSave
  267. 	$FormWeerliveConfig.CancelButton = $buttonCancel
  268. 	$FormWeerliveConfig.add_KeyUp( $FormWeerliveConfig_KeyUp )
  269. 	#$FormWeerliveConfig.add_Shown( $FormWeerliveConfig_Shown )
  270. 	$FormWeerliveConfig.add_Shown( { $comboboxLocation.SelectedItem = "$Location" } )
  271. 	$FormWeerliveConfig.ResumeLayout( $false )
  272. 	$FormWeerliveConfig.PerformLayout( )
  273. 	Add-Member -InputObject $FormWeerliveConfig -Name base -Value $base -MemberType NoteProperty
  274. 	Add-Member -InputObject $FormWeerliveConfig -Name labelAPIKey -Value $labelAPIKey -MemberType NoteProperty
  275. 	Add-Member -InputObject $FormWeerliveConfig -Name labelLocation -Value $labelLocation -MemberType NoteProperty
  276. 	Add-Member -InputObject $FormWeerliveConfig -Name comboboxLocation -Value $comboboxLocation -MemberType NoteProperty
  277. 	Add-Member -InputObject $FormWeerliveConfig -Name textboxAPIKey -Value $textboxAPIKey -MemberType NoteProperty
  278. 	Add-Member -InputObject $FormWeerliveConfig -Name buttonRequestAPIKey -Value $buttonRequestAPIKey -MemberType NoteProperty
  279. 	Add-Member -InputObject $FormWeerliveConfig -Name buttonSave -Value $buttonSave -MemberType NoteProperty
  280. 	Add-Member -InputObject $FormWeerliveConfig -Name buttonCancel -Value $buttonCancel -MemberType NoteProperty
  281.  
  282. 	[void] $FormWeerliveConfig.ShowDialog( )
  283. }
  284.  
  285. if ( $Edit -or !$APIKey -or !$Location ) {
  286. 	Read-Config
  287. }
  288.  
  289. if ( $Edit ) {
  290. 	$locations = ( Get-Locations )
  291. 	Edit-Config
  292. }
  293.  
  294. $Global:consolestatus = 1
  295.  
  296. #######################################
  297. # Hide console window                 #
  298. # by Anthony on StackOverflow.com     #
  299. # http://stackoverflow.com/a/15079092 #
  300. #######################################
  301.  
  302. $signature1 = @'
  303. public static void ShowConsoleWindow( int state )
  304. {
  305. 	var handle = GetConsoleWindow( );
  306. 	ShowWindow( handle, state );
  307. }
  308.  
  309. [System.Runtime.InteropServices.DllImport( "kernel32.dll" )]
  310. static extern IntPtr GetConsoleWindow( );
  311.  
  312. [System.Runtime.InteropServices.DllImport( "user32.dll" )]
  313. static extern bool ShowWindow( IntPtr hWnd, int nCmdShow );
  314. '@
  315.  
  316. # Hide console if requested
  317. if ( $Hide ) {
  318. 	$hideconsole = Add-Type -MemberDefinition $signature1 -Name Hide -Namespace HideConsole -ReferencedAssemblies System.Runtime.InteropServices -PassThru
  319. 	$Global:consolestatus = 0
  320. 	$hideconsole::ShowConsoleWindow( $Global:consolestatus )
  321. }
  322.  
  323. #######################
  324. # End of Hide console #
  325. #######################
  326.  
  327. ##################
  328. # Event Handlers #
  329. ##################
  330.  
  331. $buttonRequestAPIKey_Click = {
  332. 	$url = "http://weerlive.nl/api/toegang/index.php"
  333. 	Start-Process $url
  334. }
  335.  
  336. $buttonSave_Click = {
  337. 	if ( Test-Path -Path $configfile -PathType Leaf ) {
  338. 		# Backup current configuration file if it exists
  339. 		$backupcfg = "$configfile.bak"
  340. 		Get-Content -Path $configfile -ErrorAction SilentlyContinue | Out-File -FilePath $backupcfg -Encoding ASCII -Force
  341. 	}
  342. 	( "key={0}`nloc={1}`n" -f $textboxAPIKey.Text, $comboboxLocation.SelectedItem ) | Out-File -FilePath $configfile -Encoding ASCII -Force
  343. 	Start-Sleep -Seconds 1
  344. 	$FormWeerliveConfig.Close( )
  345. }
  346.  
  347. $buttonCancel_Click = {
  348. 	$FormWeerliveConfig.Close( )
  349. }
  350.  
  351. $Icon_Click = {
  352. 	if ( $Global:consolestatus -eq 0 ) {
  353. 		# Restore the hidden console window
  354. 		$Global:consolestatus = 9
  355. 		$hideconsole::ShowConsoleWindow( $Global:consolestatus )
  356. 	} else {
  357. 		# Hide console window
  358. 		$Global:consolestatus = 0
  359. 		$hideconsole::ShowConsoleWindow( $Global:consolestatus )
  360. 	}
  361. }
  362.  
  363. #########################
  364. # End of Event Handlers #
  365. #########################
  366.  
  367. function Fetch-WeerData( ) {
  368. 	$url = ( 'http://weerlive.nl/api/json-data-10min.php?key={0}&locatie={1}' -f $APIKey, $Location )
  369. 	if ( ( Test-Path -Path $cachefile -PathType 'Leaf' ) -and ( ( Get-Item -Path $cachefile ).LastWriteTime -gt ( Get-Date ).AddMinutes( -10 ) ) ) {
  370. 		$cacheage = ( [System.Math]::Round( ( ( Get-Date ) - ( Get-Item -Path $cachefile ).LastWriteTime ).TotalMinutes ) )
  371. 		# Fetch cached JSON weather data
  372. 		$json = ( Get-Content -Path $cachefile )
  373. 	} else {
  374. 		$ProgressPreference = 'SilentlyContinue'
  375. 		# Fetch live JSON weather data from Weerlive.nl
  376. 		$json = ( Invoke-WebRequest -Uri $url -TimeoutSec 10 ).Content
  377. 		$ProgressPreference = 'Continue'
  378. 		# Cache the weather data, to prevent exceeding the maximum daily allowance of live requests
  379. 		$json | Out-File -FilePath $cachefile -Force
  380. 	}
  381. 	$json
  382. }
  383.  
  384. # Define properties for System Tray icon
  385. $Global:fontfamily = [System.Drawing.FontFamily]::GenericSansSerif
  386. $Global:fontstyle = [System.Drawing.FontStyle]::Bold
  387. $Global:font = [System.Drawing.Font]::new( $fontfamily, 7, $fontstyle )
  388. $Global:blackbrush = [System.Drawing.Brushes]::Black
  389. $Global:bluebrush = [System.Drawing.Brushes]::LightBlue
  390. $Global:brightgreenbrush = [System.Drawing.Brushes]::LightGreen
  391. $Global:greenbrush = [System.Drawing.Brushes]::Green
  392. $Global:orangebrush = [System.Drawing.Brushes]::Orange
  393. $Global:redbrush = [System.Drawing.Brushes]::Red
  394. $Global:whitebrush = [System.Drawing.Brushes]::White
  395. $Global:yellowbrush = [System.Drawing.Brushes]::Yellow
  396. $Global:stringformat = [System.Drawing.StringFormat]::GenericDefault
  397.  
  398. function Create-Icon( ) {
  399. 	param (
  400. 		[Parameter(Mandatory)]$degrees
  401. 	)
  402. 	$bgbrush = $Global:yellowbrush
  403. 	$fgbrush = $Global:blackbrush
  404. 	[int]$temperature = -273
  405. 	if ( [System.Int32]::TryParse( $degrees, [ref] $temperature ) ) {
  406. 	 	if ( $temperature -le 0 ) {
  407. 			$bgbrush = $Global:bluebrush
  408. 			$fgbrush = $Global:blackbrush
  409. 		}
  410. 		if ( ( $temperature -gt 0 ) -and ( $temperature -lt 15 ) ) {
  411. 			$bgbrush = $Global:greenbrush
  412. 			$fgbrush = $Global:whitebrush
  413. 		}
  414. 		if ( ( $temperature -ge 15 ) -and ( $temperature -le 20 ) ) {
  415. 			$bgbrush = $Global:brightgreenbrush
  416. 			$fgbrush = $Global:blackbrush
  417. 		}
  418. 		if ( ( $temperature -gt 20 ) -and ( $temperature -lt 25 ) ) {
  419. 			$bgbrush = $Global:yellowbrush
  420. 			$fgbrush = $Global:blackbrush
  421. 		}
  422. 		if ( ( $temperature -ge 25 ) -and ( $temperature -lt 30 ) ) {
  423. 			$bgbrush = $Global:orangebrush
  424. 			$fgbrush = $Global:blackbrush
  425. 		}
  426. 		if ( $temperature -ge 30 ) {
  427. 			$bgbrush = $Global:redbrush
  428. 			$fgbrush = $Global:whitebrush
  429. 		}
  430. 	}
  431. 	$bitmap = [System.Drawing.Bitmap]::new( 16, 16 )
  432. 	$graphic = [System.Drawing.Graphics]::FromImage( $bitmap )
  433. 	$graphic.FillEllipse( $bgbrush, 0, 0, 16, 16 )
  434. 	$textsize = $graphic.MeasureString( $degrees, $Global:font )
  435. 	if ( $textsize.Width -gt 14 ) {
  436. 		$font = [System.Drawing.Font]::new( $Global:fontfamily, $Global:font.Size * 0.8, $Global:fontstyle )
  437. 		$textsize = $graphic.MeasureString( $text, $Global:font )
  438. 	}
  439. 	if ( $textsize.Width -lt 11.2 ) {
  440. 		$font = [System.Drawing.Font]::new( $Global:fontfamily, $Global:font.Size * 1.25, $Global:fontstyle )
  441. 		$textsize = $graphic.MeasureString( $degrees, $Global:font )
  442. 	}
  443. 	$x = [Math]::Max( 0, [Math]::Floor( ( $bitmap.Width - $textsize.Width ) / 2 ) )
  444. 	$y = [Math]::Max( 0, [Math]::Ceiling( ( $bitmap.Height - $textsize.Height ) / 2 ) )
  445. 	$graphic.DrawString( $degrees, $Global:font, $fgbrush, $x, $y, $Global:stringformat )
  446. 	$icon = [System.Drawing.Icon]::FromHandle( $bitmap.GetHicon( ) )
  447. 	$graphic.Dispose( )
  448. 	$bitmap.Dispose( )
  449. 	$icon
  450. }
  451.  
  452. function Format-Text( ) {
  453. 	param (
  454. 		[Parameter(Mandatory = $true)]
  455. 		[string]$unformatedText
  456. 	)
  457. 	$unformatedText = $unformatedText.Trim( )
  458. 	$consoleWidth = [System.Console]::WindowWidth
  459. 	$pattern = ( "^([^\s].{{1,{0}}})(\s(.*)|$)" -f ( $consoleWidth - 2 ) )
  460. 	$formatedText = ""
  461. 	do {
  462. 		if ( [System.Text.RegularExpressions.Regex]::IsMatch( $unformatedText, $pattern ) ) {
  463. 			$matches = [System.Text.RegularExpressions.Regex]::Matches( $unformatedText, $pattern )
  464. 			$line = $matches[0].Groups[1].Value
  465. 			$formatedText += $line + "`n"
  466. 			$unformatedText = $matches[0].Groups[3].Value.Trim( )
  467. 		} else {
  468. 			$line = ""
  469. 		}
  470. 	} while ( $line )
  471. 	$formatedText
  472. }
  473.  
  474. # Create new System Tray icon
  475. $notifyIcon = New-Object System.Windows.Forms.NotifyIcon
  476. $notifyIcon.Visible = $true
  477. # Add Click event handler (hides/restores console window)
  478. $notifyIcon.Add_Click( $Icon_Click )
  479. $abort = $false
  480. do {
  481. 	Clear-Host
  482. 	$data = ( Fetch-WeerData | ConvertFrom-Json -ErrorAction Stop )
  483. 	# [char]176 is the degrees symbol in codepage 437
  484. 	Write-Host ( "`n[{0}]" -f ( Get-Date ).ToString( "yyyy-MM-dd HH:mm:ss" ) ) -ForegroundColor White
  485. 	Write-Host ( "Locatie                        : {0}" -f $data.liveweer.plaats ) -ForegroundColor DarkGray
  486. 	Write-Host ( "Actuele temperatuur            : {0} {1}C" -f $data.liveweer.temp,[char]176 ) -ForegroundColor White
  487. 	Write-Host ( "Gevoelstemperatuur             : {0} {1}C" -f $data.liveweer.gtemp,[char]176 ) -ForegroundColor DarkGray
  488. 	Write-Host ( "Weersgesteldheid               : {0}" -f $data.liveweer.samenv ) -ForegroundColor White
  489. 	Write-Host ( "Relatieve luchtvochtigheid     : {0} %" -f $data.liveweer.lv ) -ForegroundColor DarkGray
  490. 	Write-Host ( "Windrichting                   : {0}" -f $data.liveweer.windr ) -ForegroundColor White
  491. 	Write-Host ( "Windsnelheid                   : {0} m/s" -f $data.liveweer.windms ) -ForegroundColor DarkGray
  492. 	Write-Host ( "Windkracht                     : {0} Bft" -f $data.liveweer.winds ) -ForegroundColor White
  493. 	Write-Host ( "Windsnelheid                   : {0} knopen" -f $data.liveweer.windk ) -ForegroundColor DarkGray
  494. 	Write-Host ( "Windsnelheid                   : {0} km/h" -f $data.liveweer.windkmh ) -ForegroundColor White
  495. 	Write-Host ( "Luchtdruk                      : {0} hPa" -f $data.liveweer.luchtd ) -ForegroundColor DarkGray
  496. 	Write-Host ( "Luchtdruk                      : {0} mm Hg" -f $data.liveweer.ldmmhg ) -ForegroundColor White
  497. 	Write-Host ( "Dauwpunt                       : {0} {1}C" -f $data.liveweer.dauwp,[char]176 ) -ForegroundColor DarkGray
  498. 	Write-Host ( "Zicht                          : {0} km" -f $data.liveweer.zicht ) -ForegroundColor White
  499. 	Write-Host ( "Korte dagverwachting           : {0}" -f $data.liveweer.verw ) -ForegroundColor DarkGray
  500. 	Write-Host ( "zon op                         : {0}" -f $data.liveweer.sup ) -ForegroundColor White
  501. 	Write-Host ( "zon onder                      : {0}" -f $data.liveweer.sunder ) -ForegroundColor DarkGray
  502. 	#Write-Host ( "afbeeldingsnaam: {0}" -f $data.liveweer.image )
  503. 	#Write-Host ( "Weericoon vandaag: {0}" -f $data.liveweer.d0weer )
  504. 	Write-Host ( "Max temp vandaag               : {0} {1}C" -f $data.liveweer.d0tmax,[char]176 ) -ForegroundColor White
  505. 	Write-Host ( "Min temp vandaag               : {0} {1}C" -f $data.liveweer.d0tmin,[char]176 ) -ForegroundColor DarkGray
  506. 	Write-Host ( "Windkracht vandaag             : {0} Bft" -f $data.liveweer.d0windk ) -ForegroundColor White
  507. 	Write-Host ( "Windrichting vandaag           : {0}" -f $data.liveweer.d0windr ) -ForegroundColor DarkGray
  508. 	Write-Host ( "Neerslagkans vandaag           : {0} %" -f $data.liveweer.d0neerslag ) -ForegroundColor White
  509. 	Write-Host ( "Zonkans vandaag                : {0} %" -f $data.liveweer.d0zon ) -ForegroundColor DarkGray
  510. 	#Write-Host ( "Weericoon morgen: {0}" -f $data.liveweer.d1weer )
  511. 	Write-Host ( "Max temp morgen                : {0} {1}C" -f $data.liveweer.d1tmax,[char]176 ) -ForegroundColor White
  512. 	Write-Host ( "Min temp morgen                : {0} {1}C" -f $data.liveweer.d1tmin,[char]176 ) -ForegroundColor DarkGray
  513. 	Write-Host ( "Windkracht morgen              : {0} Bft" -f $data.liveweer.d1windk ) -ForegroundColor White
  514. 	Write-Host ( "Windrichting morgen            : {0}" -f $data.liveweer.d1windr ) -ForegroundColor DarkGray
  515. 	Write-Host ( "Neerslagkans morgen            : {0} %" -f $data.liveweer.d1neerslag ) -ForegroundColor White
  516. 	Write-Host ( "Zonkans morgen                 : {0} %" -f $data.liveweer.d1zon ) -ForegroundColor DarkGray
  517. 	Write-Host ( "Max temp overmorgen            : {0} {1}C" -f $data.liveweer.d2tmax,[char]176 ) -ForegroundColor White
  518. 	Write-Host ( "Min temp overmorgen              : {0} {1}C" -f $data.liveweer.d2tmin,[char]176 ) -ForegroundColor DarkGray
  519. 	#Write-Host ( "Weericoon overmorgen: {0}" -f $data.liveweer.d2weer )
  520. 	Write-Host ( "Windkracht overmorgen          : {0} Bft" -f $data.liveweer.d2windk ) -ForegroundColor White
  521. 	Write-Host ( "Windrichting overmorgen        : {0}" -f $data.liveweer.d2windr ) -ForegroundColor DarkGray
  522. 	Write-Host ( "Neerslagkans overmorgen        : {0} %" -f $data.liveweer.d2neerslag ) -ForegroundColor White
  523. 	Write-Host ( "Zonkans overmorgen             : {0} %" -f $data.liveweer.d2zon ) -ForegroundColor DarkGray
  524. 	if ( $data.liveweer.alarm -eq 0 ) {
  525. 		Write-Host ( Format-Text "Weerwaarschuwing voor de regio : Nee" ) -ForegroundColor Green
  526. 	} else {
  527. 		Write-Host ( Format-Text ( "Weerwaarschuwing voor de regio : {0}" -f $data.liveweer.alarmtxt ) ) -ForegroundColor Red
  528. 	}
  529.  
  530. 	$temp = [System.Math]::Round( $data.liveweer.temp )
  531. 	$notifyIcon.Icon = ( Create-Icon ( $temp ) )
  532. 	# Tooltip text cannot exceed 64 characters, hence the Substring
  533. 	$tooltiptext = ( "Temperatuur: {0}`nGevoelstemp: {1}`n`nKlik: toon/verberg details" -f $data.liveweer.temp, $data.liveweer.gtemp )
  534. 	$notifyIcon.Text = $tooltiptext.Substring( 0, [System.Math]::Min( 63, $tooltiptext.Length ) )
  535.  
  536. 	Write-Host "`n`nKlik op het icoon in de `"System Tray`" om dit venster te verbergen of weer te herstellen."
  537. 	# Show how to break free from the endless loop
  538. 	Write-Host "`nDruk op een willekeurige toets om de temperatuurweergave te stoppen . . .  " -NoNewline
  539.  
  540. 	# Loop until a key is pressed in this console
  541. 	$loopcount = 0
  542. 	:WaitForKey while ( $true ) {
  543. 		$loopcount += 1
  544. 		if ( $Host.UI.RawUI.KeyAvailable ) {
  545. 			$abort = $true
  546. 			break WaitForKey
  547. 		} else {
  548. 			if ( $loopcount -gt 299 ) {
  549. 				break WaitForKey
  550. 			} else {
  551. 				Start-Sleep -Seconds 1
  552. 			}
  553. 		}
  554. 	}
  555. } until ( $abort )
  556.  
  557. # Remove the key from the keyboard buffer . . .
  558. [void] $Host.UI.RawUI.ReadKey( )
  559. # . . .  and wipe it from the screen
  560. Write-Host "`b `n"
  561.  
  562. # Cleanup
  563. $notifyIcon.Visible = $False
  564. $notifyIcon.Dispose( )
  565.  

page last modified: 2024-04-16; loaded in 0.0141 seconds