WLed: A binding for controlling LED strips and strings from an opensource esp8266 project

New build created for anyone that wants to test:

  • Bridge/thing structure now used
  • Global channels added
  • Lower system load as the bridge parses the data once for all segments.

Index of /openhab/wled/ (pcmus.com)

You will need to delete all things and also clear your cache as this is not backwards compatible.

1 Like

Generally works well.
Just tested:

  • Global thing works fine
  • Segment thing has some issues, Effects not showing a list of all available, only number of current effect, the same with Palettes.

…it would also be nice to have global settings for effects, palettes and colors

Effects and Palettes are now fixed in the JAR at the link in my last post, thanks for reporting.

colors should be easy, just create a group item and make all the masterControls a member of that group. openHAB will then send the same colour command to all members of the group. I’m not sure if the same thing will work for the effect and pallete channels.

How would you propose that would work?

Checked out your new JAR, now the list of effects and palettes displayed properly))

Groups in OpenHAB are certainly good, but for example, for 20 segments, you will have to create 20 things + global thing, and then for most settings, manually create group items. And it is just one Cristmas tree with lights.
It’s not a problem for me, but for beginners it looks not quite easy))

It would be much better to have all the settings for both the global things and the segment things. And then each person will be able to decide what they need. Separately manage segments → use segment things + global things. Need to manage the entire led strip, even if it is divided into segments, then use only the global thing. There are many user cases where you need to divide the LED strip into segments, but use the same settings for all segments.
But that’s just my opinion)))

However, even in the current implementation, everything is pretty cool)) Thanks for the great binding))

Can you explain why you have 20 segments on a single Christmas tree? Is this a mega tree made up of 20 strings going from 20 points around the bottom, routed straight up and all joining at the top? Understanding the use case helps as I just use a single segment on the tree. Why split it up into 20 and then want to control them all at the same time as a single light?

There has to be a balance between being flexible to do everything you want and also being simple enough that having 100+ channels that are easy for a new user to understand. For example, with 20 segments a new user may see 80 different color channels (masterControls,primary,sec,…) plus a global set of controls and totally not know where to start. This can be solved to some degree by marked them as advanced channels that are hidden by default.

  • Stay consistent with how other lighting bindings work.
  • Stay consistent with how other bindings group lights.
  • Teach the use of groups that can be used in all bindings and situations.

Playing last night with the GUI of the WLED firmware, it really can do some things which are difficult to reproduce in a consistent way and Semantic model form that openHAB’s direction is headed in. Being able to select any 4 out of 20 segments and change the fx on just them is an example of this. Single segment yes can be done, all segments yes can be done, but being able to pick and choose any combination it becomes difficult. At some point we have to stop the complexity and try to promote consistency. As you wrote, this is just one persons opinion and interested in hearing yours as to where it stops.

A global colour, fx and pallete channels I am not against as they do make sense. Consider what happens if they did exist, you send a command and the lights all change to what you want, but the controls in openhab for all the segments dont update until the next poll time arrives. This may not happen as the API allows a response to be sent to provide an instant update which the binding already does this when possible. If you use a group item, this solves the problem and the controls will all be at the correct state at the expense that multiple packets are sent instead of a single request to the WLED device. With groups it may be possible to crash (or the esp may ignore some commands) the esp device with a flood of commands spaced too closely together, would be interesting to do the test to see what happens if groups are used with a large number of segments.

Thanks, if you notice anything that needs to be changed please let me know. I need to do the documentation changes and look at the auto discovery changes mentioned and then it can be submitted for getting merged. Still tons of work to be done, but in the meantime it can be used and feedback gained as the actual functionality should be close if not already done.

EDIT:
@marsic
Doing some testing last night I noticed that you can create segments that overlap. What is wrong with creating an extra segment in the firmwares GUI that is the whole string, then you can use that ‘segment thing’ to control the whole lot? Does this work for you?

New version of the binding can be found in the marketplace and now has discovery of all segments and will auto name them with what is saved in the firmware. Updated docs are also linked in this post.

WLED Binding: New bridge / thing version with global controls - Add-on Marketplace / Bundles - openHAB Community

Because with segmentation, the effects look completely different

You almost guessed it))) I just arranged the garland vertically, and divided it into segments:

If I use one overlapping segment, then the effect will still go from the beginning of this segment to its end, but I need the effect to start at the bottom of the Christmas tree and go up to the top, for example rising up circle.

FX Intensity and Speed, as well as Primary, Secondary and Tertiary Color are also make some sense)))

good option if possible

In the WLED GUI, I can choose which segments to manage globally by simply checking the boxes
сегменты
Is it possible to do something similar for a global thing??
For example, some field in the settings of a thing where you will need to specify the numbers of segments that you want to manage globally?

I don’t know as the API documentation is not clear if this is possible and gives no examples. There is the ability to giveeach segment a selected switch, but how to send a API command to only the selected ones is not given.

It is possible your the first to ask to do it. Check on the discord for wled for an example json and if anyone does it.

But I still feel that we need to ask the question if we should do this and increase the complexity. Another way to do this is to use a WebView to display the wled UI directly. Then you have all features.

WebView not good in rules(((

complexity of binding or its use?
if its use, then here is another example:
if I want to make a rule that will control the LED strip divided into 20 segments, I need to send 20 identical commands to each segment, otherwise I would only need to send one to the global item

OK, maybe even try to ask the developer for a similar json example.

Then you can use group items. :grinning:then you can send one command in either rules or move a single control and they will all Change. It can be done already.

Hey @matt1 ,
I also tried your new binding. The discovery found 2 things for my single WLED lamp. While adding one of them I got a server error. Inbox
image

error:

2022-02-06 14:06:20.248 [ERROR] [internal.JSONResponseExceptionMapper] - Unexpected exception occurred while processing REST request.
java.lang.IllegalArgumentException: UID must have at least 3 segments.
        at org.openhab.core.common.AbstractUID.<init>(AbstractUID.java:71) ~[?:?]
        at org.openhab.core.common.AbstractUID.<init>(AbstractUID.java:49) ~[?:?]
        at org.openhab.core.thing.UID.<init>(UID.java:48) ~[?:?]
        at org.openhab.core.thing.ThingUID.<init>(ThingUID.java:130) ~[?:?]
        at org.openhab.core.io.rest.core.internal.discovery.InboxResource.approve(InboxResource.java:115) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
        at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.4.5]
        at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.4.5]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.4.5]
        at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.4.5]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[bundleFile:3.4.5]
        at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[bundleFile:3.4.5]
        at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:217) ~[bundleFile:3.4.5]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[bundleFile:3.1.0]
        at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.43.v20210629]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:71) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:602) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1434) ~[bundleFile:9.4.43.v20210629]
        at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1349) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.43.v20210629]
        at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:82) ~[bundleFile:?]
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:388) ~[bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:633) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:380) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:386) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.43.v20210629]
        at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.43.v20210629]
        at java.lang.Thread.run(Thread.java:829) [?:?]

The other thing was added fine and has channels (Global Brightness, Playlists & Presets) :
image

Not sure if this is supposed to be correct. My Wled is a v0.13.0-b5.
Thanks

Edit: Same error when trying to remove or ignore the thing. Remains in my inbox.

I did have this happen once during testing and could not get it to happen again. The thing disappeared from the inbox itself after a certain amount of time passed. Since the thing is linked to the mDNS result, it may have been leaving it turned off and not on the network whilst I did a restart that caused it to go away. I’ll take a look at this again…

After adding the bridge and it is online, do a SCAN from the inbox and it will find any segments that you have setup which includes the segments names if you have firmware 0.13.x

Also if you click on SHOW ADVANCED you will see more channels.

Thanks for your reply.
Tried your suggestion with no luck. removed the WLED device from Wifi, restarted as well as rebooted OH several times. The broken thing was always in the inbox. In the end I stopped Openhab and edited org.openhab.core.config.discovery.DiscoveryResult.json and removed the lines about the thing in the inbox.
After starting OH again, the Thing was gone and once WLED was powered again a few seconds later added automatically by discovery again.
image

Once the bridge was added a new scan also found the segment (yes, its only one)
image

I made a change to the binding a few days back to check the mac adress is not blank before adding the result to the inbox in case that was occurring. So recommend you uninstall and install again from the marketplace to get this change installed. Thanks for reporting this.

The pictures show it is working as intended on your system, all looks as it should.

Hey guys,

I just created two new selections based on Its based on WLED version 0.13.0-b7 for my sitemap to select all avilable 117 effects:

