Christian-Me / node-red-contrib-ui-iro-color-picker

Node-RED dashboard color picker widget utilizing the iro.js library. Can be configured as a widget or modal popup window. Individual components can be combined,
Apache License 2.0
4 stars 3 forks source link

Problem sending color to picker node #5

Closed Simon01011 closed 2 years ago

Simon01011 commented 3 years ago

Hi again!

I have a problem sending a color to the picker node. The flow looks like image Basically the first picker is to select a HSV color, then it is converted to RGBW. This is then sent by MQTT (here for testing a pair of link in / link out nodes) to my LED strip. The RGBW color is then converted back to HSV and sent to a second picker. In the end it will of course be the same picker that should update if the color of the LED strip is changed by e.g. its web interface.

The problem is: the second picker does not update if a color is chosen on the first picker. It should update after converting the first picker's color back and forth and sending to the second one. If I inject a color with the inject node, it works. Where is the difference and why does the update of the second picker fail?

The example flow:

[{"id":"aa8494f.efeb868","type":"ui_iro-color-picker","z":"2439f80a.e8dc48","group":"4879182a.6cee18","order":2,"width":4,"height":5,"name":"Picker RGB 1","label":"","placement":"left","hAlign":"center","vAlign":"center","stateField":"payload","enableField":"enable","layoutDirection":"vertical","widgetIndent":"0","buttonWidth":"","pickerType":"widget","popupWidth":"","popupHeight":"","pickerSize":"100","backgroundDim":"50","backgroundColor":"#000000","backgroundVariable":false,"components":[{"options":{"borderColor":"#000000","borderWidth":1,"wheelLightness":false,"wheelAngle":0,"wheelDirection":"anticlockwise"},"componentId":"picker"},{"options":{"borderColor":"#000000","borderWidth":1,"sliderType":"value"},"componentId":"slider"}],"format":"hex","outFormat":"hsv","dynOutput":"input:move","outputConfirmed":false,"outputLimit":"10","passthru":true,"topic":"topic","topicType":"msg","iroColorValue":"#4fbe30","x":360,"y":100,"wires":[["cbe41dfd.dd8b3","e8eaa4f6.878ad8","cbce5ed2.b3381"]]},{"id":"5836ca17.6a4ef4","type":"ui_text","z":"2439f80a.e8dc48","group":"4879182a.6cee18","order":13,"width":0,"height":0,"name":"Chroma out RGB","label":"","format":"HSV -> RGB: {{msg.payload}}","layout":"row-spread","x":830,"y":160,"wires":[]},{"id":"cbe41dfd.dd8b3","type":"ui_text","z":"2439f80a.e8dc48","group":"4879182a.6cee18","order":12,"width":0,"height":0,"name":"HSV original out","label":"","format":"HSV: {{msg.payload}}","layout":"row-spread","x":820,"y":100,"wires":[]},{"id":"e8eaa4f6.878ad8","type":"chroma","z":"2439f80a.e8dc48","name":"HSV -> RGB","outFormat":"rgb","array2object":true,"floatOutput":true,"inputRelativeValues":"percent","outputRelativeValues":"percent","x":590,"y":160,"wires":[["5836ca17.6a4ef4"]]},{"id":"cbce5ed2.b3381","type":"chroma","z":"2439f80a.e8dc48","name":"HSV -> RGBW","outFormat":"rgbw","array2object":true,"floatOutput":true,"inputRelativeValues":"percent","outputRelativeValues":"percent","x":600,"y":220,"wires":[["af30d261.2c517","65ec2aaa.8c5a54"]]},{"id":"af30d261.2c517","type":"ui_text","z":"2439f80a.e8dc48","group":"4879182a.6cee18","order":14,"width":0,"height":0,"name":"Chroma out RGBW","label":"","format":"HSV -> RGBW: {{msg.payload}}","layout":"row-spread","x":830,"y":220,"wires":[]},{"id":"e448c8b3.767028","type":"ui_iro-color-picker","z":"2439f80a.e8dc48","group":"18bbfd20.4a4073","order":2,"width":4,"height":5,"name":"Picker RGB 2","label":"","placement":"left","hAlign":"center","vAlign":"center","stateField":"payload","enableField":"enable","layoutDirection":"vertical","widgetIndent":"0","buttonWidth":"","pickerType":"widget","popupWidth":"","popupHeight":"","pickerSize":"100","backgroundDim":"50","backgroundColor":"#000000","backgroundVariable":false,"components":[{"options":{"borderColor":"#000000","borderWidth":1,"wheelLightness":false,"wheelAngle":0,"wheelDirection":"anticlockwise"},"componentId":"picker"},{"options":{"borderColor":"#000000","borderWidth":1,"sliderType":"value"},"componentId":"slider"}],"format":"hex","outFormat":"hsv","dynOutput":"input:move","outputConfirmed":false,"outputLimit":"10","passthru":false,"topic":"topic","topicType":"msg","iroColorValue":"#4fbe30","x":820,"y":500,"wires":[[]]},{"id":"30e59785.7459e8","type":"chroma","z":"2439f80a.e8dc48","name":"RGBW -> HSV","outFormat":"hsv","array2object":true,"floatOutput":true,"inputRelativeValues":"percent","outputRelativeValues":"percent","x":600,"y":380,"wires":[["d1fc8e03.69e13","126d102d.401aa","e448c8b3.767028"]]},{"id":"d1fc8e03.69e13","type":"ui_text","z":"2439f80a.e8dc48","group":"4879182a.6cee18","order":15,"width":0,"height":0,"name":"Chroma out HSV","label":"","format":"RGBW -> HSV: {{msg.payload}}","layout":"row-spread","x":830,"y":380,"wires":[]},{"id":"126d102d.401aa","type":"debug","z":"2439f80a.e8dc48","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":790,"y":440,"wires":[]},{"id":"542b23a3.233c4c","type":"inject","z":"2439f80a.e8dc48","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"h\":173.07707038958318,\"s\":41.05263157894736,\"v\":74.50980392156863}","payloadType":"json","x":610,"y":500,"wires":[["e448c8b3.767028","126d102d.401aa"]]},{"id":"65ec2aaa.8c5a54","type":"link out","z":"2439f80a.e8dc48","name":"To MQTT","links":["4012c966.3f3bc8"],"x":535,"y":280,"wires":[]},{"id":"4012c966.3f3bc8","type":"link in","z":"2439f80a.e8dc48","name":"From MQTT","links":["65ec2aaa.8c5a54"],"x":295,"y":380,"wires":[["30e59785.7459e8"]]},{"id":"4879182a.6cee18","type":"ui_group","name":"Picker Test 1","tab":"1f10c1ab.3e668e","order":1,"disp":true,"width":"6","collapse":false},{"id":"18bbfd20.4a4073","type":"ui_group","name":"Picker Test 2","tab":"1f10c1ab.3e668e","order":2,"disp":true,"width":"6","collapse":false},{"id":"1f10c1ab.3e668e","type":"ui_tab","name":"RGBW Picker","icon":"dashboard","order":14,"disabled":false,"hidden":false}]
Christian-Me commented 3 years ago

