core icon indicating copy to clipboard operation
core copied to clipboard

New integration: Hue BLE

Open flip-dots opened this issue 1 year ago • 13 comments

Proposed change

This integration allows for the newer Phillips Hue lights with Bluetooth to be controlled over Bluetooth by Home Assistant instead of having to use a Zigbee dongle. I think support for this is quite important because many people (myself at least) trialed Home Assistant on hardware they have lying around like a raspberry pi, old laptop, or mini pc, which have Bluetooth built in but no Zigbee support and don't want to spend money on hardware they don't necessarily need, at least without knowing that its worth it.

The features are as follows:

  • On/Off control
  • Brightness control
  • Color temp control
  • XY color control
  • Light state reading
    • Power
    • Brightness
    • Color temp
    • XY color
  • Light metadata reading
    • Name
    • Manufacturer
    • Model
    • Firmware version
    • Zigbee address
  • Push approach

Type of change

  • [ ] Dependency upgrade
  • [ ] Bugfix (non-breaking change which fixes an issue)
  • [X] New integration (thank you!)
  • [ ] New feature (which adds functionality to an existing integration)
  • [ ] Deprecation (breaking change to happen in the future)
  • [ ] Breaking change (fix/feature causing existing functionality to break)
  • [ ] Code quality improvements to existing code or addition of tests

Additional information

This is my first real integration for Home Assistant and also the first Python library I have programmed so I have probably made a few mistakes but I've been testing it for the past few months and have ironed out the issues as they have appeared, I've been using the latest version for the past two weeks and haven't gotten any errors or reliability issues, yet anyway...

The library can be found here and the docs here

I only have the LCA006 model which is 1100 lumens which does RGB and WW/CW so that is the only model confirmed to work but I have tried to design the library and integration to detect the supported features and set the flags accordingly but this is untested on other models, if anyone happens to have one of the other models that supports Bluetooth and could test it for me that would be great.

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request: https://github.com/home-assistant/home-assistant.io/pull/33042

Checklist

  • [X] The code change is tested and works locally.
  • [X] Local tests pass. Your PR cannot be merged unless tests pass
  • [X] There is no commented out code in this PR.
  • [X] I have followed the development checklist
  • [X] I have followed the perfect PR recommendations
  • [X] The code has been formatted using Ruff (ruff format homeassistant tests)
  • [X] Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • [X] The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • [X] New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • [X] For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.
  • [X] Untested files have been added to .coveragerc.

library changelog

To help with the load of incoming pull requests:

flip-dots avatar Jun 02 '24 13:06 flip-dots

The integration also fails with an uncatched exception. That might be an error in the library. If you can't fix this in the library you might want to catch this exception in the config flow

