parseFloat() return as it want value and NaN

Hello everybody, thanks about this forum, it's a nice node red encyclopedia :wink:

Generaly, i understand what i do, i can pass 1min, 1hour, 1days and more when i meet a problem but now, madness begins ...

Consider this function. I receive from my IoT an ASCII message like this : "02h05m3h".

I juste want to convert this ascii chain to 3 numbers in an array, using parseFloat() function.

var o;
var raw = {};
var ascii = {};
var splited;

o = msg.payload;

//test if there is valid raw data
if(o[0] === 2) //is a conf rawdata
{
    raw.topic = "RAM";
    raw.enabled = false; //Disable button
    raw.payload = msg.payload;
    return [raw,null];
}
else if(o[0] < 1 || 2 < o[0]) //is a ascii data ?
{
    ascii.topic = "RAM";
    ascii.enabled = false; //Disable button
    ascii.payload = msg.payload;[/code]
    
    splited = String(o); //toString
    splited = splited.replace(/[a-z]/g,":");// replace all lowercase to ':'
    splited = splited.split(":");           // Split

    for(var i=0; i<splited.length; i++)
    {
        splited[i] = parseFloat(splited[i]);// convert char to number
    }
    msg.payload = splited;
    return [null,msg];
}

It return me :

msg.payload : array[4]
[ 2, 5, NaN, NaN ]

Where is 3 number ?

However, if i send my payload just after spliting, i have this :

msg.payload : array[4]
[ "02", "05", "3", "" ]

Maybe a bad type ... but what i missed ?

Thank you very much :smile:

Another approach would be to use Date.parse like this: Parse Time HH:mm:ss without date in javascript

Edit: this function seems to work:

var regex_tx = /(\d*)h(\d*)m(\d*)h/;

const m = msg.payload.match(regex_tx);    
var res = [];
for (var n = 1; n < m.length; n++) {
 res.push(Number(m[n]));
}
msg.payload = res
return msg;

Thank you for you answer. The problem is, i can receive negative ascii value like "-2", and i understand that only parseFloat() can do this convertion.

I add that i've tried also with parseInt() and Number(), it return me the same NaN at the same position :thinking:

Ok i just post without seen your code :smile:

Then you adjust your regexp like

var regex_tx = /(-*\d*)h(-*\d*)m(-*\d*)h/;

It doesn't matter whether you use Number() or parseFloat(), it gives you the "-2"

Ok i tested you code. Below :smile:

var o;
var raw = {};
var ascii = {};

o = msg.payload;

/* test if there is valid raw data */
if(o[0] === 2) //is a conf rawdata
{
    raw.topic = "RAM";
    raw.enabled = false; //Disable button
    raw.payload = msg.payload;
    return [raw,null];
}
else if(o[0] < 1 || 2 < o[0]) //is a ascii data ?
{
    ascii.topic = "RAM";
    ascii.enabled = false; //Disable button
    ascii.payload = msg.payload;
    
    //splited = String(o);
    var regex_tx = /(\d*)h(\d*)m(\d*)h/;
    const m = msg.payload.match(regex_tx);
    var res = [];
    for (var n = 1; n < m.length; n++)
    {
        res.push(Number(m));
    }
    msg.payload = res

    return [null,msg];
}

I have this error :

TypeError: msg.payload.match is not a function

I think i must to String() before, but where ?

Almost my code, there is the index missing in the loop :wink:

Instead of msg.payload you have to use your string. In my case the string was directly in msg.payload, because I used an inject node. Maybe replace

const m = msg.payload.match(regex_tx);

with

var SomeString = String(o);
const m = SomeString match(regex_tx);

But that's just a guess. Please feed your input in the debug node and show what it says

:dizzy_face:

Well, here is the input (from my device) :

buffer[10][string]
03h10m  5h

or

msg.payload : buffer[10]
[ 48, 51, 104, 49, 48, 109, 0, 0, 53, 104 ]

You can see 2 spaces ... i will to fix it now.

The fonction node code now is :

var o;
var raw = {};
var ascii = {};

o = msg.payload;

/* test if there is valid raw data */
if(o[0] === 2) //is a conf rawdata
{
    raw.topic = "RAM";
    raw.enabled = false; //Disable button
    raw.payload = msg.payload;
    return [raw,null];
}
else if(o[0] < 1 || 2 < o[0]) //is a ascii data ?
{
    ascii.topic = "RAM";
    ascii.enabled = false; //Disable button
    ascii.payload = msg.payload;

    var regex_tx = /(\d*)h(\d*)m(\d*)h/;

    var SomeString = String(o);
    const m = SomeString.match(regex_tx);    
    var res = [];
    for (var n = 1; n < m.length; n++)
    {
        res.push(Number(m[n]));
    }
    
    msg.payload = res

    return [null,msg];
}

And i have this error at the output :

TypeError: Cannot read property 'length' of null

now i am completely lost

First thing: it's a buffer, use

var SomeString = o.toString();

Second thing: if you have spaces in the string, your regexp should be

/\s*(-*\d*)h\s*(-*\d*)m\s*(-*\d*)h/;

Regexps are a wonderful thing :grin:

Edit: why do you parse for floats if you apparently only have ints?

Ok i'm trying that.

I used parseFloat because understood that only this function convert for example "-10"
But if Number do that !

Ok i have change te code as you told me, i have always this error of type. Why length is a problem now ?
Also have deleted bad space from my device...

Assuming that it is that line that generating the error then it means that m is null.

Read the node-red docs page on Writing Functions and it will tell you how you can use node-warn to display values from within your function. You can add node.warn() statements at appropriate points to see what is going on.

As Colin said:

Something with your string that you are trying to "match" is wrong, so there is no match and the array m is null. So output the string before the match and see what's wrong

Hi!

Yesterday i have undersatnd the problem, thanks Simon01011 to shown me the way.

My electronics card send some data to red node, some time in ASCII or RAW data. I have designed a "terminal" to display commands sent or received with a text node. But, spaces characters sent by my IoT are ignored, because those value is 0x00 (not really a space char).
So by looking the input data, i've seen that IoT sent, for example if an ascii number 1 to send (has not hundred or ten), 001. Or another like -1 will viewed in debug node as - 1.

So, Number() can't process this last one and return un NaN. Same with parseFloat().

I keep preciously you code but it's more hard for me. So i have retryed my first code above, i have modified my firmware of my IoT and deleted excess 0x00 chars, and everythings is ok.

Thank you very much everybody :smile:

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