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

Add HomeKit support for fans #14351

Merged
merged 16 commits into from
May 16, 2018
Merged

Conversation

schmittx
Copy link
Contributor

@schmittx schmittx commented May 9, 2018

Description:

Adds support for fans in HomeKit. In addition to basic on/off it uses supported_features to add additional characteristics for direction and oscillation (in HomeKit, oscillation = swing_mode).

Support for speed is not being implemented yet due to the current architecture of speed_list. Refer to home-assistant/architecture#27 for more details. Once an improved architecture for speed_list is set and entities updated, HomeKit will be updated to support speed.

Related issue (if applicable): N/A

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

Example entry for configuration.yaml (if applicable):

homekit:
  filter:
    include_domains:
      - fan

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox. Your PR cannot be merged unless tests pass

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

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

  • 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.

If the code does not interact with devices:

  • Tests have been added to verify that the new code works.

Copy link
Member

@cdce8p cdce8p left a comment

Choose a reason for hiding this comment

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

This PR is already looking quite good. I didn't had time to test it yet, but nevertheless added a few small comments.

def __init__(self, *args, config):
"""Initialize a new Light accessory object."""
super().__init__(*args, category=CATEGORY_FAN)
self._domain = split_entity_id(self.entity_id)[0]
Copy link
Member

Choose a reason for hiding this comment

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

Is their a reason you use split_entity_id instead of DOMAIN imported from components.fan?
As I see it, it should be enough to use the later one.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No reason, just copied the base code from type_switches. I agree though, I've updated to import from components.fan

CHAR_ACTIVE, value=self._state, setter_callback=self.set_state)

if CHAR_ROTATION_SPEED in self.chars:
speed_list = self.hass.states.get(self.entity_id) \
Copy link
Member

Choose a reason for hiding this comment

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

Does this change over time? At the moment no homekit type accounts for chnages in supported features, so I think changing this to self.speed_list would work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, you're correct in that it doesn't change after being initialized at startup.

.attributes.get(ATTR_SPEED_LIST)
speed = speed_list[int(round(value / self.min_step)) - 1]
self.hass.components.fan.turn_on(
self.entity_id, speed=speed)
Copy link
Member

Choose a reason for hiding this comment

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

Can you use hass.services.call instead. Also for the ones below.
I just haven't gotten around to harmonize that for the other types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem, I can help with updating the other types accordingly too.

Copy link
Member

Choose a reason for hiding this comment

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

No need to do that now. I'm planing to start converting the first methods to async, maybe as soon as this weekend. I can do it then.

That in mind it would be great if we could finish up on #14159 first. As a heads up: I'm rewriting almost all tests at the moment to use pytest and async. Should get the PR out in the next few hours. It might require a rebase then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good.

I'll get #14159 wrapped up tonight so that can be closed out.

Regarding tests for this PR, should I wait for your new PR, then rebase and add/update for fans?

Copy link
Member

Choose a reason for hiding this comment

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

I just opened the PR #14377

The foundations stayed the same. It might be best if you take a look at one of the new type tests and write the new tests based on that structure. They should work even without the PR being merged.

However, it is likely that #14159 needs to be rebased once the PR is merged.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Understood, I'll look at the new tests tonight and update this PR.

Copy link
Member

Choose a reason for hiding this comment

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

I just merged the test PR, should be good to rebase now.

"""Set state if call came from HomeKit."""
_LOGGER.debug('%s: Set direction to %d', self.entity_id, value)
self._flag[CHAR_ROTATION_DIRECTION] = True
direction = HOMEKIT_TO_HASS[value]
Copy link
Member

Choose a reason for hiding this comment

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

Can we use if instead? Dictionary mapping is a bit much for just to values.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem, updated.

.attributes.get(ATTR_SUPPORTED_FEATURES)
if self._features & SUPPORT_SET_SPEED:
self.chars.append(CHAR_ROTATION_SPEED)
self._speed = None
Copy link
Member

Choose a reason for hiding this comment

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

What reason is their to define it as class variable? As I see it, it's only used in update_state. Same for self._direction and self._oscillating.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I just copied the base code from type_lights. It's not needed so I removed.

direction = new_state.attributes.get(ATTR_DIRECTION)
if not self._flag[CHAR_ROTATION_DIRECTION] and \
direction in HASS_TO_HOMEKIT:
self._direction = HASS_TO_HOMEKIT[direction]
Copy link
Member

Choose a reason for hiding this comment

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

Same as before. I think if is more than enough here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No problem, updated.

@cdce8p cdce8p mentioned this pull request May 10, 2018
2 tasks
acc.char_direction.client_update_value(1)
self.hass.block_till_done()
self.assertEqual(self.events[1].data[ATTR_DOMAIN], DOMAIN)
self.assertEqual(self.events[1].data[ATTR_SERVICE], SERVICE_SET_DIRECTION)

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)

acc.char_direction.client_update_value(0)
self.hass.block_till_done()
self.assertEqual(self.events[0].data[ATTR_DOMAIN], DOMAIN)
self.assertEqual(self.events[0].data[ATTR_SERVICE], SERVICE_SET_DIRECTION)

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)

import unittest

from homeassistant.core import callback
from homeassistant.components.fan import (

This comment was marked as outdated.

@schmittx
Copy link
Contributor Author

schmittx commented May 11, 2018

@cdce8p Please merge #14159 first, I'll rebase/update this PR afterwards.

@cdce8p cdce8p mentioned this pull request May 11, 2018
2 tasks
@schmittx schmittx changed the title [WIP] Add HomeKit support for fans Add HomeKit support for fans May 12, 2018
if CHAR_ROTATION_DIRECTION in self.chars:
direction = new_state.attributes.get(ATTR_DIRECTION)
if not self._flag[CHAR_ROTATION_DIRECTION] and \
direction in (DIRECTION_FORWARD, DIRECTION_REVERSE):
Copy link
Member

Choose a reason for hiding this comment

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

This currently doesn't work if set from the frontend. See home-assistant/frontend#1158

@schmittx
Copy link
Contributor Author

schmittx commented May 15, 2018

@cdce8p I tested the latest commit, all good here. I also updated description to explain lack of speed support. PR for docs is updated as well. Ready to merge.

@cdce8p cdce8p merged commit 25dcddf into home-assistant:dev May 16, 2018
@balloob balloob mentioned this pull request May 28, 2018
@schmittx schmittx deleted the homekit-fan-support branch June 2, 2018 00:04
@cdce8p cdce8p mentioned this pull request Jun 12, 2018
2 tasks
girlpunk pushed a commit to girlpunk/home-assistant that referenced this pull request Sep 4, 2018
@home-assistant home-assistant locked and limited conversation to collaborators Sep 5, 2018
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.

4 participants