Selection item=FX_Kuechenschrank mappings=[0="Solid", 1="Blink", 2="Breathe", 3="Wipe", 4="Random Wipe", 5="Random Colors", 6="Sweep", 7="Dynamic", 8="Color Loop", 9="Rainbow",
                                                                 10="Scan", 11="Scan Dual", 12="Fade", 13="Theater", 14="Theater Rainbow", 15="Running", 16="Saw", 17="Twinkle", 18="Dissolve", 19="Dissolve Random",
                                                                 20="Sparkle", 21="Sparkle Dark", 22="Sparkle+", 23="Strobe", 24="Strobe Rainbow", 25="Strobe Mega", 26="Blink Rainbow", 27="Android", 28="Chase", 29="Chase Random",
                                                                 30="Chase Rainbow", 31="Chase Flash", 32="Chase Flash Random", 33="Rainbow Runner", 34="Colorful", 35="Traffic Light", 36="Sweep Random", 37="Chase 2", 38="Aurora", 39="Stream",
                                                                 40="Scanner", 41="Comet", 42="Fireworks", 43="Fireworks Random", 44="Merry Christmas", 45="Fire Flicker", 46="Gradient", 47="Loading", 48="Dual Color IN/OUT", 49="Dual Color IN/IN", 
                                                                 50="Dual Color OUT/OUT", 51="Dual Color OUT/IN", 52="Circus", 53="Halloween", 54="Tricolor Chase", 55="Tricolor Wipe", 56="Tricolor Fade", 57="Lightning", 58="I.C.U", 59="Multi Comet", 
                                                                 60="Dual Scanner", 61="Random Chase", 62="Oscillate", 63="Pride", 64="Juggle", 65="Pallete", 66="Fire", 67="Colorwaves", 68="BPM", 69="Noise Fill", 
                                                                 70="Noise 1", 71="Noise 2", 72="Noise 3", 73="Noise 4", 74="Color Twinkle", 75="Lake", 76="Metor", 77="Metor Smooth", 78="Railway", 79="Ripple",
                                                                 80="Twinklefox", 81="Twinklecat", 82="Halloween Eyes", 83="Solid Pattern", 84="Solid Pattern Tri", 85="Spots", 86="Spots Fade", 87="Glitter", 88="Candle", 89="Fireworks Starburst",
                                                                 90="Firework 1D", 91="Bouncing Balls", 92="Sinelon", 93="Sinelon Dual", 94="Sinelon Rainbow", 95="Popcorn", 96="Drip", 97="Plasma", 98="Percent", 99="Ripple Rainbow",
                                                                 100="Heartbeat", 101="Pacifica", 102="Candle Multi", 103="Solid Glitter", 104="Sunrise", 105="Phased", 106="Twinkleup", 107="Noise Pal", 108="Sine", 109="Phased Noise",
                                                                 110="Flow", 111="Chunchun", 112="Dancing Shadows", 113="Washing Machine", 114="Candy Cane", 115="Blends", 116="TV Simulator", 117="Dynamic Smooth"]

and all 70 palettes:

Selection item=P_Kuechenschrank  mappings=[0="Default", 1="Random Cycle", 2="Color 1", 3="Colors 1&2", 4="Color Gradient", 5="Colors only", 6="Party", 7="Cloud", 8="Lava", 9="Ocean",
                                                       10="Forest", 11="Rainbow", 12="Rainbow Bands", 13="Sunset", 14="Rivendell", 15="Breeze", 16="Red&Blue", 17="Yellowout", 18="Analogous", 19="Splash",
                                                       20="Pastel", 21="Sunset 2", 22="Beech", 23="Vintage", 24="Departure", 25="Lanscape", 26="Beach", 27="Sherbet", 28="Hult", 29="Hult 64",
                                                       30="Drywet", 31="Jul", 32="Grintage", 33="Rewhi", 34="Tertiary", 35="Fire", 36="Icefire", 37="Cyane", 38="Light Pink", 39="Autumn",
                                                       40="Magenta", 41="Magred", 42="Yelmag", 43="Yelblu", 44="Orange&Teal", 45="Tiamat", 46="April Night", 47="Orangery", 48="C9", 49="Sakura",
                                                       50="Aurora", 51="Atlantica", 52="C9 2", 53="C9 New", 54="Temperature", 55="Aurora 2", 56="Retro Clown", 57="Candy", 58="Toxy Reaf", 59="Fairy Reaf",
                                                       60="Semi Blue", 61="Pink Candy", 62="Red Reaf", 63="Aqua Flash", 64="Yelblu Hot", 65="Lite Light", 66="Red Flash", 67="Blink Red", 68="Red Shift", 69="Red Tide",
                                                       70="Candy 2" ]

May be usefull for others!? I would like to add it to the documentation page here. But don’t know how…

I have exactly the same issue. Any solution on that?

The binding does it automatically, you do not need to do that, of course there is no harm in doing it only that you will waste time instead of using a binding to do boring repetive work that needs redoing and checking every firmware version.

Hi @matt1

Yes I just see that it works for a real item mapped to a fx channel. That is cool. I did not notice that.
But I am using 6 seperate segments in my kitchen cupboard and this is a group of the 6 channels.
Any trick to inherit this automatic feature to the group?
Or another trick to set the effect for all segements at the same time, like in the web interface?

Thanks for the binding by the way!

No idea as I have never tried to do it with a group before, it may be worth asking this in a new thread in a generic way so more people look and may reply. If the answer is NO, groups wont ever inherit the "command options" that child things have. Then we should look at adding the extra channels to the BRIDGE which @marsic was asking for this just a few posts above in this thread.

I believe you can create over lapping segments, so create an extra segment that starts at 0 LED and all the way to MAX led, then you can have a set of controls that do all segments/leds. However I have not tested this so please report back if it works or is not possible. I only pull my lights out at Christmas time so am not the best person to ask about it, but as per the posts above, I do prefer the group method as it will work for all bindings so you learn the technique once and can use it over and over again. This is why I feel asking in a new thread should be the first step to see if it is possible and if not raise it as a request to be added into the core.

Hey @olialb,
as written in the post you have to:

  • stop openhab
  • edit org.openhab.core.config.discovery.DiscoveryResult.json manually and remove the entry related to the broken thing
  • start openhab again

After that, I used the latest binding and it never happend.
Best

1 Like