Need help on apply rules with color temperature

I am using Sonoff LED with arendst firmware, I found difficult on adjust the color temperature value,
device use Color CCWW as command, CC stand for cold and WW as Warm, in Hex value from FF00 to 00FF
I am think using a dimmer item as proxy set value as 0-100 and convert to hex,

I have try to write apart but got 2 issue,

  1. when hex value lower than 10, it doesn’t come with zero, it fail at device
    2)I don’t know how to write the code for status revert as value is combine, how to write the rule to split first 2 byte for CC and last 2 byte for WW?
	var int brightness = (Light_LivingRoom_Ceiling_LED_Proxy.state as DecimalType).intValue()
		var int whitedimmer = (NoOfPairedDevices.state as DecimalType).intValue()
		val int coldwhite   = ((((whitedimmer * 255) / 100) * brightness) / 100)
		val int warmwhite   = (((((100 - whitedimmer) * 255) / 100) * brightness) / 100)
		
	logInfo("MS_Kitchen", String::format("As integer %02d, as hex %s %s", coldwhite, Integer::toHexString(coldwhite), Integer::toHexString(warmwhite)))
	sendCommand(Light_LivingRoom_Ceiling_LED_Color, Integer::toHexString(coldwhite) + Integer::toHexString(warmwhite))

I have figured it out, code is work, but calculation formula got problem so output value is not match with input,
I have to set 2 proxy 1 for input and 1 for output other wise will make it in loop.

rule "Test for color temp output"
when
	Item Light_LivingRoom_Ceiling_LED_Color_Proxy received command
then
		var int brightness = (Light_LivingRoom_Ceiling_LED_Proxy.state as DecimalType).intValue()
		var int whitedimmer = (Light_LivingRoom_Ceiling_LED_Color_Proxy.state as DecimalType).intValue()
		val warmwhite = ((((whitedimmer * 255) / 100) * brightness) / 100)
		val coldwhite = (((((100 - whitedimmer) * 255) / 100) * brightness) / 100)
		val String CCWW = String::format("%1$02X%2$02X", coldwhite, warmwhite)	
		sendCommand(Light_LivingRoom_Ceiling_LED_Color, CCWW)
		logInfo("MS_Kitchen", "As cold int: {}, Warm int: {}, as hex: {}", coldwhite, warmwhite, CCWW)
end


rule "Test for color temp input"
when
	Item Light_LivingRoom_Ceiling_LED_Color received command
then
		val CCWW = Light_LivingRoom_Ceiling_LED_Color.state.toString()
		var int brightness = (Light_LivingRoom_Ceiling_LED_Proxy.state as DecimalType).intValue()
		val coldwhiteIN = (100 - ((((Integer::parseInt(CCWW.substring(0, 2), 16) * 100)/ brightness) * 100) / 255))
		//val warmwhiteIN = (100 - ((((Integer::parseInt(CCWW.substring(2, 4), 16) * 100)/ brightness) * 100) / 255))
		postUpdate(Light_LivingRoom_Ceiling_LED_Color_Proxy, coldwhiteIN)
		logInfo("MS_Kitchen", "CCWW-IN: {},#1 Hex: {} #2 Hex: {}, As cold int: {}, Warm int: {}", CCWW, CCCWW.substring(0, 2), CCWW.substring(2, 4), coldwhiteIN, warmwhiteIN)
end

P.S. Code have modify by @rlkoshak’s advise

To avoid the loop use received command instead of received update to trigger the rules and use postUpdate instead of sendCommand when you want to update the Proxy.

I notice you are missing a closing ) on the line sendCommand(Light_LivingRoom_Ceiling_LED_Color, CCWW. Is this just a typo in the posting or does it exist in the rule?

What is the problem with the calculation? What is the specific error?

Hi Rich,

It’s a typo, usually will change some name while post as usually use some funny name for debug test. :smile:

there is some offset between my calculated value to actually value,
formula cal as hex: 1909 and LED return correct value should be Hex:1608, I tried to look at arendst firmware and can’t understand the his formula, it’s too complicated for me. let me try change to update first and see actual effect

Thanks for the tips :blush:

I found Designer is good way to quick found error, Notepad++ is good to write

works after follow your advise, you are the man, it won’t in loop now, just need to optimized the calculation part will turn it 100% functional, now it is work in 90% accurate :blush: I just like being perfect rather than 90%

Thanks for your help :laughing:I can have a good dream today,

one off topic question, Rich, how do you isolate the abnormal value from sensor?
like it should be floating around 22 degree and suddently drop/over 10degree than back to normal,
you do it by rules? or in influxdb? or in python part?

I don’t use readings like this for any calculations, just graphing. In the graph it is apparent that there is a bad reading.

If I were to try to filter out bad readings I would probably set up a proxy and check the new values against the previous value and if the change is too large throw out the bad reading.

Or I might take the average of the previous 15 minutes readings in my calculation. This would minimize the impact of the bad reading.

It really depends on the characteristics of what you are measuring and how frequently bad readings come across. For example, is a 10 degree drop enough to be certain that the reading is bad? What is the maximum drop you could expect? Do you have to take time into account (e.g. OH crashes over night and now the temp actually is 10 degrees cooler)?

This stuff gets really complicated really fast and you have to be very deliberate in thinking of everything that can happen and account for that.

Personally, I look for the simplest and easiest way to deal with the problem. Usually, that is to ignore the problem and just live with the bad readings. I make my rules robust enough that one or two bad readings won’t cause too much of an impact to behaviors.

not too much but in degrade the resolution of chart as most of my area temp is keep in stable value,
so I was think writing a rule to by pass if temperature is like 10 higher lower than before reading, than drop that,
but have no idea how to write it.

I need to search forum around see any sample I can get on and modify

I like your view that room temp with Fan on/off in chart, so I am doing same on my own, :wink: concept is every where here, I like here

Number TempReading
Number FilteredTemp
rule "Filter bad temp readings"
when
    Item TempReading changed
then
    val difference = Math::abs(FilteredTemp.state - TempReading.state)
    if(difference < 10) FilteredTemp.postUpdate(TempReading.state)
    // else ignore
end

Wow, That’s quick,
I’ll take 10 times more to figure out.
Thanks, I will implement to sensor tomorrow as getting late now,
also will try to make Motion sensor to work in proxy way, now it is bit complicate on if if rules.
Bed Time :blush:
Good Night
Thanks Rich. appreciate for your help
Best regards
Ham