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

Refactor hue to split bridge support from light platform #10691

Merged
merged 11 commits into from
Dec 10, 2017

Conversation

andreacampi
Copy link
Contributor

@andreacampi andreacampi commented Nov 20, 2017

Description:

This is in preparation to supporting sensors.

Related issue (if applicable): fixes #10609

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#4099

Example entry for configuration.yaml (if applicable):

hue:
  bridges:
    - host: 192.168.0.40
    - host: 192.168.0.80
    - filename: /tmp/phue.conf

Checklist:

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

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

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

@homeassistant homeassistant added integration: hue merging-to-master This PR is merging into the master branch and should probably change the branch to `dev`. new-platform platform: light.hue labels Nov 20, 2017
@homeassistant
Copy link
Contributor

Hi @andreacampi,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

self.config_request_id = configurator.request_config(
"Philips Hue",
lambda data: self.setup(),
description=("Press the button on the bridge to register Philips Hue "

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (82 > 79 characters)

# We got an error if this method is called while we are configuring
if self.config_request_id:
configurator.notify_errors(
self.config_request_id, "Failed to register, please try again.")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)


try:
api = self.bridge.get_api()
except phue.PhueRequestTimeout:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined name 'phue'

os.path.join(os.path.dirname(__file__), 'services.yaml'))
self.hass.services.register(DOMAIN, SERVICE_HUE_SCENE, hue_activate_scene,
descriptions.get(SERVICE_HUE_SCENE),
schema=SCENE_SCHEMA)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

