Parse Date/Time IEC 62056-21

Hi,
I’m trying to extract the date/time from a device that uses IEC 62056 protocol. I can use the buffer/parser node to split the data to output the time, but I can’t work out how I get the date. I’m sure the answers simple, but I just can’t see it.

How do i calculate the date from the string sent by the device?

Examples:
String from meter = 22080670B00021
Actual date/time =2021-10-30 06:08:22

08000871D00021
31 -10-2021 08:00:08

46191541110021
2021-11-01 15:19:46

50421942310021
2021-11-02 19:42:50

16510643510021
2021-11-03 06:51:16

472823 44710021
2021-11-04 23:28:47

I'm not sure, but it looks like you are getting the wrong data. Perhaps it has something to do with the port's connection speed.

It’s the correct data, the times easy to decide but the date doesn't make sense to me. If you -40 from the first byte you get the date (70 - 40 = 30th) and this pattern works for with all the examples, but how do i get 10/2021 from B00021?

I think i it is parsed wrong and you should look at settings in buffer parser.

Here is a function i think will produce the date and time.

[{"id":"c39a375a.75ef88","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"08000871D00021","payloadType":"str","x":130,"y":80,"wires":[["655dab49.00c5dc"]]},{"id":"655dab49.00c5dc","type":"template","z":"b779de97.b1b46","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"22080670B00021\n08000871D00021\n46191541110021\n50421942310021\n16510643510021\n47282344710021","output":"str","x":160,"y":140,"wires":[["7481eb62.24cbac"]]},{"id":"7481eb62.24cbac","type":"split","z":"b779de97.b1b46","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":300,"y":160,"wires":[["c0cbe344.c0da68"]]},{"id":"c0cbe344.c0da68","type":"function","z":"b779de97.b1b46","name":"","func":"let d = msg.payload.split(\"\");\nd[6] = String(d[6]-4);\nd[8] = \"1\";\nd[10] = \"2\";\nd = d.join(\"\").match(/.{2}/g);\nmsg.payload = `${d[3]}-${d[4]}-${d[5] + d[6]} ${d[2]}:${d[1]}:${d[0]}`;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":340,"y":100,"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":560,"y":120,"wires":[]}]

from the strings you have.

That’s it!!!! Can’t thank you enough for this!!!

It's not perfect as there may be some tweaking for single digit months. Would need to see jan and feb strings to see if it's possible to handle them.

Ah yes i see, i have an example for January 2021 and its slightly off.

String from meter: 00322041810021
2021-01-01 20:32:00

This is from the debug:
01-11-2021 20:32:00

Think it's possible, can i have a few more examples for each month just to be sure.

[edit] Give me a few mins I think i have an idea

Try this

[{"id":"c39a375a.75ef88","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"08000871D00021","payloadType":"str","x":200,"y":60,"wires":[["655dab49.00c5dc"]]},{"id":"655dab49.00c5dc","type":"template","z":"b779de97.b1b46","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"22080670B00021\n08000871D00021\n46191541110021\n50421942310021\n16510643510021\n47282344710021\n00322041810021","output":"str","x":230,"y":120,"wires":[["7481eb62.24cbac"]]},{"id":"7481eb62.24cbac","type":"split","z":"b779de97.b1b46","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":370,"y":140,"wires":[["c0cbe344.c0da68"]]},{"id":"c0cbe344.c0da68","type":"function","z":"b779de97.b1b46","name":"","func":"let d = msg.payload.split(\"\");\nd[6] = String(d[6]-4);\nd[8] = (d[8] === \"D\" || d[8] === \"B\" || Number(d[8]) < 8? \"1\" : \"0\");\nd[10] = \"2\";\nd = d.join(\"\").match(/.{2}/g);\nmsg.payload = `${d[3]}-${d[4]}-${d[5] + d[6]} ${d[2]}:${d[1]}:${d[0]}`;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":410,"y":80,"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":630,"y":100,"wires":[]}]

edited to check if char 9 is less than 8.
I think more data is needed.

24312141020021 = 1st Feb 2021

19312141030021 = 1st March 2021

15312141490021 = 1st Sep 2021

20312190100022 = 10th Oct 2022

I can cope with months 3, 4, 5, 6, 7, 8 ,9, 10, but months 1, 2, 11, 12 will need to see more data.
Then there is the issue of 2022 and days being 80 out.

I think this is a no go.

I really think you need to look at the incoming buffer and how you are parsing it.

or

Are these live reading? Could you not use the current date?

It’s live readings from the device, eventually I want to compare the time/date in the device with the actual time (Time stamp) for it flag any discrepancies.

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