Will it WLED? Govee H7050 Allure Ground Lights — Complete Reverse Engineering & Working Config

After several days of investigation including automated camera-based testing, here is the complete technical picture for the Govee H7050 (first gen, 15 pucks, 12V).

What’s inside each puck: 2 × standard WS2812B chips in series — one RGB, one Warm White. It is NOT a 4/5-channel chip. This is why SK6812, TM1814, SM16825, and TM1815 all fail.

Working WLED config:

  • LED type: WS281x

  • Color order: RBG (order=1)

  • Length: 30 (not 15 — 2 chips per puck)

  • GPIO: 16 (QuinLED Dig-Quad with level shifting required)

  • Two segments, both 0–30, spacing 1:

    • Segment 0, offset 0 = RGB channel

    • Segment 1, offset 1 = Warm White channel

Critical gotchas:

  • Global brightness scale must be 100% or white channel won’t turn off fully

  • Level shifting required — bare ESP32 gave unreliable results

White channel behavior: The WW chip is active in a low non-zero range only — bri=0 is off, bri=1 is maximum brightness, brightness decreases as value increases, and bri=255 is off again. For practical use, map white intensity to the range 1–100 for best results.

Feature request: A native WS281x_RGBWW LED type with automatic W channel inversion would make this plug-and-play. The protocol is plain WS281x — the only special behavior needed is inverting the W byte automatically so the brightness slider works normally for end users.

there is a PR about this Added support for LSC Smart connect led strips by Yannicflight · Pull Request #5177 · wled/WLED · GitHub

however, it is does not invert white and it uses CCT. Adding this much code for every variant is not a good practice, there are other variations as well. handling each one with a special case will bloat the code quickly and make it huge and slow. Imagine adding 10 of these cases over time or even more…

WLED_16.0.0-alpha_ESP32_V4_CustomBus_experiment.bin (1.3 MB)

I cooked somethig up. Please try if this works.
Go to LED settings, select “Custom Digital” as a LED type.
It lets you enter whatever channel layout you wish, including inverting outputs or inverting color channels.
Note that this is highly experimental code, it may crash or not work at all. Also it can corrupt the config.

The channels you set are the channels that get sent out, i.e. if you set 6 chanels it sends 6 color values per pixel, you can send a color value (red, green, blue, white, warm white cold white, unused will send “black") on multiple “physical” channels if you want.

Please link to the PR, or provide an Ethernet binary. I would like to test but need Ethernet connectivity. Thanks.

all in good time. for a test you do not need an ethernet binary, just use wifi.

I flashed from 16.0.0-beta (with firmware validation disabled), the device reboots, waits for some time then reverts back to the previous firmware.

thats the boot loop recovery kicking in. you can check serial output on what happens, there is probably a hundred things that can go wrong.

Well, it seems to flash fine on another board. Let me see if removing those outputs and re-adding them after flashing helps.
No luck, I tried disabling the per-output limiter but can’t get anywhere. Would be nice to have but afraid I need to just get this big matrix working as a light for the immediate future. Will try to loop back when I have more time.

can you share the config or the way you achieve it to boot loop?

Certainly, the config is nothing fancy. I have a relay configured and audioreactive mic.

JSON config
{
  "rev": [1, 0],
  "vid": 2603020,
  "id": { "mdns": "", "name": "Dig-Octa-32-8L", "inv": "Light", "sui": false },
  "nw": {
    "espnow": false,
    "linked_remote": [""],
    "ins": [
      {
        "ssid": "iot",
        "pskl": 12,
        "bssid": "",
        "ip": [0, 0, 0, 0],
        "gw": [0, 0, 0, 0],
        "sn": [255, 255, 255, 0]
      }
    ],
    "dns": [8, 8, 8, 8]
  },
  "ap": {
    "ssid": "WLED-AP",
    "pskl": 8,
    "chan": 1,
    "hide": 0,
    "behav": 0,
    "ip": [4, 3, 2, 1]
  },
  "wifi": { "sleep": false, "phy": false, "txpwr": 78 },
  "eth": { "type": 8, "pin": [21, 19, 22, 25, 26, 27, 23, 18, 17] },
  "hw": {
    "led": {
      "total": 4096,
      "maxpwr": 0,
      "cct": false,
      "cr": false,
      "ic": false,
      "cb": 0,
      "fps": 60,
      "rgbwm": 255,
      "matrix": {
        "mpc": 16,
        "panels": [
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 0,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 16,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 16,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 0,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 32,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 48,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 48,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 32,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 80,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 64,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 64,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 80,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 112,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": true,
            "r": true,
            "v": true,
            "s": true,
            "x": 96,
            "y": 0,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 96,
            "y": 16,
            "h": 16,
            "w": 16
          },
          {
            "b": false,
            "r": false,
            "v": true,
            "s": true,
            "x": 112,
            "y": 16,
            "h": 16,
            "w": 16
          }
        ]
      },
      "ins": [
        {
          "start": 0,
          "len": 512,
          "pin": [0],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 512,
          "len": 512,
          "pin": [1],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 1024,
          "len": 512,
          "pin": [2],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 1536,
          "len": 512,
          "pin": [3],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 2048,
          "len": 512,
          "pin": [4],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 2560,
          "len": 512,
          "pin": [5],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 3072,
          "len": 512,
          "pin": [12],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        },
        {
          "start": 3584,
          "len": 512,
          "pin": [13],
          "order": 0,
          "rev": false,
          "skip": 0,
          "type": 22,
          "ref": false,
          "rgbwm": 0,
          "freq": 0,
          "maxpwr": 6000,
          "ledma": 55,
          "drv": 0,
          "text": ""
        }
      ]
    },
    "com": [],
    "btn": {
      "max": 32,
      "pull": true,
      "ins": [{ "type": 2, "pin": [34], "macros": [0, 0, 0] }],
      "tt": 32,
      "mqtt": false
    },
    "ir": { "pin": -1, "type": 0, "sel": true },
    "relay": { "pin": 33, "rev": false, "odrain": false },
    "baud": 1152,
    "if": { "i2c-pin": [-1, -1], "spi-pin": [-1, -1, -1] }
  },
  "light": {
    "scale-bri": 100,
    "pal-mode": 0,
    "aseg": false,
    "gc": { "bri": 1, "col": 2.8, "val": 2.8 },
    "tr": { "dur": 0, "rpc": 5, "hrp": true },
    "nl": { "mode": 1, "dur": 60, "tbri": 0, "macro": 0 }
  },
  "def": { "ps": 0, "on": false, "bri": 128 },
  "if": {
    "sync": {
      "port0": 21324,
      "port1": 65506,
      "espnow": false,
      "recv": {
        "bri": true,
        "col": true,
        "fx": true,
        "pal": true,
        "grp": 1,
        "seg": false,
        "sb": false
      },
      "send": {
        "en": false,
        "dir": false,
        "btn": false,
        "va": false,
        "hue": true,
        "grp": 1,
        "ret": 0
      }
    },
    "nodes": { "list": true, "bcast": true },
    "live": {
      "en": true,
      "mso": false,
      "rlm": true,
      "port": 5568,
      "mc": false,
      "dmx": {
        "uni": 1,
        "seqskip": false,
        "e131prio": 0,
        "addr": 1,
        "dss": 0,
        "mode": 4,
        "inputRxPin": 0,
        "inputTxPin": 0,
        "inputEnablePin": 0,
        "dmxInputPort": 2
      },
      "timeout": 25,
      "maxbri": false,
      "no-gc": true,
      "offset": 0
    },
    "va": { "alexa": false, "macros": [0, 0], "p": 0 },
    "mqtt": {
      "en": false,
      "broker": "",
      "port": 1883,
      "user": "",
      "pskl": 0,
      "cid": "WLED-aa38d0",
      "rtn": false,
      "topics": { "device": "wled/aa38d0", "group": "wled/all" }
    },
    "hue": {
      "en": false,
      "id": 1,
      "iv": 25,
      "recv": { "on": false, "bri": false, "col": false },
      "ip": [192, 168, 0, 0]
    },
    "ntp": {
      "en": false,
      "host": "0.wled.pool.ntp.org",
      "tz": 0,
      "offset": 0,
      "ampm": false,
      "ln": 0,
      "lt": 0
    }
  },
  "ol": {
    "clock": 0,
    "cntdwn": false,
    "min": 0,
    "max": 239,
    "o12pix": 0,
    "o5m": false,
    "osec": false,
    "osb": false
  },
  "timers": {
    "cntdwn": { "goal": [20, 1, 1, 0, 0, 0], "macro": 0 },
    "ins": []
  },
  "ota": {
    "lock": false,
    "lock-wifi": false,
    "pskl": 7,
    "aota": true,
    "same-subnet": true
  },
  "um": {
    "AudioReactive": {
      "enabled": true,
      "add-palettes": true,
      "analogmic": { "pin": -1 },
      "digitalmic": { "type": 1, "pin": [14, 15, 16, -1] },
      "config": { "squelch": 10, "gain": 60, "AGC": 0 },
      "frequency": { "scale": 3 },
      "dynamics": { "limiter": true, "rise": 80, "fall": 1400 },
      "sync": { "port": 11988, "mode": 0 }
    }
  }
}

