WLED control without the binding

Foreword

I was interested in controlling WLED without using the binding. In the end I learned a bit more about:

  • Javascript transforms
  • XML (XPATH) transforms
  • Chaining multiple transforms
  • Jython personal functions

If you want easy setup, don’t copy me - use the binding from here WLed: A binding for controlling LED strips and strings from an opensource esp8266 project and forget you ever saw this post.

This post (#1) shows my final setup. The next post (#2) shows my first attempt in all its glory, for posterity.

Introduction

I have a NodeMCU clone flashed with WLED connected to a WS2812B LED strip. A WS2812B LED strip enables each LED to be individually controlled.

Setup

Device

Once connected to the local wifi, setup MQTT on the device:

  • Enable MQTT
  • Point to the local Mosquitto broker.
  • Name the device (Client ID)
  • Set the Device Topic

image

OpenHAB

Things

bridge.things

I have a separate file which just contains the bridge Thing to my Mosquitto MQTT broker:

Bridge mqtt:broker:MosquittoMqttBroker "Mosquitto MQTT Broker" [
	host="192.168.1.92",
	secure=false,
	port=1883,
	clientID="OpenHAB2"
]

wled.things

Differences from first attempt
  • Culled 4 javascript transforms
  • switch stateTopic changed to the brightness topic, as that’s all we were extracting with XPATH anyway. Now we only need the JS transform.
  • brightness channel has lost both of its javascript transforms, in favour of the min, max and step options.
  • speed and intensity channels have lost both of their javascript transforms, in favour of the min, max and step options.
    • OUT: also used formatBeforePublish to add the API prefix of “SX=” and “IX=” in front of the speed or intensity number
  • effect and palette channels have been added, using formatBeforePublish to publish directly to the WLED api topic, and an XPATH transform to receive messages on the v topic.
	Thing mqtt:topic:swRGB2 "RGB2 lights" (mqtt:broker:MosquittoMqttBroker) {
		Channels:
			Type switch : switch "Power Switch" [ 
				commandTopic="wled/RGB2",
				on="ON",
				off="OFF",
				stateTopic="wled/RGB2/g",
				transformationPattern="JS:dimmer2switch.js"
			]
            Type colorRGB : colour "Colour" [ 
				commandTopic="wled/RGB2/col",
				transformationPatternOut="JS:rgb2hex.js",
                stateTopic="wled/RGB2/c",
                transformationPattern="JS:hex2rgb.js"
			]

            Type dimmer : brightness "Brightness" [ 
				commandTopic="wled/RGB2",                
                stateTopic="wled/RGB2/g", 
				min=0, 
				max=255, 
				step=1
			]

			Type dimmer : speed "Speed" [
				commandTopic="wled/RGB2/api",
				formatBeforePublish="SX=%s",
				stateTopic="wled/RGB2/v",
				transformationPattern="XPATH:/vs/sx/text()", 
				min=0, 
				max=255, 
				step=1
			]

			Type dimmer : intensity "Intensity" [
				commandTopic="wled/RGB2/api",
				formatBeforePublish="IX=%s",
				stateTopic="wled/RGB2/v",
				transformationPattern="XPATH:/vs/ix/text()", 
				min=0, 
				max=255, 
				step=1
			]

			Type number : effect "Effect" [
				commandTopic="wled/RGB2/api",
				formatBeforePublish="FX=%s",
				stateTopic="wled/RGB2/v",
				transformationPattern="XPATH:/vs/fx/text()"
			]

			Type number : palette "Palette" [
				commandTopic="wled/RGB2/api",
				formatBeforePublish="FP=%s",
				stateTopic="wled/RGB2/v",
				transformationPattern="XPATH:/vs/fp/text()"
			]

			Type string : api "api" [
				commandTopic="wled/RGB2/api"
			]
	}

Transforms

Quite frankly, heavily indebted to the generous souls on StackExchange for quite a few of these…!

dimmer2switch.js

(function(x) {
    if(x == 0){
        return "OFF";
    }
    else{
        return "ON";
    }
})(input)

rgb2hex.js

(function(x) {
    var splitstring = x.split(',');
    var r = splitstring[0];
    var g = splitstring[1];
    var b = splitstring[2];
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
})(input)

function componentToHex(rgb) { 
    var hex = Number(rgb).toString(16);
    if (hex.length < 2) {
         hex = "0" + hex;
    }
    return hex;
}

hex2rgb.js

(function(colour) {
    var r,g,b;
    if ( colour.charAt(0) == '#' ) {
        colour = colour.substr(1);
    }
    if ( colour.length == 3 ) {
        colour = colour.substr(0,1) + colour.substr(0,1) + colour.substr(1,2) + colour.substr(1,2) + colour.substr(2,3) + colour.substr(2,3);
    }
    r = colour.charAt(0) + '' + colour.charAt(1);
    g = colour.charAt(2) + '' + colour.charAt(3);
    b = colour.charAt(4) + '' + colour.charAt(5);
    r = parseInt( r,16 );
    g = parseInt( g,16 );
    b = parseInt( b ,16);
  
    return r + ","  +g + ","  +b ;
})(input)

Items

Differences from first attempt

Here I added autoUpdate="false" to the three dimmer items, to prevent the slider from jumping around. Also added the effect and palette things

Switch sRGB2 "RGB2 lights" {channel="mqtt:topic:swRGB2:switch"}
Dimmer dRGB2Brightness "RGB2 Brightness" {channel="mqtt:topic:swRGB2:brightness", autoupdate="false"}
Color cRGB2Colour "RGB2 RGB lights colour" {channel="mqtt:topic:swRGB2:colour"}
Dimmer dRGB2Speed "RGB2 Speed" {channel="mqtt:topic:swRGB2:speed", autoupdate="false"}
Dimmer dRGB2Intensity "RGB2 Intensity" {channel="mqtt:topic:swRGB2:intensity", autoupdate="false"}
Number nRGB2Effect "RGB2 Effect" {channel="mqtt:topic:swRGB2:effect"}
Number nRGB2Palette "RGB2 Palette" {channel="mqtt:topic:swRGB2:palette"}
String strRGB2API "RGB2 API" {channel="mqtt:topic:swRGB2:api"}

Sitemap

Differences from first attempt

Here I added formatting to the slider labels so that it didn’t display a value with 200 significant figures. Also added effect and palette selection widgets.

Switch item=sRGB2 label="RGB2" icon="light" 
Slider item=dRGB2Brightness label="RGB2 brightness [%d %%]" icon="slider"
Colorpicker item=cRGB2Colour label="RGB2 colour"
Slider item=dRGB2Speed label="RGB2 speed [%d %%]"
Slider item=dRGB2Intensity label="RGB2 intensity [%d %%]"
Selection item=nRGB2Effect label="RGB2 effect [%s]" mappings=[27='Android', 1='Blink', 26='Blink Rainbow', 91='Bouncing Balls', 68='BPM', 2='Breathe', 88='Candle', 102='Candle Multi', 28='Chase', 31='Chase Flash', 32='Chase Flash Rnd', 30='Chase Rainbow', 29='Chase Random', 111='Chunchun', 52='Circus', 34='Colorful', 8='Colorloop', 74='Colortwinkle', 67='Colorwaves', 112='Dancing Shadows', 21='Dark Sparkle', 18='Dissolve', 19='Dissolve Rnd', 96='Drip', 11='Dual Scan', 60='Dual Scanner', 7='Dynamic', 12='Fade', 69='Fill Noise', 66='Fire 2012', 45='Fire Flicker', 42='Fireworks', 90='Fireworks 1D', 89='Fireworks Starburst', 110='Flow', 87='Glitter', 46='Gradient', 53='Halloween', 82='Halloween Eyes', 100='Heartbeat', 58='ICU', 64='Juggle', 75='Lake', 41='Lighthouse', 57='Lightning', 47='Loading', 25='Mega Strobe', 44='Merry Christmas', 76='Meteor', 59='Multi Comet', 70='Noise 1', 71='Noise 2', 72='Noise 3', 73='Noise 4', 107='Noise Pal', 62='Oscillate', 101='Pacifica', 65='Palette', 98='Percent', 105='Phased', 109='Phased Noise', 97='Plasma', 48='Police', 49='Police All', 95='Popcorn', 63='Pride 2015', 78='Railway', 43='Rain', 9='Rainbow', 33='Rainbow Runner', 5='Random Colors', 38='Red & Blue', 79='Ripple', 99='Ripple Rainbow', 15='Running', 37='Running 2', 16='Saw', 10='Scan', 40='Scanner', 92='Sinelon', 93='Sinelon Dual', 94='Sinelon Rainbow', 108='Sinewave', 77='Smooth Meteor', 0='Solid', 103='Solid Glitter', 83='Solid Pattern', 84='Solid Pattern Tri', 20='Sparkle', 22='Sparkle+', 85='Spots', 86='Spots Fade', 39='Stream', 61='Stream 2', 23='Strobe', 24='Strobe Rainbow', 104='Sunrise', 6='Sweep', 36='Sweep Random', 13='Theater', 14='Theater Rainbow', 35='Traffic Light', 54='Tri Chase', 56='Tri Fade', 55='Tri Wipe', 17='Twinkle', 106='Twinkle Up', 81='Twinklecat', 80='Twinklefox', 51='Two Areas', 50='Two Dots', 113='Washing machine', 3='Wipe', 4='Wipe Random']
Selection item=nRGB2Palette label="RGB2 palette [%s]" mappings=[18='Analoguous', 46='April Night', 50='Aurora', 39='Autumn', 3='Based on primary', 5='Based on set', 26='Beach', 22='Beech', 15='Breeze', 48='C9', 7='Cloud', 37='Cyane', 0='Default', 24='Departure', 30='Drywet', 35='Fire', 10='Forest', 32='Grintage', 28='Hult', 29='Hult 64', 36='Icefire', 31='Jul', 25='Landscape', 8='Lava', 38='Light Pink', 40='Magenta', 41='Magred', 9='Ocean', 44='Orange & Teal', 47='Orangery', 6='Party', 20='Pastel', 2='Primary color', 11='Rainbow', 12='Rainbow bands', 1='Random Cycle', 16='Red & Blue', 33='Rewhi', 14='Rivendell', 49='Sakura', 4='Set colors', 27='Sherbet', 19='Splash', 13='Sunset', 21='Sunset 2', 34='Tertiary', 45='Tiamat', 23='Vintage', 43='Yelblu', 17='Yellowout', 42='Yelmag']		

Rules

I’m using jython to create rules.

In $OPENHAB_CONF/automation/lib/python/personal I have a file called personal_functions.py which contains, amongst other things:

def set_wled(switch=None, colour=None, brightness=None, effect=None, speed=None, intensity=None, nightlight=None):
    
    a = "&A=" + str(get_8bit_number(brightness)) if brightness != None else ""
    t = "&T=" + str(switch) if switch != None else ""
    c = "&R=" + str(colour[0]) + "&G=" + str(colour[1]) + "&B=" + str(colour[2]) if colour != None else "" 
    fx = "&FX=" +str(effect) if effect != None else ""
    sx = "&SX=" + str(get_8bit_number(speed)) if speed != None else ""
    ix = "&IX=" + str(get_8bit_number(intensity)) if intensity != None else ""
    nl = "&NL=" + str(nightlight) if nightlight != None else ""

    returnString = a + t + c + fx + sx + ix + nl
    
    return returnString[1:]
    
def get_8bit_number(number):
    return int(float(number)/100*255)

This function will take in

  • a switch state (1 or 0 for on and off)
  • a colour in RGB formatted as (R,G,B)
  • a brightness (0-100)
  • an effect index
  • a speed (0-100)
  • an intensity (0-100)
  • a nighlight countdown time (in minutes)

and will return a string formatted for sending to WLED via the api channel. All arguments are optional. This function is used in a number of jython rules, remembering to import the personal_functions.py into each rule file. If the nightlight parameter is provided, this will set the nightlight time and activate the nightlight function.

Sample rules


import personal.personal_functions
reload(personal.personal_functions)
from personal.personal_functions import set_wled

----

#Turns the LED strip on, sets the colour to pink, sets brightness to 100%, sets the effect to Dual Scan, sets speed to 95% and intensity to 50%
events.sendCommand("strRGB2API",set_wled(switch=1,colour=(255,192,203),brightness=100,effect=11,speed=95,intensity=50))

EDIT: 08/11/2020 - Swap first two posts around, so that the first post has the final, working solution. Updated function to include nightlight feature.
EDIT: 01/11/2020 - Update and alphabetise effects and palettes.

4 Likes

Foreword

If you want easy setup, don’t copy me - use the binding from here WLed: A binding for controlling LED strips and strings from an opensource esp8266 project and forget you ever saw this post.

This post (#2) shows my first attempt in all its glory, for posterity. The first post (#1) simplifies the things file somewhat, and adds features thanks to @sujitrp.

Introduction

I have a NodeMCU clone flashed with WLED connected to a WS2812B LED strip. A WS2812B LED strip enables each LED to be individually controlled.

Setup

Device

Once connected to the local wifi, setup MQTT on the device:

  • Enable MQTT
  • Point to the local Mosquitto broker.
  • Name the device (Client ID)
  • Set the Device Topic

image

OpenHAB

Things

Notes
  • There is a separate things file which defines the bridge to the Mosquitto broker.
  • WLED MQTT information is on the WLED wiki. In short, you can command three topics:
    • A brightness or power on/off/toggle to the Device Topic (wled/rgb2)
    • A colour in hex to wled/rgb2/col
    • Almost everything using the HTTP API syntax to wled/rgb2/api
  • Return topics are almost identical:
    • Brightness from wled/rgb2/g
    • Colour from wled/rgb2/c
    • Almost everything in xml format from wled/rgb2/v. A typical xml string looks as follows, where all parameters are described at HTTP API syntax:
<?xml version="1.0" ?><vs><ac>28</ac><cl>255</cl><cl>0</cl><cl>212</cl><cs>0</cs><cs>0</cs><cs>0</cs><ns>0</ns><nr>1</nr><nl>1</nl><nf>1</nf><nd>60</nd><nt>0</nt><fx>9</fx><sx>127</sx><ix>63</ix><fp>0</fp><wv>0</wv><ws>0</ws><ps>0</ps><cy>0</cy><ds>WLED</ds><ss>0</ss></vs>
  • The switch channel
    • Sends an ON or OFF command on wled/rgb2
    • Receives the full XML string on wled/rgb2/v and:
      • Extracts the resultant brightness (<ac>) via XPATH (there is no on/off parameter in the xml), then
      • Transforms the brightness value into a switch ‘boolean’ through a javascript transform. If brightness is zero, switch is off; if brightness is not zero, switch is on.
        • You could probably do this with a single transform by capturing wled/rgb2/g instead (see the brightness channel below)
  • The colour channel
    • Sends a hex colour on wled/rgb2/col by
      • Transforming the RGB colour to hex with an outbound javascript transform.
    • Receives the resultant hex colour on wled/rgb2/c and
      • Transforms the hex to RGB with a javascript transform.
  • The brightness channel
    • Sends a brightness value (0-255) on wled/rgb2 by
      • Transforming the dimmer percent (0-100%) via an outbound javascript transform.
    • Receives the resultant brightness on wled/rgb2/g and
      • Transforms the brightness (0-255) into a dimmer percentage (0-100%) with a javascript transform.
  • The speed channel
    • Sends speed value (0-255) on wled/rgb2/api by
      • Transforming the dimmer percent (0-100%) and adding HTTP API specific parameter identifications via an outbound javascript transform.
    • Receives the resultant speed on wled/rgb2/v and
      • Extracts the resultant speed (<sx>) via XPATH, then
      • Transforms the speed value (0-255) into a dimmer value through a javascript transform.
  • The intensity channel
    • Sends intensity value (0-255) on wled/rgb2/api by
      • Transforming the dimmer percent (0-100%) and adding HTTP API specific parameter identifications via an outbound javascript transform.
    • Receives the resultant intensity on wled/rgb2/v and
      • Extracts the resultant intensity (<ix>) via XPATH, then
      • Transforms the intensity value (0-255) into a dimmer value through a javascript transform.
  • The api channel is used to send commands directly from rules, rather than sitemap widgets.
Thing mqtt:topic:swRGB2 "RGB2 lights" (mqtt:broker:MosquittoMqttBroker) {
		Channels:
			Type switch : switch "Power Switch" [ 
				commandTopic="wled/rgb2",
				on="ON",
				off="OFF",
				stateTopic="wled/rgb2/v",
				transformationPattern="XPATH:/vs/ac/text()∩JS:dimmer2switch.js"
			]
            Type colorRGB : colour "Colour" [ 
				commandTopic="wled/rgb2/col",
				transformationPatternOut="JS:rgb2hex.js",
                stateTopic="wled/rgb2/c",
                transformationPattern="JS:hex2rgb.js"
			]

            Type dimmer : brightness "Brightness" [ 
				commandTopic="wled/rgb2",
                transformationPatternOut="JS:openhab2wled.js",                
                stateTopic="wled/rgb2/g",
                transformationPattern="JS:wled2openhab.js"
			]

			Type dimmer : speed "Speed" [
				commandTopic="wled/rgb2/api",
				transformationPatternOut="JS:openhab2wled-speed.js",
				stateTopic="wled/rgb2/v",
				transformationPattern="XPATH:/vs/sx/text()∩JS:wled2openhab.js"
			]

			Type dimmer : intensity "Intensity" [
				commandTopic="wled/rgb2/api",
				transformationPatternOut="JS:openhab2wled-intensity.js",
				stateTopic="wled/rgb2/v",
				transformationPattern="XPATH:/vs/ix/text()∩JS:wled2openhab.js"
			]

			Type string : api "api" [
				commandTopic="wled/rgb2/api"
			]
	}

Transforms

Quite frankly, heavily indebted to the generous souls on StackExchange for quite a few of these…!

dimmer2switch.js
(function(x) {
    if(x == 0){
        return "OFF";
    }
    else{
        return "ON";
    }
})(input)
rgb2hex.js
(function(x) {
    var splitstring = x.split(',');
    var r = splitstring[0];
    var g = splitstring[1];
    var b = splitstring[2];
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
})(input)

function componentToHex(rgb) { 
    var hex = Number(rgb).toString(16);
    if (hex.length < 2) {
         hex = "0" + hex;
    }
    return hex;
}
hex2rgb.js
(function(colour) {
    var r,g,b;
    if ( colour.charAt(0) == '#' ) {
        colour = colour.substr(1);
    }
    if ( colour.length == 3 ) {
        colour = colour.substr(0,1) + colour.substr(0,1) + colour.substr(1,2) + colour.substr(1,2) + colour.substr(2,3) + colour.substr(2,3);
    }
    r = colour.charAt(0) + '' + colour.charAt(1);
    g = colour.charAt(2) + '' + colour.charAt(3);
    b = colour.charAt(4) + '' + colour.charAt(5);
    r = parseInt( r,16 );
    g = parseInt( g,16 );
    b = parseInt( b ,16);
  
    return r + ","  +g + ","  +b ;
})(input)
openhab2wled.js
(function(x) {
    return Math.round(((x / 100) * 255));
})(input)
wled2openhab.js
(function(x) {
    return Math.round(((x / 255) * 100));
})(input)
openhab2wled-speed.js
(function(x) {
    return "SX=" +Math.round(((x / 100) * 255));
})(input)
openhab2wled-intensity.js
(function(x) {
    return "IX=" +Math.round(((x / 100) * 255));
})(input)

Items

Switch sRGB2 "RGB2 lights switch" {channel="mqtt:topic:swRGB2:switch"}
Dimmer dRGB2Brightness "RGB2 Brightness" {channel="mqtt:topic:swRGB2:brightness"}
Color cRGB2Colour "RGB2 colour" {channel="mqtt:topic:swRGB2:colour"}
Dimmer dRGB2Speed "RGB2 speed" {channel="mqtt:topic:swRGB2:speed"}
Dimmer dRGB2Intensity "RGB2 intensity" {channel="mqtt:topic:swRGB2:intensity"}
String strRGB2API "RGB2 API" {channel="mqtt:topic:swRGB2:api"}

Sitemap

Switch item=sRGB2 label="RGB2" icon="light" 
Slider item=dRGB2Brightness label="RGB2 brightness [%d %%]" icon="slider" sendFrequency=500
Colorpicker item=cRGB2Colour label="RGB2 colour"
Slider item=dRGB2Speed label="RGB2 speed"
Slider item=dRGB2Intensity label="RGB2 intensity"

Rules

I’m using jython to create rules.

In $OPENHAB_CONF/automation/lib/python/personal I have a file called personal_functions.py which contains, amongst other things:

personal_functions.py
def set_wled(switch, colour="op", brightness="op", effect="op", speed="op", intensity="op", nightlight="op"):
    
    a = "&A=" + str(get_8bit_number(brightness)) if brightness != "op" else ""
    t = "T=1" if switch else "T=0"
    c = "&R=" + str(colour[0]) + "&G=" + str(colour[1]) + "&B=" + str(colour[2]) if colour != "op" else "" 
    fx = "&FX=" +str(effect) if effect != "op" else ""
    sx = "&SX=" + str(get_8bit_number(speed)) if speed != "op" else ""
    ix = "&IX=" + str(get_8bit_number(intensity)) if intensity != "op" else ""
    nl = "&NL=" + str(nightlight) if nightlight != "op" else ""
    
    return a + t + c + fx + sx + ix + nl  
  
def get_8bit_number(number):
    return int(float(number)/100*255)

This function will take in

  • a switch state (1 or 0 for on and off)
  • a colour in RGB formatted as (R,G,B)
  • a brightness (0-100)
  • an effect index
  • a speed (0-100)
  • an intensity (0-100)

and will return a string formatted for sending to WLED via the api channel. Only the switch argument is mandatory - all others are optional. This function is used in a number of jython rules, remembering to import the personal_functions.py into each rule file.

Sample rules
import personal.personal_functions
reload(personal.personal_functions)
from personal.personal_functions import set_wled

----

#Turns the LED strip on, sets the colour to pink, sets brightness to 100%, sets the effect to Dual Scan, sets speed to 95% and intensity to 50%
events.sendCommand("strRGB2API",set_wled(switch=1,colour=(255,192,203),brightness=100,effect=11,speed=95,intensity=50))

To Do

  • Try and reduce the number of different javascript transforms required! (Not sure how!) See first post for how!
2 Likes

modified to add more channel

Frame {
        Switch item=bedrgb icon="light" 
        Slider item=bedrgbBrightness  icon="slider" sendFrequency=500
        Colorpicker item=bedrgbColour 
        Slider item=bedrgbSpeed  icon="slider" 
        Slider item=bedrgbIntensity  icon="slider" 
        Selection item=bedrgbcolor2 mappings=[ 60='WHITE',61='SILVER',62='GRAY',63='BLACK',64='RED',65='MAROON',66='YELLOW',67='OLIVE',68='LIME',69='GREEN',70='AQUA',71='TEAL',72='BLUE',73='NAVY',74='FUCHSIA',75='PURPLE' ]
        Selection item=bedrgbeffects mappings=[10100='Solid',10101='Blink',10102='Breathe',10103='Wipe',10104='Wipe_Random',10105='Random_Colors',10106='Sweep',10107='Dynamic',10108='Colorloop',10109='Rainbow',10110='Scan',10111='Dual_Scan',10112='Fade',10113='Theater',10114='Theater_Rainbow',10115='Running',10116='Saw',10117='Twinkle',10118='Dissolve',10119='Dissolve_Rnd',10120='Sparkle',10121='Dark_Sparkle',10122='Sparkle+',10123='Strobe',10124='Strobe_Rainbow',10125='Mega_Strobe',10126='Blink_Rainbow',10127='Android',10128='Chase',10129='Chase_Random',10130='Chase_Rainbow',10131='Chase_Flash',10132='Chase_Flash_Rnd',10133='Rainbow_Runner',10134='Colorful',10135='Traffic_Light',10136='Sweep_Random',10137='Running_2',10138='Red_&_Blue',10139='Stream',10140='Scanner',10141='Lighthouse',10142='Fireworks',10143='Rain',10144='Merry_Christmas',10145='Fire_Flicker',10146='Gradient',10147='Loading',10148='Police',10149='Police_All',10150='Two_Dots',10151='Two_Areas',10152='Circus',10153='Halloween',10154='Tri_Chase',10155='Tri_Wipe',10156='Tri_Fade',10157='Lightning',10158='ICU',10159='Multi_Comet',10160='Dual_Scanner',10161='Stream_2',10162='Oscillate',10163='Pride_2015',10164='Juggle',10165='Palette',10166='Fire_2012',10167='Colorwaves',10168='BPM',10169='Fill_Noise',10170='Noise_1',10171='Noise_2',10172='Noise_3',10173='Noise_4',10174='Colortwinkle',10175='Lake',10176='Meteor',10177='Smooth_Meteor',10178='Railway',10179='Ripple',10180='Twinklefox',10181='Twinklecat',10182='Halloween_Eyes',10183='Solid_Pattern',10184='Solid_Pattern_Tri',10185='Spots',10186='Spots_Fade',10187='Glitter',10188='Candle',10189='Fireworks_Starburst',10190='Fireworks_1D',10191='Bouncing_Balls',10192='Sinelon',10193='Sinelon_Dual',10194='Sinelon_Rainbow',10195='Popcorn',10196='Drip',10197='Plasma',10198='Percent',10199='Ripple_Rainbow',10200='Heartbeat',10201='Pacifica',10202='Candle_Multi',10203='Solid_Glitter',10204='Sunrise',10205='Phased',10206='Twinkle_Up',10207='Noise_Pal',10208='Sinewave',10209='Phased_Noise',10210='Flow']
        Selection item=bedrgbpalettes mappings=[20001='Default',20002='Random Cycle',20003='Primary color',20004='Based on primary',20005='Set colors',20006='Based on set',20007='Party',20008='Cloud',20009='Lava',20010='Ocean',20011='Forest',20012='Rainbow',20013='Rainbow bands',20014='Sunset',20015='Rivendell',20016='Breeze',20017='Red & Blue',20018='Yellowout',20019='Analoguous',20020='Splash',20021='Pastel',20022='Sunset 2',20023='Beech',20024='Vintage',20025='Departure',20026='Landscape',20027='Beach',20028='Sherbet',20029='Hult',20030='Hult 64',20031='Drywet',20032='Jul',20033='Grintage',20034='Rewhi',20035='Tertiary',20036='Fire',20037='Icefire',20038='Cyane',20039='Light Pink',20040='Autumn',20041='Magenta',20042='Magred',20043='Yelmag',20044='Yelblu',20045='Orange & Teal',20046='Tiamat',20047='April Night',20048='Orangery',20049='C9',20050='Sakura',20051='Aurora']
        Selection item=bedrgbpreset mappings=[1='PreSet_1',2='PreSet_2',3='PreSet_3',4='PreSet_4',5='PreSet_5',6='PreSet_6',7='PreSet_7',8='PreSet_8',9='PreSet_9',10='PreSet_10',11='PreSet_11',12='PreSet_12',13='PreSet_13',14='PreSet_14',15='PreSet_15',16='PreSet_16']
    }

Switch bedrgb "BED Room Night switch" {channel="mqtt:topic:bedrgb:switch"}
  Dimmer bedrgbBrightness "BED Night Brightness [%d %%]" {channel="mqtt:topic:bedrgb:brightness"}
Color bedrgbColour "Bed Night colour" {channel="mqtt:topic:bedrgb:colour"}
Dimmer bedrgbSpeed "Bed Night speed [%d %%]" {channel="mqtt:topic:bedrgb:speed"}
Dimmer bedrgbIntensity "Bed Night intensity [%d %%]" {channel="mqtt:topic:bedrgb:intensity"}
String bedrgbAPI "Ned Night API" {channel="mqtt:topic:bedrgb:api"}
Number bedrgbcolor2 "Bed Night Color" {channel="mqtt:topic:bedrgb:color2"}
Number bedrgbeffects "Bed Night Effects" {channel="mqtt:topic:bedrgb:effects"}
Number bedrgbpalettes "Bed Night Palettes" {channel="mqtt:topic:bedrgb:palettes"}
Number bedrgbpreset "Bed Night Preset" {channel="mqtt:topic:bedrgb:preset"}

Bridge mqtt:broker:mqtt “Mosquitto” [ host=“192.168.1.100”, secure=false, port=1883, clientID=“Oh2Mqtt2”, username=“esp8266”, password=“sujitrp82”]

{ 

    Thing mqtt:topic:bedrgb "godlight2 lights" {

                Channels:

                    Type switch : switch "Power Switch" [ 

                        commandTopic="wled/godlight2",

                        on="ON",

                        off="OFF",

                        stateTopic="wled/godlight2/v",

                        transformationPattern="XPATH:/vs/ac/text()∩JS:dimmer2switch.js"

                    ]

                    Type colorRGB : colour "Colour" [ 

                        commandTopic="wled/godlight2/col",

                        transformationPatternOut="JS:rgb2hex.js",

                        stateTopic="wled/godlight2/c",

                        transformationPattern="JS:hex2rgb.js"

                    ]

                    Type dimmer : brightness "Brightness" [ 

                        commandTopic="wled/godlight2",

                        transformationPatternOut="JS:openhab2wled.js",                

                        stateTopic="wled/godlight2/g",

                        transformationPattern="JS:wled2openhab.js"

                    ]

                    Type dimmer : speed "Speed" [

                        commandTopic="wled/godlight2/api",

                        transformationPatternOut="JS:openhab2wled-speed.js",

                        stateTopic="wled/godlight2/v",

                        transformationPattern="XPATH:/vs/sx/text()∩JS:wled2openhab.js"

                    ]

                    Type dimmer : intensity "Intensity" [

                        commandTopic="wled/godlight2/api",

                        transformationPatternOut="JS:openhab2wled-intensity.js",

                        stateTopic="wled/godlight2/v",

                        transformationPattern="XPATH:/vs/ix/text()∩JS:wled2openhab.js"

                    ]

                    Type string : api "api" [

                        commandTopic="wled/godlight2/api"

                    ]

                    Type number : color2 "Color2" [

                        commandTopic="wled/godlight2/col",

                        transformationPatternOut="MAP:wledColoreffectsJSON.map"               

                    ]

                    

                    Type number : effects "effects" [ 

                        commandTopic="wled/godlight2/api",

                        transformationPatternOut="MAP:wledColoreffectsJSON.map", 

                        stateTopic="wled/godlight2/v",

                        transformationPattern="XPATH:/vs/fx/text()∩MAP:wledeffects.map"

                    ]   

                    Type number : palettes "palettes" [ 

                        commandTopic="wled/godlight2/api",

                        transformationPatternOut="MAP:wledColoreffectsJSON.map", 

                        stateTopic="wled/godlight2/v",

                        transformationPattern="XPATH:/vs/fp/text()∩MAP:wledpalettes.map"

                    ] 

                    Type number : preset "Preset" [

                        commandTopic="wled/godlight2/api",

                        transformationPatternOut="MAP:wledColoreffectsJSON.map"               

                    ]

                    

            }

}

Looks cool!

Would you also be able to share all your map files to complete the example?

Hi Please find CFG file at following location

You made me to do my 1st mqtt 1.0X to 2.5 which was long pending at my end :slight_smile: Thanks

State topic requires work for state subscription . This will help to maintain the correct status on Openhab end if the state change done using WLED WEB UI / Push Button .
I tried but not working .

Also I will like to learn on jython rule .

For me, every time something is changed with WLED (either via openHAB, or the web UI or the app), WLED always responds with all three MQTT response topics: g, c and v.

openHAB will always pick this up, whether or not the original command came from openHAB, and my items will update almost instantaneously.

I haven’t changed anything from default on WLED except for enabling MQTT in the first place. It’s strange that it doesn’t work for you.

` effects, palettes & preset the additional Item I added .System gives the Log message like this

2020-06-23 17:02:22.383 [WARN ] [ab.binding.mqtt.generic.ChannelState] - Incoming payload 'Bouncing Balls' not supported by type 'NumberValue'
2020-06-23 17:02:22.396 [WARN ] [ab.binding.mqtt.generic.ChannelState] - Incoming payload 'Rainbow' not supported by type 'NumberValue'

I am trying to update the number item with a text value. What I want is to update the number Item and respective text value to be picked up from the map file.

In general, I would keep the channel as a number, the item as a number and the sitemap widget as a selection - all of these deal with numbers. Then (using effect (FX) as an example):

  • On the sitemap widget you have mappings (as you already do) to show the user more friendly effect names. (It would be great if these could be defined in a map file, but it doesn’t look like it from the docs). Make sure that each effect number and name match those defined by WLED.
  • On the channel use formatBeforePublish="FX=%s" instead of transformationPatternOut. This will send out “FX=22” if you selected “Sparkle+” from the sitemap selection box.
  • On the channel, keep the XPATH transform on transformationPattern. This number will then be passed back to the sitemap selection box, and the currently active effect will be displayed with your friendlier name.

EDIT: Now implemented in post #1

Done Bingo works perfectly. I shall upload Dropbox and update the configuration soon.

Hi guys,
If understood correctly second post is optimized code from post no 1. Looks much smoother but got lost somewhere I guess.
We do have three blocks of code to copy/paste into THINGS, ITEMS and SITEMAP and done that. However not using Mosquitto but MQTT Embedded Broker, anyone adapted that code for different broker?

This depends on how you’ve set your embedded broker up. If your broker does not yet have a bridge Thing associated with it, then you can use the one from the example and adjust the parameters.

If you do already have a bridge Thing, and you set this up using PaperUI then I’m afraid I don’t quite know what the next step would be.

I will say this: if you intend to upgrade to OH3, the embedded broker is being removed completely. I would recommend moving to a dedicated MQTT broker such as Mosquitto to future proof yourself…

EDIT: Just realised this example doesn’t include the code for a bridge Thing. Use the one from this post for now (scroll to bridge.things).

It`s working now :slight_smile:
First changed (mqtt:broker:MosquittoMqttBroker) into (mqtt:systemBroker:embedded-mqtt-broker) , then installed Xpath and javascript transformations (before used only jsonpath) and finally rebooted OH (not sure if neccessary).

Thanks hafniumzinc !!

@sujitrp Why in MAP files you use “:” instead of “=”?

No specific reason .

Any chance of getting “Sleep” running or did I missed something.

BUUUUT ALL IN ALL - Guys great - really love it.
Took me a few minutes and it works like a charm!

Thx for sharing!

Clyde

Do you mean the dimming timer? I’ve got a proof of concept working - will write it up over the weekend.

Yeah, correct. The dimming timer.
Which switches “off” the lights after /default 60 mins.

Would be awesome. Will try to help/test :wink:

Getting full control over Sleep is awkward, involving rules and metadata, and there’s also this problem.

A simple method, which just involves a switch, is as follows. This will use the Default Duration and Default Target brightness in the WLED settings:

Channel

Type switch : sleep "Sleep" [
	stateTopic="wled/RGB2/v",
	transformationPattern="XPATH:/vs/nl/text()",
	commandTopic="wled/RGB2/api",
	formatBeforePublish="ND",
	on="1",
	off="0"
]

Item

Switch sRGB2Sleep "Sleep" {channel="mqtt:topic:swRGB2:sleep"}

WLED settings

Change to suit
image

The challenge with configuring Sleep over MQTT is that you can send an NL= command, which takes a number in minutes as an argument. This will set the Sleep Default Duration to that time, BUT ALSO will turn Sleep ON! So without a rule I haven’t found a way to change ONLY the Default Duration. You may want to check out the WLED binding options for Sleep.

1 Like

Faniumzinc: Wh00p Whoop - tested works. NICE!
Thx for help. This suits my needs totally. I just want to set a timer for nightlight and done.
60 mins are fine and if I want to change it I can do it via the GUI.

:slight_smile: pure awesomeness!

Any chance to control Presets through MQTT as well? I see these are reported on strings named ps
1