Cloudless Windows 10 Notification

Provide cloudless Windows10 Notifications with the use of Windows PowerShell. Inspired by an article “Netzwerkpost” published in c’t 8/2020 p. 158. https://ct.de

First, we need Windows PowerShell with the module „BurntToast” installed: https://github.com/Windos/BurntToast. Verification: The following PowerShell command produces a two-line Notification:

Toast  -Text "Hallo", "Do you read me?"

Next, we need to setup a UDP connection between Home Assistant and the Windows 10 engine:

A simple ps1-script listens on UDP port 514 for incoming notifications:

# original file published by c't: notify.ps1 
# Stellen Sie hier den Port ein, auf dem das Skript lauschen soll
param( $address="any", $port=514 )

# Speicherort des Powershell-Skripts herausfinden
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
 
# UDP-Socket öffnen
$endpoint = new-object System.Net.IPEndPoint([IPAddress]::$address, $port)
$udpclient = new-object System.Net.Sockets.UdpClient $port

# Begruessung ausgeben
Write-Host -ForegroundColor Cyan "*** UDP Notification-Receiver, listens on port $($port) ***"

# Eingehende UDP-Pakete verarbeiten
while( $true )
{
	if( $udpclient.Available )
	{	# UDP-Paket auswerten und Benachrichtigung anzeigen
		$udpmessage = $([Text.Encoding]::UTF8.GetString($udpclient.Receive([ref]$endpoint)))
		# Modification: Define first 25 character of UDP string  as Title, and the rest as Message
        	$title = $udpmessage.Substring(0,25)
        	$message = $udpmessage.Substring(25)
		Toast -AppLogo $ScriptDir\ha.png -Silent -Text  $title ,  $message
	}
	# Abfrageschleife verzoegern, um CPU-Auslastung auf ein Minimum zu reduzieren
	Start-Sleep -s 2
}

Specify the logo and IP to your needs. For continuous use, call this this script in Autostart.

On the Home Assistant side: Provide in configuration.yaml a new Notification definition, using pipes:

    notify:
      - name: win10desktop   
        platform: command_line
        command:  "cat | nc -u 192.168.178.19 514"

An action call in automation.yaml will generate a notification:

        action:
          - service: notify.win10desktop
            data:
               message: "Warnung: Wasser im Keller Dringend nachschauen"

The result:
win10notify

7 Likes

Very cool - this is just a static notification right?

Is it possible to make notifications on WIN10 actionable? For example, I have IOTlink running as a service on my main laptop, which exposes the idle time of the laptop. I’d like to be asked by HA if I’d like to turn a light on if the idle time on my laptop is under gets reset to zero.

I had this working when using ha OS. I have since switched over to running pi os lite with ha supervised installed and I cannot get to work. Could this not have access to send the command?

When I SSH in to the box and send the command it works but not when I call notify.win10desktop from home assistant

Any thoughts?

This screams “no netcat is installed”.
(nc is an alias for netcat).

Thankyou! it is working but I have some minor input
When you insert the sample data it works all perfect

service: notify.win10desktop
data:
  message: The garage door has been open for 10 minutes.

But when you take something shorter like the example below it isn’t going to work because the substring would be outside the source string

service: notify.win10desktop
data:
  message: Is it Working?

Powershell is throwing the following errors

Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within the string.
Parameter name: length"
Exception calling "Substring" with "1" argument(s): "startIndex cannot be larger than length of string.
Parameter name: startIndex"

resulting in a blank notification
1

Below I took your script and change is a little bit to bypass this. Also I added a uniqueidentifier to the toast message. This is a personal preference. But I like to keep it clean

# original file published by c't: notify.ps1 
# Stellen Sie hier den Port ein, auf dem das Skript lauschen soll
param( $address="any", $port=514 )

# Speicherort des Powershell-Skripts herausfinden
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
 
# UDP-Socket öffnen
$endpoint = new-object System.Net.IPEndPoint([IPAddress]::$address, $port)

$udpclient = new-object System.Net.Sockets.UdpClient $port

# Begruessung ausgeben
Write-Host -ForegroundColor Cyan "*** UDP Notification-Receiver, listens on port $($port) ***"

# Eingehende UDP-Pakete verarbeiten
while( $true )
{
	if( $udpclient.Available )
	{	# UDP-Paket auswerten und Benachrichtigung anzeigen
		$udpmessage = $([Text.Encoding]::UTF8.GetString($udpclient.Receive([ref]$endpoint)))
		# Modification: Define first 25 character of UDP string  as Title, and the rest as Message
		if ($udpmessage.length -lt 25){
			$message = $udpmessage
			$title = "Message from HomeAssistant"
		}else{
			$title = $udpmessage.Substring(0,25)
			$message = $udpmessage.Substring(25)
		}
		Toast -AppLogo $ScriptDir\ha.png -Silent -Text  $title ,  $message -UniqueIdentifier 'HA'
	}
	# Abfrageschleife verzoegern, um CPU-Auslastung auf ein Minimum zu reduzieren
	Start-Sleep -s 2
}
1 Like

I am getting a timeout error.

Timeout for command: cat | nc -u 192.168.1.111 514
7:52:47 PM – (ERROR) command_line - message first occurred at 7:43:40 PM and shows up 3 times

This is my notify.yaml. The ip is the windows pc?

  - name: desktop   
    platform: command_line
    command:  "cat | nc -u 192.168.1.111 514"

test message:

Ok. I figured out my issued. I had notification turned off in Windows. Just need to enable it again. I can see the notification coming in now.

For continuous use, call this this script in Autostart.

I had to do some searching on how to go about having the script to autostart when Windows boot up. We need to create another file with a .cmd and paste these text in. Change the path to your .ps1 file location and name the .cmd anything you want.

PowerShell -Command "Set-ExecutionPolicy Unrestricted -Force" >> "%TEMP%\StartupLog.txt" 2>&1
PowerShell -windowstyle hidden D:\Scripts\homeassistant\notify_desktop.ps1 >> "%TEMP%\StartupLog.txt" 2>&1
PowerShell -Command "Set-ExecutionPolicy Restricted" >> "%TEMP%\StartupLog.txt" 2>&1

Place the .cmd file at this location. Windows should start the script when it boots up and hides the prompt.

C:\Users\Duc\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

2 Likes

nice to see another approach. I run it as a service ( link )

also you should use straight quotes instead of curly ones even if cmd is changing them automatically

1 Like

Hmm. Though, the service seems like it is working. I receive the text, HA log still gives me this error.

Timeout for command: cat | nc -u 192.168.1.111 514
7:52:47 PM – (ERROR) command_line - message first occurred at 7:43:40 PM and shows up 3 times

Do you see anything in the extended log?

extended log

As in supervisor log? I do not see any errors there.