Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow proxy HCI packets to Home Assistant Bluetooth stack #1354

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

myhomeiot
Copy link
Collaborator

This change will allow to proxy all or some packets (like Apple BTLE continuity and beacon's) into Home Assistant bluetooth stack using ESPHome BLE Gateway and use it for tracking devices over Private BLE Device and Bermuda BLE Trilateration integrations.

If you will proxy all packets it's will looks like you are using ESPHome Bluetooth Proxy component except possibility to make connection from Home Assistant to devices.

Home Assistant config:

  - alias: ESPHome BLE Advertise
    mode: queued
    trigger:
      - platform: event
        event_type: esphome.on_ble_advertise
    action:
      - service: ble_monitor.parse_data
        data: "{{ trigger.event.data }}"

or

      - service: ble_monitor.parse_data
        data:
          packet: "{{ trigger.event.data.packet }}"
          device_id: "{{ trigger.event.data.device_id if trigger.event.data.device_id is defined else None }}"
          gateway_id: "{{ trigger.event.data.gateway_id if trigger.event.data.gateway_id is defined else 'unknown' }}"
          proxy: "{{ trigger.event.data.proxy if trigger.event.data.proxy is defined else false }}"

ESPHome configuration for proxy Apple BTLE continuity and beacon's packets:

esp32_ble_tracker:
  on_ble_advertise:
    then:
      - if:
          condition:
            lambda: |-
              static const esp32_ble_tracker::ESPBTUUID apple_manufacturer_id = esp32_ble_tracker::ESPBTUUID::from_uint16(0x004C);
              for (auto data : x.get_manufacturer_datas())
                if (data.uuid == apple_manufacturer_id)
                  return true;
              return false;
          then:
            - homeassistant.event:
                event: esphome.on_ble_advertise
                data:
                  packet: !lambda return ble_gateway::BLEGateway::scan_result_to_hci_packet_hex(x.get_scan_result());
                  gateway_id: ${device_id}
                  proxy: !lambda return true;
#            - lambda: |-
#                ESP_LOGD("Proxy", "[%s] Packet %s", x.address_str().c_str(),
#                  ble_gateway::BLEGateway::scan_result_to_hci_packet_hex(x.get_scan_result()).c_str());

ESPHome configuration for proxy all BLE Advertisement packets:

esp32_ble_tracker:
  on_ble_advertise:
    then:
      - homeassistant.event:
          event: esphome.on_ble_advertise
          data:
            packet: !lambda return ble_gateway::BLEGateway::scan_result_to_hci_packet_hex(x.get_scan_result());
            gateway_id: ${device_id}
            proxy: !lambda return true;

@andrewjswan
Copy link

Looks very interesting.

@Ernst79
Copy link
Collaborator

Ernst79 commented May 15, 2024

We have to wait till the change got merged into ESPHome. After that, this PR will be merged.

ToDo: documentation

@mihsu81
Copy link
Contributor

mihsu81 commented Jul 5, 2024

I've tried the PR and it is causing tens of errors in HA like the below, even without the packets sent over by the ESPHome BLE gateway.

Source: core.py:2696
First occurred: 08:40:13 (4559 occurrences)
Last logged: 08:53:48

Error doing job: Task exception was never retrieved (None)
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/core.py", line 2696, in async_call
    processed_data: dict[str, Any] = handler.schema(service_data)
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/voluptuous/schema_builder.py", line 595, in validate_dict
    return base_validate(path, iteritems(data), out)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/voluptuous/schema_builder.py", line 433, in validate_mapping
    raise er.MultipleInvalid(errors)
voluptuous.error.MultipleInvalid: string value is None for dictionary value @ data['device_id']

@myhomeiot
Copy link
Collaborator Author

myhomeiot commented Jul 5, 2024

@mihsu81 Sorry I doesn't update this PR with latest changes of ble_monitor, you can try now.
I tested this PR for a month and it's works good. You will need ESPHome 2024.6+ with IRK fix if you want to proxy just presence packets like in proxy_by_irk.yaml example which you can see here.
I hope next week I will make PR for update ble_monitor documentation and this PR will be merged.

@mihsu81
Copy link
Contributor

mihsu81 commented Jul 6, 2024

@myhomeiot I had replaced init.py and const.py in my HA ble_monitor custom component with your proposed changes. After restarting HA it gets flooded with the error mentioned previously.
I guess I'll wait for the PR to be merged in Passive BLE Monitor and try my luck then, if you don't get these errors on your side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants