Всем привет, сегодня будем скрашивать никак не наступающую зиму всякими забавными штуками типа заливания прошивки в esp32, и установки тотальной слежки за всеми внутри квартиры. Основа всех этих изысканий вот эта статья. Вся магия будет происходить исключительно тыканием в кнопки UI и написанием yaml. Основная идея - прошить несколько esp32 прошивкой, которая будет будет стучать про слышимые BLE дева��сы через wifi в HomeAssistant . А потом раскидать их по квартире.

Нам понадобится

  • HomeAssisstant

  • Несколько ESP32. Лучше одинаковых, у меня, к сожалению не так, это c3-mini и c6, что делает настройку несколько интереснее. ESP32 лучше брать с торчащей сверху антенной

В моем случае у обоих ESP32 по два порта Type-C и RGB светодод. Светоидод яркий и вполне тянет на ночник. На али такое стоит рублей 300-400, в озоне, с быстрой доставкой, раза в 3 дороже.
В моем случае у обоих ESP32 по два порта Type-C и RGB светодод. Светоидод яркий и вполне тянет на ночник. На али такое стоит рублей 300-400, в озоне, с быстрой доставкой, раза в 3 дороже.

Первое, ставим ESPHome. Один момент, при сборке оно лезет на что то заблоченное, и просто висит. Мне известен тока один рецепт - трехбуквенное то, о чем нельзя говорить. Потом подключаем ESP32 к HomeAssistant (портом USB(на С3)/ESP32C6 (на С6)) и создаем у себя на диске вот такой yaml. Назовем его bt-tracker-c3-bedroom.yaml

Скрытый текст
---
packages:
  rgb_status_led: 
    url: https://github.com/Flo-R1der/ESPHome_RGB-Status-LED_Package
    file: status_led_package.yaml

light:
  - platform: esp32_rmt_led_strip
    id: system_status_led             # DO NOT CHANGE
    pin: GPIO8                       # check your board
    rgb_order: GRB                    # check your board
    num_leds: 1
    chipset: WS2812                  # check your board
    name: "onboard LED"
    disabled_by_default: true
    default_transition_length: 200ms
    icon: mdi:led-outline
    restore_mode: ALWAYS_OFF
    effects:
      - pulse:
          name: "Slow Pulse"          # REQUIRED
          update_interval: 2s         # can be adjusted
      - pulse:
          name: "Fast Pulse"          # REQUIRED
          update_interval: 500ms      # can be adjusted
             
esphome:
  name: "bt-tracker-c3-bedroom"
  friendly_name: BT tracker c3 bedroom

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf

# Enable logging
logger:
  level: DEBUG
  baud_rate: 115200
  hardware_uart: USB_SERIAL_JTAG


# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Bt Fallback Hotspot"
    password: "xxxxxxxx"

captive_portal:

mdns:
  disabled: false

web_server:
  port: 80

esp32_ble_tracker:
  scan_parameters:
    active: true
    interval: 211ms
    window: 180ms
    continuous: true

bluetooth_proxy:
  active: true

sensor:
  - platform: uptime
    name: "Uptime"
    unit_of_measurement: "h"
    accuracy_decimals: 2
    update_interval: 60s
    filters:
      - lambda: return x / 3600.0;  # Convert seconds to hours

  - platform: internal_temperature
    name: "Internal Temp"
    entity_category: diagnostic

  - platform: wifi_signal
    name: "Wi-Fi Signal"
    update_interval: 30s
    entity_category: diagnostic

text_sensor:
  - platform: wifi_info
    bssid:
      name: "BSSID"
      entity_category: diagnostic
    ip_address:
      name: "IP"
      entity_category: diagnostic

time:
  - platform: sntp
    id: sntp_time
    servers:
      - 0.pool.ntp.org
      - 1.pool.ntp.org

Заменяем xxxxxxxx на нормальные рандомные строки. Так же меняем раздел esphome: на что то нужное именно вам. Пример заточен под esp32-c3, если у вас что-то другое то надо поменять и 'esp32: -> board:' . По идее при инициализации дополнение спросит креды wifi и сохранит в файле secrets.yaml в HomeAssistant. Открываем настройки ESPHome, импортируем в него созданный yaml, жмем там Install, выбираем нужный порт USB и собираем проект. Сборка на Raspberry Pi 4 занимает наверное минуты 3-4 . После прошивки esp32 лучше его отключить от HA. У меня, например, при перезагрузке HA немного растерялся и запутался в esp32 и двух Zigbee свистках, от чего Zigbee2MQTT немного потерял все устройства. Было немного неприятненько. Перезагрузка без подключенного esp32 все починила.

