Replacing Values in Payload

I don't know if this is a question for here or a more programming forum. But since it's in Node-Red I thought I'd start here.

I have a function that started off checking for spaces in a value for a specific object in the payload and replacing them with an '_'. It works wonderfully (cause I stole ah, borrowed the code :wink: ) so I've repeated it a few times for some other values that also needed to be massage for the flow to work.

Now I need to add about 20 more. I know just enough about programming to be dangerous, but I do know that poor coding can impact performance and I'm wondering if there is a better, more efficient way to handle the replacing I need to do.

I'm taking a spoken input from rhasspy to set the thermostat to a specific temperature.

'Set the temperature to 21 degrees'.

Because of Phonetics, I've set the values (in Rhasspy) from Ten to Thirty (words not numeric) in half degree incriments. I've sorted out how to deal with 'point five' or 'and a half'.
Is there a better way to handle this statement without repeating it for each value?

In this example 'twenty' can be any degree value between Ten and Thirty, and '20' would be the corresponding numerical value of the written degree value.

if (msg.slots.degrees) {
    msg.slots.degrees = msg.slots.degrees.replace("twenty", "20");
}

I will be very surprised if you cannot find some code that will do that for you. Google something like
javascript words to numbers
Or possibly this might help, but I don't know how it copes with extra words in the string, if there are such in your case words-to-numbers - npm

maybe you could use an object
{one: 1,two:2,three:3 ......}
then look up the text key for the number.

var number = {one:2, two:2, twenty:20}
msg.payload = number[msg.payload]
return msg;
still learning myself but maybe an option

    {
        "id": "532160cadf9506de",
        "type": "function",
        "z": "a7b96b8807d3d0de",
        "name": "",
        "func": "var number = {one:1, two:2,twenty:20}\nmsg.payload = number[msg.payload]\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 690,
        "y": 500,
        "wires": [
            [
                "0f09da12afbb4b06"
            ]
        ]
    },
    {
        "id": "660766a1e94af014",
        "type": "inject",
        "z": "a7b96b8807d3d0de",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "one",
        "payloadType": "str",
        "x": 500,
        "y": 460,
        "wires": [
            [
                "532160cadf9506de"
            ]
        ]
    },
    {
        "id": "6e68a599ae90fff6",
        "type": "inject",
        "z": "a7b96b8807d3d0de",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "two",
        "payloadType": "str",
        "x": 510,
        "y": 520,
        "wires": [
            [
                "532160cadf9506de"
            ]
        ]
    },
    {
        "id": "40aa9f89e9b1d9da",
        "type": "inject",
        "z": "a7b96b8807d3d0de",
        "name": "",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "twenty",
        "payloadType": "str",
        "x": 510,
        "y": 580,
        "wires": [
            [
                "532160cadf9506de"
            ]
        ]
    },
    {
        "id": "0f09da12afbb4b06",
        "type": "debug",
        "z": "a7b96b8807d3d0de",
        "name": "",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 860,
        "y": 500,
        "wires": []
    }
]```

You could try something like this

[{"id":"792ba474.9ffa84","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"slots.degrees","v":"Set the temperature to Twenty five point five degrees","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":190,"y":40,"wires":[["93e7cdb6.9408"]]},{"id":"93e7cdb6.9408","type":"function","z":"b779de97.b1b46","name":"","func":"const lookup = { // add more lookups for other numbers\n    \"twenty\": 20, \n    \"five\": 5,\n    \"one\": 1, \n    \"point five\": 0.5,\n    \"and a half\": 0.5\n};\nlet pattern = RegExp(Object.keys(lookup).join(\"|\"), \"gi\")\nlet look_up_keys = msg.slots.degrees.match(pattern);\nlet sum = look_up_keys.reduce((a,v) => a+lookup[v.toLowerCase()],0);\nmsg.payload = msg.slots.degrees.replace(look_up_keys.join(\" \"), sum);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":340,"y":40,"wires":[["5b7b3dbe.2f2e4c"]]},{"id":"5b7b3dbe.2f2e4c","type":"debug","z":"b779de97.b1b46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":830,"y":40,"wires":[]}]
const lookup = { // add more lookups for other numbers
    "twenty": 20, 
    "five": 5,
    "one": 1, 
    "point five": 0.5,
    "and a half": 0.5
};
let pattern = RegExp(Object.keys(lookup).join("|"), "gi")
let look_up_keys = msg.slots.degrees.match(pattern);
let sum = look_up_keys.reduce((a,v) => a+lookup[v.toLowerCase()],0);
msg.payload = msg.slots.degrees.replace(look_up_keys.join(" "), sum);
return msg;

input Set the temperature to twenty five point five degrees
output Set the temperature to 25.5 degrees
[edit] edited to allow lower and upper case
[edit] and punctuation

const lookup = { // add more lookups for other numbers
    "one hundred": 100,
    "ninety": 90,
    "eighty": 80,
    "seventy": 70,
    "sixty":60,
    "fifty": 50,
    "fourty": 40,
    "thirty": 30,
    "twenty": 20,
    "nineteen": 19,
    "eightteen": 18,
    "seventeen": 17,
    "sixteen": 16,
    "fifteen": 15,
    "fourteen": 14,
    "thirteen": 13,
    "twelve": 12,
    "eleven": 11,
    "ten": 10,
    "nine": 9,
    "eight": 8,
    "seven": 7,
    "six": 6,
    "five": 5,
    "four": 4,
    "three": 3,
    "two": 2,
    "one": 1, 
    "point five": 0.5,
    "a half": 0.5,
};

let pattern = RegExp(Object.keys(lookup).join("|"), "gi")
let look_up_keys = msg.slots.degrees.match(pattern);
let sum = look_up_keys.reduce((a,v) => a+lookup[v.toLowerCase()],0);
pattern = look_up_keys.length > 1 ? [look_up_keys[0],look_up_keys[look_up_keys.length-1]].join(".*") : look_up_keys[0];
pattern = RegExp(pattern);
msg.payload = msg.slots.degrees.replace(pattern, sum);
return msg;
1 Like

@E1cid
It's like magic. Even when I understand the regex it's still magical when it works.
And work it does!

I noticed you set the output to msg.payload. Is that proper form? I've been changing the value of slots.degrees.

example using your code

msg.slots.degrees = msg.slots.degrees.replace(look_up_keys.join(" "), sum);

Glad it helped.

I set it to msg.payload as i'm lazy and did not wish to edit the debug node. You can set it to any msg property you wish.

@E1cid

Ah, excellent. I didn't want to be mucking about changing things that shouldn't be changed.

Anyways Thank You!

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