Skip to content

Use case 04 GPS Access Point

yOyOeK1 edited this page Aug 26, 2022 · 2 revisions

GPS Access Point – that is nice one :) Imagine you have wifi access point on your boat, house, rv, car, …. not only it’s your weather forecast station but also IP TCP nmea multiplexer and a node-red. You have a laptop. It have a opencpn on it but it need gps to give you your location. Node-Red flow will give you that.

You will need: working node-red, ySensorsService, ySensorService manager (node-red)

After this exercise you will have Port 11226 on your IP of your oiyshTerminal with nmea data coming from it. RMC, XDR pitch and roll, XDR temp air, hdm (magnetic). Using it in opencpn.

Ok lets’do it!

In repository you can find directory nodeRedGPSAccessPoint11226 it contains json file you need to past content of it to import option in node-red.

Import json to node red as new flow node red json:

[ { "id": "c912ccbd424745b3", "type": "inject", "z": "0a5e45f66bde827b", "name": "", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "9.613203 -79.584372", "payloadType": "str", "x": 200, "y": 300, "wires": [ [ "6eb88a2af43d2681" ] ] }, { "id": "166115fce950c9f5", "type": "debug", "z": "0a5e45f66bde827b", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "false", "statusVal": "", "statusType": "auto", "x": 510, "y": 320, "wires": [] }, { "id": "6eb88a2af43d2681", "type": "function", "z": "0a5e45f66bde827b", "name": "", "func": "sendIt = false;\n\nif( msg.topic == 'and/lat' ){\n flow.set(\"and_lat\", msg.payload);\n \n}else if( msg.topic == 'and/lon' ){\n msg.payload = flow.get(\"and_lat\")+\" \"+\n msg.payload;\n \n node.status({text:\"ll from and/[lat lon]\"});\n \n sendIt = true;\n}else{\n node.status({text:\"ll from huGps/ll\"});\n sendIt = true;\n}\n\n\nif( sendIt ){\n sp = msg.payload.split(\" \");\n \n function toDegreesMinutesAndSeconds(coordinate) {\n deg = Math.abs(coordinate);\n //console.log(deg);\n t = String(deg).split(\".\");\n //console.log(t);\n \n return (parseInt(t[0])*100) + (parseFloat(\"0.\"+t[1])*60) ;\n }\n \n \n lat = toDegreesMinutesAndSeconds(sp[0]);\n if( parseInt(sp[0])>=0.0 )\n latNS = 'N';\n else \n latNS = 'S';\n \n lon = toDegreesMinutesAndSeconds(sp[1]);\n if( parseInt(sp[1])<=0.0 )\n lonWE = 'W';\n else \n lonWE = 'E';\n \n \n nrrmc = '$NRRMC,,A,'+lat+','+latNS+\n ','+lon+','+lonWE+',,,,,,A\\r\\n';\n \n flow.set(\"nrrmc\",nrrmc);\n \n //$YKRMC,,A,0936.770489,N,07935.157794,W,4.75,82.88,,,,A\n return {\n 'payload': nrrmc\n \n };\n}", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 510, "y": 380, "wires": [ [ "63ed976524ed6b39", "e2fc1387f6dc6947" ] ] }, { "id": "4b92b38744029ff1", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "huGps/gps/ll", "topic": "huGps/gps/ll", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 230, "y": 340, "wires": [ [ "166115fce950c9f5", "6eb88a2af43d2681" ] ] }, { "id": "63ed976524ed6b39", "type": "debug", "z": "0a5e45f66bde827b", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 690, "y": 500, "wires": [] }, { "id": "e2fc1387f6dc6947", "type": "tcp out", "z": "0a5e45f66bde827b", "host": "", "port": "11226", "beserver": "server", "base64": false, "end": false, "name": "nmea at :11226", "x": 900, "y": 560, "wires": [] }, { "id": "0a42d0450e12c84d", "type": "inject", "z": "0a5e45f66bde827b", "name": "resend rmc to not time out opencpn", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "3", "crontab": "", "once": true, "onceDelay": "1", "topic": "", "payload": "", "payloadType": "str", "x": 190, "y": 240, "wires": [ [ "267116a856ee7e1c" ] ] }, { "id": "267116a856ee7e1c", "type": "function", "z": "0a5e45f66bde827b", "name": "", "func": "\nreturn {\n 'payload': '\\r\\n'+( flow.get(\"nrrmc\")||\"\" )\n};", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 520, "y": 240, "wires": [ [ "e2fc1387f6dc6947" ] ] }, { "id": "e30deb1ea1fad329", "type": "function", "z": "0a5e45f66bde827b", "name": "", "func": "\n\nnrhdg = '$NRHDM,'+parseInt(msg.payload)+',M\\r\\n';\n//'$NRHDM,'+parseInt(msg.payload)+',W,0,E\\r\\n';\n\nnode.status({\n fill:'blue',\n shape: 'ring',\n text:\"HDM: \"+parseInt(msg.payload)\n });\n\nreturn {'payload': nrhdg };", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 400, "y": 860, "wires": [ [ "e2fc1387f6dc6947" ] ] }, { "id": "c85213b89730275b", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "and/mag", "topic": "and/mag", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 160, "y": 860, "wires": [ [ "e30deb1ea1fad329" ] ] }, { "id": "370f354bc0ae17ea", "type": "status", "z": "0a5e45f66bde827b", "name": "", "scope": [ "e2fc1387f6dc6947" ], "x": 920, "y": 620, "wires": [ [ "d72c7ff305d06eee" ] ] }, { "id": "7620f8ec8c0a801b", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "and/lat", "topic": "and/lat", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 250, "y": 460, "wires": [ [ "6eb88a2af43d2681" ] ] }, { "id": "2e1fa7080199cdd4", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "and/lon", "topic": "and/lon", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 250, "y": 500, "wires": [ [ "6eb88a2af43d2681" ] ] }, { "id": "d72c7ff305d06eee", "type": "link out", "z": "0a5e45f66bde827b", "name": "", "mode": "link", "links": [ "52f734b330961380" ], "x": 1035, "y": 620, "wires": [] }, { "id": "9e7b97c3239be01f", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "", "topic": "e01Mux/C", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 160, "y": 800, "wires": [ [ "04012f0ee9b535fa" ] ] }, { "id": "04012f0ee9b535fa", "type": "function", "z": "0a5e45f66bde827b", "name": "to TempAir", "func": "//$IIXDR,C,19.52,C,TempAir*19\nnode.status({\n text:\"temp:\"+msg.payload+\"C\" \n});\nreturn {payload:\"$NRXDR,C,\"+msg.payload+\",C,TempAir,\\r\\n\"};", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 390, "y": 800, "wires": [ [ "e2fc1387f6dc6947" ] ] }, { "id": "12434ed4b13b315d", "type": "function", "z": "0a5e45f66bde827b", "name": "", "func": "//$YKXDR,A,%s,,PTCH,A,%s,,ROLL,\nif( msg.topic == 'and/orient/pitch'){\n flow.set(\"andOrientPitch\",msg.payload);\n\n \n}else{\n p = parseFloat(flow.get('andOrientPitch')||0).toFixed(2);\n h = parseFloat(msg.payload).toFixed(2);\n \n node.status({\n text: 'P:'+p+' H:'+h\n });\n \n return {\n payload: \"$NRXDR,A,\"+p+\n \",,PTCH,A,\"+h+\n \",,ROLL,\\r\\n\"\n };\n \n}", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 400, "y": 700, "wires": [ [ "e2fc1387f6dc6947" ] ] }, { "id": "898f2ea4d72044e3", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "and/orient/pitch", "topic": "and/orient/pitch", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 180, "y": 680, "wires": [ [ "12434ed4b13b315d" ] ] }, { "id": "f96f00c24a755a58", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "and/orient/pitch", "topic": "and/orient/heel", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 180, "y": 740, "wires": [ [ "12434ed4b13b315d" ] ] }, { "id": "23ad5f3e9e9a307c", "type": "mqtt in", "z": "0a5e45f66bde827b", "name": "nex7/gps/ll", "topic": "nex7/gps/ll", "qos": "2", "datatype": "auto", "broker": "d611ceefa2b9fd0b", "nl": false, "rap": true, "rh": 0, "inputs": 0, "x": 220, "y": 400, "wires": [ [ "6eb88a2af43d2681" ] ] }, { "id": "d611ceefa2b9fd0b", "type": "mqtt-broker", "name": "nodeRedAtHu", "broker": "localhost", "port": "10883", "clientid": "nodeRedHu", "autoConnect": true, "usetls": false, "protocolVersion": "4", "keepalive": "60", "cleansession": true, "birthTopic": "", "birthQos": "0", "birthPayload": "", "birthMsg": {}, "closeTopic": "", "closeQos": "0", "closePayload": "", "closeMsg": {}, "willTopic": "", "willQos": "0", "willPayload": "", "willMsg": {}, "sessionExpiry": "" } ]

you can import it as a new flow or add it to existing one. You need to edit some stuff?

do Deploy in node-red.

So easy

Clone this wiki locally