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 yeelight code #22547

Merged
merged 13 commits into from
Jun 13, 2019
Merged

Refactor yeelight code #22547

merged 13 commits into from
Jun 13, 2019

Conversation

zewelor
Copy link
Contributor

@zewelor zewelor commented Mar 29, 2019

Breaking changes:

When starting HA, and some light is not available and doesn't have model declared. It won't be added until properties can be fetched. When model is declared in config, it will be added as before.

Description:

Split yeelight classes, for logic simplification, some nasty nested ifs are removed. Its for easier handling future component improvements. It fixes bugs when yeelights are exported, for example to homekit, before correct supported_features are set ( on first update from device ). If it gets exported earlier, light gets marked as brightness only. It fixes #24018 and #23871.

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.

homeassistant/components/yeelight/light.py Show resolved Hide resolved
homeassistant/components/yeelight/light.py Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
@zewelor zewelor marked this pull request as ready for review April 6, 2019 08:15
@zewelor zewelor requested a review from rytilahti as a code owner April 6, 2019 08:15
@zewelor
Copy link
Contributor Author

zewelor commented Apr 7, 2019

Please don't merge before 0.93

@codecov
Copy link

codecov bot commented Apr 8, 2019

Codecov Report

Merging #22547 into dev will decrease coverage by 0.29%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##              dev   #22547     +/-   ##
=========================================
- Coverage   94.13%   93.83%   -0.3%     
=========================================
  Files         502      448     -54     
  Lines       39349    36528   -2821     
=========================================
- Hits        37040    34275   -2765     
+ Misses       2309     2253     -56
Impacted Files Coverage Δ
homeassistant/components/owntracks/config_flow.py 44.82% <0%> (-41.66%) ⬇️
homeassistant/components/mqtt/fan.py 74.33% <0%> (-23.64%) ⬇️
homeassistant/components/mqtt/light/schema_json.py 73.06% <0%> (-20.65%) ⬇️
homeassistant/bootstrap.py 58.08% <0%> (-17.21%) ⬇️
homeassistant/components/config/script.py 90% <0%> (-10%) ⬇️
homeassistant/components/mqtt/lock.py 91.83% <0%> (-8.17%) ⬇️
homeassistant/components/axis/device.py 93.02% <0%> (-6.98%) ⬇️
homeassistant/components/hassio/ingress.py 71.3% <0%> (-6.75%) ⬇️
homeassistant/helpers/template.py 95.54% <0%> (-4.46%) ⬇️
homeassistant/components/html5/notify.py 85.6% <0%> (-2.43%) ⬇️
... and 264 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c928f82...2c24b9e. Read the comment docs.

@zewelor
Copy link
Contributor Author

zewelor commented May 21, 2019

@rytilahti Seeing that you are active now, maybe you could take a look here ? Main idea was to simplify code and get rid of nasty ifs in update method, also be sure that all devices has defined supported features, from the start. It needs rebase, I will do it, if there is any hope to push this forward.

@rytilahti
Copy link
Member

@zewelor I'll try to do a code review asap, unfortunately I won't have access to any bulbs until later this year, so I hope someone else chimes in to test the functionality.

@zewelor
Copy link
Contributor Author

zewelor commented Jun 2, 2019

Looks like it fixes some issues with homekit and yeelight, #24018 (comment)

Copy link
Member

@rytilahti rytilahti left a comment

Choose a reason for hiding this comment

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

Sorry for taking my time, I added some comments and I think this can be merged after those are handled.


# F821: https://github.com/PyCQA/pyflakes/issues/373
@property
def _bulb(self) -> 'yeelight.Bulb': # noqa: F821
Copy link
Member

Choose a reason for hiding this comment

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

As imports can be done on the top level, this could be converted to simply Bulb, right?

return self.device.bulb

@property
def _properties(self) -> dict:
Copy link
Member

Choose a reason for hiding this comment

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