descriptions = load_yaml_config_file(
os.path.join(os.path.dirname(__file__), 'services.yaml'))
self.hass.services.register(DOMAIN, SERVICE_HUE_SCENE, hue_activate_scene,
descriptions.get(SERVICE_HUE_SCENE),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent


GROUP_NAME_ALL_HUE_LIGHTS = "All Hue Lights"

def _find_host_from_config(hass, filename=PHUE_CONFIG_FILE):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

self.assertEqual(1, len(self.hass.states.all()))
self.assertEqual('configure', self.hass.states.all()[0].state)
self.assertEqual('Failed to register, please try again.',
self.hass.states.all()[0].attributes.get(configurator.ATTR_ERRORS))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent


# We should see a total of two identical calls
args = call('localhost',
config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent


# We should see a total of two identical calls
args = call('localhost',
config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent


# We should see a total of two identical calls
args = call('localhost',
config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

@andreacampi
Copy link
Contributor Author

andreacampi commented Nov 20, 2017

There are a few things I still have to clean up, but I wanted to get the ball rolling and get early feedback.

To do:

  • support multiple bridges;
  • support the older config schema and provide upgrade instructions;
  • add back support for discovery;
  • more unit tests, including:
    • the bridge service (hue_activate_scene)
    • lights

Re config, this changes from:

light:
  - platform: hue
    host: DEVICE_IP_ADDRESS

to:

hue:
  - host: DEVICE_IP_ADDRESS

I find this makes more sense when the component can support more than just lights, yes?

@andreacampi
Copy link
Contributor Author

cc @robmarkcole

@homeassistant
Copy link
Contributor

Hi @andreacampi,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!


mock_bridge.assert_called_once_with(
'localhost',
config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (83 > 79 characters)


with assert_setup_component(1):
with patch('homeassistant.components.hue._find_host_from_config',
return_value='localhost') as mock_config:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent
local variable 'mock_config' is assigned to but never used

with patch('homeassistant.helpers.discovery.load_platform') \
as mock_load:
self.assertTrue(setup_component(
self.hass, hue.DOMAIN, {hue.DOMAIN: {CONF_HOST: 'localhost'}}))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (83 > 79 characters)


from homeassistant.components import configurator, hue
# import homeassistant.components.configurator as configurator
from homeassistant.const import CONF_HOST, CONF_PLATFORM

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'homeassistant.const.CONF_PLATFORM' imported but unused

import logging
import unittest
from unittest.mock import call, MagicMock, patch
import os

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'os' imported but unused


import logging
import unittest
from unittest.mock import call, MagicMock, patch

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'unittest.mock.MagicMock' imported but unused

@homeassistant
Copy link
Contributor

Hi @andreacampi,

It seems you haven't yet signed a CLA. Please do so here.

Once you do that we will be able to review and accept this pull request.

Thanks!

@balloob balloob changed the base branch from master to dev November 20, 2017 01:36
@balloob
Copy link
Member

balloob commented Nov 20, 2017

It seems like you have some commits in this branch that are not yours, please base your work off a fresh copy of the dev branch.

@balloob
Copy link
Member

balloob commented Nov 20, 2017

I haven't looked at the code at all, but yes, migrating hue from just a platform to be a component for auth and a platform for lights = 👍

@robmarkcole
Copy link
Contributor

Im not sure I follow this refactor, appears to be a lot of light specific code in components/hue.py which is the hub/auth..?

@andreacampi
Copy link
Contributor Author

@robmarkcole yeah that's fair, not sure why I decided to go that way. I'll clean that up and/or explain.

@andreacampi
Copy link
Contributor Author

I'll rebase and check the failed tests; just not today as I've had a long day on ~4 hours of sleep.

@balloob balloob removed the merging-to-master This PR is merging into the master branch and should probably change the branch to `dev`. label Nov 21, 2017
self.mock_bridge, mock.ANY, self.mock_bridge_type,
self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue,
True),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

call(0, {'name': 'All Hue Lights', 'state': {'any_on': True}},
self.mock_bridge, mock.ANY, self.mock_bridge_type,
self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

self.mock_bridge.allow_in_emulated_hue, True),
call(0, {'name': 'All Hue Lights', 'state': {'any_on': True}},
self.mock_bridge, mock.ANY, self.mock_bridge_type,
self.mock_bridge.allow_unreachable,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

self.mock_bridge_type, self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue, True),
call(0, {'name': 'All Hue Lights', 'state': {'any_on': True}},
self.mock_bridge, mock.ANY, self.mock_bridge_type,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

mock_hue_light.assert_has_calls([
call(2, {'state': 'off'}, self.mock_bridge, mock.ANY,
self.mock_bridge_type, self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue, True),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

self.mock_bridge.allow_in_emulated_hue, True),
call(2, {'state': 'off'}, self.mock_bridge, mock.ANY,
self.mock_bridge_type, self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue, True),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

self.mock_bridge_type, self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue, True),
call(2, {'state': 'off'}, self.mock_bridge, mock.ANY,
self.mock_bridge_type, self.mock_bridge.allow_unreachable,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

mock_hue_light.assert_has_calls([
call(1, {'state': 'on'}, self.mock_bridge, mock.ANY,
self.mock_bridge_type, self.mock_bridge.allow_unreachable,
self.mock_bridge.allow_in_emulated_hue, True),

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

self.assertEquals(len(ret), 3)
mock_hue_light.assert_has_calls([
call(1, {'state': 'on'}, self.mock_bridge, mock.ANY,
self.mock_bridge_type, self.mock_bridge.allow_unreachable,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

self.mock_api.get.return_value = {1: {'state': 'on'}, 2: {'state': 'off'}}

ret = hue_light.process_groups(self.hass,
self.mock_api, self.mock_bridge, self.mock_bridge_type)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

Not only this looks nicer, but it also nicely solves additional bridges being added after initial setup (e.g. pairing a second bridge should work now, I believe it required a restart before).
@balloob balloob merged commit 8197488 into home-assistant:dev Dec 10, 2017
@balloob
Copy link
Member

balloob commented Dec 10, 2017

🎉 🐬 Awesome, great job !

akatrevorjay added a commit to akatrevorjay/home-assistant that referenced this pull request Dec 11, 2017
…ent-being-nonexistent

* origin/dev:
  Volvo on call: Optional use of Scandinavian miles. Also add average fuel consumption property (home-assistant#11051)
  add custom bypass status to total connect (home-assistant#11042)
  Refactor hue to split bridge support from light platform (home-assistant#10691)
  Add GPS coords to meraki (home-assistant#10998)
  Add a caldav calendar component (home-assistant#10842)
  Added support for cover in tellstick (home-assistant#10858)
akatrevorjay added a commit to akatrevorjay/home-assistant that referenced this pull request Dec 11, 2017
…into dev

* 'dev' of https://github.com/home-assistant/home-assistant:
  Volvo on call: Optional use of Scandinavian miles. Also add average fuel consumption property (home-assistant#11051)
  add custom bypass status to total connect (home-assistant#11042)
  Refactor hue to split bridge support from light platform (home-assistant#10691)
  Add GPS coords to meraki (home-assistant#10998)
  Add a caldav calendar component (home-assistant#10842)
  Added support for cover in tellstick (home-assistant#10858)
@mezz64
Copy link
Contributor

mezz64 commented Dec 12, 2017

These changes seem to be allowing HASS to discover it's own emulated hue bridge as a bridge device and throws an error because it can't find the config file.

@m2k2
Copy link

m2k2 commented Dec 13, 2017

I'm also having some problems since this commit after re-working my configuration. Once the hubs are added with emulated hue disabled, I see the error below for each light. Should I open up a new issue?

Update for light.garage__right fails
Traceback (most recent call last):
  File "/srv/homeassistant/homeassistant_venv/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 199, in async_update_ha_state
    yield from self.async_device_update()
  File "/srv/homeassistant/homeassistant_venv/lib/python3.5/site-packages/homeassistant/helpers/entity.py", line 306, in async_device_update
    yield from self.hass.async_add_job(self.update)
  File "/usr/lib/python3.5/asyncio/futures.py", line 380, in __iter__
    yield self  # This tells Task to wait for completion.
  File "/usr/lib/python3.5/asyncio/tasks.py", line 304, in _wakeup
    future.result()
  File "/usr/lib/python3.5/asyncio/futures.py", line 293, in result
    raise self._exception
  File "/usr/lib/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.5/site-packages/homeassistant/components/light/hue.py", line 385, in update
    self.update_lights(no_throttle=True)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.5/site-packages/homeassistant/components/light/hue.py", line 149, in <lambda>
    lambda **kw: update_lights(hass, bridge, add_devices, **kw))
  File "/srv/homeassistant/homeassistant_venv/lib/python3.5/site-packages/homeassistant/util/__init__.py", line 306, in wrapper
    result = method(*args, **kwargs)
  File "/srv/homeassistant/homeassistant_venv/lib/python3.5/site-packages/homeassistant/util/__init__.py", line 306, in wrapper
    result = method(*args, **kwargs)
TypeError: update_lights() got an unexpected keyword argument 'no_throttle'

@andreacampi
Copy link
Contributor Author

Both of these are pretty bad :( I'll try to report and open tasks as needed, but @mezz64 @m2k2 if you want to do that'd be helpful.

@m2k2 unless I broke something last second while iterating on unit tests, I don't know that I have enough to reproduce it. I'll ping you if I have trouble.

@andreacampi andreacampi deleted the pr10609 branch December 13, 2017 20:58
@andreacampi
Copy link
Contributor Author

@balloob thoughts on me removing the @Throttle annotation? that would remove the issue @m2k2 is seeing.

@andreacampi
Copy link
Contributor Author

See #11126

@andreacampi
Copy link
Contributor Author

Another pull request: #11128

balloob pushed a commit to home-assistant/home-assistant.io that referenced this pull request Dec 14, 2017
* Update documentation for Philips Hue changes.

See home-assistant/core#10691 for more info.

* Update hue.markdown
@fabaff fabaff mentioned this pull request Dec 16, 2017
ntalekt added a commit to ntalekt/homeassistant that referenced this pull request Dec 18, 2017
pschmitt added a commit to pschmitt/hass-config that referenced this pull request Dec 20, 2017
@brent20
Copy link

brent20 commented Dec 22, 2017

How would one set the scan_interval now on the new hue component? Before I was able to set it per the docs here: https://home-assistant.io/docs/configuration/platform_options/

Leaving this in place with the new Hue component seemed to break the configuration. Once I know the new way to set a scan_interval, I'll go ahead and submit a PR to update the docs.

Thanks!

@MartinHjelmare
Copy link
Member

Please open an issue if you suspect a bug. If you need help please use our help channels:
https://home-assistant.io/help/#communication-channels

Merged PRs should not be used for support or bug reports. Thanks!

@mcoms
Copy link

mcoms commented Dec 28, 2017

This work appears to change the filename of the default phue.conf to phue-<bridge serial number>.conf for discovered bridges. After upgrading, this causes HomeAssistant to boot with:

2017-12-28 10:15:26 INFO (MainThread) [homeassistant.setup] Setting up hue
2017-12-28 10:15:26 INFO (MainThread) [homeassistant.setup] Setup of domain hue took 0.0 seconds.
2017-12-28 10:15:26 INFO (MainThread) [homeassistant.core] Bus:Handling <Event component_loaded[L]: component=hue>
2017-12-28 10:15:26 INFO (MainThread) [homeassistant.core] Bus:Handling <Event platform_discovered[L]: service=philips_hue, discovered=host=192.168.1.150, port=80, ssdp_description=http://192.168.1.150:80/description.xml, name=Fhue (192.168.1.150), model_name=Philips hue bridge 2015, model_number=BSB002, serial=00178848ac26>
2017-12-28 10:15:26 INFO (SyncWorker_6) [phue] Attempting to connect to the bridge...
2017-12-28 10:15:26 INFO (SyncWorker_6) [phue] Error opening config file, will attempt bridge registration
2017-12-28 10:15:26 WARNING (SyncWorker_6) [homeassistant.components.hue] Connected to Hue at 192.168.1.150 but not registered.
2017-12-28 10:15:27 INFO (SyncWorker_6) [homeassistant.loader] Loaded configurator from homeassistant.components.configurator
2017-12-28 10:15:27 INFO (MainThread) [homeassistant.core] Bus:Handling <Event service_registered[L]: domain=configurator, service=configure>
2017-12-28 10:15:27 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: entity_id=configurator.philips_hue, old_state=None, new_state=<state configurator.philips_hue=configure; configure_id=139857224447368-1, fields=[], friendly_name=Philips Hue, entity_picture=/static/images/logo_philips_hue.png, description=
Press the button on the bridge to register Philips Hue with Home Assistant.

![Location of button on bridge](/static/images/config_philips_hue.jpg)
, submit_caption=I have pressed the button @ 2017-12-28T10:15:27.009680+00:00>>

And to fail to connect to the bridge.

My hue bridge is in the roof and pressing the button was quite a pain.

It would be handy to either, upgrade (i.e. rename) the existing phue.conf file automatically, or, to have a log message showing the filename the component was trying to read, so I could manually rename it.

May also be useful to update the docs to give the filename of the hue token file, since I looked there first of all to see if there'd been a change.

@MartinHjelmare
Copy link
Member

Please open an issue in the appropriate reoo if you suspect a bug or there's a problem with documentation. If you need help please use our help channels:
https://home-assistant.io/help/#communication-channels

Merged PRs should not be used for support or bug reports. You can link to the PR that you want to tag from the issue. Thanks!

@home-assistant home-assistant locked and limited conversation to collaborators Dec 28, 2017
@ghost ghost removed the platform: light.hue label Mar 21, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor the Philips Hue component to support more than just lights