`Range` node setting values from variables

I am wanting to use a range node but the scales need to be set by external values.

I don't mind doing all this with a function node, but thought I would ask.

(map is the command to basically do what the range node does)
(Ok, no it isn't the command.)
scale? index?

The help for the Range node tells you what properties it responds to.

In this instance, you'll see it only uses msg.payload - there is no way to configure its behaviour using message properties.

1 Like

I thought so.

So I am going to have to make a function node to do the work - yes?
Now I'm stuck on what the command is to do what the node does.

It depends on which mode of the Range node you're interested in, but you can see the code for the basic range function here: https://github.com/node-red/node-red/blob/master/packages/node_modules/@node-red/nodes/core/function/16-range.js#L43

Where n is the value being ranged (ie msg.payload), and the min/max of the input range is specified by node.minin and node.maxin and the output range is node.minout and node.maxout

1 Like

Thanks, that sounds like the node at which I am looking.

Was trying to find the complete name and look at the code, but hadn't found the name before you replied.

Thanks again.

From the code in the link, I tried to reverse engineer the maths.

This is a test flow which is not quite cutting it.

[{"id":"692eb68e.19b71","type":"function","z":"3caae529.4226aa","name":"","func":"var maxin = parseInt(msg.maxin);\nvar minin = parseInt(msg.minin);\nvar maxout = parseInt(msg.maxout);\nvar minout = parseInt(msg.minout);\nvar x = parseInt(msg.payload);\n\nvar divisor = maxin - minin;\nvar n = ((x - minin) % divisor + divisor) % divisor + minin;\n\nvar value = ((n - minin) / (maxin - minin) * (maxout - minout)) + minout;\n\nmsg.payload = value;\n\n\n\n\nreturn msg;","outputs":1,"noerr":0,"x":570,"y":1530,"wires":[["600b5a5e.b66c14"]]},{"id":"e3295788.2fa6d","type":"change","z":"3caae529.4226aa","name":"Limits","rules":[{"t":"set","p":"maxin","pt":"msg","to":"10","tot":"num"},{"t":"set","p":"minin","pt":"msg","to":"1","tot":"num"},{"t":"set","p":"maxout","pt":"msg","to":"100","tot":"num"},{"t":"set","p":"minout","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":420,"y":1530,"wires":[["692eb68e.19b71"]]},{"id":"600b5a5e.b66c14","type":"debug","z":"3caae529.4226aa","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":740,"y":1530,"wires":[]},{"id":"fdeff99.4adb008","type":"inject","z":"3caae529.4226aa","name":"","topic":"","payload":"1","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1470,"wires":[["e3295788.2fa6d"]]},{"id":"d2bb109f.59a5f8","type":"inject","z":"3caae529.4226aa","name":"","topic":"","payload":"2","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1510,"wires":[["e3295788.2fa6d"]]},{"id":"6107f5ed.008bfc","type":"inject","z":"3caae529.4226aa","name":"","topic":"","payload":"3","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1550,"wires":[["e3295788.2fa6d"]]},{"id":"ae397d2f.9cb35","type":"inject","z":"3caae529.4226aa","name":"","topic":"","payload":"7","payloadType":"num","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240,"y":1590,"wires":[["e3295788.2fa6d"]]}]

The important stuff is in the function node - of course.
The rest is just showing how I test it, and to have all cards on the table.

Thanks again in advance.

Which mode of the Range node are you trying to replicate?

The one which comes in NR as a stock node.....

I don't know how to get it's full name.

This one. If that is any help.

Yes, I know which node you are talking about - I pointed you at its source code.

The node offers three different options for its behaviour:


Yes, but I want to adjust the maxin maxout minin and minout values.

And after looking at it again and changing the minout value in the flow I posted, I think it does what I want.
I stupidly had the values set as:
minin 1
maxin 10
minout 1
maxout 100

When minout should be 10 for simple translation.

It isn't crucial (well it probably will be because I said it won't be) it is just for testing something else.

I understand you want to change the range values, but without know what type of range function you want, we cannot help you get the algorithm right.

But it sounds like you've figured it out yourself.

Yes, and again: I am sorry, I also mis-parsed your saying:

The node offers three different options for its behaviour:

I didn't understand what that means/meant.

What have you got in your function node now?

Sorry, it isn't that simple.

The idea is that I get the temperature and range that to control the colour of a NeoPixel LED.

Alas I can't post the flow/code because the machine is now shut down.

If you want next time I have it turned on, I could copy/pate it for you.

I was just interested in the function node you have built that emulates a Range node but with variable range.

Ok, this is what it is....

Given it receives the temperature and it is sending a message for a Neopixel LED.

[{"id":"5429065c.0700c","type":"change","z":"3caae529.4226aa","name":"Limits","rules":[{"t":"set","p":"minin","pt":"msg","to":"FanStop","tot":"global"},{"t":"set","p":"maxin","pt":"msg","to":"shutdown_temperature","tot":"global"},{"t":"set","p":"minout","pt":"msg","to":"30","tot":"num"},{"t":"set","p":"maxout","pt":"msg","to":"255","tot":"num"},{"t":"set","p":"Temperature_LED","pt":"msg","to":"Temperature_LED","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":590,"wires":[["eeef5cd5.74fb2"]]},{"id":"eeef5cd5.74fb2","type":"function","z":"3caae529.4226aa","name":"Scale for colour","func":"var maxin = parseInt(msg.maxin);\nvar minin = parseInt(msg.minin);\nvar maxout = parseInt(msg.maxout);\nvar minout = parseInt(msg.minout);\nvar x = parseInt(msg.payload);\n\nif (msg.payload < minin)\n{\n    msg.payload = 0;\n    return msg;\n}\n\nvar divisor = maxin - minin;\nvar n = ((x - minin) % divisor + divisor) % divisor + minin;\n\nvar value = parseInt(((n - minin) / (maxin - minin) * (maxout - minout)) + minout);\n\nmsg.payload = value;\n\n//msg.Temperature_LED = flow.get(\"Temperature_LED\");\n\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":540,"wires":[["d1bb6aed.c23948"]]}]

Though I don't think that part is in this bit.

OK, thanks. I see you are using it like a Range node in wrap-around mode. There is a very small efficiency saving you could make by using divisor rather than maxin-minin in line 16.

Well, I looked at the link @knolleary gave me.

I am a bit happy with myself in that I back engineered the maths to get the desired result.

I may look at it later.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.