Hi all,
I thought I’d share my solution for location based rules, maybe somebody finds it useful. It can be used e.g. for preventing the lights from switching off at a certain location when you are still there or automatically start-up security or logging, or maybe stop security cameras depending on where you are.
It is based on the property that WiFi clients tend to connect to the closest access point. You obviously do need multiple access points to get a location within a house, otherwise you only get “home or not”. My setup consists of 2 APs and a separate router (without WiFi), all running OpenWRT. On each device I have usteer
running. This app provides the means of extracting the required information on OpenWrt. On the router I have the following script executed once per minute:
#!/bin/ash
connected_nodes=$(ubus call usteer get_client_info '{"address":"aa:bb:cc:dd:ee:ff"}' | grep -B 1 '"connected": true' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
connected_nodes2=$(ubus call usteer get_client_info '{"address":"ab:bc:cd:de:ef:fa"}' | grep -B 1 '"connected": true' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+')
mosquitto_pub -h 192.168.1.100 -t "test" -m "{\"aabbccddeeff\": \"$connected_nodes\",\"abbccddeefa\": \"$connected_nodes2\"}" -u "mosq" -P "password"
return 0
This script grabs for two different MAC addresses the APs they are connected to. . The example is for 2 MAC addresses, but it can be trivially extended to any number. You do of course also have to install the mosquitto-client
either the SSL or non-SSL version.
On my RPi (192.168.1.100) which runs my OpenHAB, i also have a mosquitto server running, which will receive the message from the router.
Add a mqqt.things
file:
Bridge mqtt:broker:rpiBroker [ host="127.0.0.1", secure=false, username="mosq", password="password" ]
Thing mqtt:topic:Presence (mqtt:broker:rpiBroker) {
Channels:
Type string : PhoneLocation "Location" [ stateTopic="test",transformationPattern="JSONPATH:$.aabbccddeeff" ]
Type string : Phone2Location "Location" [ stateTopic="test",transformationPattern="JSONPATH:$.abbccddeeffa" ]
}
And add a mqqt.items
file:
String PresencePhone {channel="mqtt:topic:Presence:PhoneLocation" }
String PresencePhone2 {channel="mqtt:topic:Presence:Phone2Location" }
You can now use a rule like:
if (!PresencePhone.state.toString.contains("192.168.1.2"))
Note that the state of the item may contain multiple APs with a space in between, as clients take some time to disconnect, hence the reason to use e.g. contains
.
Hope this can inspire somebody.
Best regards,
Ramon