Flux.led component not updating state properly

I am new to Home Assistant and have recently connected my RGBW wifi controller with LED strip to it through flux_led component. My issue relates to the state in frontend not updating properly.

Problem explained: When I click on color picker / brightness slider / white slider, it will bounce back to it’s origin / previous state. Let’s say the light is green, I click red, it will bounce back to green. If I now click blue, it will bounce back to red. And so on. Waiting up to 30 seconds will also result in the state updating itself properly.

What I have tried:
I have tried the ledenet protocol, but mine are certainly not.
Creating a custom component in config/custom_components/light/flux_led.py is my last try. Adding the line:
self._bulb.update_state(retry=2)
to the end of turn_off() and turn_on(). It was suggested in another post.

However, this does not seem to change anything, neither am I sure if the custom component is run instead of the built-in. As I understood it should override the built-in when the file/folder pattern matches.

I am using the configurator addon for changes, and reset the server from server management from Home Assistant Configuration menu.

I hope anyone have stumbled upon a solution for this or can guide me in the right direction

So after a littlebit of trying and failing it seems as I have found a temporary solution:
At the bottom of function for turn off/on

import time
#CODE
time.sleep(1)
self._bulb.update_state(retry=2)

I can confirm that issue. I also have one controller that behaves the way you describe it. Is there any solution to be released?

Yes! I did find a solution. It is not very nice, but it works. If you are familiar with custom components.
create custom_components/flux_led/light.py. The change I have done is to poll for state one extra time, and it does work quite well.

CODE (posting in a sec)

"""
Support for Flux lights.
For more details about this platform, please refer to the documentation at
https://home-assistant.io/components/light.flux_led/
"""
import logging
import socket
import random
import time

import voluptuous as vol

from homeassistant.const import CONF_DEVICES, CONF_NAME, CONF_PROTOCOL
from homeassistant.components.light import (
    ATTR_BRIGHTNESS, ATTR_HS_COLOR, ATTR_EFFECT, ATTR_WHITE_VALUE,
    EFFECT_COLORLOOP, EFFECT_RANDOM, SUPPORT_BRIGHTNESS, SUPPORT_EFFECT,
    SUPPORT_COLOR, SUPPORT_WHITE_VALUE, Light, PLATFORM_SCHEMA)
import homeassistant.helpers.config_validation as cv
import homeassistant.util.color as color_util

REQUIREMENTS = ['flux_led==0.22']

_LOGGER = logging.getLogger(__name__)

CONF_AUTOMATIC_ADD = 'automatic_add'
ATTR_MODE = 'mode'

DOMAIN = 'flux_led'

SUPPORT_FLUX_LED = (SUPPORT_BRIGHTNESS | SUPPORT_EFFECT |
                    SUPPORT_COLOR)

MODE_RGB = 'rgb'
MODE_RGBW = 'rgbw'

# This mode enables white value to be controlled by brightness.
# RGB value is ignored when this mode is specified.
MODE_WHITE = 'w'

# List of supported effects which aren't already declared in LIGHT
EFFECT_RED_FADE = 'red_fade'
EFFECT_GREEN_FADE = 'green_fade'
EFFECT_BLUE_FADE = 'blue_fade'
EFFECT_YELLOW_FADE = 'yellow_fade'
EFFECT_CYAN_FADE = 'cyan_fade'
EFFECT_PURPLE_FADE = 'purple_fade'
EFFECT_WHITE_FADE = 'white_fade'
EFFECT_RED_GREEN_CROSS_FADE = 'rg_cross_fade'
EFFECT_RED_BLUE_CROSS_FADE = 'rb_cross_fade'
EFFECT_GREEN_BLUE_CROSS_FADE = 'gb_cross_fade'
EFFECT_COLORSTROBE = 'colorstrobe'
EFFECT_RED_STROBE = 'red_strobe'
EFFECT_GREEN_STROBE = 'green_strobe'
EFFECT_BLUE_STROBE = 'blue_strobe'
EFFECT_YELLOW_STROBE = 'yellow_strobe'
EFFECT_CYAN_STROBE = 'cyan_strobe'
EFFECT_PURPLE_STROBE = 'purple_strobe'
EFFECT_WHITE_STROBE = 'white_strobe'
EFFECT_COLORJUMP = 'colorjump'