2024-06-29 19:52:37.239 ERROR (MainThread) [HueBLE] Exception connecting to light "Hue filament bulb". Error "'NoneType' object has no attribute 'get'".
2024-06-29 19:52:37.442 INFO (MainThread) [HueBLE] Received expected disconnect from "HaBleakClientWrapper, xx:xx:xx:xx:xx:xx".
2024-06-29 19:52:37.443 ERROR (MainThread) [homeassistant.components.hue_ble.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 147, in async_step_confirm
    await validate_input(self.hass, user_input)
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 50, in validate_input
    if not light.authenticated:
           ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/ha-venv/lib/python3.12/site-packages/HueBLE.py", line 933, in authenticated
    if properties.get("Paired") is True:
       ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

tr4nt0r avatar Jun 29 '24 19:06 tr4nt0r

The integration also fails with an uncatched exception. That might be an error in the library. If you can't fix this in the library you might want to catch this exception in the config flow

2024-06-29 19:52:37.239 ERROR (MainThread) [HueBLE] Exception connecting to light "Hue filament bulb". Error "'NoneType' object has no attribute 'get'".
2024-06-29 19:52:37.442 INFO (MainThread) [HueBLE] Received expected disconnect from "HaBleakClientWrapper, xx:xx:xx:xx:xx:xx".
2024-06-29 19:52:37.443 ERROR (MainThread) [homeassistant.components.hue_ble.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 147, in async_step_confirm
    await validate_input(self.hass, user_input)
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 50, in validate_input
    if not light.authenticated:
           ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/ha-venv/lib/python3.12/site-packages/HueBLE.py", line 933, in authenticated
    if properties.get("Paired") is True:
       ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Seems like my method for detecting if a device is authenticated doesn't work for all Linux systems, (It works fine on HAOS and Mint tho which is strange), I updated the library so the method returns None if it cannot determine the authentication status on a Linux system and updated the integration to ignore if it can't tell if its authenticated and proceed anyway.

flip-dots avatar Jun 30 '24 14:06 flip-dots

The integration also fails with an uncatched exception. That might be an error in the library. If you can't fix this in the library you might want to catch this exception in the config flow

2024-06-29 19:52:37.239 ERROR (MainThread) [HueBLE] Exception connecting to light "Hue filament bulb". Error "'NoneType' object has no attribute 'get'".
2024-06-29 19:52:37.442 INFO (MainThread) [HueBLE] Received expected disconnect from "HaBleakClientWrapper, xx:xx:xx:xx:xx:xx".
2024-06-29 19:52:37.443 ERROR (MainThread) [homeassistant.components.hue_ble.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 147, in async_step_confirm
    await validate_input(self.hass, user_input)
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 50, in validate_input
    if not light.authenticated:
           ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/ha-venv/lib/python3.12/site-packages/HueBLE.py", line 933, in authenticated
    if properties.get("Paired") is True:
       ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Seems like my method for detecting if a device is authenticated doesn't work for all Linux systems, (It works fine on HAOS and Mint tho which is strange), I updated the library so the method returns None if it cannot determine the authentication status on a Linux system and updated the integration to ignore if it can't tell if its authenticated and proceed anyway.

I'm still not able to connect to my hue lamp so i can't really test. (I'm getting error code 82), would be good if you work on making the library more robust and test it more thoroughly with different setups. I am testing it in the Home Assistant Devcontainer (on Windows with WSL2) and an ESPHome Bluetooth proxy. )

tr4nt0r avatar Jul 03 '24 12:07 tr4nt0r

I've marked this PR, as changes are requested that need to be processed. Please un-draft it once it is ready for review again by clicking the "Ready for review" button.

Thanks! 👍

../Frenck

Learn more about our pull request process.

frenck avatar Jul 06 '24 12:07 frenck

The integration also fails with an uncatched exception. That might be an error in the library. If you can't fix this in the library you might want to catch this exception in the config flow

2024-06-29 19:52:37.239 ERROR (MainThread) [HueBLE] Exception connecting to light "Hue filament bulb". Error "'NoneType' object has no attribute 'get'".
2024-06-29 19:52:37.442 INFO (MainThread) [HueBLE] Received expected disconnect from "HaBleakClientWrapper, xx:xx:xx:xx:xx:xx".
2024-06-29 19:52:37.443 ERROR (MainThread) [homeassistant.components.hue_ble.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 147, in async_step_confirm
    await validate_input(self.hass, user_input)
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 50, in validate_input
    if not light.authenticated:
           ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/ha-venv/lib/python3.12/site-packages/HueBLE.py", line 933, in authenticated
    if properties.get("Paired") is True:
       ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Seems like my method for detecting if a device is authenticated doesn't work for all Linux systems, (It works fine on HAOS and Mint tho which is strange), I updated the library so the method returns None if it cannot determine the authentication status on a Linux system and updated the integration to ignore if it can't tell if its authenticated and proceed anyway.

I'm still not able to connect to my hue lamp so i can't really test. (I'm getting error code 82), would be good if you work on making the library more robust and test it more thoroughly with different setups. I am testing it in the Home Assistant Devcontainer (on Windows with WSL2) and an ESPHome Bluetooth proxy. )

That authentication error makes sense now, I never designed this system with the idea of a Bluetooth proxy in mind, I have been developing on Mint using the devcontainer to pass through my laptops Bluetooth card by editing the container file and my Home Assistant server is using a USB dongle. That being said I don't think there should be any issue using a Bluetooth proxy though I don't have one to test, if its important I can buy one to try to get it to work, I think its more likely something to do with that light working slightly differently from the model I have and can use to test, if you have a moment my test library has some example scripts which should work on Windows and could rule that out.

flip-dots avatar Jul 13 '24 13:07 flip-dots

The integration also fails with an uncatched exception. That might be an error in the library. If you can't fix this in the library you might want to catch this exception in the config flow

2024-06-29 19:52:37.239 ERROR (MainThread) [HueBLE] Exception connecting to light "Hue filament bulb". Error "'NoneType' object has no attribute 'get'".
2024-06-29 19:52:37.442 INFO (MainThread) [HueBLE] Received expected disconnect from "HaBleakClientWrapper, xx:xx:xx:xx:xx:xx".
2024-06-29 19:52:37.443 ERROR (MainThread) [homeassistant.components.hue_ble.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 147, in async_step_confirm
    await validate_input(self.hass, user_input)
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 50, in validate_input
    if not light.authenticated:
           ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/ha-venv/lib/python3.12/site-packages/HueBLE.py", line 933, in authenticated
    if properties.get("Paired") is True:
       ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Seems like my method for detecting if a device is authenticated doesn't work for all Linux systems, (It works fine on HAOS and Mint tho which is strange), I updated the library so the method returns None if it cannot determine the authentication status on a Linux system and updated the integration to ignore if it can't tell if its authenticated and proceed anyway.

I'm still not able to connect to my hue lamp so i can't really test. (I'm getting error code 82), would be good if you work on making the library more robust and test it more thoroughly with different setups. I am testing it in the Home Assistant Devcontainer (on Windows with WSL2) and an ESPHome Bluetooth proxy. )

That authentication error makes sense now, I never designed this system with the idea of a Bluetooth proxy in mind, I have been developing on Mint using the devcontainer to pass through my laptops Bluetooth card by editing the container file and my Home Assistant server is using a USB dongle. That being said I don't think there should be any issue using a Bluetooth proxy though I don't have one to test, if its important I can buy one to try to get it to work, I think its more likely something to do with that light working slightly differently from the model I have and can use to test, if you have a moment my test library has some example scripts which should work on Windows and could rule that out.

I have obtained an ESP32 and set it up as a Bluetooth proxy and it seems to work fine, I think the error must be to do with that specific model of light, its probably controlled using different GATT addresses.

flip-dots avatar Jul 19 '24 16:07 flip-dots

The integration also fails with an uncatched exception. That might be an error in the library. If you can't fix this in the library you might want to catch this exception in the config flow

2024-06-29 19:52:37.239 ERROR (MainThread) [HueBLE] Exception connecting to light "Hue filament bulb". Error "'NoneType' object has no attribute 'get'".
2024-06-29 19:52:37.442 INFO (MainThread) [HueBLE] Received expected disconnect from "HaBleakClientWrapper, xx:xx:xx:xx:xx:xx".
2024-06-29 19:52:37.443 ERROR (MainThread) [homeassistant.components.hue_ble.config_flow] Unexpected exception
Traceback (most recent call last):
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 147, in async_step_confirm
    await validate_input(self.hass, user_input)
  File "/workspaces/ha-core/homeassistant/components/hue_ble/config_flow.py", line 50, in validate_input
    if not light.authenticated:
           ^^^^^^^^^^^^^^^^^^^
  File "/home/vscode/.local/ha-venv/lib/python3.12/site-packages/HueBLE.py", line 933, in authenticated
    if properties.get("Paired") is True:
       ^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Seems like my method for detecting if a device is authenticated doesn't work for all Linux systems, (It works fine on HAOS and Mint tho which is strange), I updated the library so the method returns None if it cannot determine the authentication status on a Linux system and updated the integration to ignore if it can't tell if its authenticated and proceed anyway.

I'm still not able to connect to my hue lamp so i can't really test. (I'm getting error code 82), would be good if you work on making the library more robust and test it more thoroughly with different setups. I am testing it in the Home Assistant Devcontainer (on Windows with WSL2) and an ESPHome Bluetooth proxy. )

That authentication error makes sense now, I never designed this system with the idea of a Bluetooth proxy in mind, I have been developing on Mint using the devcontainer to pass through my laptops Bluetooth card by editing the container file and my Home Assistant server is using a USB dongle. That being said I don't think there should be any issue using a Bluetooth proxy though I don't have one to test, if its important I can buy one to try to get it to work, I think its more likely something to do with that light working slightly differently from the model I have and can use to test, if you have a moment my test library has some example scripts which should work on Windows and could rule that out.

I have obtained an ESP32 and set it up as a Bluetooth proxy and it seems to work fine, I think the error must be to do with that specific model of light, its probably controlled using different GATT addresses.

Hmm, that's weird, because it is also an LCA006 that I have

tr4nt0r avatar Jul 19 '24 19:07 tr4nt0r

Please click the "Ready for review" button when the comments have been addressed

emontnemery avatar Aug 22 '24 08:08 emontnemery

@flip-dots CI is not passing, please fix the failures. Be sure to follow the development guide here so you can run the linters and other checks in your development environment: https://developers.home-assistant.io/docs/development_environment

emontnemery avatar Sep 12 '24 09:09 emontnemery

@flip-dots You still need to update homeassistant/brands/philips.json with the hue_ble integration. There's some documentation here https://developers.home-assistant.io/docs/creating_integration_brand explaining what that does

emontnemery avatar Oct 16 '24 08:10 emontnemery

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks :+1:

Learn more about our pull request process.

home-assistant[bot] avatar Nov 08 '24 13:11 home-assistant[bot]

There hasn't been any activity on this pull request recently. This pull request has been automatically marked as stale because of that and will be closed if no further activity occurs within 7 days. If you are the author of this PR, please leave a comment if you want to keep it open. Also, please rebase your PR onto the latest dev branch to ensure that it's up to date with the latest changes. Thank you for your contribution!

github-actions[bot] avatar Mar 27 '25 14:03 github-actions[bot]

Not stale. Awaits review

Note that this likely won't get a review until the CI is passing

bdraco avatar Mar 27 '25 18:03 bdraco