Flux Led/MagicLight don't work since few updated

How confident are you with a soldering iron?

I’m pretty good. I came across https://quinled.info/ and had considered doing this with some of the LED strips. Not sure at this point, but was thinking of moving to individual addressable LEDs lights and make one of these controllers.

i have tried your fix, any time i adjust the brightness i get "nonetype object is not subscriptable " as an error.

the brigtness changes, but it keeps popping up, theres also no option to change the RGB colors.

is there anything else you could suggest please?

Just flash your MagicHome controller with the Tasmota firmware, it will work much better than flux_led. You just need to open up the MagicHome controller and solder a couple of wires to the bottom of the board, there are already labelled test points that are very easy to solder to (you don’t have to solder wires to the legs of ICs etc)

You can use Ras Pi or Arduino to flash it if you don’t have a serial programmer. I ended up giving up on flux_led and just flashed all of my devices.

I was able to use @john32’s initial code fix with some more files/instructions to get it to actually load into my HomeAssistant as a custom component, I added a github here for others that may find it useful.

This fix works here as well [FIXED] Flux_led does not set brightness or color correctly when device is initially off

The issue is due to the slight delay that is necessary between turning the light on and reading the brightness as the guy explains; which resolves both issues in this thread and the thread in the link at the same time!

When I use in automations or in UI HA turn on led lights - I have delay, sometimes 5-10 sec. After push light in HA UI or run automation and light turn ON. If I do same in Magic Home app - LED turn ON very fast. Anybody have same problem? How fix it? Please help!

This should resolve your issue [FIXED] Flux_led does not set brightness or color correctly when device is initially off

Hello, I have the same problem. I have created a new custom component inside the custom_components folder and added the @CorneliousJD lux-led folder. When I turn on HA, I see in my log that if my custom component is being loaded, the problem is that I still cannot turn on the led strip from HA. Any other solution? My configuration is as follows:

light:

  • platform: flux_led
    devices:
    192.168.1.41:
    name: Led televisión
    protocol: ‘ledenet’

Just wanted to chime in on this - I was only focused on getting my RGB LEDs working - they aren’t “ledenet” protocol so you may be experiencing issues w/ the custom component I uploaded because of that, sorry :frowning:

I just made some modifications that should resolve all these issues. If you have a single color controller (white only), please set the mode to rgbw. Also, at first it will not work properly as it has to register the old brightness, but once you turn off/on a bulb once or set brightness, you are good to go:

"""Support for Flux lights."""
import logging
import random
###
# Added for MagicLight hack
import time
   

from flux_led import BulbScanner, WifiLedBulb
import voluptuous as vol

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

_LOGGER = logging.getLogger(__name__)

CONF_AUTOMATIC_ADD = "automatic_add"
CONF_CUSTOM_EFFECT = "custom_effect"
CONF_COLORS = "colors"
CONF_SPEED_PCT = "speed_pct"
CONF_TRANSITION = "transition"

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"

# Constant color temp values for 2 flux_led special modes
# Warm-white and Cool-white modes
COLOR_TEMP_WARM_VS_COLD_WHITE_CUT_OFF = 285

# 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_CUSTOM = "custom"

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,
}
EFFECT_CUSTOM_CODE = 0x60

TRANSITION_GRADUAL = "gradual"
TRANSITION_JUMP = "jump"
TRANSITION_STROBE = "strobe"

FLUX_EFFECT_LIST = sorted(list(EFFECT_MAP)) + [EFFECT_RANDOM]

