Well, summer is coming to the northern hemisphere. Without fail my kids will use their tablets outside and on at least one occasion, will forget them overnight.
I figured I can solve this problem automagically. Below is how it’ve done it.
It uses the great Unifi binding by @mgbowman
What you need
- I’ve got multiple APs in the house (4) and in the garden (2).
- 3 of the APs can be seen clearly from the garden by most devices. Devices cling on to them whilst in the garden.
- I specify which are “Questionable” APs and which are “Barred” APs.
- When an event triggers like night time, rain started or Bedtime scene, the rule will run.
- Any wifi devices connected to the questionable APs will be kicked and wait for a reconnect.
- Once reconnected they will be checked again. If they’re still outside or have now moved outside, an alert is sent. Thinking email, app or Alexa.
This is still WIP so any feedback welcome.
This could have been done better with FIND3 but this way you don’t need anything else other than your existing APs and Unifi.
Items
Group g_PhonesAPs
Group g_PhonesBlocked
Group g_QuestionPhones
Switch CrispinPhone "Crispin [MAP(unifi.map):%s]" <boy_2> (g_PhonesPresent, g_WhosHome, g_QuestionPhones) { channel="unifi:wirelessClient:home:crispinPhone:online" }
String CrispinPhoneAP "Crispin's Phone: AP [%s]" (g_persist_change, g_PhonesAPs) { channel="unifi:wirelessClient:home:crispinPhone:ap" }
Switch CrispinPhoneBlocked "Crispin Blocked" (g_PhonesBlocked) { channel="unifi:wirelessClient:home:crispinPhone:blocked" }
Switch DenisePhone "Denise [MAP(unifi.map):%s]" <girl_3> (g_PhonesPresent, g_WhosHome, g_QuestionPhones) { channel="unifi:wirelessClient:home:denisePhone:online" }
String DenisePhoneAP "Denise's Phone: AP [%s]" (g_persist_change, g_PhonesAPs) { channel="unifi:wirelessClient:home:denisePhone:ap" }
Switch DenisePhoneBlocked "Denise Blocked" (g_PhonesBlocked) { channel="unifi:wirelessClient:home:denisePhone:blocked" }
rule
var questionAPs = newArrayList(
"AP Garden",
"AP Shed",
"AP Utility",
"AP.Backroom.1"
)
var barredAPs = newArrayList(
"AP Garden",
"AP Shed"
)
rule "Question Phones"
when Item KKLL changed
then
logWarn("KKLL", "Starting")
g_QuestionPhones?.allMembers.forEach[item |
val apItem = g_PhonesAPs.members.findFirst[ t | t.name == item.name + "AP" ] as StringItem
if (apItem === null){
logError("Question Phones", "Could not find AP Item for " + item.name)
return;
}
logWarn("Question Phones", item.name + " - AP Found:" + apItem.name)
logWarn("Question Phones", item.name + " - Location:" + apItem.state.toString)
if (questionAPs.contains(apItem.state.toString)){
logWarn("Question Phones", item.name + " IS LOCATED " + apItem.state.toString)
val blockedItem = g_PhonesBlocked?.members.findFirst[ t | t.name == item.name + "Blocked" ] as SwitchItem
if (blockedItem === null){
logError("Question Phones", "Could not find Blocked Item for " + item.name)
return;
}
blockedItem.sendCommand(ON)
Thread::sleep(500)
blockedItem.sendCommand(OFF)
logWarn("Question Phones", item.name + " was kicked ")
Thread::sleep(3000)
logWarn("Question Phones", item.name + " - Location:" + apItem.state.toString)
//where is it now.
if (barredAPs.contains(apItem.state.toString)){
logError("Question Phones", item.name + " is still located in " + apItem.state.toString)
//this is where you send your error alert.
}
}
// else {
// logWarn("Question Phones", item.name + " IS NOT LOCATED " + apItem.state.toString)
// }
]
end
TODO:
- I want to remove the sleeps.
- Need to improve error handling in some of the cases.
Feedback always welcome with this.
C