EFFECT_MAP = {
    EFFECT_COLORLOOP:             0x25,
    EFFECT_RED_FADE:              0x26,
    EFFECT_GREEN_FADE:            0x27,
    EFFECT_BLUE_FADE:             0x28,
    EFFECT_YELLOW_FADE:           0x29,
    EFFECT_CYAN_FADE:             0x2a,
    EFFECT_PURPLE_FADE:           0x2b,
    EFFECT_WHITE_FADE:            0x2c,
    EFFECT_RED_GREEN_CROSS_FADE:  0x2d,
    EFFECT_RED_BLUE_CROSS_FADE:   0x2e,
    EFFECT_GREEN_BLUE_CROSS_FADE: 0x2f,
    EFFECT_COLORSTROBE:           0x30,
    EFFECT_RED_STROBE:            0x31,
    EFFECT_GREEN_STROBE:          0x32,
    EFFECT_BLUE_STROBE:            0x33,
    EFFECT_YELLOW_STROBE:         0x34,
    EFFECT_CYAN_STROBE:           0x35,
    EFFECT_PURPLE_STROBE:         0x36,
    EFFECT_WHITE_STROBE:          0x37,
    EFFECT_COLORJUMP:             0x38
}

FLUX_EFFECT_LIST = [
    EFFECT_RANDOM,
    ] + list(EFFECT_MAP)

DEVICE_SCHEMA = vol.Schema({
    vol.Optional(CONF_NAME): cv.string,
    vol.Optional(ATTR_MODE, default=MODE_RGBW):
        vol.All(cv.string, vol.In([MODE_RGBW, MODE_RGB, MODE_WHITE])),
    vol.Optional(CONF_PROTOCOL):
        vol.All(cv.string, vol.In(['ledenet'])),
})

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
    vol.Optional(CONF_DEVICES, default={}): {cv.string: DEVICE_SCHEMA},
    vol.Optional(CONF_AUTOMATIC_ADD, default=False):  cv.boolean,
})


def setup_platform(hass, config, add_entities, discovery_info=None):
    """Set up the Flux lights."""
    import flux_led
    lights = []
    light_ips = []

    for ipaddr, device_config in config.get(CONF_DEVICES, {}).items():
        device = {}
        device['name'] = device_config[CONF_NAME]
        device['ipaddr'] = ipaddr
        device[CONF_PROTOCOL] = device_config.get(CONF_PROTOCOL)
        device[ATTR_MODE] = device_config[ATTR_MODE]
        light = FluxLight(device)
        lights.append(light)
        light_ips.append(ipaddr)

    if not config.get(CONF_AUTOMATIC_ADD, False):
        add_entities(lights, True)
        return

    # Find the bulbs on the LAN
    scanner = flux_led.BulbScanner()
    scanner.scan(timeout=10)
    for device in scanner.getBulbInfo():
        ipaddr = device['ipaddr']
        if ipaddr in light_ips:
            continue
        device['name'] = '{} {}'.format(device['id'], ipaddr)
        device[ATTR_MODE] = MODE_RGBW
        device[CONF_PROTOCOL] = None
        light = FluxLight(device)
        lights.append(light)

    add_entities(lights, True)