Если вы все сделали правильно, то должен побежать лог билда, а потом логи самой прошивки, в том числе коннекта к wifi. Там даже умудрились воткнуть графики уровня сигнала wifi, выглядит прикольно. Светодиод должен загореться зеленым.

Потом создаем копию bt-tracker-c3-bedroom.yaml, например bt-tracker-c6-hall.yaml и правим там борду и название, примерно так:

Скрытый текст
esphome:
  name: "bt-tracker-c6-hall"
  friendly_name: BT tracker c6 hall

esp32:
  board: esp32-c6-devkitm-1
  framework:
    type: esp-idf

Если вы все сделали правильно то должно быть примерно так.

Если все ок то при нажатии кнопки visit должно открываться нечто такое

Тут видно логи, а так же можно поиграть светодиододом. Яркостью и режимом работы.
Тут видно логи, а так же можно поиграть светодиододом. Яркостью и режимом работы.

Теперь идем в настройки BT и ставим каждому трекеру правильное место положение, а так же расставляем ESP32 на местности. При их установке лучше всего следовать этим рекомендациям. В настройках это выглядит примерно так.

Железная структура готова, продолжаем настройку. Теперь надо поставить в HA интеграцию Private BLE Device. Так как BLE устройства используют Resolvable Private Addresses (RPA) и генерят рандомные MACи нам нужно получить  Identity Resolving Key (IRK). В доке по интеграции описаны хитрые способы их получить. Я так из Keychain Access получил IRK для Samsung S24 и iPad. Есть другой способ. С помощью ESPHome и вот этого yaml (вариант для esp32c3)

Скрытый текст
esphome:
  name: "irk-capture"
  friendly_name: IRK capture

packages:
  rgb_status_led:
    url: https://github.com/Flo-R1der/ESPHome_RGB-Status-LED_Package
    file: status_led_package.yaml


light:
  - platform: esp32_rmt_led_strip
    id: system_status_led             # DO NOT CHANGE
    pin: GPIO8                       # check your board
    rgb_order: GRB                    # check your board
    num_leds: 1
    chipset: WS2812                  # check your board
    name: "onboard LED"
    disabled_by_default: true
    default_transition_length: 200ms
    icon: mdi:led-outline
    restore_mode: ALWAYS_OFF
    effects:
      - pulse:
          name: "Slow Pulse"          # REQUIRED
          update_interval: 2s         # can be adjusted
      - pulse:
          name: "Fast Pulse"          # REQUIRED
          update_interval: 500ms      # can be adjusted

esp32:
  variant: esp32c3
  board: seeed_xiao_esp32c3
  framework:
    type: esp-idf
    version: recommended
    sdkconfig_options:
      # Enable Bluetooth and NimBLE, disable Bluedroid
      CONFIG_BT_ENABLED: "y"
      CONFIG_BT_BLUEDROID_ENABLED: "n"
      CONFIG_BT_NIMBLE_ENABLED: "y"

      # Roles (peripheral/broadcaster sufficient)
      CONFIG_BT_NIMBLE_ROLE_PERIPHERAL: "y"
      CONFIG_BT_NIMBLE_ROLE_BROADCASTER: "y"
      CONFIG_BT_NIMBLE_ROLE_CENTRAL: "n"
      CONFIG_BT_NIMBLE_ROLE_OBSERVER: "n"

      # Security (bonding + LESC)
      CONFIG_BT_NIMBLE_SECURITY_ENABLE: "y"
      CONFIG_BT_NIMBLE_SM_LEGACY: "y"
      CONFIG_BT_NIMBLE_SM_SC: "y"

web_server:
  port: 80


logger:
  level: DEBUG
  baud_rate: 115200
  hardware_uart: USB_CDC

api:
  encryption:
    key: "xxxxxxxxxxxxx"

ota:
  - platform: esphome
    password: "xxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  power_save_mode: NONE
  fast_connect: true
  enable_on_boot: true
  reboot_timeout: 10min
  ap:
    ssid: "BLE tracker fallback"
    password: "xxxxxxxxx"
    ap_timeout: 120s

