## Description:
More fixes flagged by pylint 2 that don't hurt to have before the actual pylint 2 upgrade (which I'll submit soon).
## Checklist:
- [ ] The code change is tested and works locally.
- [x] Local tests pass with `tox`. **Your PR cannot be merged unless tests pass**
* Accept and report both xy and RGB color for lights
* Fix demo light supported_features
* Add new XY color util functions
* Always make color changes available as xy and RGB
* Always expose color as RGB and XY
* Consolidate color supported_features
* Test fixes
* Additional test fix
* Use hue/sat as the hass core color interface
* Tests updates
* Assume MQTT RGB devices need full RGB brightness
* Convert new platforms
* More migration
* Use float for HS API
* Fix backwards conversion for KNX lights
* Adjust limitless min saturation for new scale
* Lazy loading of service descriptions
* Fix tests
* Load YAML in executor
* Return a copy of available services to allow mutations
* Remove lint
* Add zha/services.yaml
* Only cache descriptions for known services
* Remove lint
* Remove description loading during service registration
* Remove description parameter from async_register
* Test async_get_all_descriptions
* Remove lint
* Fix typos from multi-edit
* Remove unused arguments
* Remove unused import os
* Remove unused import os, part 2
* Remove unneeded coroutine decorator
* Only use executor for loading files
* Cleanups suggested in review
* Increase test coverage
* Fix races in existing tests
With this optimization we can send a single UDP packet to the light rather
than one packet per zone (up to 80 packets for LIFX Z). This removes a
potential multi-second latency on the frontend color picker.
The aiolifx 0.6.0 release fixes an issue where an effect color could
remain set after stopping the effect. This only affected multi-zone
lights (i.e. LIFX Z) and only if the effect was stopped by setting
the light brightness or the color (but not both).
The aiolifx 0.6.0 release also defaults end_index to start_index+7,
so we can remove that argument.
Finally, aiolifx_effects 0.1.2 adds support for aiolifx 0.6.0.
* Get full multizone state during registration
We used to rely on the periodic update to get the state of each zone, only
establishing the number of zones during registration. This resulted in errors
if the current state was needed for a partial color change before the first
async_update happened.
Now we do a full update before adding the light. Thus async_update can no
longer assume device.color_zones to be defined and must instead use the
response message to decide the total number of zones.
* Insist on getting the initial state
If a response to the initial state query is lost we used to just carry on.
This resulted in type errors when we next tried to access the undefined state.
After this commit the light is not added before we have the full state.
This scenario mostly happens when something is misbehaving and the type errors
were actually useful in figuring out what happend. So an error message is
logged in their place.
* Remove lint
* LIFX: improve performance of multi-light transitions
To avoid hub overload, the light.turn_on call will change each light
sequentially.
As LIFX has no hub we can safely increase performance by starting all
light transitions concurrently.
* Improve state updates after light changes
The light.turn_on call will set a new state and then immediately read it
back. However, reading the state of a LIFX light right after a state
change can still return the old value.
To handle this situation we have previously delayed the update request a
little while to allow a potential state change to settle. Because light
updates are now run in parallel, this delay might be too short when many
lights are set at once.
This commit introduces a per-light Lock to make it explicit when the
state cannot yet be trusted.
We must then do the state update ourselves. This was already done at the
end of a long transition and that code can be reused for also doing the
update at the start of a transition.
* Make aiolifx modules easily available
* Use aiolifx features_map for deciding bulb features
Also move the feature detection out of Light so it is available even
during the initial detection.
* Move each LIFX light type to a separate class
* Simplify AwaitAioLIFX
This has become possible with recent aiolifx that calls the callback even
when a message is lost.
Now the wrapper can be used also before a Light is added though the register
callback then has to become a coroutine.
* Refactor send_color
* Add support for multizone
This lets lifx_set_state work on individual zones.
Also update to aiolifx_effects 0.1.1 that restores the state for individual
zones.
The default aiolifx timers are tuned for a network with few lost packets.
This means that lights can become "unavailable" from just a two second
dropout. An unavailable light is completely useless for HA until it is
rediscovered so this is an undesirable state to be in.
These tweaks make aiolifx try harder to get its messages through to the
bulbs, at the cost of some latency in detecting lights that actually are
unavailable.
* LIFX: Move light effects to external library
This moves the LIFX light effects to the external library aiolifx_effects.
To get the light state synchronized between that library and HA, the LIFX
platform no longer maintains the light state itself. Instead, it uses the
cached state that aiolifx maintains.
The reorganization also includes the addition of a cleanup handler.
* Fix style
* Refactor into find_hsbk
This will be useful for new methods that also have to find passed in colors.
* Add AwaitAioLIFX
This encapsulates the callback and Event that aiolifx needs and thus avoids an
explosion of those when new calls are added.
The refresh_state is now generally useful, so move it into its own method.
* Initial effects support for LIFX
These effects are useful as notifications. They mimic the breathe and pulse
effects from the LIFX HTTP API:
https://api.developer.lifx.com/docs/breathe-effecthttps://api.developer.lifx.com/docs/pulse-effect
However, this implementation runs locally with the LIFX LAN protocol.
* Saturate LIFX no color value
Now the color is "full saturation, no brightness". This avoids a lot of
temporary white when fading from the "no color" value and into a real color.
* Organize LIFX effects in classes
This is to move the setup/restore away from the actual effect, making it quite
simple to add additional effects.
* Stop running LIFX effects on conflicting service calls
Turning the light on/off or starting a new effect will now stop the running
effect.
* Present default LIFX effects as light.turn_on effects
This makes the effects (with default parameters) easily accessible from
the UI.
* Add LIFX colorloop effect
This cycles the HSV colors, so that is added as an internal way to set a
color.
* Move lifx to its own package and split effects into a separate file
* Always show LIFX light name in logs
The name is actually the easiest way to identify a bulb so just using it
as a fallback was a bit odd.
* Compact effect getter
* Always use full brightness for random flash color
This is a stopgap. When a bit more infrastructure is in place, the intention
is to turn the current hue some degrees. This will guarantee a flash color
that is both unlike the current color and unlike white.
* Clear effects concurrently
We have to wait for the bulbs, so let us wait for all of them at once.
* Add lifx_effect_stop
The colorloop effect is most impressive if run on many lights. Testing
this has revealed the need for an easy way to stop effects on all lights
and return to the initial state of each bulb. This new call does just that.
Calling turn_on/turn_off could also stop the effect but that would not
restore the initial state.
* Always calculate the initial effect color
To fade nicely from power off, the breathe effect needs to keep an
unchanging hue. So give up on using a static start color and just find the
correct hue from the target color.
The colorloop effect can start from anything but we use a random color
just to keep things a little interesting during power on.
* Fix lint
* Update .coveragerc
* Cache the name of LIFX lights
After #7031 the LIFX device will change during an unregister/register
transition. This has the user-visible effect of the new device missing
a friendly name until the next poll.
We now cache the name internally and it will then transfer to the new
device when it registers.
* Allow LIFX logging even without an available device
This will allow us to set the device to None when it unregisters.
* Calculate LIFX availability from the existence of a device
This has become possible because the device is no longer needed
to provide the name of the light when it is unavailable.
We just have to forget the device when it unregisters.
* Plug file leak on LIFX unregister
The aiolifx 0.4.4 release closes its socket when the unregister callback is
called. This plugs a file descriptor leak but also means that we must be
careful to not use the device after it goes unavailable.
Also, when a light reappears, it has a new device that must be used.
* Do not test self.available in service calls
The core will learn to handle that.
* Add legacy LIFX platform for Windows support
The async platform introduced in 9ef084d903 has
turned out to use Python functionality that is not available in Windows.
This commit restores the previous implementation, now named lifx_legacy.
* Add a comment about the platform being a legacy implementation
* Warn when using unsupported lifx platform on Windows
* Update .coveragerc
* Fix LIFX unregister races
If the initial state request never got a response, we tried to unregister
a device that was not yet registered.
Also, aiolifx 0.4.2 has an "unregister" race fix.
* Update requirements
* Move LIFX to aiolifx for driving the bulbs
* Fix whitespace
* Fix more whitespace
* Fix lint
* Define _available in init
* Add @callback decorators
* Use hass.async_add_job
* Rename class
A LIFX bulb maintains its previous color even when the light is off.
For example, if the previous color is blue and the bulb is turned on
and then set to a red color, it will transition through purple colors.
After this commit, the target color is set while the bulb is still
turned off. This overrides the previous color and brightness that the
bulb remembered. The light is then turned on with the requested
transition duration.
For the example, this gives the expected result of only going through
red colors.