Featured image of post Find my keys with Home Assistant

Find my keys with Home Assistant

Create an automation which helps find your keys, wallet or else with Home Assistant.

Introduction

A man leaves the house with three things. Those would be wallet, keys and a phone. The catch is, that we are always searching for one of those three things around the house.

Previously I tackled the issue of finding the phone, you can find that tutorial here. Now it is time to find the keys and wallet.

The idea is to trigger a loud sound on the key chain after pressing a button on the Home Assistant dashboard. This will hopefully be enough for me to locate them.

Please note that this implementation is not suited for large homes, but rather for smaller apartments like mine, since the range is limited to around 10 meters.


Required Hardware

To build this we will need:

  • Home Assistant instance – Since you are reading this, you probably already have it set up.
  • ESP32 board – Any ESPHome compatible variant of the board will work.
  • Bluetooth beeper tags – These are mostly generic, with a single clickable button.

The heart of the project are these cheap Bluetooth beeping tags you can find on AliExpress or Temu.

Various bluetooth tags

They mostly have a replaceable battery, feature BLE(Bluetooth Low Energy) and have a single clickable button on them. This makes them perfect for the job. They come in a few flavors, and I have ordered three types to test each for robustness, beeping volume and battery life. Personally I found the tag pictured in the middle of the photo to be the best.

They are intended to connect to your phone via Bluetooth through an app called ISearchingApp. This then allows you to trigger a beeping sound from te app itself.

Sadly I could not find a Home Assistant integration available for them so I had to improvise with an ESP32 board running ESPHome.

Implementation

To make the tag a valid component in Home Assistant, we need to:

  • Connect the tags to Home Assistant.
  • Make the tags start and stop beeping on demand from Home Assistant.
  • Find a way to make the Single click on the tag button register in Home Assistant.
  • Find a way to make the Double click on the tag button register in Home Assistant.

Once the this is done we will make a few automatons to:

  • Trigger a beeping sound ON from a Home Assistant Dashboard.
  • Once the beeping sound is active, and we have found the key, we need a convenient way to turn the beeping OFF without going all the way to the Dashboard or taking my phone out. For this I will be using the Single click of the tag button. By clicking the tag once the beeping will stop.
  • BONUS Feature - Make the Double click of the tag button trigger the Find My Phone automation so that, when I have my keys I can easily find my Phone.

ESPHome setup

I am not going to go into detail on how you can setup the ESP32 board to work with Home Assistant. There are plenty of tutorials for that. Instead I am going to share the YAML code needed to make the tags usable with Home Assistant.

First I started out by trying to reverse engineer the communication between the ISearching App and the Bluetooth tags. As luck would have it someone already managed to do this.

My code is mostly a further modification of this great tutorial by Hugatry’s HackVlog. Here I found everything I needed for this build.

ESPHome configuration

Here is the YAML code I have used for connecting to the three tags I have, one for the apartment, car and wallet each.

Please understand that there will be a bunch of code here so I will do my best to explain what each part of the code does.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# BLE Clients
ble_client:
  - mac_address: 00:00:00:00:00:00 #Put your tag MAC address here in uppercase.
    id: vlade_house_key_tag
    on_connect:
      then:
        - delay: 2s
        - ble_client.ble_write:
            id: vlade_house_key_tag
            service_uuid: FFE0
            characteristic_uuid: FFE2
            value: [0x00]

  - mac_address: 00:00:00:00:00:00 #Put your second tag MAC address here in uppercase.
    id: vlade_car_key_tag
    on_connect:
      then:
        - delay: 2s
        - ble_client.ble_write:
            id: vlade_car_key_tag
            service_uuid: FFE0
            characteristic_uuid: FFE2
            value: [0x00]

  - mac_address: 00:00:00:00:00:00 #Put your third tag MAC address here in uppercase.
    id: vlade_wallet_tag
    on_connect:
      then:
        - delay: 2s
        - ble_client.ble_write:
            id: vlade_wallet_tag
            service_uuid: FFE0
            characteristic_uuid: FFE2
            value: [0x00]

