[monitor] Reliable, Multi-User, Distributed Bluetooth Occupancy/Presence Detection

@vin, @davst @Tony321

mosquitto updated this morning to fix the issue you identified. Please update mosquitto to at least 1.6.2.

Thanks for the report!

sudo apt-get update
sudo apt-get upgrade

Thank you! Iā€™ll try later this week. Should I just follow step 7 in your GitHub instructions?

If youā€™ve already installed mosquitto, a simple sudo apt-get update and sudo apt-get upgrade will do the trick.

1 Like

@andrewjfreyer I actually updated my mosquitto yesterday I think it loaded the latest one.

Been running monitor since yesterday and so far it has not stopped.

however Iā€™m getting a bunch of

`[+] 0.2.186 30-04-2019 12:50:19 PM [CMD-INFO] cycling bluetooth hardware on hci0. please wait a momentā€¦

*** Error in `/usr/bin/mosquitto_pubā€™: free(): invalid pointer: 0x7e86a864 ***
./support/mqtt: line 46: 28543 Aborted $mosquitto_pub_path -I ā€œ$mqtt_publisher_identityā€ $mqtt_version_append $mqtt_ca_file_append -L ā€œ$mqtt_url$mqtt_topicpath/$mqtt_publisher_identity/statusā€ -m ā€œonlineā€ -q ā€œ2ā€ 2>&1

The invalid pointer issue will be solved by updating mosquitto to 1.6.2+. This is specifically the issue that was pushed in a release by mosquitto devs this morning in response to an issue report I drafted, so you likely do not have the most recent version.

As far as the cycling warning, see this FAQ. Make sure only one monitor instance is running at a time and that no other services are using the bluetooth hardware.

ok thanks will update mosquitto again.

I had the monitor running on boot then run the monitor again with the -F and -V again thats why I was getting the cycling warning.

1 Like

Hmm, so Iā€™ve just set this up and I do get 100 confidence MQTT messages come through my my iphone and my wifes Samsung (I have these filters set up), however when I turn off bluetooth on my phone (or even put it in airplane mode), nothing seems to happen and I never get a message sent out. Iā€™m sure iā€™m missing something simple but still getting my head around all thisā€¦

@hansel what command line options are you using?

Thanksā€¦ gonna update tonight

1 Like

Right now, just sudo bash monitor.sh -x -b -V

I have two bluetooth mac addresses in the known_static_addresses file and one in the known_beacon file (a Tile).

My behaviour file is:

#MAX RETRY ATTEMPTS FOR ARRIVAL
PREF_ARRIVAL_SCAN_ATTEMPTS=2

#MAX RETRY ATTEMPTS FOR DEPART
PREF_DEPART_SCAN_ATTEMPTS=2

#SECONDS UNTIL A BEACON IS CONSIDERED EXPIRED
PREF_BEACON_EXPIRATION=240

#MINIMUM TIME BEWTEEN THE SAME TYPE OF SCAN (ARRIVE SCAN, DEPART SCAN)
PREF_MINIMUM_TIME_BETWEEN_SCANS=15

#ARRIVE TRIGGER FILTER(S)
PREF_PASS_FILTER_ADV_FLAGS_ARRIVE=".*"
PREF_PASS_FILTER_MANUFACTURER_ARRIVE="Apple|Samsung"

#ARRIVE TRIGGER NEGATIVE FILTER(S)
PREF_FAIL_FILTER_ADV_FLAGS_ARRIVE="NONE"
PREF_FAIL_FILTER_MANUFACTURER_ARRIVE="NONE"

My mqtt_preferences file is:

# ---------------------------
#
# MOSQUITTO PREFERENCES
#
# ---------------------------

# IP ADDRESS OR HOSTNAME OF MQTT BROKER
mqtt_address=192.168.1.161

# MQTT BROKER USERNAME
mqtt_user=myuser

# MQTT BROKER PASSWORD
mqtt_password=mypass

# MQTT PUBLISH TOPIC ROOT
mqtt_topicpath=monitor

# PUBLISHER IDENTITY
mqtt_publisher_identity='ha-monitor'

# MQTT PORT
mqtt_port='1883'

# MQTT CERTIFICATE FILE
mqtt_certificate_path=''

#MQTT VERSION (EXAMPLE: 'mqttv311')
mqtt_version=''

Where 192.168.1.161 is the IP of the Pi monitor is running on (can i use localhost there?)

Iā€™m using Node-RED to check for messages:

1 Like

Hi @hansel, i had the same behaviour when i disable bluetooth through of the iphone control center. If i turn off bluetooth from config -> settings everything works ok.

1 Like

Interesting, Iā€™ll try that tonight, thanks. I did put it in airplane mode though, youā€™d think thatā€™d be a fairly hard cut off of the signals.

