Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@ImTheDeveloper
Created April 13, 2014 15:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ImTheDeveloper/1aab1d44e387da96b3fe to your computer and use it in GitHub Desktop.
Save ImTheDeveloper/1aab1d44e387da96b3fe to your computer and use it in GitHub Desktop.
Live Google Maps Update - Websockets

The following flow illustrates how you can use websockets to update a google map live with coordinates received.

To setup this flow drag the json on to your node-red canvas. You will need to ensure you have your websocket nodes set up correctly with the following settings.

Path: /ws/location
Send/Receive Payload

Once you have these configured the only other adjustment you may have to make is within the template function node which is wedged in the middle of the [get]map flow.

Open up the template function node and scroll down to the following line:

var socketaddy = "ws://192.168.0.5:1880/ws/location";

Change the ip address to point to the ip of whatever you have hosting node-red.

Once that is complete just close the template node and hit deploy.

Browse to: http://node-redlocation/map

By default it will just drop to some random co-ordinate, if you use the injection nodes to inject values you will see the map jump to the co-ordinates supplied! In my actual flow I have owntracks feeding this instead of the inject nodes and you could even use the twitter lat/longitude flow to see live updates of where tweets are coming from.

The input should be in the format shown in the inject nodes, you can supply an array of these coordinates with as many as you want.

[{"id":"54651cc0.ab9ae4","type":"websocket-listener","path":"/ws/location","wholemsg":"false"},{"id":"eaebe5b5.151418","type":"websocket out","name":"","server":"54651cc0.ab9ae4","x":576,"y":175,"z":"d0ca7dde.2f358","wires":[]},{"id":"fff1c609.000e38","type":"function","name":"","func":"// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n// console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n// context = {};\ncontext.global.location = msg.payload;\n\nreturn msg;","outputs":1,"x":337,"y":149,"z":"d0ca7dde.2f358","wires":[["eaebe5b5.151418"]]},{"id":"2c6ab189.d3954e","type":"websocket in","name":"","server":"54651cc0.ab9ae4","x":166,"y":209,"z":"d0ca7dde.2f358","wires":[["6c05683f.93fa98"]]},{"id":"6c05683f.93fa98","type":"function","name":"","func":"// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n// console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n// context = {};\n\nmsg.payload = context.global.location;\nreturn msg;","outputs":1,"x":339,"y":215,"z":"d0ca7dde.2f358","wires":[["eaebe5b5.151418"]]},{"id":"971e5dc2.68e1a","type":"template","name":"","template":"<!DOCTYPE html>\n<html>\n<head>\n <title>Owntracks & Node-Red Live Map</title>\n <script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js\"></script>\n <script type=\"text/javascript\" src=\"http://maps.google.com/maps/api/js?sensor=true\"></script>\n <script type=\"text/javascript\" src=\"http://yourjavascript.com/4594301102/gmaps.js\"></script>\n \n <style type=\"text/css\" media=\"screen\">\n #map {\n position:absolute;\n top: 0; bottom: 0; left: 0; right: 0;\n }\n </style>\n</head>\n<body>\n \n <div id=\"map\"></div>\n <script type=\"text/javascript\">\n var socketaddy = \"ws://192.168.0.5:1880/ws/location\";\n var map;\n var sock;\n $(document).ready(function(){\n \n map = new GMaps({\n div: '#map',\n lat: -12.043333,\n lng: -77.028333\n });\n \n \n sock = new WebSocket(socketaddy);\n sock.onopen = function(){ console.log(\"Connected websocket\");\n\t console.log(\"Sending ping..\");\n\t sock.send(\"Ping!\");\n\t console.log(\"Ping sent..\");\n };\n sock.onerror = function(){ console.log(\"Websocket error\"); };\n sock.onmessage = function(evt){\n var latlng = JSON.parse(evt.data);\n var array = $.map(latlng, function(el) {\n \t\t\treturn [[el.lat, el.lng]];\n\t\t\t});\n \n map.removeMarkers();\n map.removePolylines();\n \tconsole.log(\"Got marker at \" + latlng[0].lat + \", \" + latlng[0].lng, latlng);\n map.setZoom(17);\n \tmap.setCenter(latlng[0].lat, latlng[0].lng);\n map.addMarkers(latlng);\n \tmap.drawPolyline({\n\t\t path: array,\n\t\t strokeColor: '#131540',\n\t\t strokeOpacity: 0.6,\n\t\t strokeWeight: 6\n\t\t});\n }\n });\n </script>\n</body>\n</html>","x":369,"y":286,"z":"d0ca7dde.2f358","wires":[["b2bb0466.4d44f8"]]},{"id":"b2bb0466.4d44f8","type":"http response","name":"","x":553,"y":286,"z":"d0ca7dde.2f358","wires":[]},{"id":"bffd62ba.4002a","type":"http in","name":"","url":"/map","method":"get","x":148,"y":291,"z":"d0ca7dde.2f358","wires":[["971e5dc2.68e1a"]]},{"id":"73465be9.8cb9a4","type":"debug","name":"","active":true,"console":false,"complete":false,"x":413,"y":94,"z":"d0ca7dde.2f358","wires":[]},{"id":"256e06da.da91fa","type":"inject","name":"Array of Co-ords","topic":"","payload":"[{\"lat\":54.9619349,\"lng\":-1.6003813},{\"lat\":54.9656694,\"lng\":-1.5239833},{\"lat\":54.9696456,\"lng\":-1.5069755},{\"lat\":54.9378907,\"lng\":-1.5273729}]","payloadType":"string","repeat":"","crontab":"","once":false,"x":119,"y":98,"z":"d0ca7dde.2f358","wires":[["fff1c609.000e38","73465be9.8cb9a4"]]},{"id":"d0d2a343.2f2d6","type":"inject","name":"Single Co-ord","topic":"","payload":"[{\"lat\":54.9696456,\"lng\":-1.5069755}]","payloadType":"string","repeat":"","crontab":"","once":false,"x":109,"y":144,"z":"d0ca7dde.2f358","wires":[["fff1c609.000e38"]]}]
@dceejay
Copy link

dceejay commented Apr 13, 2014

Hi - if you use - var socketaddy = "ws://"+window.server.location+":1880/ws/location";
it "should just work" in the majority of cases....

@thebaldgeek
Copy link

Hi MrMobberley,

Thanks for the flow, Im really interested in using it in my Node-RED setup, just two questions if I may.

  1. Not sure where I need to set the path in my websocket node. Somewhere in driver.js?
  2. I am using owntracks and and the data format from my debug Node looks like this;
    {"_type": "location", "lat": "33.5037994", "lon": "-117.1647686", "tst": "1398262769", "acc": "20.0", "batt": "93", "event": "enter"}
    I am unsure if I need to change some settings in the Android app, or write a function Node to create the data structure your flow requires. Any suggestions you have on that would be helpful.
    Thanks.

@thebaldgeek
Copy link

Hi,

Some progress.
The guys at the Node-Red Google Group assure me that I dont have to worry about the websocket node config.
Also, they confirmed that I would need to use a function node to change the OwnTracks string to look your your string.

So, I have the map showing up ok, and I now have my OwnTracks data string looking exactly the same as the example.
But the map does not move.

So I took a step back and deleted all my work and just imported your sample flow.... I found that the example does not move to the sample co-ords of either the single or the array.

If you could please take a moment to either re-export what you have, or check it against what you have posted, that would be really helpful.

Thanks.

Ben.

@thebaldgeek
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment