thanks.
Here are the options when using webcore.
The setEffect option allows these choices:
So I can't figure how to apply this:
thanks.
Here are the options when using webcore.
The setEffect option allows these choices:
So I can't figure how to apply this:
solved, I think.
Posted over at the webcore forum (WLED webcore query (can't duplicate function from RM) - Hubitat - webCoRE Community Forum).
This reply came along:
I can't code, at all. But I tried just replacing all references to "setEffect" with "setEffectCustom".
ie.
/**
*
* WLED Device Type
*
* Author: bryan@joyful.house
*
* Date: 2019-11-27
*/
import java.net.URLEncoder
metadata {
definition (name: "WLED-mod", namespace: "joyfulhouse", author: "Bryan Li") {
capability "Color Control"
capability "Color Temperature"
capability "Refresh"
capability "Switch"
capability "Switch Level"
capability "Light"
capability "ColorMode"
capability "Alarm"
attribute "colorName", "string"
attribute "effectName", "string"
attribute "paletteName", "string"
//command "getEffects"
//command "getPalettes"
command "setEffectCustom",
[
[name:"FX ID", type: "NUMBER", description: "Effect ID", constraints: []],
[name:"FX Speed", type: "NUMBER", description: "Relative Effect Speed (0-255)", constraints: []],
[name:"FX Intensity", type: "NUMBER", description: "Effect Intensity(0-255)", constraints: []],
[name:"Color Palette", type: "NUMBER", description: "Color Palette", constraints: []]
]
}
// simulator metadata
simulator {
}
// Preferences
preferences {
input "uri", "text", title: "URI", description: "(eg. http://[wled_ip_address])", required: true, displayDuringSetup: true
input name: "ledSegment", type: "number", title: "LED Segment", defaultValue: 0
input name: "transitionTime", type: "enum", description: "", title: "Transition time", options: [[500:"500ms"],[1000:"1s"],[1500:"1.5s"],[2000:"2s"],[5000:"5s"]], defaultValue: 1000
input name: "refreshInterval", type: "enum", description: "", title: "Refresh interval", options: [
[30: "30 Seconds"],[60:"1 Minute"],[300:"5 Minutes"],[600:"10 Minutes"],[1800:"30 Minutes"],[3600:"1 Hour"],[0:"Disabled"]],
defaultValue: 3600
input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true
input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true
}
}
def initialize() {
installed()
}
def installed() {
setSchedule()
refresh()
}
def updated() {
setSchedule()
refresh()
}
def setSchedule() {
logDebug "Setting refresh interval to ${settings.refreshInterval}s"
unschedule()
switch(settings.refreshInterval){
case "0":
unschedule()
break
case "30":
schedule("0/30 * * ? * * *", refresh)
break
case "60":
schedule("0 * * ? * * *", refresh)
break
case "300":
schedule("0 0/5 * ? * * *", refresh)
break
case "600":
schedule("0 0/10 * ? * * *", refresh)
break
case "1800":
schedule("0 0/30 * ? * * *", refresh)
break
case "3600":
schedule("0 * 0/1 ? * * *", refresh)
break
default:
unschedule()
}
}
def logsOff(){
log.warn "debug logging disabled..."
device.updateSetting("logEnable",[value:"false",type:"bool"])
}
def parseResp(resp) {
// Handle Effects and Palettes
if(!state.effects)
getEffects()
if(!state.palettes)
getPalettes()
def effects = state.effects
def palettes = state.palettes
// Update State
state = resp.data
state.effects = effects
state.palettes = palettes
synchronize(resp.data)
}
def parsePostResp(resp){
}
def synchronize(data){
logDebug "Synchronizing status: ${data.seg[settings.ledSegment?.toInteger() ?: 0]}}"
seg = data.seg[settings.ledSegment?.toInteger() ?: 0]
// Power
if(seg.on){
if(device.currentValue("switch") != "on")
sendEvent(name: "switch", value: "on")
}
else {
if(device.currentValue("switch") == "on")
sendEvent(name: "switch", value: "off")
}
//TODO: Synchronize everything else
}
// Switch Capabilities
def on() {
sendEthernetPost("/json/state","{\"on\":true, \"seg\": [{\"id\": ${ledSegment}, \"on\":true}]}")
sendEvent(name: "switch", value: "on")
}
def off() {
sendEthernetPost("/json/state","{\"on\":true, \"seg\": [{\"id\": ${ledSegment}, \"on\":false}]}")
sendEvent(name: "switch", value: "off")
}
// Color Names
def setGenericTempName(temp){
if (!temp) return
def genericName
def value = temp.toInteger()
if (value <= 2000) genericName = "Sodium"
else if (value <= 2100) genericName = "Starlight"
else if (value < 2400) genericName = "Sunrise"
else if (value < 2800) genericName = "Incandescent"
else if (value < 3300) genericName = "Soft White"
else if (value < 3500) genericName = "Warm White"
else if (value < 4150) genericName = "Moonlight"
else if (value <= 5000) genericName = "Horizon"
else if (value < 5500) genericName = "Daylight"
else if (value < 6000) genericName = "Electronic"
else if (value <= 6500) genericName = "Skylight"
else if (value < 20000) genericName = "Polar"
def descriptionText = "${device.getDisplayName()} color is ${genericName}"
if (txtEnable) log.info "${descriptionText}"
sendEvent(name: "colorName", value: genericName ,descriptionText: descriptionText)
}
def setGenericName(hue){
def colorName
hue = hue.toInteger()
if (!hiRezHue) hue = (hue * 3.6)
switch (hue.toInteger()){
case 0..15: colorName = "Red"
break
case 16..45: colorName = "Orange"
break
case 46..75: colorName = "Yellow"
break
case 76..105: colorName = "Chartreuse"
break
case 106..135: colorName = "Green"
break
case 136..165: colorName = "Spring"
break
case 166..195: colorName = "Cyan"
break
case 196..225: colorName = "Azure"
break
case 226..255: colorName = "Blue"
break
case 256..285: colorName = "Violet"
break
case 286..315: colorName = "Magenta"
break
case 316..345: colorName = "Rose"
break
case 346..360: colorName = "Red"
break
}
def descriptionText = "${device.getDisplayName()} color is ${colorName}"
if (txtEnable) log.info "${descriptionText}"
sendEvent(name: "colorName", value: colorName ,descriptionText: descriptionText)
}
// Dimmer function
def setLevel(value) {
setLevel(value,(transitionTime?.toBigDecimal() ?: 1000) / 1000)
}
def setLevel(value,rate) {
rate = rate.toBigDecimal()
def scaledRate = (rate * 10).toInteger()
if(value > 0){
def isOn = device.currentValue("switch") == "on"
if(!isOn)
on()
if(value >= 100) {
setValue = 255
value = 100
}
else {
setValue = (value.toInteger() * 2.55).toInteger()
}
msg = "{\"on\":true, \"seg\": [{\"id\": ${ledSegment}, \"on\":true, \"bri\": ${setValue}}]}"
sendEthernetPost("/json/state", msg)
sendEvent(name: "level", value: value, descriptionText: "${device.displayName} is ${value}%", unit: "%")
} else {
off()
}
refresh()
}
// Color Functions
def setColor(value){
if (value.hue == null || value.saturation == null) return
def rate = transitionTime?.toInteger() ?: 1000
// Turn off if level is set to 0/black
if (value.level == 0) {
off()
return
} else if(value.level >= 100) {
level = 255
} else {
level = value.level * 256
}
// Convert to RGB from HSV
rgbValue = hsvToRgb(value.hue, value.saturation, value.level)
// Send to WLED
logDebug("Setting RGB Color to ${rgbValue}")
setRgbColor(rgbValue)
setGenericName(value.hue)
}
def setColorTemperature(temp){
on()
rgbValue = colorTempToRgb(temp)
setRgbColor(rgbValue)
setGenericTempName(temp)
}
def setHue(value){
//TODO: Fix color conversion
def color = [:]
color.hue = value
color.level = 255
color.saturation = 100
setColor(color)
}
def setRgbColor(rgbValue){
// Turn off any active effects
setEffectCustom(0,0)
// Send Color
body = "{\"on\":true, \"seg\": [{\"id\": ${ledSegment}, \"on\":true, \"col\": [${rgbValue}]}]}"
logDebug("Setting color: ${body}")
sendEthernetPost("/json/state", body)
refresh()
}
// Device Functions
def refresh() {
sendEthernet("/json/state")
}
def sendEthernet(path) {
if(settings.uri != null){
def params = [
uri: "${settings.uri}",
path: "${path}",
headers: [:]
]
try {
httpGet(params) { resp ->
parseResp(resp)
}
} catch (e) {
log.error "something went wrong: $e"
}
}
}
def sendEthernetPost(path, body) {
if(settings.uri != null){
def params = [
uri: "${settings.uri}",
path: "${path}",
headers: [
"Content-Type": "application/json",
"Accept": "*/*"
],
body: "${body}"
]
try {
httpPost(params) { resp ->
parsePostResp(resp)
}
} catch (e) {
log.error "something went wrong: $e"
}
}
}
// Helper Functions
def logDebug(message){
if(logEnable) log.debug(message)
}
def hsvToRgb(float hue, float saturation, float value) {
if(hue==100) hue = 99
hue = hue/100
saturation = saturation/100
value = value/100
int h = (int)(hue * 6)
float f = hue * 6 - h
float p = value * (1 - saturation)
float q = value * (1 - f * saturation)
float t = value * (1 - (1 - f) * saturation)
switch (h) {
case 0: return rgbToString(value, t, p)
case 1: return rgbToString(q, value, p)
case 2: return rgbToString(p, value, t)
case 3: return rgbToString(p, q, value)
case 4: return rgbToString(t, p, value)
case 5: return rgbToString(value, p, q)
default: log.error "Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value
}
}
def colorTempToRgb(kelvin){
temp = kelvin/100
if( temp <= 66 ){
red = 255
green = temp
green = 99.4708025861 * Math.log(green) - 161.1195681661
if( temp <= 19){
blue = 0
} else {
blue = temp-10
blue = 138.5177312231 * Math.log(blue) - 305.0447927307
}
} else {
red = temp - 60
red = 329.698727446 * Math.pow(red, -0.1332047592)
green = temp - 60
green = 288.1221695283 * Math.pow(green, -0.0755148492 )
blue = 255
}
rs = clamp(red,0, 255)
gs = clamp(green,0,255)
bs = clamp(blue,0, 255)
return "[" + rs + "," + gs + "," + bs + "]";
}
def rgbToString(float r, float g, float b) {
String rs = (int)(r * 255)
String gs = (int)(g * 255)
String bs = (int)(b * 255)
return "[" + rs + "," + gs + "," + bs + "]";
}
def clamp( x, min, max ) {
if(x<min){ return min; }
if(x>max){ return max; }
return x;
}
// FastLED FX and Palletes
def getEffects(){
logDebug "Getting Effects List"
def params = [
uri: "${settings.uri}",
path: "/json/effects",
headers: [
"Content-Type": "application/json",
"Accept": "*/*"
],
body: "${body}"
]
try {
httpGet(params) {
resp ->
state.effects = resp.data
}
} catch (e) {
log.error "something went wrong: $e"
}
}
def getPalettes(){
logDebug "Getting Effects List"
def params = [
uri: "${settings.uri}",
path: "/json/palettes",
headers: [
"Content-Type": "application/json",
"Accept": "*/*"
],
body: "${body}"
]
try {
httpGet(params) {
resp ->
state.palettes = resp.data
}
} catch (e) {
log.error "something went wrong: $e"
}
}
def setEffectCustom(fx){
def i = ledSegment?.toInteger() ?: 0
setEffectCustom(fx, state.seg[i].sx, state.seg[i].ix, state.seg.pal)
}
def setEffectCustom(fx, pal){
def i = ledSegment?.toInteger() ?: 0
setEffectCustom(fx, state.seg[i].sx, state.seg[i].ix, pal)
}
def setEffectCustom(fx,sx,ix){
def i = ledSegment?.toInteger() ?: 0
setEffectCustom(fx, sx, ix, state.seg[i].pal)
}
def setEffectCustom(fx, sx, ix, pal){
logDebug("Setting Effect: [{\"id\": ${ledSegment},\"fx\": ${fx},\"sx\": ${sx},\"ix\": ${ix},\"pal\": ${pal}}]")
body = "{\"on\":true, \"seg\": [{\"id\": ${ledSegment},\"fx\": ${fx},\"sx\": ${sx},\"ix\": ${ix},\"pal\": ${pal}}]}"
sendEthernetPost("/json/state", body)
// Effect Name
def effectName = state.effects.getAt(fx.intValue())
def descriptionText = "${device.getDisplayName()} effect is ${effectName}"
if (txtEnable) log.info "${descriptionText}"
sendEvent(name: "effectName", value: effectName, descriptionText: descriptionText)
// Palette Name
def paletteName = state.palettes.getAt(pal.intValue())
descriptionText = "${device.getDisplayName()} color palette is ${paletteName}"
if (txtEnable) log.info "${descriptionText}"
sendEvent(name: "paletteName", value: paletteName, descriptionText: descriptionText)
if(fx > 0){
// Color Name
descriptionText = "${device.getDisplayName()} color is defined by palette"
sendEvent(name: "colorName", value: "Palette", descriptionText: descriptionText)
}
// Refresh
refresh()
}
// Alarm Functions
def siren(){
// Play "Siren" effect
logDebug("Alarm \"siren\" activated")
setEffectCustom(38,255,255,0)
}
def strobe(){
// Set Effect to Strobe
logDebug("Alarm strobe activated")
setEffectCustom(23,255,255,0)
}
def both(){
//Cannot do both, default to strobe
strobe()
}
Which (after a quick add/remove device for webcore) allowed this option:
...instead of the single integer option previously, i.e ...
Thus:
Solved....?
Hi @djh_wolf !
Updated my driver using the WLED-mod you posted (with the SetEffectCustom changes) and added the changes made by @TroyP that allows me to turn it On/Off.
Still no luck in changing colors / effects / Temp... even thru the Devices Tab on HE's interface.
Hey @djh_wolf !
So yours has 0 segments?
Mine was imported by the driver with the 39 segments on my strip.
I’ll test that as soon as I get home in a couple of hours!
There you go. That's your problem
Ok!
Solved!!
Can control effects, colors and so ob thru HE’s devices tab.
Now… time for some webcore tinkering…
@djh_wolf
With the help of @joaomf the driver now returns Effect and Palette numbers.
Rationale: I'm trying to create a Webcore piston in which each pressing of a button would change de effect to the next one. The same idea would be used for double presses and the palette. (Assuming speed and intensity would always remain the same).
Will do some tinkering and maybe webcore will allow one parameter to be changed, without altering the others...
Interested in how this progresses...
Any one know if the aircookie drive can work with segments?
Im using a esp32 with 3 segments but the driver will only turn off one segment?
Should have waited 1 min as just worked out i can have a preset of OFF which works
I tried that and it would only connect to the first one i set up...
Just tried again and looks like its working
So next question...
I have quite a few zigbbe colour bulbs and i would like to colour match wled to these bulbs or the other way not really fussed.
But i cant seem to find a colour name in wled or settings that are accessed in Hubitat.
Revisiting this thread after some time, needed to make a minor fixes anyway, so I added the setEffectCustom function for use with WebCORE. Thanks for looking into that. Technically it works with setEffect and passing only a single parameter but you won't be able to control the other settings (speed, intensity, palette).
Updated code in the github repo.
Fantastic! Cheers!
I was looking at the Hypercubes after seeing them on Paul Hibbert's tech channel. Pretty nice looking, so I reached out. It turns out that these support WLED so it should be possible to integrate them readily with Hubitat.
I am actually not that familiar with WLED. When I made my own WS2812-based lights a couple years ago I wrote my own code for it and created my own Hubitat drivers. They work well for the Christmas lights I made them as.
Anyways, my HyperCube arrived so I wrote a driver for it. I tried one of the WLED drivers I found on the forum but it was a bit old and most things did not quite work. So I just pulled up the WLED docs, found out about the JSON API, and then just reworked one of my other drivers for it instead last night. Considering I have a bunch of API drivers and it is so simple... it was pretty easy to do.
Hi,
Any idea why I'm seeing this error? It seems to appear every minute.
I'm using an ESP 8266 running WLED version 0.13.3
Thanks in advance.
Paul
dev:332023-05-17 13:15:00.242errorjava.lang.NullPointerException: Cannot get property 'on' on null object on line 156 (method parseResp)
dev:332023-05-17 13:15:00.232debugSynchronizing status: null}
dev:332023-05-17 13:15:00.228debug[bri:255, lor:0, mainseg:0, nl:[dur:60, mode:1, on:false, rem:-1, tbri:0], on: false, pl:-1, ps:-1, seg:[[bri:255, cct:127, col:[[255, 221, 172], [0, 0, 0], [0, 0, 0]], frz:false, fx:0, grp:1, id:0, ix:128, len:68, mi:false, of:0, on:true, pal:0, rev:false, sel:true, spc:0, start:0, stop:68, sx:128]], transition:7, udpn:[recv:true, send: false]]
I'm having some problems with Hubitat's color picker popup.
Installed and configured the WLED driver no problem, and the commands all work perfectly from the devices page, but the trouble is on the dashboard. When I adjust the color (on the dashboard) it works great while I'm making the adjustment, however, the moment I close Hubitat's color selector popup, Hubitat sends 255,255,255 (white) to the WLED driver.
Here is the Log where I set the color:
dev:122024-01-07 11:14:33.809 PMdebugSetting RGB Color to [53,25,229]
And here is what happens when I close the color selector popup:
dev:122024-01-07 11:14:36.960 PMdebugSetting RGB Color to [255,255,255]
I'm running WLED 0.14.0 and Hubitat 2.3.7.145
Thank you for any advice,
LLL