Bootloop occurs when I try the normal OTA flash on this, it’s running v16.0.0-beta build 2604110 and is a QuinLED Dig-Octa.

found the reason for your bootloop: you used pin1, the bin uses debug so pin1 is not useable which causes a nasty pin conflict that was not handled well: here is what happened:

  • buses are assigned and created
  • when buses are instantiated, the first bus fails as it can not use pin 1 → init loop stops
  • other buses still exist but do not get instantiated → WLED runs the buses and tries to write to their buffers - which were not allocated → crash.

fixed that by not stopping if one bus fails but just stash that bus and still finish initializing the remaining ones.

Did you post the new binary somewhere? Also could I build without debug so I can use the 8 busses, trying to test perf so need to see if the output is smooth or stuttering.

here is an ethernet build that includes the fix, I dont have hardware to test this so zero warranty :wink:

WLED_16.0.0-alpha_ESP32_Ethernet_CustomBus_experiment.bin (1.2 MB)

Works nicely. I see a slight increase in RMT speeds from ~29fps to 35fps but the i2s speed is around 45fps (albeit only driving 7/8 outputs). So that’s 35fps with 3584 pixels on i2s and 45fps with 4096 pixels on RMT.

Hard to tell if the results would be better using GPIO 1 as well, unfortunately the have only 8 outputs via the level shifter here so can’t substitute another GPIO.

Unfortunately that i2s performance appears to come at the cost of disrupting network IO - DDP inputs suffer from noticeable skipped updates leading to inconsistent frame rates. RMT is much more consistent with DDP inputs.

I2S is less heavy on the CPU - as you can see from the higher FPS. I have no explanation on why it would skip frames on DDP and RMT would not, might have something to do with interrupt duration.

i finally got back to this, thank you for giving it shot. i can report: it works. absolutely stunning. these lights have been on my to-do list for years. i had them outside one season with the inverted white and strictly used presets. now i can control these from home assistant with much better control. this is incredible. thank you so much for this. would WLED ever consider making this functionality part of the release?

thanks for the confirmation. If I get it to work completely and no other library pops up then this will make it.

i cannot thank you enough. fwiw, this might be helpful for a lot of people and their govee lights. im going to try this on a set of H7021’s that also require the staggered segments, although these don’t need the inverted white’s. but with that “custom digital” i can now manually control them. this is incredible.

Further update with exact Custom Digital config for H7050:

H7050 Custom Digital config (15 pucks, 12V):

  • Length: 15

  • Channels: 6

  • Ch1: R, Ch2: G, Ch3: B

  • Ch4: W inverted, Ch5: W inverted, Ch6: W inverted

  • Timing: T0H=300 T0L=900 T1H=700 T1L=500 Reset=300

Note: Use W not WW for the white channels.

Also tested on Govee H7021 outdoor string lights — same Custom Digital approach works with slightly different channel mapping (GBR color order, W not inverted).

Feature suggestion: When using Custom Digital with dedicated W channels, the CCT/color temperature slider behaves unexpectedly — dragging it shifts colors in ways that don’t match the physical LED behavior. A way to disable or lock CCT when using Custom Digital would be helpful.