How to convert array byte to ASCII

Guys Happy new year!

I working in my device and need to decode a array byte to ASCII stream, like you can see below:

image

I using let param1 = msg.payload[28], for example to get a byte.
I need to create a variable that will have within the word derived from the byte sequence of the buffer.

in my PIC above, as example, the array bytes becomes in the word RWL020.
0x52, 0x57, 0x4c, 0x30, 0x32, 0x30 => RWL020

Anybody can help, please?

Best Regards,
Alex

add this to a function node and see if it works

msg.payload = Buffer.from(msg.payload);
msg.payload = msg.payload.toString();
return msg;

Hi zenofmud,
I did it but is not working, as you can see in part of my code below:

if(msg.payload[26]!=2){		
	
}else{
																						let a = msg.payload[27];
let attriblengthb2 = (a^0x10).toString(16).padStart(2,"0");
}
let stream = msg.payload[28].toString();
msg.payload = Buffer.from(msg.payload[28]);
msg.payload = msg.payload.toString();
return msg;
																									//let str = String.fromCharCode(parseInt(stream.substr(i, 2), 16));
																									//return str;
																							}

image

I tried to use also ~~~ String.fromCharCode(parseInt(stream.substr(i, 2), 16)); ~~~
But is not working also. You can see PIC below:

image

Do you have any idea how to fix it?

Please attach a debug node - set to display the complete msg object - to the node generating the array. Then copy and past the debug output.

Also - try commenting out all your code in the function so just the lines i gave you remain - what result do you get?

Could be done with this code in a function node:

msg.payload = String.fromCharCode(0x52, 0x57, 0x4c, 0x30, 0x32, 0x30);
return msg;

Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode

Hi Paul,
As you requested me, you can see below the debug message error after i comment out my code:

image

Best Regards,
Alex

Hi Andrei,
thanks.
now is working well to get one byte.

my code using buffer component:

let stream = msg.payload[32];		
msg.payload = String.fromCharCode(stream);
return msg;

image

I would like to create a word, as example RWL020, from the specific buffer positions.I have a byte that content the byte stream length, Would you can advise me the best way to do it?

@aargollo I wanted to see the data going into the function which is why I asked to connect the debug to the node generating the array.

In such case fallback to @zenofmud solution, :joy:

The only point is that you need to know the start and the end for the extraction. Only knowing how many bytes to extract from the buffer won't be useful, right?

I amended Paul´s solution to include your latest requirement. You can test code below inside a function node. Use different values for start and end for the testing. I am assuming you will input in the function a buffer inside msg.payload

function sliceBuf(buf, start, end) {
    return buf.toString("ascii").slice(start,end);
}

msg.sliced = sliceBuf(msg.payload,21,25);
return msg;

r-01

1 Like

Hi Paul and Zenofmud!
Working well like Swiss clock! :slight_smile:
Thanks you for the help you and Zenofmud gave me!

Best Regards
Alex

Hi All, I saw this post and was wondering if you could help me build a function node that will convert a number in decimal format to its ASCII equivalent? I think it has something to do with "charCodeAt" but I am not sure.

Put a debug node showing the data you are receiving and post the output here. Also tell us exactly what you would like to see it converted to.

Greetings,

I thought I would revive this topic rather than starting a new one. This topic has a number of similarities to the problem I am trying to solve, so I hope I can find a solution here. In a nutshell, I am querying a solar inverter via TCP and receiving a hex output.

Here's my issue... I have inserted the function provided by zenofmud and am receiving an ascii like output. Here's what zenofmud provided:

msg.payload = Buffer.from(msg.payload);
msg.payload = msg.payload.toString();
return msg;

Here's the hex output received from the solar inverter via debug:-

[0 … 9]
0: 0x7b
1: 0x30
2: 0x31
3: 0x3b
4: 0x46
5: 0x42
6: 0x3b
7: 0x32
8: 0x39
9: 0x7c
[10 … 19]
10: 0x36
11: 0x34
12: 0x3a
13: 0x4b
14: 0x44
15: 0x59
16: 0x3d
17: 0x35
18: 0x3b
19: 0x4b
[20 … 29]
20: 0x54
21: 0x30
22: 0x3d
23: 0x35
24: 0x32
25: 0x44
26: 0x43
27: 0x3b
28: 0x50
29: 0x41
[30 … 39]
30: 0x43
31: 0x3d
32: 0x32
33: 0x34
34: 0x41
35: 0x7c
36: 0x30
37: 0x38
38: 0x45
39: 0x38
[40 … 40]
40: 0x7d

After inserting zenofmud code into a function I received the following via debug:-

{01;FB;29|64:KDY=5;KT0=52DC;PAC=24A|08E8}