Hi nice you find a "probably" bug ... try this ....

image

This works on my side ... I have to test why it is necessary to delete the socketId (I know that I test for the existence of the socketid to prevent double updates = messages emitted bouncing back. But I have to test if this is still necessary).

Via mqtt the socketid should get lost anyway. Do you plan to feed in the "confirmation" to the same picker? I'm using the homie convention for that and it works great. Every settable parameter has a value and a set topic. So a simple setup works like this

image

It is totally fine if any other device publish a /set messages. The device updates its parameter on success and all UIs stay in sync. If the device is offline the last set waits as a retained message and if it is alive again it will be confirmed.

This works on my home brew firmware with up to around 100msg/sec during scrubbing as the color picker ignores all inputs until mouse release. Or you block the output until the last messages is confirmed on the input. Slower as you are limited by a complete loop but adopts dynamically. Only make sure that you NEVER enable passthrough to avoid an infinite loop

[{"id":"aa8494f.efeb868","type":"ui_iro-color-picker","z":"f08cc0eb.537d9","group":"4879182a.6cee18","order":2,"width":4,"height":5,"name":"Picker RGB 1","label":"","placement":"left","hAlign":"center","vAlign":"center","stateField":"payload","enableField":"enable","layoutDirection":"vertical","widgetIndent":"0","buttonWidth":"","pickerType":"widget","popupWidth":"","popupHeight":"","pickerSize":"100","backgroundDim":"50","backgroundColor":"#000000","backgroundVariable":false,"components":[{"options":{"borderColor":"#000000","borderWidth":1,"wheelLightness":false,"wheelAngle":0,"wheelDirection":"anticlockwise"},"componentId":"picker"},{"options":{"borderColor":"#000000","borderWidth":1,"sliderType":"value"},"componentId":"slider"}],"format":"hex","outFormat":"hsv","dynOutput":"input:move","outputConfirmed":false,"outputLimit":"10","passthru":true,"topic":"topic","topicType":"msg","iroColorValue":"#4fbe30","x":267,"y":170,"wires":[["cbe41dfd.dd8b3","e8eaa4f6.878ad8","cbce5ed2.b3381"]]},{"id":"5836ca17.6a4ef4","type":"ui_text","z":"f08cc0eb.537d9","group":"4879182a.6cee18","order":13,"width":0,"height":0,"name":"Chroma out RGB","label":"","format":"HSV -> RGB: {{msg.payload}}","layout":"row-spread","x":737,"y":230,"wires":[]},{"id":"cbe41dfd.dd8b3","type":"ui_text","z":"f08cc0eb.537d9","group":"4879182a.6cee18","order":12,"width":0,"height":0,"name":"HSV original out","label":"","format":"HSV: {{msg.payload}}","layout":"row-spread","x":727,"y":170,"wires":[]},{"id":"e8eaa4f6.878ad8","type":"chroma","z":"f08cc0eb.537d9","name":"HSV -> RGB","outFormat":"rgb","array2object":true,"floatOutput":true,"inputRelativeValues":"percent","outputRelativeValues":"percent","x":497,"y":230,"wires":[["5836ca17.6a4ef4"]]},{"id":"cbce5ed2.b3381","type":"chroma","z":"f08cc0eb.537d9","name":"HSV -> RGBW","outFormat":"rgbw","array2object":true,"floatOutput":true,"inputRelativeValues":"percent","outputRelativeValues":"percent","x":507,"y":290,"wires":[["af30d261.2c517","65ec2aaa.8c5a54"]]},{"id":"af30d261.2c517","type":"ui_text","z":"f08cc0eb.537d9","group":"4879182a.6cee18","order":14,"width":0,"height":0,"name":"Chroma out RGBW","label":"","format":"HSV -> RGBW: {{msg.payload}}","layout":"row-spread","x":737,"y":290,"wires":[]},{"id":"e448c8b3.767028","type":"ui_iro-color-picker","z":"f08cc0eb.537d9","group":"18bbfd20.4a4073","order":2,"width":4,"height":5,"name":"Picker RGB 2","label":"","placement":"left","hAlign":"center","vAlign":"center","stateField":"payload","enableField":"enable","layoutDirection":"vertical","widgetIndent":"0","buttonWidth":"","pickerType":"widget","popupWidth":"","popupHeight":"","pickerSize":"100","backgroundDim":"50","backgroundColor":"#000000","backgroundVariable":false,"components":[{"options":{"borderColor":"#000000","borderWidth":1,"wheelLightness":false,"wheelAngle":0,"wheelDirection":"anticlockwise","minTemperature":3000,"maxTemperature":6000},"componentId":"picker"},{"options":{"borderColor":"#000000","borderWidth":1,"sliderType":"value","minTemperature":3000,"maxTemperature":6000},"componentId":"slider"}],"format":"hex","outFormat":"hsv","dynOutput":"input:move","outputConfirmed":false,"outputLimit":"10","passthru":false,"topic":"topic","topicType":"msg","iroColorValue":"#4fbe30","x":727,"y":570,"wires":[[]]},{"id":"30e59785.7459e8","type":"chroma","z":"f08cc0eb.537d9","name":"RGBW -> HSV","outFormat":"hsv","array2object":true,"floatOutput":true,"inputRelativeValues":"percent","outputRelativeValues":"percent","x":505,"y":442,"wires":[["d1fc8e03.69e13","126d102d.401aa","e448c8b3.767028"]]},{"id":"d1fc8e03.69e13","type":"ui_text","z":"f08cc0eb.537d9","group":"4879182a.6cee18","order":15,"width":0,"height":0,"name":"Chroma out HSV","label":"","format":"RGBW -> HSV: {{msg.payload}}","layout":"row-spread","x":736,"y":442,"wires":[]},{"id":"126d102d.401aa","type":"debug","z":"f08cc0eb.537d9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":697,"y":510,"wires":[]},{"id":"542b23a3.233c4c","type":"inject","z":"f08cc0eb.537d9","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"h\":173.07707038958318,\"s\":41.05263157894736,\"v\":74.50980392156863}","payloadType":"json","x":517,"y":570,"wires":[["e448c8b3.767028","126d102d.401aa"]]},{"id":"65ec2aaa.8c5a54","type":"link out","z":"f08cc0eb.537d9","name":"To MQTT","links":["4012c966.3f3bc8"],"x":442,"y":350,"wires":[]},{"id":"4012c966.3f3bc8","type":"link in","z":"f08cc0eb.537d9","name":"From MQTT","links":["65ec2aaa.8c5a54"],"x":134,"y":442,"wires":[["fdfabea1.d91e7","7c6f0790.ae4fd8"]]},{"id":"fdfabea1.d91e7","type":"debug","z":"f08cc0eb.537d9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":254,"y":493,"wires":[]},{"id":"7c6f0790.ae4fd8","type":"change","z":"f08cc0eb.537d9","name":"","rules":[{"t":"delete","p":"socketid","pt":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":304,"y":442,"wires":[["30e59785.7459e8"]]},{"id":"4879182a.6cee18","type":"ui_group","name":"Picker Test 1","tab":"1f10c1ab.3e668e","order":1,"disp":true,"width":"6","collapse":false},{"id":"18bbfd20.4a4073","type":"ui_group","name":"Picker Test 2","tab":"1f10c1ab.3e668e","order":2,"disp":true,"width":"6","collapse":false},{"id":"1f10c1ab.3e668e","type":"ui_tab","name":"RGBW Picker","icon":"dashboard","order":14,"disabled":false,"hidden":false}]
Simon01011 commented 3 years ago

Deleting the socketid does the trick!

I think you are right that MQTT deletes the socketid anyway. This issue catched my eye while doing a dry run first before messing everything up with a "open heart surgery" (is this a valid english idiom?) 😀

In the end the flow will look like in your case. So a change on the device web interface will immediately be broadcast by MQTT and thus shown on the dashboard as well.

Christian-Me commented 3 years ago

Fine that it works now ... Only be aware of the possible feedback loop (which could bring Node-RED down). image

Simon01011 commented 3 years ago

Yes, that's for sure a good idea to avoid this loop 😄

So it's up to you to decide if the socketid-issue is a bug or not, for me the problem is solved!

I have just another problem/question with the color conversion, but that relates to the chroma node. Eventually I will come back there later

Christian-Me commented 3 years ago

Fine, and if you have problems or questions with chroma ... all feedback welcome!

Simon01011 commented 2 years ago

Okay, tested with MQTT and it works without problems. So I close this 😃

Christian-Me commented 2 years ago

Hi just to let you know version 0.1.6 on github lets messages with ´msg.socketid´ pass. This results the emitting client will get its own message back but at the same is more stable and predictable updating the ui. I originally implemented this to avoid jumpy responses during continuous updates when a "old" value come back during scrubbing. But there is a second mechanism in place to ignore all messages arriving during mouse down state. Hope this works for all ;)