sensor:
  - platform: ble_client
    type: characteristic
    ble_client_id: vlade_house_key_tag
    id: vlade_house_key_tag_ble_btn
    service_uuid: 'FFE0'
    characteristic_uuid: 'FFE1'
    icon: "mdi:button"
    notify: true
    update_interval: never
    on_notify:
      then:
        - binary_sensor.template.publish:
            id: vlade_house_key_tag_btn
            state: ON
        - delay: 20ms
        - binary_sensor.template.publish:
            id: vlade_house_key_tag_btn
            state: OFF

  - platform: ble_client
    type: characteristic
    ble_client_id: vlade_car_key_tag
    id: vlade_car_key_tag_ble_btn
    service_uuid: 'FFE0'
    characteristic_uuid: 'FFE1'
    icon: "mdi:button"
    notify: true
    update_interval: never
    on_notify:
      then:
        - binary_sensor.template.publish:
            id: vlade_car_key_tag_btn
            state: ON
        - delay: 20ms
        - binary_sensor.template.publish:
            id: vlade_car_key_tag_btn
            state: OFF

  - platform: ble_client
    type: characteristic
    ble_client_id: vlade_wallet_tag
    id: vlade_wallet_tag_ble_btn
    service_uuid: 'FFE0'
    characteristic_uuid: 'FFE1'
    icon: "mdi:button"
    notify: true
    update_interval: never
    on_notify:
      then:
        - binary_sensor.template.publish:
            id: vlade_wallet_tag_btn
            state: ON
        - delay: 20ms
        - binary_sensor.template.publish:
            id: vlade_wallet_tag_btn
            state: OFF

binary_sensor:
  - platform: template
    id: vlade_house_key_tag_btn
    on_multi_click:
      - timing:
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'single'
                tag: 'switch.find_my_keys_esphome_vlade_house_keys_beeper'
      - timing:
          - ON for at most 0.3s
          - OFF for at most 0.8s
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'double'
                tag: 'switch.find_my_keys_esphome_vlade_house_keys_beeper'

  - platform: template
    id: vlade_car_key_tag_btn
    on_multi_click:
      - timing:
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'single'
                tag: 'switch.find_my_keys_esphome_vlade_car_keys_beeper'
      - timing:
          - ON for at most 0.3s
          - OFF for at most 0.8s
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'double'
                tag: 'switch.find_my_keys_esphome_vlade_car_keys_beeper'

  - platform: template
    id: vlade_wallet_tag_btn
    on_multi_click:
      - timing:
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'single'
                tag: 'switch.find_my_keys_esphome_vlade_wallet_beeper'
      - timing:
          - ON for at most 0.3s
          - OFF for at most 0.8s
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'double'
                tag: 'switch.find_my_keys_esphome_vlade_wallet_beeper'

switch:
  - platform: template
    name: "Vlade House Keys Beeper"
    id: vlade_house_key_tag_beeper
    icon: "mdi:key-chain-variant"
    optimistic: true
    turn_on_action:
      - ble_client.ble_write:
          id: vlade_house_key_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x01]
    turn_off_action:
      - ble_client.ble_write:
          id: vlade_house_key_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x00]

  - platform: template
    name: "Vlade Car Keys Beeper"
    id: vlade_car_key_tag_beeper
    icon: "mdi:car-key"
    optimistic: true
    turn_on_action:
      - ble_client.ble_write:
          id: vlade_car_key_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x01]
    turn_off_action:
      - ble_client.ble_write:
          id: vlade_car_key_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x00]

  - platform: template
    name: "Vlade Wallet Beeper"
    id: vlade_wallet_beeper
    icon: "mdi:wallet"
    optimistic: true
    turn_on_action:
      - ble_client.ble_write:
          id: vlade_wallet_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x01]
    turn_off_action:
      - ble_client.ble_write:
          id: vlade_wallet_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x00]

Connect the tags to Home Assistant

This is the code responsible for connecting the ESP32 to the Bluetooth tag. Replace the zeros with the MAC address of your own tag.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
  - mac_address: 00:00:00:00:00:00 #Put your tag MAC address here in uppercase.
    id: vlade_house_key_tag
    on_connect:
      then:
        - delay: 2s
        - ble_client.ble_write:
            id: vlade_house_key_tag
            service_uuid: FFE0
            characteristic_uuid: FFE2
            value: [0x00]

To find the MAC address of the tags, I have used an app called nRF Connect for Mobile.

You can see that this section is duplicated to connect to all the three tags (house keys, car keys, wallet), so if you have more or less tags, just be sure to have one section for each of them.

The on_connect section with the delay is there as a quality of life improvement. These tags have a feature which makes them beep once the tag is disconnected from your phone due to it being out of range. I do not want this, so by sending the bluetooth write command, I am disabling this feature. I suggest that you also copy this section completely.

Create Home Assistant controls for the tags.

Next lets configure the toggle for turning the beeping ON and OFF, to do that I will be using a toggle switch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19

switch:
  - platform: template
    name: "Vlade House Keys Beeper"
    id: vlade_house_key_tag_beeper
    icon: "mdi:key-chain-variant"
    optimistic: true
    turn_on_action:
      - ble_client.ble_write:
          id: vlade_house_key_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x01]
    turn_off_action:
      - ble_client.ble_write:
          id: vlade_house_key_tag
          service_uuid: '1802'
          characteristic_uuid: '2A06'
          value: [0x00]

Note the turn_on and turn_off actions. We are sending Bluetooth commands to turn the beeping ON and OFF.

With this in place, and the code uploaded to your ESP32, the toggles should be visible in Home Assistant.

ESPHome toggles

You can now try out manually toggling the beeping ON and OFF. With any luck you should hear them beeping.

Register the single and double clicks

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
sensor:
  - platform: ble_client
    type: characteristic
    ble_client_id: vlade_house_key_tag
    id: vlade_house_key_tag_ble_btn
    service_uuid: 'FFE0'
    characteristic_uuid: 'FFE1'
    icon: "mdi:button"
    notify: true
    update_interval: never
    on_notify:
      then:
        - binary_sensor.template.publish:
            id: vlade_house_key_tag_btn
            state: ON
        - delay: 20ms
        - binary_sensor.template.publish:
            id: vlade_house_key_tag_btn
            state: OFF
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
binary_sensor:
  - platform: template
    id: vlade_house_key_tag_btn
    on_multi_click:
      - timing:
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'single'
                tag: 'switch.find_my_keys_esphome_vlade_house_keys_beeper' #When a click is detected I dispatch a home assistant event.
      - timing:
          - ON for at most 0.3s
          - OFF for at most 0.8s
          - ON for at most 0.3s
          - OFF for at least 0.8s
        then:
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'double'
                tag: 'switch.find_my_keys_esphome_vlade_house_keys_beeper'

Registering the Single and Double clicks required some code gymnastics. The bottom line is this code allows you to receive the clicks as Home Assistant events.

1
2
3
4
5
          - homeassistant.event:
              event: esphome.tag_click
              data:
                click_type: 'single'
                tag: 'switch.find_my_keys_esphome_vlade_house_keys_beeper'

I opted to use a single event which I named esphome.tag_click for all of my tags. Then in the data object I provide the click type (single, double) and the ID of the clicked tag beeper. You do not have to do the same, but I found it useful since all the tags have a shared behavior.

And with that we have successfully integrated the tags with Home Assistant. In the documentation for ESP32 it is said that it can handle 9 simultaneous bluetooth connections. So the three tags I have connected should not be an issue.

Setting up the UI and the rest of the automations

Add the new toggles to a convenient dashboard. Mine are right next to the button used to find the phone.

Dashboard

Single click turn OFF beeping automation

The first automation will be to make the single click to the tag button disable beeping.

To do this we will need to create an automation which is triggered by the single click, identifies the correct tag, and sends a command for it to stop beeping.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

alias: Turn Off Tag Beeper
description: Turn the tag beeping off when the tag button is pressed once
triggers:
  - event_type: esphome.tag_click
    event_data:
      click_type: single
    trigger: event
conditions: []
actions:
  - data:
      entity_id: "{{ trigger.event.data.tag }}"
    action: homeassistant.turn_off
mode: parallel

You can now see the reason why I included the ID of the tag in the click event data.

1
entity_id: "{{ trigger.event.data.tag }}"

This way I can easily figure out which tag is the target to turn the beeping off.

Double click trigger Find My Phone automation

I also wanted the double click on any of my tags to trigger the Find My Phone automation.

We need to make the automation listen to the esphome.tag_click event. When the event_data of the event contains the click_type = double, the automation will be triggered.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
alias: Find my Phone
description: Automation used to find my phone.
triggers:
  - entity_id:
      - input_button.find_my_phone
    trigger: state
  - trigger: event #New event trigger.
    event_type: esphome.tag_click
    event_data:
      click_type: double
conditions: []
actions:
  - data:
      message: "{{ notification_message }}"
      title: "{{ notification_title }}"
      data:
        ttl: 0
        priority: high
        importance: high
        channel: "{{ notification_channel }}"
    action: "{{ target_device }}"
variables:
  target_device: notify.mobile_app_vlade_poco
  notification_channel: find_my_phone
  notification_title: Find my Phone
  notification_message: Hey phone, someone is looking for you!
mode: single

Conclusion

I have been testing this for about a month so far. The only thing which I have found troublesome is that sometimes I turn the tags OFF completely by mistake. This sometimes happens when I sit on the keys. But other than that it works fine.

Potential improvements will include adding a battery state monitor for each of the tags, so that I can check if the battery is running out.

Thank you for reading this far, I hope it helps you!

comments powered by Disqus