Only issue, it seems to me some of the numbers are still in hex? These are the ones I am concerned about... KT0=52DC and PAC=24A which I am led to beleive should be numbers. Here's a post I used for reference. Domoticz Forum Post

So my question... is there a further function I can use to convert the KTO and PAC output to a number? Or is the conversion from hex to ascii correct?

None of the values you see are strictly Numbers, they are characters representing digits. For example the "01" on the front is actually two characters, "0" and "1". The string "52DC" presumably represents the hexadecimal value 0x52DC in exactly the same way as the "01" represents the decimal number 1 (presumable). It is just that one is in base 16 and one is in base 10.

So if you want any of them as Numbers you are first going to have to split up the string and then convert them to numbers. Whether you actually need to do that depends on what you want to do with the data, so if you give us some more information on that it will be easier to suggest the best route to take.

Hi Colin,

Thank you for the reply. Let me step back and give you a bigger picture of what I am trying to achieve.

As you know from my previous post I have a SolarMax Inverter, which right now utilises software called MaxTalk to display the inverter statistics. The MaxTalk software connects to the inverter via an ethernet network TCP connection.

The MaxTalk is an isolated solution and will not as far as I am aware interface with either Mosquitto MQTT or Node-Red, therefore I've chosen to try and connect directly to the inverter from Node-Red. As per my previous post I have successfully connected to the inverter from node-red but not sure the data is in the correct format?

Once I have the data in an understandable format I want to 'massage' into a format that can be shared with the Blynk application, which I currently use with other data I collect through Mosquitto and Node-Red. The interface with Blynk is working great, so the addition of the inverter data would be great.

Hope this helps explain the situation and my intent. If there's any additional information you require please let me know. I really appreciate any help/advice from the members of this forum.

Thanks, Mark

What format do you want it in? Take the example data you posted and show us what you would like to get out. Presumably you want a javascript object in msg.payload, but what exactly do you want the example you posted to be converted to?

Hi Colin,

I am expecting Node-Red to send the following parameters to Blynk, that being the KDY and KT0 parameters, which I expect to be whole numbers... such as...

KDY = energy today (kWh) so a whole number representing the kilowatt hours, which 24A is not correct because it is not a whole number?

Likewise...

KT0 = energy total (kWh) I am expecting a number representing the kilowatt hours, which 52DC is not a whole number?

Here are several outputs from the debug in NodeRed...

{01;FB;29|64:KDY=5;KT0=52DC;PAC=24A|08E8}
{01;FB;2A|64:KDY=6B;KT0=52F3;PAC=580|091B}
{01;FB;2A|64:KDY=6C;KT0=52F3;PAC=598|0925}

You may notice that KT0 and KDY are sometimes numbers, and other times numbers and letters?

So, in a nutshell, I am expecting the output from the inverter to be 'massaged' somehow so it is an actual number, and not a combination of numbers and letters.

This LINK here shows how the inverter protocol was reverse engineered and provides a list of parameters (the output is shown as numbers... so not sure why I am seeing letters and numbers?)

The link above also provides a LINK to a PERL Script, but unfortunately I am not a Perl programmer, so not sure what is being done to the data from the inverter to change the output to pure numbers. I suspect a Perl programmer would probably solve the mystery easily.

From the link above they provide examples... which shows numbers without letters:-
Energy today [Wh] (KDY): 12900
Energy total [kWh] (KT0): 6356

Hope this is clear? Let me know.

Thanks, Mark

Well it seems the first thing you need to do is to find out what the values like 52DC and 24A mean. To find that out you will presumably have to go back to the source of the data. Perhaps they are hexadecimal numbers, in which case are they just hexadecimal integers or what?

Once you know that then you can go about splitting the string up, probably by writing some javascript in a function node. You can start by using the javascript split() function to split it up on the semicolons.

Hi Colin,

I have been doing some digging and a generous gentleman George at Ardexa gave me the following python code...

# If its a voltage reading or frequency, divide by 10 to get Volts
# Same for "energy today"
elif key in ('UL2', 'UL1', 'UL3', 'KDY', 'UD01', 'UD02', 'UD03'):
    value_int = int(value, 16)
    value_fl = float(value_int)/10.0
    retval = str(value_fl)

The code from George starts around line 137 at this link... https://github.com/ardexa/solarmax-inverters/blob/master/solarmax_ardexa.py

So it would appear from my limited knowledge the value needs to be converted from an integer to a float value, or multiplied by 10? Unfortunately I am no python coder, so perhaps someone on here is skilled in that area and can tell me what is happening in the code?

Your example has KDY=6C; KT0=52F3 Those are hexadecimal numbers which are the equivalent of 108 and 21235 in decimal. If those are 10 times the required answer then that would give 10.8 and 2123.5. Are those the correct values? I notice that KT0 is not mentioned in the code snippet you posted.