Changing lamp color based on a variable

Hi all

Firstly I have done a bunch of searching without coming up with a solution.

Using Node-RED, I would like to change the colour of a RGB lamp, based on a changing variable from a illumination sensor. The sensor outputs on a scale of 0-1000 lux. I would like the lamp to change from red, through orange, yellow, etc to blue as the brightness increases.

I have written some script for a Function Node that I believe will suit my needs:

//An alternative that uses hr_color
//variable 'aa' has a range of 0-1000
//the hue colour wheel is 360, but the red to blue spectrum
//covers 0-250

//Gather variables
var aa = parseFloat(msg.payload);

let hr_color = aa/4;
//gives a number between 0-250
//with low illum indicated by red, high by blue, as above

msg.payload = hr_color;
return msg;

The msg.payload will be a number between zero and 250, which I hope to pass to the RGB lamp as the Hue part of an ‘hr_color’ command.

I have searched for a method to do this extensively, including nodes that accept Mustache Templates, with no luck.

I have succeeded with a granular (5 step) flow using a Switch node and Call Service nodes, but I hope to get greater colour resolution.

Any advice would be appreciated


Could you please give some more information?
If i understand you correctly, based on the input of one sensor, you want to dynamically adjust the output of the lights. That’s should be doable without too much effort.

I have some questions though:

  1. What is HR_Color? In HomeAssistant Documentation i only see HS_Color. Which also goes from 0 - 360.

  2. How granular is your illumination sensor reporting?

  3. What are your service calls? Do you specify the Colors manually? Maybe you can export the whole flow and post the code here? Makes it easier to troubleshoot.

I think you can probably just extend on your function node to make the appropriate service calls.
What you need to figure out is a formula to translate the desired illumination into a color code that the service call understands.

EDIT After playing around with HS_Color you could probably just send your hr_color variable directly into the service call. It will then change automatically the light once there is a new brightness threshold reached (i.e.: Every 4 LUX)
You can do that for example by just replacing a part of the message in the function directly:

newmsg.payload = { data: { "message":msg.message}}

Thank you for your response and questions Marcus.

You seem to understand my dilemma despite some errors on my part. ‘HR_color’ (whilst just a variable), is a typo. The correct variable would be ‘hs_color’. Whilst the ‘hue’ range goes from 0-360, being a circle, values above approximately 250 move back towards the red end of the spectrum which would be confusing in high illumination environments. See this screenshot from the URL I posted above.

My Tuya illumination sensor has a granularity of 1000 steps and I am sampling it once every 10 seconds currently. To simplify the maths, dividing the output by 4 gives me the scale to 250 I think will work.

Please understand that I am not fluent in JavaScript or JSON. Thank you for the suggestion for the function node.

I guess to rephrase my dilemma: I think my function adequately outputs (via msg.payload) the ‘hue’ variable to change the colour of the lamp to something proportional to the illumination. My problem is ‘how’ to get that variable passed to the light.

I have tried extensively various inputs to the ‘Data’ field in the Call Service node without luck. I have tried different Mustache variables - eg { "hs_color": [ {{payload}}, 100] } - to no avail. I subsequently read (on the ‘Call Service Tips and Tricks’ link) that Mustache templates are only accepted in the domain, service and entity_id fields. That is disappointing.

The flow I propose is simple:

Do you have any advice on how to insert the ‘hue variable’ into the Call Service node in a way that it will be passed to the connected entity?

Thank you for reading this far, I appreciate your assistance


You can use this flow. It works for me in testing.
If you dont want 100% Saturation, just change the value or you can also make it dynamic based on a different msg.

[{"id":"f3a8d56cc593d90d","type":"inject","z":"5c5d6708.65ab48","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"40","payloadType":"num","x":150,"y":800,"wires":[["83e8db7f2219e39f"]]},{"id":"83e8db7f2219e39f","type":"function","z":"5c5d6708.65ab48","name":"Payload to HS_Color","func":"newmsg = {}\n\nnewmsg.payload = { data: { \"hs_color\":[msg.payload, 100]} }\n\nreturn newmsg;\n","outputs":1,"noerr":1,"initialize":"","finalize":"","libs":[],"x":400,"y":800,"wires":[["9553885803764f31","e3d1bb2346f4d73b"]]},{"id":"e3d1bb2346f4d73b","type":"debug","z":"5c5d6708.65ab48","name":"debug 5","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":700,"y":800,"wires":[]},{"id":"9553885803764f31","type":"api-call-service","z":"5c5d6708.65ab48","name":"","server":"","version":5,"debugenabled":false,"domain":"light","service":"turn_on","areaId":[],"deviceId":["f6354e1a4d3e0310afcbda4601ada4fa"],"entityId":[],"data":"","dataType":"jsonata","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":510,"y":900,"wires":[["e3d1bb2346f4d73b"]]}]

Scrubbed via: Scrubber | node-red-contrib-home-assistant-websocket

Thank you very much for your reply Marcus. I apologise for the delay in responding.

Your suggestions achieves my aim more elegantly that anything I produced. It is exactly what I needed.

Thank you


1 Like