This is correct. Disabling from control center on an iPhone does not disable the bluetooth radio. Phones can still be detected by monitor.

Airplane mode should disable the radio, however. @Hansel please let me know if you have any continuing issues.

Right ok, Iā€™ve mostly been testing by disabling through control center (itā€™s probably worth adding a line to the guide about that), but Iā€™ll try airplane mode again when I get home tonight (unfortunately about 11 hours away).

Actually, as Iā€™m out of the house, if I ssh in and enabled Monitor now, will it send a message that my device is missing, or will it only send those once itā€™s seen it and it then disappears?

If you ssh restart monitor, your device will be marked as ā€˜not presentā€™ (0% confidence), and an mqtt message will be sent

Ok cool, Iā€™ll try that now then :slight_smile:

Sweet, looks good. Did I get two messages due to the MAX RETRY ATTEMPTS options set above?)

Hi Andrew,

Out of interest, could you post your node-red flow for arrival scans (assuming you have one)?

Also, assuming I want to be cautious of minimizing any interference, I assume I should be using -tad? Iā€™ve already set up a trigger (using your example in your post Iā€™m replying to) for departs when my front door lock is activated (I notice in your example you have it set to trigger on both lock and unlock (or any state change at least) ), and it makes sense to do the same for arrivals. Logically Iā€™d use the same trigger (the door lock state changing), but that would mean both a depart and and arrive scan triggered at the same time (is that ok?)

1 Like

I have four monitor nodes in the house. The two on the first floor (garage, 1st floor) are set to -tdr and the other two (2nd floor, 3rd floor) are set to -tad.

This means that the 1FL/garage nodes listen for advertisements to detect arrival of devices but ONLY scan for depart in response to an MQTT instruction. Also, this means that the 2FL/3FL nodes ONLY scan for arrive or depart in response to an MQTT instruction.

As a result of this architecture, when I arrive home, either the 1FL or garage node will observe an advertisement from my phone. That node will begin scanning and it will find my phone and report 100% confidence. Then, because of the r suboption in my -tdr setting, that node will report to the three other nodes that at least one device has arrived. Thereafter, the three other nodes will start scanning for my phone too.

In HA, I just use a YAML automation based on the state of a numeric sensor that takes the max of my four monitor nodesā€™ confidence:

  - platform: min_max
    name: "Andrew Occupancy Confidence"
    type: max
    entity_ids:
      - sensor.andrew_garage
      - sensor.andrew_third_floor
      - sensor.andrew_second_floor
      - sensor.andrew_first_floor

This is my full automation, with minor redactions/changes:

- alias: andrew on
    initial_state: 'on'
    hide_entity: true
    trigger:
      - platform: numeric_state
        entity_id: sensor.andrew_occupancy_confidence
        above: '90.0'      
    condition:
      condition: and
      conditions:
        - condition: state
          entity_id: 'input_boolean.andrew_occupancy'
          state: 'off'
        - condition: template
          value_template: "{{ (as_timestamp(now()) - as_timestamp(state_attr('automation.andrew_on', 'last_triggered') | default(0)) | int > 5)}}" 
    action:
      - service: notify.ios_andrews_iphone
        data:
          title: "Home Alert"
          message: 'Welcome home, Andrew. You were away for {{relative_time(states. input_boolean.andrew_occupancy.last_updated)}}. Need access?'
          data:
            push:
              badge: 0
              category: 'door'
            action_data:
              entity_id: light.test
      - service: notify.ios_wifes_iphone
        data:
          title: "Home Alert"
          message: 'Your loving husband has arrived back home.'
      - service: media_player.volume_set
        entity_id: media_player.nursery
        data:
          volume_level: '0.3'
      - service: notify.alexa_media
        data_template:
          target: 
            - media_player.kitchen 
            - media_player.nursery
            - media_player.garage 
            - media_player.master_bedroom
          title: "Home Assistant"
          data:
            type: announce
            method: all
          message: "Andrew has arrived home. He was away for {{relative_time(states.input_boolean.andrew_occupancy.last_updated)}}." 
      - service: input_boolean.turn_on
        data:
          entity_id: input_boolean.andrew_occupancy

In pseudocode/English:

IF

  • (andrewā€™s input_boolean is off) AND
  • (at least one monitor node changes to 100% confidence) AND
  • (this automation has not run in the last 5 seconds [debouncing])

THEN

  • send an actionable iOS alert to Andrewā€™s phone that includes an option to unlock the door
  • send a simple alert to wife letter her know Iā€™m home
  • turn down the volume of the babyā€™s Alexa so that I donā€™t accidentally wake him if heā€™s sleeping
  • announce that Andrew is home on every Alexa in the house
  • set the input boolean that represents Andrewā€™s home/away status to ON
6 Likes