captive_portal:

mdns:


# Pull your irk_capture external component (ESP-IDF NimBLE version)
external_components:
  - source:
      type: git
      url: https://github.com/DerekSeaman/irk-capture
      ref: main
    components: [irk_capture]
    refresh: 0s

# Configure the custom IRK capture component
irk_capture:
  id: irk
  ble_name: "IRK Capture"
  start_on_boot: true

# Single text_sensor block with both Wi‑Fi info and IRK capture sensors
text_sensor:
  - platform: wifi_info
    bssid:
      name: "BSSID"
      entity_category: diagnostic
    ip_address:
      name: "IP"
      entity_category: diagnostic

  - platform: irk_capture
    irk_capture_id: irk
    last_irk:
      id: last_irk
      name: "IRK"
    last_address:
      id: last_addr
      name: "Device MAC"

# BLE advertising on/off (drives start/stop advertising)
switch:
  - platform: irk_capture
    irk_capture_id: irk
    advertising:
      id: ble_advertising
      name: "BLE Advertising"
      restore_mode: ALWAYS_OFF

# Buttons
button:
  - platform: irk_capture
    irk_capture_id: irk
    new_mac:
      id: new_mac_btn
      name: "Generate New MAC"
  - platform: restart
    name: "Restart Device"

# Text input to change the BLE name dynamically
text:
  - platform: irk_capture
    irk_capture_id: irk
    ble_name:
      id: ble_name_input
      name: "BLE Device Name"
      mode: text

# Diagnostics and basics
sensor:
  - platform: uptime
    name: "Uptime"
    unit_of_measurement: "h"
    accuracy_decimals: 2
    update_interval: 60s
    filters:
      - lambda: return x / 3600.0;

  - platform: internal_temperature
    name: "Internal Temp"
    entity_category: diagnostic

  - platform: wifi_signal
    name: "Wi-Fi Signal"
    update_interval: 30s
    entity_category: diagnostic

time:
  - platform: sntp
    id: sntp_time
    servers:
      - 0.pool.ntp.org
      - 1.pool.ntp.org

Так же меняем xxxxxxxx на радомные строки, прошиваем, и идем в вебинтерфейс. Дальше на устройстве, которое хочем трекать, паримся по BT с девайсом 'IRK Capture' и веб интерфейсе забираем IRK. Этот способ правда работает не на все 100%, например два телефона Samsung этот девайс не видело, MacBook M1 и M2 тоже, а вот iPad нормально законнектился и отдал IRK. Добавляем ключи в интеграцию.

Добавленные ключи, для добавление нужно что бы устройство было рядом.
Добавленные ключи, для добавление нужно что бы устройство было рядом.

Но, это еще не все :) Ставим интеграцию Bermuda BLE Trilateration.

По идее после добавления все добавленные устройства должны появится и там.

И это еще не все ! Теперь нам надо настроить все поставленное. Смысл в том что подкрутить параметры так что-бы нужный трекер сообщал что устройство рядом. В приниципе это не сложно. Кладем смартфон в метре от любого из трекеров. Жмем шестеренку и выбираем Calibration1: Global

И там выбираем трекер и устройство и играемся с настройкой Reference Power, выставляя разные значения и нажимая Подтвердить. Сверху появляется табличка, наша цель что бы в Estimate был примерно 1 метр.

Когда получили нужное, ставим галку Save and Close и жмем Подтвердить. Дальше, по инструкции , надо отнести телефон на 5 метров и играться с Attenuation что бы получить 5 метров. Но мне это не помогло. Помогло другое

В настройках идем в Calibration 2: Scanner RSSI Offsets и там играемся так же, жмем Подтвердить меняя циферки в yaml пока не получим циферки расстояния похожие на реальные

В результате получается как-то так

Борда на скору руку
Борда на скору руку

Срабатывает довольно быстро, даже при выключенном экране на устройстве и вполне подходит для автоматизации.

Вот так легко и просто настроить BLE трекинг во всей квартире или доме, за смешные деньги. А так же залить прошивку в esp32 используя исключительно yaml. Все как мы, DevOpsы, любим :)

В вообще стоить присмотреться к esphome, компонент там дофига.