As to how to do this from your home assistant, I have no good idea. This is what I did to allow remote booting a PC via a WoL packet from the router.
This is a modification of a script that I got years ago here on the forum that would search the router log on a schedule looking for login and logout attempts.
For this script I modified it so that it was looking for the string "PC boot Port Knock Family room" in the log. When it finds it, ultimately it executes the code in the about the last dozen lines that sends a WoL packet three times - 10 seconds apart. It also sends me an E-Mail to tell me that it executed.
Now your next question is how does the string "PC boot Port Knock Family room" get into the router log?
I have a four step port knock process. This last step adds the source address to an address list, but that really doesn't accomplish anything. However, it writes a log entry - and that does.
add action=add-src-to-address-list address-list="PCB Knock-4" \
address-list-timeout=1s chain=PC-Boot comment=\
"PC boot Port Knock Family room" dst-port=12345 in-interface-list=WAN log=\
yes log-prefix="PC boot Port Knock Family room" protocol=tcp \
src-address-list="PCB Knock-3"
Now that there is the required log entry, here is the script that parses the log and runs the WoL Please don't ask me details on how this script works as I largely can't tell you. I could figure out to modify the script for my own purposes, but that is about it. There is a schedule that runs this script every minute.
# BEGIN SETUP
:local scheduleName "Family Rm PCB from Port Knock"
:local emailAddress1 "jim@xxx.com"
:local emailAddress2 "jim@yyy.org"
:local startBuf [:toarray [/log find message~"PC boot Port Knock Family room"]]
:local removeThese {"zippo";"whatever string you want"}
# END SETUP
# warn if schedule does not exist
:if ([:len [/system scheduler find name="$scheduleName"]] = 0) do={
/log warning "[LOGMON] ERROR: Schedule does not exist. Create schedule and edit script to match name"
}
# get last time
:local lastTime [/system scheduler get [find name="$scheduleName"] comment]
# for checking time of each log entry
:local currentTime
# log message
:local message
# final output
:local output
:local keepOutput false
# if lastTime is empty, set keepOutput to true
:if ([:len $lastTime] = 0) do={
:set keepOutput true
}
:local counter 0
# loop through all log entries that have been found
:foreach i in=$startBuf do={
# loop through all removeThese array items
:local keepLog true
:foreach j in=$removeThese do={
# if this log entry contains any of them, it will be ignored
:if ([/log get $i message] ~ "$j") do={
:set keepLog false
}
}
:if ($keepLog = true) do={
:set message [/log get $i message]
# LOG DATE
# depending on log date/time, the format may be different. 3 known formats
# format of jan/01/2002 00:00:00 which shows up at unknown date/time. Using as default
:set currentTime [ /log get $i time ]
# format of 00:00:00 which shows up on current day's logs
:if ([:len $currentTime] = 8 ) do={
:set currentTime ([:pick [/system clock get date] 0 11]." ".$currentTime)
} else={
# format of jan/01 00:00:00 which shows up on previous day's logs
:if ([:len $currentTime] = 15 ) do={
:set currentTime ([:pick $currentTime 0 6]."/".[:pick [/system clock get date] 7 11]." ".[:pick $currentTime 7 15])
}
}
# if keepOutput is true, add this log entry to output
:if ($keepOutput = true) do={
:set output ($output.$currentTime." ".$message."\r\n\n")
}
# if currentTime = lastTime, set keepOutput so any further logs found will be added to output
# reset output in the case we have multiple identical date/time entries in a row as the last matching logs
# otherwise, it would stop at the first found matching log, thus all following logs would be output
:if ($currentTime = $lastTime) do={
:set keepOutput true
:set output ""
}
}
# if this is last log entry
:if ($counter = ([:len $startBuf]-1)) do={
# If keepOutput is still false after loop, this means lastTime has a value, but a matching currentTime was never found.
# This can happen if 1) The router was rebooted and matching logs stored in memory were wiped, or 2) An item is added
# to the removeThese array that then ignores the last log that determined the lastTime variable.
# This resets the comment to nothing. The next run will be like the first time, and you will get all matching logs
:if ($keepOutput = false) do={
# if previous log was found, this will be our new lastTime entry
:if ([:len $message] > 0) do={
:set output ($output.$currentTime." ".$message."\r\n")
}
}
}
:set counter ($counter + 1)
}
# If we have output, save new date/time, and send email
if ([:len $output] > 0) do={
/log err "[LOGMON] Family room PC WoL from Port Knock."
/system scheduler set [find name="$scheduleName"] comment=$currentTime
:log info "Sending WoL Magic Packet to Family room 2018 PC"
/tool wol interface=E06-p10_201 mac=11:22:33:44:55:66
:delay 00:00:10
/tool wol interface=E06-p10_201 mac=11:22:33:44:55:66
:delay 00:00:10
/tool wol interface=E06-p10_201 mac=11:22:33:44:55:66
:log info "WoL script completed"
}
Now, it I am already into the router (normally that would be via WinBox), there is a MUCH shorter script that I can call to issue the WoL packets
# Policy needed: Test
:log info "Sending WoL Magic Packet to Family room 2018 PC"
/tool wol interface=E2-p4_101 mac=11:22:33:44:55:66
:delay 00:00:10
/tool wol interface=E2-p4_101 mac=11:22:33:44:55:66
:delay 00:00:10
/tool wol interface=E2-p4_101 mac=11:22:33:44:55:66
:log info "WoL script completed"
FYI, I have several of these so I can remote boot several computers at the house.