I don't think dict is a correct type hint, is it? Or is using Dict from typing only necessary if you want to describe the contained 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.

I believe dict type hint was introducend here by you rytilahti@cf5d9ce#diff-1395165791bf7671502a6e2e7bd7d4cbR173 . I'm not sure whats best here. Whats wrong with dict ? Maybe we can skip type hint ?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if there's something wrong with just using dict, the typing module has Dict, but maybe it is just for those cases where you want to define types of its keys and values. So I suppose this is fine..

homeassistant/components/yeelight/light.py Outdated Show resolved Hide resolved
def _lights_setup_helper(klass):
lights.append(klass(device, custom_effects=custom_effects))

if model in ('mono', 'mono1') or device.type == BulbType.White:
Copy link
Member

Choose a reason for hiding this comment

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

I don't really like mixing model and device.type comparison like this, as it makes reading hard. But it's not a showstopper.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I will work on splitting it into 2 methods, when model is declared or fetched via device.type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Its simplified now. Please take a look


def setup(self):
"""Initialize device and send initialized signal."""
if self._update_properties() or self.model:
Copy link
Member

Choose a reason for hiding this comment

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

Should the one above also check for self.model like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure which one ? Can you link to code line ?

Copy link
Member

Choose a reason for hiding this comment

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

Line 289, in update(). I think this code structure is a bit confusing and could be made easier to follow by restructuring it somehow.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Model was only needed in setup, when update fails, but we have model declared, we can build correct Yeelight class. I've simplified this code, I hope it easier to follow now.

@property
def is_nightlight_enabled(self) -> bool:
"""Return true / false if nightlight is currently enabled."""
if self.bulb is None:
return False

return self.bulb.last_properties.get('active_mode') == '1'
return self._active_mode == '1'
Copy link
Member

Choose a reason for hiding this comment

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

Maybe define ACTIVE_MODE_NIGHTLIGHT = '1' and use the constant here for readability. What are the other possible modes and should they also be handled somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

From yeelight docs:

0: daylight mode / 1: moonlight mode (ceiling light only) . I don't think we need to handle anything more now. Added suggested const.

Copy link
Member

@rytilahti rytilahti left a comment

Choose a reason for hiding this comment

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

Looks much cleaner now, thanks! I added a very minor nitpick; you used a multi line comment for a single line commentary. Other than that let's get this merged :-)

initial_update = self._update_properties()

if not initial_update and self.model:
"""We can build correct class anyway."""
Copy link
Member

Choose a reason for hiding this comment

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

Use single line comment (#) here, other than that this looks good to go from my side :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right, even lint complained about it. Fixed

@zewelor
Copy link
Contributor Author

zewelor commented Jun 12, 2019

Great, thanks for review.

@rytilahti
Copy link
Member

This fixes both #24018 and #23871? Are there other known issues this is fixing (just that they can be linked to the description).

@zewelor
Copy link
Contributor Author

zewelor commented Jun 13, 2019

I've linked them from the description. Not that I'm aware of.

@rytilahti
Copy link
Member

Great, let's get this merged 🎉

@rytilahti rytilahti merged commit 6d3c3ce into home-assistant:dev Jun 13, 2019
@zewelor zewelor deleted the refactor_yeelight_code branch June 13, 2019 20:36
@balloob balloob mentioned this pull request Jun 26, 2019
alandtse pushed a commit to alandtse/home-assistant that referenced this pull request Oct 12, 2019
* Separate yeelight light classes

* Removed not used variable

* Allow to create device right away, when model is declared

* Lint fixes

* Use correct brightness, when nightlight mode is on

* Pylint fix

* Add power property

* Fix imports

* Update homeassistant/components/yeelight/light.py

Co-Authored-By: Teemu R. <[email protected]>

* Small PR fixes

* Simplify device to yeelight class mapping

* Simplify device initialization code

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

Successfully merging this pull request may close these issues.

Yeelight add support for MiBedsideLamp2 (MJCTD02YL)
5 participants