Presence Detection Alarm system using Bluetooth Ping

Tags: #<Tag:0x00007fc2085ac518>

It took me a long time to get the presence detection running. Most of the following is from here: https://klenzel.de/3328
I just hope that I can explain it easier.

In my scenario my girlfriend and me, we both got our Smartphone, which is used for presence detection. When we open the door, the system checks whether one of us is already connected to the wifi and if not, it is checked for bluetooth presence. For checking the wifi connection I used the binding for my router (Fritzbox).
For an alarm system using presence detection via bluetooth you need:

  • bluetooth_present.items:
String Tobias_BT "Handy Tobias Bluetooth" (grp_PRAESENZ) {channel="exec:command:bttobias:output"}
String Theres_BT "Handy Theres Bluetooth" (grp_PRAESENZ) {channel="exec:command:bttheres:output"}
Switch Tobias_BT_update "Handy Tobias Bluetooth" (grp_PRAESENZ) {channel="exec:command:bttobias:run"}
Switch Theres_BT_update "Handy Theres Bluetooth" (grp_PRAESENZ) {channel="exec:command:bttheres:run"}

Switch Tobias_BT_ONOFF  <presence>
Switch Theres_BT_ONOFF  <presence>
  • A Trigger Item as a doorsensor
Contact WindowSwitch_Status <window>  channel.....
  • Alarm.rules:
rule "Alarmanlage Basic"
when 
  Item WindowSwitch_Status changed from CLOSED to OPEN 
then
 if (Anwesend.state ==ON)
{
// everything is fine, we are already connected to the wifi.
}
    if (Anwesend.state ==OFF)
    {
                    var Number Loopzaehler = 1
                    while (Anwesend.state == OFF && Tobias_BT_ONOFF.state == OFF && Theres_BT_ONOFF.state == OFF)
		    {
                         if (Loopzaehler == 15) {
                           // you can make something happen after 15 seconds without any detection
                         }
                         if (Loopzaehler ==25) {
                           //another thing after 25 seconds
                         }
                         if (Loopzaehler ==35) {
                           //and so on
                         }
                         Tobias_BT_update.sendCommand(ON) 
                         Theres_BT_update.sendCommand(ON)
                         Thread::sleep(1000)
                         Loopzaehler = Loopzaehler +1
                    }
                   // what should happen after the alarm is off/you are detected, goes here
                   if (Loopzaehler > 10) 
                   { 
                       //lif you just want something happen after alarm is finished but you have not been detected for 10 seconds
                
                   }
           
    }
end

presence.rules:

rule "Bluetooth on off Tobias"
when 
    Item Tobias_BT received update
then
    if (Tobias_BT.state =="ON") { Tobias_BT_ONOFF.sendCommand(ON)}
    if (Tobias_BT.state =="OFF") { Tobias_BT_ONOFF.sendCommand(OFF)}
end 

rule "Bluetooth on off Theres"
when 
    Item Theres_BT received update
then
    if (Theres_BT.state =="ON") { Theres_BT_ONOFF.sendCommand(ON)}
    if (Theres_BT.state =="OFF") { Theres_BT_ONOFF.sendCommand(OFF)}
end
  • bluethooth_present.things:
Thing exec:command:bttobias [command="/home/openhabian/scripts/bt.sh 1", transform="REGEX((.*?))", interval=0, timeout=5, autorun=true]
Thing exec:command:bttheres [command="/home/openhabian/scripts/bt.sh 2", transform="REGEX((.*?))", interval=0, timeout=5, autorun=true]
  • in /home/openhabian/scripts/ you need bt.sh containing:
#!/bin/bash
 
#1=Tobias, 2=Theres
case $1 in
   1) MAC="Bluetooth MAC Adress of Phone" ;;
   2) MAC="Bluetooth MAC Adress of Phone2" ;;
esac
 
if /usr/bin/sudo /usr/bin/l2ping -c 1 $MAC &> /dev/null
   then
      echo "ON"
   else
      echo "OFF"
fi

How to find the Bluetooth mac adress you find via

hcitool scan

in the console via ssh

And you need to change in the sudoers:
using

nano /etc/sudoers

Add at the bottom the following line:

openhab ALL = NOPASSWD: /usr/bin/l2ping

And of course you need the exec binding installed.

I hope you can understand my alarm system and the presence detection, for this is my first tutorial. Of course you can find all of it somewhere else, it’s just not that easy to collect it all together. So this way I hope I could make it easier for some of you.

4 Likes

Please keep in mind, that this rule will block a thread in openHAB, even worse, the rule can be started more than once at a time, so it’s possible to block openHAB completely!
It’s far better to use a timer instead of Thread::sleep.

var Timer tAlarm = null
var Integer nLoopCount = 0

rule "Alarmanlage Basic"
when 
    Item WindowSwitch_Status changed from CLOSED to OPEN 
then
    if (Anwesend.state==ON) {
        // everything is fine, we are already connected to the wifi.
    } else if (Anwesend.state!=ON) {
        tAlarm?.cancel
        tAlarm = createTimer(now.plusSeconds(1),[|
            if(Anwesend.state!=ON) {
                nLoopCount += 1
                Tobias_BT_update.sendCommand(ON) 
                Theres_BT_update.sendCommand(ON)
                switch (nLoopCount) {
                    case 15 : {
                        // you can make something happen after 15 seconds without any detection
                    }
                    case 25 : {
                        // another thing after 25 seconds
                    }
                    case 35 : {
                        // and so on
                    }
                }
                tAlarm.reschedule(now.plusSeconds(1))
            } else {
                nLoopCount = 0
                tAlarm = null
            }
        ])
    }
end
1 Like

Thank you, that is a great hint. I am going to update my rules :wink: