core: Problems controlling Flux Led Smart Lights through Homeassistant
Home Assistant release with the issue:
0.92.2
Operating environment (Hass.io/Docker/Windows/etc.):
Hass.io
Raspbian GNU/Linux 9 (stretch)
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux
Raspberry Pi 3 statel B 64bit
Component/platform:
light
https://www.home-assistant.io/components/flux_led/
Description of problem: Ever since I bought “Flux Led Smart Bulb” https://www.amazon.com/Flux-Bluetooth-LED-Smart-Bulb/dp/B00GWBBZ2I I’ve been having issues controlling it through my Homeassistant. However, there was no problem utilizing the bulbs through an official app, or through Flux Light’s Alexa/Google Home skill that would route requests over their servers (not Homeassistant). I didn’t like later approach since my smart bulbs had to send data (and could potentially be controlled from) to some unknown remote server. That’s why I configured them along with my Homeassistant instance, but right away I noticed that the lights could not be properly controlled through Homeassistant’s Google Home component.
For example, Flux Led Smart Bulb works in 3 states (RGBW, static Warm White, and static Cool White) where Warm White and Cool White states cannot be replicated using RGBW:
Warm white is essentially a “normal incandescent” color, that’s separated from RGBW, the brightest possible level the light can operate in:
If you try to replicate the color in RGBW, it will be a much fainter color:
The main problem with controlling these lights through Homeassistant’s Google Home component was that I could not set those 2 special states warm white and cool white. I started looking at the implementation of the component, and I realized that it is a simple wrapper around https://github.com/beville/flux_led utility (that’s not an official API for Flux led, but rather a script “reverse-engineered by studying packet captures between a bulb and the controlling mobile app”), so it does have its downsides.
Anyways, I started investigating how does beville/flux_led
sets those 2 special states, and I found out the following. The script has a CLI interface that calls methods from WifiLedBulb
class (the same class used in Homeassistant’s flux_led component. And if I wanted to set bulbs to warm white state, I’d have to execute the following CLI command: <script> --warmwhite=<level 1-100>
. Then I looked at the stack that this command evaluates, it calls bulb.setWarmWhite(level=options.ww, ...)
, then calls a wrapper self.setWarmWhite255(level=utils.percentToByte(level), ...)
, and then finally calls a method self.setRgbw(r=None, g=None, b=None, w=level, brightness=None, w2=None, ...)
.
As you can see, in order to activate warm white state, rgb
values as well as brightness
and w2
should all be set to None. I played around with the script, and discovered the following:
-
In order to activate warm white state, all values but
w
should beNone
, whilew
can be between 0 and 255. If any other parameter is notNone
, the call will not result in any action -
In order to activate cool white state, all values but
w2
should beNone
, whilew2
can be between 0 and 255. If any other parameter is notNone
, the call will not result in any action -
In order to set lights to a particular RGB color (3rd state),
r
,g
,b
variables should be set to any value between 0 and 255, whilew
andw2
variables must be set toNone
. However,brightness
becomes an optional variable in RGB state, it can beNone
, but it also can be a value between 1 and 100, that will be used to calculate new rgb triplet:
# beville/flux_led
if brightness != None:
(r, g, b) = self._calculateBrightness((r, g, b), brightness)
Ex., (0,0,255)
with brightness set to 50
will result in a new triplet (0,0,127)
.
After I finished investigating inner workings of beville/flux_led
script, I switched back to Homeassistant’s flux_led
component to understand where does it fail to utilize the script in an intended way.
The entry point is _turn_on
method in flux_led.py
file. Where it calls internal beville/flux_led
methods. Here is what I found:
if self._mode == MODE_RGBW:
if white is None:
self._bulb.setRgbw(*color_util.color_hsv_to_RGB(*color))
else:
self._bulb.setRgbw(w=white)
Where the first call setRgbw(*color_util.color_hsv_to_RGB(*color))
(“rgbw” state) falls under condition (3) from above i.e. r
, b
, b
triplet is non-null and w=None
, brightness=None
, w2=None
.
Then the second call setRgbw(w=white)
("warm-white state) falls under condition (1) from above i.e. w
variable is non-null and r=None
, g=None
, b=None
, w=None
, brightness=None
, w2=None
.
Both calls work successfully, however there are two caveats:
- There is no way in
flux_led
component to set a “cold-white” state i.e. condition listed under (2) wherew2
is non-null andr=None
,g=None
,b=None
,w=None
,brightness=None
,w=None
- You cannot set “warm-white” state from your smart speaker i.e. Google Home or Alexa. The problem is that if you ask them to “set light to warm-white/cold-white”, homeassistant never sets “white” value
white = kwargs.get(ATTR_WHITE_VALUE)
, thereforeself._bulb.setRgbw(w=white)
never gets called. Instead, it passes warm-white as(29.6, 58.824)
hs_color that gets converted to RGB triplet, and then callssetRgbw(*color_util.color_hsv_to_RGB(*color))
. And as I explained above, “warm-white” cannot be replicated using RGB.
As, you can see this confusion was caused by 3 mutually exclusive states that could not be handled properly by homeassistant.
Here is my proposal, create 2 special cases in flux_led
component:
# Special case warm-white mode
if hs_color == (29.6, 58.824):
# will eventually call `setRgbw(w=white)`
# Special case cool-white mode
else if hs_color == (60.0, 16.0):
# will eventually call `setRgbw(w2=cool-white)`
I summon @Sidney @balloob to look at my report and consider a proposal.
Meanwhile, I’ll create a PR and attach it under this issue.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 29 (27 by maintainers)
I don’t think we need architectural changes.
I can give input. However, let’s first verify that @yeralin is still around and willing to work more on this?
You probably need to sync devices so Google gets the latest info. I don’t know if you also need to implement the
color_temp
property to make it work.That is the way to set a white light. Google asking for a HSV color is wrong. We should fix that, not add another wrong thing to cover up the first mistake.
It still is considered rude. Code owners are automatically tagged when an issue for their components is opened (tagged actually). So please stop tagging people just because you think they might have something to do with it. In this case and in many other cases if you care to take a look at the repo Paulus and I are listed as only contributors not because we were the sole creators of those components but because of recent restructuring of the code base.
Sidney is @autinerd 😃