Color temperature rule (5-channel RGBWW+HTTP+ESP8266)

working on rules for a 5-channel LEDstrip controller I found on Eryk.io’s website, which i gratefully use. Unfortunately I couldn’t find out how he managed to drive it using OpenHAB from his webpage and google, but I’ve managed to get the it working in Openhab with the HTTP binding and the following files. For the most part at least.

I’ve managed to fix the light temperature balance using smart home designer (which actually is a great help designing the rules!). Just started work on the brightness slider for the overall brightness that would give me individual control over the white light (K) and the RGB, but allow me to dim the light proportionally.

So, the only part so far not working is the brightness slider. The problem I have is that my warm white goes to maximum brightness when I set the brightness to 0. When I use only cold-white, there is no problem.

It would be somewhere in the math, which is not my strong suit. If you spot the error, please let me know :smile:

rule "Brightness_RGBWW"
    when
                Item esp8266_5_br changed or
               	Item esp8266_5_temp changed or
               	Item esp8266_5_rgb changed
    then
		var hsbValue = HSBesp8266_5_rgb.state as HSBType
		logInfo("esp8266_5 ", "hsbValue: " + hsbValue)
		
		var inputTemperature =  esp8266_5_temp.state as DecimalType
		logInfo("esp8266_5 ", "inputTemperature: " + inputTemperature)
		
		var inputBrightness = esp8266_5_br.state as DecimalType
	   	var br = Math::round(inputBrightness.floatValue)
	   	logInfo("esp8266_5_br", "Brightness rounded: "+ br)
		// RGB TO HEX
    	var String rHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
	    var String gHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
	    var String bHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
		//concatenate strings to hexadecimal code
    	var String color = rHEX +  gHEX + bHEX
            
			
			//log value of inputTemperature to info log
        	logInfo("esp8266_5_br", "br: "+ br)
        	logInfo("esp8266_5_br", "hsbValue: "+ hsbValue)

// 			print inputTemperature
       		logInfo("esp8266_5 ", " esp8266_5_temp " + esp8266_5_temp)
        	logInfo("esp8266_5 ", "input: " + inputTemperature)
			
			//Turn inputTemperature into a hex string for the cold-white LED
        	var String cwHEX = String.format("%02X", (Math::round((max-((inputTemperature/q) * br) *2.55).floatValue())))
       		logInfo("esp8266_5 ", " cwHEX: " + cwHEX)

//			Turn inputTemperature into a hex string for the warm-white LED
						var wwFLOAT =     (((inputTemperature / q) * br * 2.55).floatValue())
		logInfo("esp8266_5 ", " wwFLOAT:  " + wwFLOAT)
		    var wwINT =  Math::round(wwFLOAT)
			logInfo("esp8266_5 ", " wwINT: " + wwINT)
			val String wwHEX = String.format("%02X",wwINT)
			logInfo("esp8266_5 ", " wwHEX: " + wwHEX)
			
			
//			concatenate strings to hexadecimal code
	        val String temperature = wwHEX +  cwHEX + "00"    	
    	
    	
    	//print variables
    	logInfo("esp8266_5_rgb","Color: "+ color)
    	logInfo("esp8266_5_temp","Temperature: "+ temperature)
    	logInfo("esp8266_5_br", "Brightness: "+ br)
    	
    	//send commands
    	sendCommand( RGBesp8266_5_rgb, color )
    	sendCommand( esp8266_5_wb, temperature )
	end

sitemap:

sitemap RGBWW label="RGBWW" {
       Frame label="RGB" {
        	Colorpicker item=HSBesp8266_5_rgb icon="colorlight"
		Slider item=esp8266_5_temp label="Temperature [%s]"
		Slider item=esp8266_5_br label="Brightness"
        }
}

items:

Group gRGBWW

