2

I have flow for controling WS2812b strip. I'm using switch which is sending Boolean variable to following function where im getting global variable where im storing current color in HSL. After switching off(false) script load current color and change "L" to 0 (working), but when i switch it on again (true) it get again L=0 even if im not changing it anywhere.

if(msg.payload === false)
{
    col = global.get("color");
    col.l = 0;
}

if(msg.payload === true)
{
    col = global.get("color");
}
msg.payload = col;
return msg;

Flow:

[{"id":"79df9203.a409ec","type":"tab","label":"Obyvací pokoj","disabled":false,"info":""},{"id":"431fac94.09cba4","type":"mqtt out","z":"79df9203.a409ec","name":"","topic":"/TV_LED/cmd","qos":"","retain":"","broker":"e17662db.a0a03","x":1100,"y":140,"wires":[]},{"id":"a31190b1.8af6c","type":"function","z":"79df9203.a409ec","name":"hsl > neopixel","func":"var hslToRgb = function(hue, saturation, lightness){\n  // based on algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV#Converting_to_RGB\n  if( hue == undefined ){\n    return [0, 0, 0];\n  }\n\n  var chroma = (1 - Math.abs((2 * lightness) - 1)) * saturation;\n  var huePrime = hue / 60;\n  var secondComponent = chroma * (1 - Math.abs((huePrime % 2) - 1));\n\n  huePrime = Math.floor(huePrime);\n  var red;\n  var green;\n  var blue;\n\n  if( huePrime === 0 ){\n    red = chroma;\n    green = secondComponent;\n    blue = 0;\n  }else if( huePrime === 1 ){\n    red = secondComponent;\n    green = chroma;\n    blue = 0;\n  }else if( huePrime === 2 ){\n    red = 0;\n    green = chroma;\n    blue = secondComponent;\n  }else if( huePrime === 3 ){\n    red = 0;\n    green = secondComponent;\n    blue = chroma;\n  }else if( huePrime === 4 ){\n    red = secondComponent;\n    green = 0;\n    blue = chroma;    \n  }else if( huePrime === 5 ){\n    red = chroma;\n    green = 0;\n    blue = secondComponent;\n  }\n\n  var lightnessAdjustment = lightness - (chroma / 2);\n  red += lightnessAdjustment;\n  green += lightnessAdjustment;\n  blue += lightnessAdjustment;\n  \n    return {\n        r: Math.round(red * 255),\n        g: Math.round(green * 255),\n        b: Math.round(blue * 255)\n    };\n}\nnode.warn(msg.payload);\nmsg.payload = hslToRgb(msg.payload.h,msg.payload.s,msg.payload.l);\nmsg.payload = \"Neopixelall,\"+msg.payload.r+\",\"+msg.payload.g+\",\"+msg.payload.b;\nreturn msg;\n\n","outputs":1,"noerr":0,"x":920,"y":140,"wires":[["431fac94.09cba4"]]},{"id":"5e030bab.a9e354","type":"mqtt in","z":"79df9203.a409ec","name":"","topic":"/TV_LED/color","qos":"2","broker":"e17662db.a0a03","x":300,"y":340,"wires":[["d5993f0b.74a52"]]},{"id":"d5993f0b.74a52","type":"ui_text","z":"79df9203.a409ec","group":"aec2f80b.a31aa8","order":5,"width":0,"height":0,"name":"","label":"Stored color:","format":"{{msg.payload}}","layout":"row-spread","x":490,"y":340,"wires":[]},{"id":"30c421ea.7900fe","type":"mqtt in","z":"79df9203.a409ec","name":"","topic":"/TV_LED/color","qos":"2","broker":"e17662db.a0a03","x":160,"y":140,"wires":[["90df2140.97555"]]},{"id":"4ac39175.f01b8","type":"mqtt out","z":"79df9203.a409ec","name":"","topic":"/TV_LED/color","qos":"","retain":"true","broker":"e17662db.a0a03","x":1100,"y":100,"wires":[]},{"id":"c2735b8.0f402a8","type":"link out","z":"79df9203.a409ec","name":"LED_TV","links":["5db90cc7.188e14"],"x":735,"y":120,"wires":[]},{"id":"5db90cc7.188e14","type":"link in","z":"79df9203.a409ec","name":"","links":["c2735b8.0f402a8"],"x":775,"y":120,"wires":[["a31190b1.8af6c","e53fc48c.f09088"]]},{"id":"90df2140.97555","type":"function","z":"79df9203.a409ec","name":"string>light","func":"msg.payload= JSON.parse(msg.payload);\nglobal.set(\"color\",msg.payload);\n\nmsg.payload = msg.payload.l;\nreturn msg;\n","outputs":1,"noerr":0,"x":330,"y":140,"wires":[["5dec6394.05474c"]]},{"id":"5dec6394.05474c","type":"ui_slider","z":"79df9203.a409ec","name":"","label":"Lightness","tooltip":"","group":"aec2f80b.a31aa8","order":5,"width":0,"height":0,"passthru":false,"outs":"end","topic":"","min":0,"max":"1","step":"0.1","x":480,"y":140,"wires":[["47416ab5.d30f44"]]},{"id":"f0d4dbfb.267d68","type":"ui_colour_picker","z":"79df9203.a409ec","name":"","label":"","group":"aec2f80b.a31aa8","format":"hsl","outformat":"object","showSwatch":true,"showPicker":false,"showValue":false,"showHue":false,"showAlpha":false,"showLightness":false,"dynOutput":"false","order":8,"width":0,"height":0,"passthru":true,"topic":"","x":470,"y":80,"wires":[["c2735b8.0f402a8"]]},{"id":"e53fc48c.f09088","type":"function","z":"79df9203.a409ec","name":"not black","func":"if(msg.payload.l !== 0)\n    return msg; \n","outputs":1,"noerr":0,"x":900,"y":100,"wires":[["4ac39175.f01b8"]]},{"id":"94fe53c2.444ea","type":"ui_switch","z":"79df9203.a409ec","name":"","label":"On / Off","tooltip":"","group":"aec2f80b.a31aa8","order":8,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","x":480,"y":240,"wires":[["1a00a4b.e0dbe5b"]]},{"id":"47416ab5.d30f44","type":"function","z":"79df9203.a409ec","name":"light>hsl","func":"var col = global.get(\"color\");\ncol.l = msg.payload;\nmsg.payload = col;\nreturn msg;\n","outputs":1,"noerr":0,"x":620,"y":140,"wires":[["c2735b8.0f402a8"]]},{"id":"1a00a4b.e0dbe5b","type":"function","z":"79df9203.a409ec","name":"light off","func":"if(msg.payload === false)\n{\n    col = global.get(\"color\");\n    col.l = 0;\n}\n    \nif(msg.payload === true)\n{\n    col = global.get(\"color\");\n}\nmsg.payload = col;\nreturn msg;","outputs":1,"noerr":0,"x":620,"y":240,"wires":[["c2735b8.0f402a8"]]},{"id":"e17662db.a0a03","type":"mqtt-broker","z":"","name":"Broker","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"aec2f80b.a31aa8","type":"ui_group","z":"","name":"LED - TV","tab":"5b27353d.d34fbc","order":3,"disp":true,"width":"4","collapse":false},{"id":"5b27353d.d34fbc","type":"ui_tab","z":"","name":"Obývací pokoj","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

EDIT: I don't know if this is correct behavior of JS but here is small debug:

    col = global.get("color");
    global.set("ori_color",col);
    node.warn(global.get("ori_color")); //1
    col.l = 0;
    node.warn(global.get("ori_color")); //2
    msg.payload = col;

Debug: 1) H: 300, S: 1, L:0.5 2) H: 300, S: 1, L:0

So it basically retrospectively change global variable trough col variable.. wierd

  • Are you saying the "Stored colour" UI never changed accordingly? As far as this function, it seems to be correct. I noticed that your `not black` function only publish the mqtt subject only if the `msg.payload.l` is not 0, so the "Stored colour" display never change even after the `global.set()`. – hcheung Feb 10 '19 at 02:44
  • Example: 1) pick color from picker..let's say H: 300 S:1 L:0.5 > in mqtt is color stored as expected and stored in global variable, LED strip goes on as expected. 2) Switch "off" > stored color stay unchanged because it will not go throw "not black" function, LED strip goes off 3) Switch "on" > now function have to take original color with L:0.5 from global variable, BUT it take L:0 and strip keep off... So it looks like during switching off is somehow stored global variable overwrited and I don't know how or where .. – Karel Sniper Žák Feb 10 '19 at 11:40

1 Answers1

0

In JavaScript objects are passed and assigned by reference. That mean you have to assign new object to col variable (make copy).

if(msg.payload === false)
{
    var col = Object.assign({}, global.get("color"));
    col.l = 0;
    msg.payload = col;
}
else
    col = global.get("color");

msg.payload = col;
return msg;