I used a Raspberry Pi 4 running Rasbian, but as far as I know, this should work on any version of Linux. YMMV.
What we want is a cleaned-up version of the output “iwlist wlan0 scan” creates. Unfortunately, iwlist needs sudo to run. Fortunately, we can make that happen! Start with this:
sudo visudo -f /etc/sudoers.d/010_openhab-nopasswd
The sudoers.d directory holds any files that gives (or removes) sudo access to/from programs and users. This allows openhab to use the sudo command - but we don’t want it to be able to run absolutely anything, that’s a security risk. So, we add the following line, limiting the passwordless sudo command to one specific command:
openhab ALL=(root) NOPASSWD: /sbin/iwlist wlan0 scan
This assumes your openhab user is called “openhab”, and your wifi device name is “wlan0”.
Save and close, and now openhab has permission to use sudo to run the scan command! Of course, the output is rather overwhelming; we’re only looking for one specific SSID. Additionally, OpenHAB doesn’t use a “real” shell to run commands, so sudo will complain. To fix both problems, we’ll wrap our sudo command in a command line script (if your openhab directory is elsewhere, use that instead of ‘/etc/openhab2/’):
Inside the script file, add the following:
SSIDs=`sudo /sbin/iwlist wlan0 scan`
names=`echo "$SSIDs" | grep -oP "ESSID:\K(\"[^\"]+\")" | sort`
[[ $names =~ "\"MyNetwork\"" ]] || exit 1
This will use a “real” shell to get the full output of iwlist, break it down into a list of double-quoted SSIDs, print that list, and check if the list contains the one network you’re looking for; if so, it exist with status 0, otherwise, status 1. Note that this searches by name, so DO NOT use this to unlock doors or disarm security systems! Anyone could create a wifi network with the right name and it would work!
Save and close it, then test it out:
sudo su openhab -c /etc/openhab2/runwifiscan.sh
Hopefully, it should return a list of wifi networks, like this (without asking for a password!):
That’s the command line stuff done; next, we make a new Exec thing. For the command, use:
Set the timeout to something low, like 5 (or 10 if you have a lot of networks nearby); set it to run no more frequently than your timeout (I suggest at least 1 minute). The Output will be the list of wifi networks; the exit code will be the presence indicator, 0 if the network is in range, 1 if it is out of range. In my sitemap, I have the following:
Text item=CommandWiFiCheck_ExitValue label="My car is... [MAP(homeaway.map):%s]" icon="car_red"
Where homeaway.map contains:
And that’s all it took; not as easy as some things, but at least I didn’t have to make a weirdly convoluted rule for it.