I've been messing around with this today. It might give you some ideas. Import it into a new flow in Node-RED.
Code:
[
{
"id": "8ec62a14.f63ac8",
"type": "switch",
"z": "f9bd0a33.c9b318",
"name": "Filter RMC, pass everything else",
"property": "payload",
"propertyType": "msg",
"rules": [
{
"t": "regex",
"v": "^(?=...*RMC)",
"vt": "str",
"case": false
},
{
"t": "else"
}
],
"checkall": "true",
"outputs": 2,
"x": 530,
"y": 480,
"wires": [
[
"6519c937.dc56b8"
],
[
"e1799bbe.a60b08"
]
],
"inputLabels": [
"Input"
],
"outputLabels": [
"RMC",
""
]
},
{
"id": "f1d525e4.908778",
"type": "function",
"z": "f9bd0a33.c9b318",
"name": "calc checksum",
"func": "var nmea = msg.payload;\nvar checksum = 0; \n\nfor(var i = 0; i < nmea.length; i++) { \n checksum = checksum ^ nmea.charCodeAt(i); \n}\nchecksum = checksum.toString(16); //convert to hex\nnmea = '$' + nmea + '*' + checksum; //make the full nmea sentence again\n\nmessage = 'Full message =' + nmea + '\\r\\n' + 'Checksum = ' + checksum ;\n\nmsg.payload = nmea;\nmsg.payload = msg.payload+\"\\r\\n\";\n\nvar msg1 = {\n payload: msg.payload\n };\n return msg1;",
"outputs": 1,
"noerr": 0,
"x": 1180,
"y": 540,
"wires": [
[
"9648f94e.06f568",
"b4d70c7e.c6a58"
]
]
},
{
"id": "9648f94e.06f568",
"type": "udp out",
"z": "f9bd0a33.c9b318",
"name": "",
"addr": "127.0.0.1",
"iface": "",
"port": "10108",
"ipv": "udp4",
"outport": "",
"base64": false,
"multicast": "false",
"x": 1400,
"y": 460,
"wires": []
},
{
"id": "5640ac5c.6b5634",
"type": "comment",
"z": "f9bd0a33.c9b318",
"name": "This takes NMEA Output, changes date string and adds checksum",
"info": "",
"x": 800,
"y": 260,
"wires": []
},
{
"id": "e7485e56.706cb",
"type": "serial in",
"z": "f9bd0a33.c9b318",
"name": "NMEA Input",
"serial": "c5d7ff46.19d73",
"x": 230,
"y": 700,
"wires": [
[
"8ec62a14.f63ac8"
]
]
},
{
"id": "7c9f7c22.f815c4",
"type": "inject",
"z": "f9bd0a33.c9b318",
"name": "Inject GLL String",
"topic": "",
"payload": "$GPGLL,5930.030,N,00254.792,E,163415,A*11",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 240,
"y": 480,
"wires": [
[
"8ec62a14.f63ac8"
]
]
},
{
"id": "6db2a42d.3e034c",
"type": "inject",
"z": "f9bd0a33.c9b318",
"name": "Inject RMC String",
"topic": "",
"payload": "$GPRMC,163415,A,5930.030,N,00254.792,E,00.0,000.,171197,000.8,E*79",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 238,
"y": 556.9999876022339,
"wires": [
[
"8ec62a14.f63ac8"
]
]
},
{
"id": "b4d70c7e.c6a58",
"type": "debug",
"z": "f9bd0a33.c9b318",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 1370,
"y": 660,
"wires": []
},
{
"id": "e1799bbe.a60b08",
"type": "function",
"z": "f9bd0a33.c9b318",
"name": "Create unmodified string - change only device code",
"func": "var nmeaFull=msg.payload;\n\nvar nmeaStripped=\"\";\n//If it has a checksum, strip it\nvar n = nmeaFull.indexOf(\"*\")\nif (n > 0){\n nmeaStripped=nmeaFull.substring(0, n);}\nelse {\n nmeaStripped=nmeaFull;\n}\n\nvar nmeaSplit=nmeaStripped.split(\",\");\n\nvar deviceCode=\"AB\";\n \nvar nmeaFinal=deviceCode+nmeaSplit[0].substring(3,6)+\",\";\n\nvar i=1;\n\ndo {\n nmeaFinal += nmeaSplit[i] + \",\";\n i++;\n}\nwhile (i < (nmeaSplit.length-2));\n\nnmeaFinal=nmeaFinal+nmeaSplit[(nmeaSplit.length-1)];\n\nmsg.payload = nmeaFinal;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 850,
"y": 600,
"wires": [
[
"f1d525e4.908778"
]
]
},
{
"id": "3c8b2779.e12068",
"type": "inject",
"z": "f9bd0a33.c9b318",
"name": "Inject GGA String",
"topic": "",
"payload": "$GPGGA,163415,5930.030,N,00254.792,E,1,04,001,0001,M,040,M,,",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 239.99993133544922,
"y": 399.9999170303345,
"wires": [
[
"8ec62a14.f63ac8"
]
]
},
{
"id": "a7fb3463.c10b98",
"type": "inject",
"z": "f9bd0a33.c9b318",
"name": "Inject VTG String",
"topic": "",
"payload": "$GPVTG,000,T,359,M,00.0,N,00.0,K",
"payloadType": "str",
"repeat": "",
"crontab": "",
"once": false,
"x": 239.99993133544922,
"y": 319.9999170303345,
"wires": [
[
"8ec62a14.f63ac8"
]
]
},
{
"id": "6519c937.dc56b8",
"type": "function",
"z": "f9bd0a33.c9b318",
"name": "Create RMC string with correct year",
"func": "var nmeaFull=msg.payload;\n\nvar nmeaStripped=\"\";\n//If it has a checksum, strip it\nvar n = nmeaFull.indexOf(\"*\")\nif (n > 0){\n nmeaStripped=nmeaFull.substring(0, n);}\nelse {\n nmeaStripped=nmeaFull;\n}\n\n\nvar nmeaSplit=nmeaStripped.split(\",\");\n\nvar nmeaYear=nmeaSplit[9].substring(4, 6);\nvar nmeaMonth=nmeaSplit[9].substring(2, 4);\nvar nmeaDay=nmeaSplit[9].substring(0, 2);\n\nvar nmeaYearInt=parseInt(nmeaYear)+1920;\nvar nmeaYearStr=nmeaYearInt.toString();\nnmeaYear=nmeaYearStr.substring(2,4);\n\nnmeaSplit[9]=nmeaDay+nmeaMonth+nmeaYear;\n\nvar nmeaFinal=\"ABRMC,\";\n\nvar i=1;\n\ndo {\n nmeaFinal += nmeaSplit[i] + \",\";\n i++;\n}\nwhile (i < (nmeaSplit.length-2));\n\nnmeaFinal=nmeaFinal+nmeaSplit[(nmeaSplit.length-1)];\n\nmsg.payload = nmeaFinal;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 860,
"y": 380,
"wires": [
[
"f1d525e4.908778"
]
]
},
{
"id": "c5d7ff46.19d73",
"type": "serial-port",
"z": "",
"serialport": "/dev/ttyOP_485",
"serialbaud": "4800",
"databits": "8",
"parity": "none",
"stopbits": "1",
"newline": "\\n",
"bin": "false",
"out": "char",
"addchar": false
}
]