-
-
Notifications
You must be signed in to change notification settings - Fork 32k
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
Refactor yeelight code #22547
Conversation
Please don't merge before 0.93 |
Codecov Report
@@ 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
Continue to review full report at Codecov.
|
@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. |
@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. |
Looks like it fixes some issues with homekit and yeelight, #24018 (comment) |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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..
def _lights_setup_helper(klass): | ||
lights.append(klass(device, custom_effects=custom_effects)) | ||
|
||
if model in ('mono', 'mono1') or device.type == BulbType.White: |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Co-Authored-By: Teemu R. <[email protected]>
There was a problem hiding this 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.""" |
There was a problem hiding this comment.
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 :-)
There was a problem hiding this comment.
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
Great, thanks for review. |
I've linked them from the description. Not that I'm aware of. |
Great, let's get this merged 🎉 |
* 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
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:
tox
. Your PR cannot be merged unless tests pass