// WiFi RGB 2
Group		esp8266_5      			"esp8266_5"             (gRGBWW)
Color		HSBesp8266_5_rgb               	"esp8266_5_rgb"         (esp8266_5)       
String		RGBesp8266_5_rgb		"esp8266_5_rgb"		(esp8266_5)		{ http=">[*:GET:http://10.0.1.5/rgb/%2$s/]"}
Dimmer          esp8266_5_temp                  "esp8266_5_wb"          (gRGBWW)
String          esp8266_5_wb                    "esp8266_5_wb"          (esp8266_5)  { http=">[*:GET:http://10.0.1.5/ww/%2$s/]"}
Dimmer		esp8266_5_br			"esp8266_5_br"		(esp8266_5)	

helpful suggestions always appreciated!

I think I got the math right now, but now it throws an exception:

$ tail -f /var/log/openhab2/openhab.log | grep WARN
2017-08-11 02:04:49.082 [WARN ] [org.apache.karaf.services.eventadmin] - EventAdmin: Exception during event dispatch [org.osgi.service.event.Event [topic=openhab/command/RGBesp8266_5_rgb] {bridgemarker=true, item=RGBesp8266_5_rgb, command=outputColor: 101010} | {org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler}={event.topics=openhab/*, service.pid=org.openhab.http, component.name=org.openhab.binding.http, component.id=10, service.id=867, service.bundleid=183, service.scope=bundle} | Bundle(org.openhab.binding.http_1.11.0.201708050109 [183])]
var float q = 100
var int max = 255

var double maxinv = max/q

rule "Brightness_RGBWW"
    when
                Item esp8266_5_br changed or
               	Item esp8266_5_temp changed or
               	Item esp8266_5_rgb changed
    then
		var hsbValue = HSBesp8266_5_rgb.state as HSBType
		logInfo("esp8266_5 ", "hsbValue: " + hsbValue)
		
		var inputTemperature =  esp8266_5_temp.state as DecimalType
		logInfo("esp8266_5 ", "inputTemperature: " + inputTemperature)
		
		//var inputBrightness = esp8266_5_br.sat.intValue as DecimalType
		val inputBrightness = hsbValue.brightness.intValue
		logInfo("esp8266_5_br", "Brightness: "+ inputBrightness)
	   	var br = Math::round(inputBrightness.floatValue)
	   	logInfo("esp8266_5_br", "br rounded: "+ br)
		// RGB TO HEX
    	var String rHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
	    var String gHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
	    var String bHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
		//concatenate strings to hexadecimal code
    	var String outputColor = rHEX +  gHEX + bHEX
        //print variables
    	logInfo("esp8266_5_rgb","outputColor: "+ outputColor )    
		//log value of inputTemperature to info log
        logInfo("esp8266_5_br", "br: "+ br)
        logInfo("esp8266_5_br", "hsbValue: "+ hsbValue)
//		print inputTemperature
   		logInfo("esp8266_5 ", " esp8266_5_temp state " + esp8266_5_temp)
       	logInfo("esp8266_5 ", "inputTemperature: " + inputTemperature)

//WARM WHITE		
		var invertedinputTemperature = (q - inputTemperature)
		//Turn inputTemperature into a hex string for the warm-white LED
		
		var wwFLOAT = ((invertedinputTemperature * maxinv / q) * br).floatValue()
		logInfo("esp8266_5 ", " wwFLOAT:  " + wwFLOAT)
	    var wwINT =  Math::round(wwFLOAT)
		logInfo("esp8266_5 ", " wwINT: " + wwINT)
		val String wwHEX = String.format("%02X",wwINT)
		logInfo("esp8266_5 ", " wwHEX: " + wwHEX)


//COLD WHITE			
//		Turn inputTemperature into a hex string for the cold-white LED

		var cwFLOAT = (((inputTemperature * maxinv) / q ) * br ).floatValue()
		logInfo("esp8266_5 ", " cwFLOAT:  " + cwFLOAT)
		var cwINT =  Math::round(cwFLOAT)
		logInfo("esp8266_5 ", " cwINT: " + cwINT)
		val String cwHEX = String.format("%02X",cwINT)
		logInfo("esp8266_5 ", " cwHEX: " + cwHEX)

		// concatenate strings to hexadecimal code

	    var String outputTemperature = wwHEX +  cwHEX + "00"    	
	    logInfo("esp8266_5_temp","outputTemperature: "+ outputTemperature)
			 	


    	//send commands
    	sendCommand( RGBesp8266_5_rgb,"outputColor: "+ outputColor )
    	sendCommand( esp8266_5_wb,"outputTemperature: " + outputTemperature )
	end

That line doesn’t show what the exception is.

Sorry about that, it was a late night for me :stuck_out_tongue:

Thanks for responding

2017-08-15 01:42:11.527 [WARN ] [me.internal.engine.RuleContextHelper] - Variable 'maxinv' on rule file '05_esp8266_5_brightness.rules' cannot be initialized with value '<XFeatureCallImplCustom> / <XFeatureCallImplCustom>': An error occurred during the script execution: Could not invoke method: org.eclipse.xtext.xbase.lib.IntegerExtensions.operator_divide(int,float) on instance: null
2017-08-15 01:42:11.827 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Brightness_RGBWW': org.eclipse.smarthome.core.library.types.HSBType
2017-08-15 01:42:11.837 [ERROR] [.script.engine.ScriptExecutionThread] - Rule 'Brightness_RGBWW': org.eclipse.smarthome.core.library.types.HSBType

this is the error

modded the rule, as I made the error of initializing a var with an equation.

var float q = 100
var int max = 255
var double maxinv = 0
var maxinv = max/q

rule "Brightness_RGBWW"
    when
                Item esp8266_5_br changed or
               	Item esp8266_5_temp changed or
               	Item esp8266_5_rgb changed
    then
		var hsbValue = HSBesp8266_5_rgb.state as HSBType
		logInfo("esp8266_5 ", "hsbValue: " + hsbValue)
		
		var inputTemperature =  esp8266_5_temp.state as DecimalType
		logInfo("esp8266_5 ", "inputTemperature: " + inputTemperature)
		
		//var inputBrightness = esp8266_5_br.sat.intValue as DecimalType
		val inputBrightness = hsbValue.brightness.intValue
		logInfo("esp8266_5_br", "Brightness: "+ inputBrightness)
	   	var br = Math::round(inputBrightness.floatValue)
	   	logInfo("esp8266_5_br", "br rounded: "+ br)
		// RGB TO HEX
    	var String rHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
	    var String gHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
	    var String bHEX     = String.format("%02X", ((((hsbValue.red.intValue * 255) / 100) * br) / 100));
		//concatenate strings to hexadecimal code
    	var String outputColor = rHEX +  gHEX + bHEX
        //print variables
    	logInfo("esp8266_5_rgb","outputColor: "+ outputColor )    
		//log value of inputTemperature to info log
        logInfo("esp8266_5_br", "br: "+ br)
        logInfo("esp8266_5_br", "hsbValue: "+ hsbValue)
//		print inputTemperature
   		logInfo("esp8266_5 ", " esp8266_5_temp state " + esp8266_5_temp)
       	logInfo("esp8266_5 ", "inputTemperature: " + inputTemperature)

//WARM WHITE		
		var invertedinputTemperature = (q - inputTemperature)
		//Turn inputTemperature into a hex string for the warm-white LED
		
		var wwFLOAT = ((invertedinputTemperature * maxinv / q) * br).floatValue()
		logInfo("esp8266_5 ", " wwFLOAT:  " + wwFLOAT)
	    var wwINT =  Math::round(wwFLOAT)
		logInfo("esp8266_5 ", " wwINT: " + wwINT)
		val String wwHEX = String.format("%02X",wwINT)
		logInfo("esp8266_5 ", " wwHEX: " + wwHEX)


//COLD WHITE			
//		Turn inputTemperature into a hex string for the cold-white LED

		var cwFLOAT = (((inputTemperature * maxinv) / q ) * br ).floatValue()
		logInfo("esp8266_5 ", " cwFLOAT:  " + cwFLOAT)
		var cwINT =  Math::round(cwFLOAT)
		logInfo("esp8266_5 ", " cwINT: " + cwINT)
		val String cwHEX = String.format("%02X",cwINT)
		logInfo("esp8266_5 ", " cwHEX: " + cwHEX)

		// concatenate strings to hexadecimal code

	    var String outputTemperature = wwHEX +  cwHEX + "00"    	
	    logInfo("esp8266_5_temp","outputTemperature: "+ outputTemperature)
			 	


    	//send commands
    	sendCommand( RGBesp8266_5_rgb,"outputColor: "+ outputColor )
    	sendCommand( esp8266_5_wb,"outputTemperature: " + outputTemperature )
	end

now it throws this:

2017-08-16 12:10:54.797 [WARN ] [org.apache.karaf.services.eventadmin] - EventAdmin: Exception during event dispatch [org.osgi.service.event.Event [topic=openhab/command/RGBesp8266_5_rgb] {bridgemarker=true, item=RGBesp8266_5_rgb, command=outputColor: CECECE} | {org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler}={event.topics=openhab/*, service.pid=org.openhab.http, component.name=org.openhab.binding.http, component.id=10, service.id=864, service.bundleid=183, service.scope=bundle} | Bundle(org.openhab.binding.http_1.11.0.201708050109 [183])]
2017-08-16 12:10:54.814 [WARN ] [org.apache.karaf.services.eventadmin] - EventAdmin: Exception during event dispatch [org.osgi.service.event.Event [topic=openhab/command/esp8266_5_wb] {bridgemarker=true, item=esp8266_5_wb, command=outputTemperature: 000000} | {org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler}={event.topics=openhab/*, service.pid=org.openhab.http, component.name=org.openhab.binding.http, component.id=10, service.id=864, service.bundleid=183, service.scope=bundle} | Bundle(org.openhab.binding.http_1.11.0.201708050109 [183])]

As far as I can tell these lines don’t capture the actual exception. Check the lines in the log that come below this WARN line.

2017-08-17 14:18:29.523 [WARN ] [org.apache.karaf.services.eventadmin] - EventAdmin: Exception during event dispatch [org.osgi.service.event.Event [topic=openhab/command/RGBesp8266_5_rgb] {bridgemarker=true, item=RGBesp8266_5_rgb, command=outputColor: 686868} | {org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler}={event.topics=openhab/*, service.pid=org.openhab.http, component.name=org.openhab.binding.http, component.id=10, service.id=864, service.bundleid=183, service.scope=bundle} | Bundle(org.openhab.binding.http_1.11.0.201708050109 [183])]
java.lang.IllegalArgumentException: Invalid uri 'http://10.0.1.5/rgb/outputColor: 686868/': escaped absolute path not valid
        at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222)[182:org.apache.servicemix.bundles.commons-httpclient:3.1.0.7]
        at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)[182:org.apache.servicemix.bundles.commons-httpclient:3.1.0.7]
        at org.openhab.io.net.http.HttpUtil.createHttpMethod(HttpUtil.java:314)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.io.net.http.HttpUtil.executeUrl(HttpUtil.java:167)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.io.net.http.HttpUtil.executeUrl(HttpUtil.java:130)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.binding.http.internal.HttpBinding.formatAndExecute(HttpBinding.java:285)[183:org.openhab.binding.http:1.11.0.201708050109]
        at org.openhab.binding.http.internal.HttpBinding.internalReceiveCommand(HttpBinding.java:130)[183:org.openhab.binding.http:1.11.0.201708050109]
        at org.openhab.core.binding.AbstractBinding.receiveCommand(AbstractBinding.java:97)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.core.events.AbstractEventSubscriber.handleEvent(AbstractEventSubscriber.java:45)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.sendEvent(EventHandlerProxy.java:415)[6:org.apache.karaf.services.eventadmin:4.0.8]
        at org.apache.felix.eventadmin.impl.tasks.HandlerTask.run(HandlerTask.java:90)[6:org.apache.karaf.services.eventadmin:4.0.8]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)[:1.8.0_144]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_144]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[:1.8.0_144]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)[:1.8.0_144]
        at java.lang.Thread.run(Thread.java:748)[:1.8.0_144]
2017-08-17 14:18:29.537 [WARN ] [org.apache.karaf.services.eventadmin] - EventAdmin: Exception during event dispatch [org.osgi.service.event.Event [topic=openhab/command/esp8266_5_wb] {bridgemarker=true, item=esp8266_5_wb, command=outputTemperature: 000000} | {org.osgi.service.cm.ManagedService, org.osgi.service.event.EventHandler}={event.topics=openhab/*, service.pid=org.openhab.http, component.name=org.openhab.binding.http, component.id=10, service.id=864, service.bundleid=183, service.scope=bundle} | Bundle(org.openhab.binding.http_1.11.0.201708050109 [183])]
java.lang.IllegalArgumentException: Invalid uri 'http://10.0.1.5/ww/outputTemperature: 000000/': escaped absolute path not valid
        at org.apache.commons.httpclient.HttpMethodBase.<init>(HttpMethodBase.java:222)[182:org.apache.servicemix.bundles.commons-httpclient:3.1.0.7]
        at org.apache.commons.httpclient.methods.GetMethod.<init>(GetMethod.java:89)[182:org.apache.servicemix.bundles.commons-httpclient:3.1.0.7]
        at org.openhab.io.net.http.HttpUtil.createHttpMethod(HttpUtil.java:314)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.io.net.http.HttpUtil.executeUrl(HttpUtil.java:167)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.io.net.http.HttpUtil.executeUrl(HttpUtil.java:130)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.binding.http.internal.HttpBinding.formatAndExecute(HttpBinding.java:285)[183:org.openhab.binding.http:1.11.0.201708050109]
        at org.openhab.binding.http.internal.HttpBinding.internalReceiveCommand(HttpBinding.java:130)[183:org.openhab.binding.http:1.11.0.201708050109]
        at org.openhab.core.binding.AbstractBinding.receiveCommand(AbstractBinding.java:97)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.openhab.core.events.AbstractEventSubscriber.handleEvent(AbstractEventSubscriber.java:45)[185:org.openhab.core.compat1x:2.2.0.201708071438]
        at org.apache.felix.eventadmin.impl.handler.EventHandlerProxy.sendEvent(EventHandlerProxy.java:415)[6:org.apache.karaf.services.eventadmin:4.0.8]
        at org.apache.felix.eventadmin.impl.tasks.HandlerTask.run(HandlerTask.java:90)[6:org.apache.karaf.services.eventadmin:4.0.8]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)[:1.8.0_144]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)[:1.8.0_144]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)[:1.8.0_144]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)[:1.8.0_144]
        at java.lang.Thread.run(Thread.java:748)[:1.8.0_144]

Ah, I see what went wrong :wink:

So, problem solved?

no unfortunately not, I’m getting all zero values now. A friend hinted that it was a var type mismatch, so I’ll get back on it soon. but it’s weird that smart home designer doesn’t seem to mind :\

Just a wild guess, but wouldn’t it be better to URL encode the colon and the space?

That was fixed by turning this

var String outputTemperature = wwHEX +  cwHEX + "00"    	
	    logInfo("esp8266_5_temp","outputTemperature: "+ outputTemperature)
			 	


    	//send commands
    	sendCommand( RGBesp8266_5_rgb,"outputColor: "+ outputColor )
    	sendCommand( esp8266_5_wb,"outputTemperature: " + outputTemperature )

into this

 var String outputTemperature = wwHEX +  cwHEX + "00"    	
	    logInfo("esp8266_5_temp","outputTemperature: "+ outputTemperature)
			 	


    	//send commands
    	sendCommand( RGBesp8266_5_rgb, outputColor )
    	sendCommand( esp8266_5_wb, outputTemperature )

The problem is now that all my output numbers seem to be 0.

likely caused by doing calculus with 2 different var types.
But I don’t have time to fix it today, maybe tomorrow!