class FluxLight(Light):
    """Representation of a Flux light."""

    def __init__(self, device):
        """Initialize the light."""
        self._name = device['name']
        self._ipaddr = device['ipaddr']
        self._protocol = device[CONF_PROTOCOL]
        self._mode = device[ATTR_MODE]
        self._bulb = None
        self._error_reported = False

    def _connect(self):
        """Connect to Flux light."""
        import flux_led

        self._bulb = flux_led.WifiLedBulb(self._ipaddr, timeout=5)
        if self._protocol:
            self._bulb.setProtocol(self._protocol)

        # After bulb object is created the status is updated. We can
        # now set the correct mode if it was not explicitly defined.
        if not self._mode:
            if self._bulb.rgbwcapable:
                self._mode = MODE_RGBW
            else:
                self._mode = MODE_RGB

    def _disconnect(self):
        """Disconnect from Flux light."""
        self._bulb = None

    @property
    def available(self) -> bool:
        """Return True if entity is available."""
        return self._bulb is not None

    @property
    def name(self):
        """Return the name of the device if any."""
        return self._name

    @property
    def is_on(self):
        """Return true if device is on."""
        return self._bulb.isOn()

    @property
    def brightness(self):
        """Return the brightness of this light between 0..255."""
        if self._mode == MODE_WHITE:
            return self.white_value

        return self._bulb.brightness

    @property
    def hs_color(self):
        """Return the color property."""
        return color_util.color_RGB_to_hs(*self._bulb.getRgb())

    @property
    def supported_features(self):
        """Flag supported features."""
        if self._mode == MODE_RGBW:
            return SUPPORT_FLUX_LED | SUPPORT_WHITE_VALUE

        if self._mode == MODE_WHITE:
            return SUPPORT_BRIGHTNESS

        return SUPPORT_FLUX_LED

    @property
    def white_value(self):
        """Return the white value of this light between 0..255."""
        return self._bulb.getRgbw()[3]

    @property
    def effect_list(self):
        """Return the list of supported effects."""
        return FLUX_EFFECT_LIST

    def turn_on(self, **kwargs):
        """Turn the specified or all lights on."""
        if not self.is_on:
            self._bulb.turnOn()

        hs_color = kwargs.get(ATTR_HS_COLOR)

        if hs_color:
            rgb = color_util.color_hs_to_RGB(*hs_color)
        else:
            rgb = None

        brightness = kwargs.get(ATTR_BRIGHTNESS)
        effect = kwargs.get(ATTR_EFFECT)
        white = kwargs.get(ATTR_WHITE_VALUE)

        # Show warning if effect set with rgb, brightness, or white level
        if effect and (brightness or white or rgb):
            _LOGGER.warning("RGB, brightness and white level are ignored when"
                            " an effect is specified for a flux bulb")

        # Random color effect
        if effect == EFFECT_RANDOM:
            self._bulb.setRgb(random.randint(0, 255),
                              random.randint(0, 255),
                              random.randint(0, 255))
            return

        # Effect selection
        if effect in EFFECT_MAP:
            self._bulb.setPresetPattern(EFFECT_MAP[effect], 95)
            return

        # Preserve current brightness on color/white level change
        if brightness is None:
            brightness = self.brightness

        # Preserve color on brightness/white level change
        if rgb is None:
            rgb = self._bulb.getRgb()

        if white is None and self._mode == MODE_RGBW:
            white = self.white_value

        # handle W only mode (use brightness instead of white value)
        if self._mode == MODE_WHITE:
            self._bulb.setRgbw(0, 0, 0, w=brightness)

        # handle RGBW mode
        elif self._mode == MODE_RGBW:
            self._bulb.setRgbw(*tuple(rgb), w=white, brightness=brightness)

        # handle RGB mode
        else:
            self._bulb.setRgb(*tuple(rgb), brightness=brightness)
        time.sleep(1)
        self._bulb.update_state(retry=2)

    def turn_off(self, **kwargs):
        """Turn the specified or all lights off."""
        self._bulb.turnOff()
        time.sleep(1)
        self._bulb.update_state(retry=2)

    def update(self):
        """Synchronize state with bulb."""
        if not self.available:
            try:
                self._connect()
                self._error_reported = False
            except socket.error:
                self._disconnect()
                if not self._error_reported:
                    _LOGGER.warning("Failed to connect to bulb %s, %s",
                                    self._ipaddr, self._name)
                    self._error_reported = True
                return

        self._bulb.update_state(retry=2)

Thank you for your solution. Is just adding this to the custom components and will it work? Do i need to do something in home assistant configuration.yalm?

Tried to add this to custom_components\flux_led\light.py
Did not work. Should work right or does not override the default component?

It should not be necessary to do any more than that. However, I have not been using this custom component since the time I posted it. Had to do a fresh install of hassio a while ago and did not bother to install the custom component again, so might be that it does not work for later versions.

Solved it for version 0.99.2

Downloaded the default component from Home Assistant source code and edit it to add:
import time
#code
time.sleep(1)
self._bulb.update_state(retry=2)

in the turn.on and turn.off data

Here is the link with the edit files and working, you just need to add it to the \config\custom_components\flux_led folder

1 Like

More than one year later, this bug is still unresolved in official component. Your fix works perfectly, is there any chance to do a pull request?

Good evening, I’m interested in this solution. I wanted to know if it works with latest version of HA.
Thank you!

The newer RGBW controllers should work correctly in 2021.11