Format payload string

Hi all,

I am receiving a string which I want to format and extract only some information from it.
This is the string I am receiving:

openWB/system/Uptime : msg.payload : string[67]

" 12:31:14 up 15 days, 16:38, 1 user, load average: 1,03, 1,48, 1,40"

this is what I want to get from the string (bold)
" 12:31:14 up 15 days, 16:38, 1 user, load average: 1,03, 1,48, 1,40"

In a python module, I am using this for the format... now I need to translate this into a node-red function...

            # Reformat uptime sensor
            if "uptime" in self.entity_id:
                days = self._attr_native_value[12:].split(',')[0][:-5]
                hourmins = self._attr_native_value[12:].split(',')[1]
                hours = hourmins[1:].split(":")[0]
                mins = hourmins[2:].split(":")[1]
                self._attr_native_value = days + " d " + hours + " h " + mins + " min"

Any Idea on how I can do this?
Thanks :slight_smile:

let text = " 12:31:14 up 15 days, 16:38, 1 user, load average: 1,03, 1,48, 1,40";
const myArray = text.split(" ");  // lets make a array

payload =  myArray[3]  + "  " + myArray[4] + " - " + myArray[5];
1 Like

Hi, thanks :slight_smile:
That worked - unfortunately, only until a reboot.

I haven't recognized, that the "15 days" will not be available after rebooting the system :frowning:

So the string is now

" 09:09:04 up 12:33, 1 user, load average: 0,75, 0,65, 0,89"

and therefore, the split does not work properly.

I would like to split the string into sections like:

[0] days
[1] hours
[2] minutes

so the above example should be: 0 days, 12 hours, 33 mins
or the previous example should be 15 days, 16 hours, 38 mins

Is there a way on how I could remove the first 12 characters which would be the " 12:31:14 up in the example?
Then, the next thing is that x days will have another comma before were the hours and mins are comming, but not when there are no days available....

" 12:31:14 up 15 days, 16:38, 1 user, load average: 1,03, 1,48, 1,40"
" 09:09:04 up 12:33, 1 user, load average: 0,75, 0,65, 0,89"

sorry - I beleive that's a very basic thing ... but somehow, I can't figure it out at the moment :frowning:

The string you are receiving looks like the output from the uptime command.

There is an option uptime -p which seems to give exactly the info you are trying to extract

Hi,
thank you!
Yes, that's the uptime information from a System - but I don't know, if I can use the command.

I am receiving this from my EV Charger over MQTT... So I don't know If I can use any command options here.

Here is a workaround using regex...

Output ...
image

Demo Flow...

[{"id":"9642e02504fb2aa8","type":"inject","z":"10ece3ab98e93683","name":"not long after boot","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"not long after boot","payload":" 09:09:04 up 12:33, 1 user, load average: 0,75, 0,65, 0,89","payloadType":"str","x":750,"y":320,"wires":[["c9a8809a05ef5f05"]]},{"id":"c9a8809a05ef5f05","type":"function","z":"10ece3ab98e93683","name":"extract time parts","func":"if(/(\\d{2}:\\d{2}:\\d{2}) up (\\d{2}:\\d{2}),/.test(msg.payload)) {\n    const parts = /(\\d{2}:\\d{2}:\\d{2}) up (\\d{2}:\\d{2}),/.exec(msg.payload)\n    msg.payload = {\n        queryTime: parts[1],\n        upTime: parts[2],\n    }\n} else if (/(\\d{2}:\\d{2}:\\d{2}) up (\\d{2} \\w*?), (\\d{2}:\\d{2}),/.test(msg.payload)) {\n    const parts = /(\\d{2}:\\d{2}:\\d{2}) up (\\d{2} \\w*?), (\\d{2}:\\d{2}),/.exec(msg.payload)\n    msg.payload = {\n        queryTime: parts[1],\n        upDuration: parts[2],\n        upTime: parts[3],\n    }\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":990,"y":360,"wires":[["0c4256d18a143979"]]},{"id":"0c4256d18a143979","type":"debug","z":"10ece3ab98e93683","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1190,"y":360,"wires":[]},{"id":"1fe70e933ecf25e0","type":"inject","z":"10ece3ab98e93683","name":"after 15 days","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"after 15 days","payload":" 12:31:14 up 15 days, 16:38, 1 user, load average: 1,03, 1,48, 1,40","payloadType":"str","x":730,"y":380,"wires":[["c9a8809a05ef5f05"]]}]
1 Like

Thanks :slight_smile:
I am trying it with this... but in my current flow I am getting the following error:

msg : string[134]
"Entity API error.  Error Message: expected bool for dictionary value @ data['state']. Got {'queryTime': '09:46:05', 'upTime': '13:10'}"

That is something downstream (a HA node by the looks of it). As you can see, your data is being parsed as I said it would...

Since i have no idea what you are in intending to do with the result, I cannot help further. All I can say is with the code I supplied, you will get consistent results - it is up to you to format the data into the required shape for the downstream nodes.

Ah thanks for that :slight_smile:
Then I know, what to do... :slight_smile:

I am using an HomeAssistant Entity, which should receive the information ... but right, since this is not a single string, this entity will cause problems with the data it receives.

Thanks a lot, I should be able to fix this now.