CUSTOM_EFFECT_SCHEMA = vol.Schema(
    {
        vol.Required(CONF_COLORS): vol.All(
            cv.ensure_list,
            vol.Length(min=1, max=16),
            [
                vol.All(
                    vol.ExactSequence((cv.byte, cv.byte, cv.byte)), vol.Coerce(tuple)
                )
            ],
        ),
        vol.Optional(CONF_SPEED_PCT, default=50): vol.All(
            vol.Range(min=0, max=100), vol.Coerce(int)
        ),
        vol.Optional(CONF_TRANSITION, default=TRANSITION_GRADUAL): vol.All(
            cv.string, vol.In([TRANSITION_GRADUAL, TRANSITION_JUMP, TRANSITION_STROBE])
        ),
    }
)

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"])),
        vol.Optional(CONF_CUSTOM_EFFECT): CUSTOM_EFFECT_SCHEMA,
    }
)

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."""
    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]
        device[CONF_CUSTOM_EFFECT] = device_config.get(CONF_CUSTOM_EFFECT)
        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 = BulbScanner()
    scanner.scan(timeout=10)
    for device in scanner.getBulbInfo():
        ipaddr = device["ipaddr"]
        if ipaddr in light_ips:
            continue
        device["name"] = f"{device['id']} {ipaddr}"
        device[ATTR_MODE] = None
        device[CONF_PROTOCOL] = None
        device[CONF_CUSTOM_EFFECT] = None
        light = FluxLight(device)
        lights.append(light)

    add_entities(lights, True)


class FluxLight(LightEntity):
    """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._custom_effect = device[CONF_CUSTOM_EFFECT]
        self._bulb = None
        self._error_reported = False
        self._old_brightness = None
        self._is_on = None

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

        self._bulb = 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._is_on

    @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 | SUPPORT_COLOR_TEMP

        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."""
        if self._custom_effect:
            return FLUX_EFFECT_LIST + [EFFECT_CUSTOM]

        return FLUX_EFFECT_LIST

    @property
    def effect(self):
        """Return the current effect."""
        current_mode = self._bulb.raw_state[3]

        if current_mode == EFFECT_CUSTOM_CODE:
            return EFFECT_CUSTOM

        for effect, code in EFFECT_MAP.items():
            if current_mode == code:
                return effect

        return None

    def turn_on(self, **kwargs):

        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)
        color_temp = kwargs.get(ATTR_COLOR_TEMP)

        # handle special modes
        if color_temp is not None:
            if brightness is None:
                brightness = self.brightness
            if color_temp > COLOR_TEMP_WARM_VS_COLD_WHITE_CUT_OFF:
                self._bulb.setRgbw(w=brightness)
            else:
                self._bulb.setRgbw(w2=brightness)
            return

        # 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

        if effect == EFFECT_CUSTOM:
            if self._custom_effect:
                self._bulb.setCustomPattern(
                    self._custom_effect[CONF_COLORS],
                    self._custom_effect[CONF_SPEED_PCT],
                    self._custom_effect[CONF_TRANSITION],
                )
            return

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

        # Preserve current brightness on color/white level change
        if brightness is None:
            brightness = self._old_brightness
            
        if brightness is None or brightness == 0:
            brightness = 255
            
        self._old_brightness = brightness
        
        #_LOGGER.warning("BRIGHTNESS: %d", 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)

        self._is_on = True

    def turn_off(self, **kwargs):
        
        rgb = self._bulb.getRgb()
        
        # handle W only mode (use brightness instead of white value)
        if self._mode == MODE_WHITE:
            self._bulb.setRgbw(0, 0, 0, w=0)
        
        # handle RGBW mode
        elif self._mode == MODE_RGBW:
            self._bulb.setRgbw(*tuple(rgb), w=0, brightness=0)
            
        # handle RGB mode
        else:
            self._bulb.setRgb(*tuple(rgb), brightness=0)
        
        self._is_on = False

    def update(self):
        """Synchronize state with bulb."""
        if not self.available:
            try:
                self._connect()
                self._error_reported = False
            except OSError:
                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)

1 Like

Here, final version: fixed other bugs that appear with when Google Home and Alexa also handle the same controllers, especially when controller state changes from on and off and so on when used as Automation triggers in Hassio: https://gist.github.com/ybarigou/52d42cd2e6b44bb70cbdb317a059e623

… and again, if your controller handles only one color (‘W’), please set the mode to RGBW

Hello, I have faced with same error.
I took latest code from githab and plased it /config/custom_components/flux_led/light.py

light.yaml

  - platform: flux_led
    devices:
      192.168.0.214:
        name: rgb_stripe
        mode: 'rgb'

I am able to change color and set effect. Once I try change brightness I see that it shows previous state on UI but, in fact it changes. Other worst thing that if stripe powered off then it will not turn on. After, led controller stucks, then it needs to be reboot.

Hi Ybarigou. I put this file in …/config/custom_components/flux_led/light.py amd I supposed to do more here than just that? json or init? I’m new to HA so not very clear atm.

Hi Repomanz,

Copy the whole thing from https://github.com/home-assistant/core/tree/dev/homeassistant/components/flux_led to your …/config/custom_components/flux_led/ and override the light.py with my script

Then you need to add the config to your .yaml:

light:
  - platform: flux_led
    automatic_add: true

(or add devices specifically with their IP addresses: https://www.home-assistant.io/integrations/flux_led/)

Hi ybarigou - thanks for the fix; seems I’m back up in running. Do you think the main dev will merge this code into main branch at some point? like the additional UI updates for the lovelace controls.

Hi,
Maybe someone has problem with turning on and delay of updating state. I am not able turn on device and don’t see any log. Is there any way to debug what the problem?
ybarigou could you give me some advice about it?

Hey, yes can confirm, at least I am still having issues with my Flux LED lights. If i turn them on or off using a switch on the Lovelace UI, it seems to break them, so that the next time they are called to be turned on, they don’t light up, whatsoever. However, in my automation, I notice that I can switch on a light so long as I add brightness or color temp data along with the request:

{
    "color_temp": 250,
    "brightness": 125
}

So now, If I need to manually control the lights, I do so by google home/assistant. And home assistant only interacts with the lights via automation where I can send the color temp and brightness.

I updated the code with a dirty fix should work now without the need to select RGBW for White only bulbs/led controllers; therefore, the mode can just be ‘w’ for monochromatic lights.

Also, RGBW bulbs are now directly considered RGB to fix the problem. In conclusion, with using the code I provided here, just keep every bulb’s mode in the configuration.yaml as is, i.e.:

  • for RGBW bulbs/controllers:

mode: rgbw

  • for RGB bulbs/controllers:

mode: rgb

  • for monochromatic bulbs/controllers:

mode: w

1 Like