Help with stripping a message to what I want

(If I don't ask, I will get stuck. If I ask I may work it out myself. But if I don't - as said: I'll get stuck)

Here goes:

exec node.
ntpdate -q 192.168.17.39

I get:

server 192.168.17.39, stratum 3, offset -0.000113, delay 0.02623
 3 Sep 16:33:26 ntpdate[5770]: adjust time server 192.168.17.39 offset -0.000113 sec

I want the 3 Sep 16:33:26 part.

Help, I am not that good with the string node.

1 Like

At first glance.

It seems there are two delimiters bring used in that string.

A comma the separate the tags and values

And a space to separate the value from the tag.

I'm a long way from being any imagination, so I have to assume there is a lot nicer way of doing it that I do.

I would create a loop to spilt tags & values and put them into an array.

Then call whichever part of the array you want later.


I'm not using my PC right now, when I fire it up later I'll paste a bit of sample code that I used recently for working with a Black Magic Design, HyperDeck that sends its replies in a simple text string, with New Line /n delimiters

1 Like

(as I said.... If I didn't ask.)

This is what I concocted in the mean time:

[{"id":"71269203f11f4531","type":"inject","z":"650fc4d9.b1c234","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":250,"y":3280,"wires":[["1d429c3dd01e6174"]]},{"id":"7e483af4eca8f8d4","type":"exec","z":"650fc4d9.b1c234","command":"ntpdate -q 192.168.17.39","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":470,"y":3380,"wires":[["ee262f99dde4430f","644be43955c648da","f2d01e650a1f911d"],[],[]]},{"id":"ee262f99dde4430f","type":"string","z":"650fc4d9.b1c234","name":"","methods":[{"name":"delRightMost","params":[{"type":"str","value":"adjust"}]},{"name":"delLeftMost","params":[{"type":"str","value":"\\n"}]},{"name":"delRightMost","params":[{"type":"str","value":"ntp"}]}],"prop":"payload","propout":"payload","object":"msg","objectout":"msg","x":730,"y":3370,"wires":[["f46bea53719f1010","d9722e5510ae34eb"]]},{"id":"d9722e5510ae34eb","type":"debug","z":"650fc4d9.b1c234","name":"NTP time","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":870,"y":3410,"wires":[]}]

Thoughts?

Quick question

Is this

server 192.168.17.39, stratum 3, offset -0.000113, delay 0.02623
 3 Sep 16:33:26 ntpdate[5770]: adjust time server 192.168.17.39 offset -0.000113 sec

the exact string that gets returned or are there any /n in there too?

It's not even 8am here and I haven't had a coffee yet....

I'll take a look when I fire up a PC :nerd_face:

Oh, sorry. You don't have access to NR just now.

Screen shot.

:wink:

Is that better?
(Again: sorry.)

Quickly splitting by space, filtering out the ones you are after and re-joining

image

image

1 Like

That's another way I guess.

Thanks.

Thoughts on the way I posted?

Works as well - probably more robust than my method :slight_smile:

1 Like

I'm not sure as I haven't really tested it if there is no NTP connection.

(Ooops.)

I guess all I need to do is put in a wrong IP address and see what comes out. :wink:

Regex is ideal for these.

image

/*
  FUNCTION  NOTES:
  \d+ means 1 or more numbers (d for digits)
  \w+ any word char (a-Z0-9)

  therefore   \d+ \w+ \d+:\d+:\d+ 
  matches      10 Jan 11:22:33
  matches       3 Sep 16:33:26

  You can be more strict if required e.g.
  *   \w\w\w or \w{3}   means get 3 WORD chars exacly
  *   \d\d or \d{2}     means get 2 numbers exaclty

  // see playground here: https://regex101.com/r/i1aXg6/1
*/

const result = /(\d+ \w+ \d+:\d+:\d+)/gm.exec(msg.payload)
if (result && result.length) {
    msg.payload = result[1]
}
return msg;
2 Likes

I like that Steve as I can then add a message that is sent if the if fails - which I hadn't got to in this bit.
I'll give it a go now.

1 Like

I've only just got access to a coffee machine :rofl:

:slight_smile:

I hear you.

Nothing beats a good coffee.

@Trying_to_learn

Arrr, yes, I see in your screen grab that the returned string does include new lines, which impacts the method I would have used.

server 192.168.17.39, stratum 3, offset -0.000113, delay 0.02623/n
 3 Sep 16:33:26 ntpdate[5770]: adjust time server 192.168.17.39 offset -0.000113 sec/n

Steve's method works perfectly if you only ever want the date or extract section.

My approach is always to "capture all", even if I discard it ms later.

Only because my mind curses me by thinking, "ohhh, I could use that other variable"

As seen in a solution I provided for a "Riedel Bolero" radio pack station loading Dashboard

This is some code I am writing for my network tester flow.

Tests network availability, DNS, blocks and NTP.

So I needed to add this bit to get the NTP part working.

1 Like

(Sorry @Steve-Mcl)

I just tested that code to braking it.

This is what I get if it can't get to the NTP specified.

ntpdate -q 192.168.17.39
server 192.168.17.39, stratum 0, offset 0.000000, delay 0.00000
 3 Sep 17:39:45 ntpdate[8123]: no server suitable for synchronization found

So I need to make sure that end bit is not there.
If it is: Send a different message.

SORRY.

If you wish to avoid bugs, I strongly recommend you also extract the IP and check it against what you expected - this will avoid any ambiguity about the NTP response.

Here is an update that:

  1. gets the IP and time string (you should check the IP is what you expected)
  2. returns an object - because objects are future proof (returning a string means lots of re-work if something changes)
  3. has a 2nd output if not found (for error processing)

const result = /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*?(\d+ \w{3} \d+:\d+:\d+)/s.exec(msg.payload)
if (result && result.length == 3) {
    msg.payload = {
      ip: result[1],
      time: result[2]
    }
  return [msg, null]
}

msg.payload = {
  error: 'ip and time strings not found'
}
return [null, msg]
2 Likes

Yeah, sorry Steve.

I maybe should have declared that at the start maybe.

This is all for local testing my new network.

I need to make sure the NTP is working - which it isn't just now.
Before this I didn't know that.

A simple pre-check will solve that (e.g. if(msg.payload.contains('no server suitable for synchronization found')) { ... } BUT - I suspect the better solution is to check the other 2 outputs of the exec node. I would hope it returns an error code - that is more definitive than a string search

In short, on the exec node, what do you get out of pin2 and pin3 for :-

  • a successful execution?
  • an unsuccessful execution?

identify the difference & use that BEFORE running the regex function.