I frequently cover large distances by car, be it visiting friends or moving to work or university. At the moment it seems I can’t go very far without arriving at some part of the country disrupted by Smart Motorway upgrades, horrible peak time traffic, or something else entirely!
I’m normally well equipped to deal with such hold ups, however without the ability to contact people while on the road, I can’t let them know where I am.
The idea then is fairly simple - provide my current location on a map, so people can see where I am in my journey. There are of course a multitude of apps that can do this already, but how much you can trust a service provider with your exact live location is questionable! Thus I decided to build my own!
This was another of my quick weekend projects that I one day hope to sit down and polish up properly!
Design
There are three parts to this system:
- A GPS receiver that sends requests to a server.
- A server to receive and record the incoming data.
- A web front-end that allows users with permission to see the location data on a map.
GPS Receiver
The GPS hardware itself is perhaps the most important part. At the moment I’m using a module based on the ublox NEO-6M receiver. This module has a serial output, transmitting a fairly standard set of NMEA 0183 sentences. I’ve worked with these sentences before on a project at work, and was fully prepared to start writing a parser for them in python. Perhaps I shouldn’t have been so surprised to discover though, that somebody else beat me to it! The pynmea2 package shaved a bunch of time off the development of this project.
In this prototype the GPS talks to my laptop via a C232HM cable. (which comes highly recommended!) A python script reads in the sentences from the serial port, picks out the ones it wants, and pulls the location and speed information.
Every 10 seconds this data is passed to my server by a POST request using Python’s requests library. In keeping with the security theme, the connection is SSL encrypted, and the page is password protected to keep out any spoof requests.
For the moment, the internet connection is provided by my phone which is USB tethered to my laptop. The signal has held up very well for the trips I’ve taken so far, apart from while travelling over hilly terrain in remote areas. EE’s promise to cover 99% of the population seems to hold up fairly well!
Receive Server
All the web end scripts run on my VPS (the same one serving you this page!).
The receive server is really just a PHP page. Fortunately this wasn’t completely new to me, as an IET workshop had given me a very useful insight into what I needed to do. From there I developed a very primitive framework for a few home automation projects that never took off. Much of the code was still applicable here, so I repurposed it for this.
Once the location script has negotiated making an SSL connection and passing htdigest authentication, then it is able to deliver it’s POST data to the PHP script. If all the fields are in order, the script pops the data into a .json file, along with a timestamp. That’s the job done, the server returns nothing but an empty 200 OK header.
Web Front-end
The web front-end is possibly the most complicated body of code in the whole system! It is written almost entirely in JavaScript, which was initially a bit daunting. The C like syntax, and Python similarities made it pretty quick to pick up however. There’s plenty of other people out there asking the newbie questions too, so it’s fairly simple to find answers.
I’m by no means a web developer, CSS is a whole new world to me, so as a consequence, the webpage isn’t beautiful. It doesn’t need to be though!
Openstreetmap is used as the map source, since I don’t need to faff on with API tokens, simply generate an embed URL. I have a reasonable degree of trust that my data isn’t being farmed by OSM, and of course it’s free to use and distribute!
The JavaScript frequently refreshes an invisible iframe, which contains the .json file generated by PHP script. When the timestamp in the file changes, the JavaScript updates the embed URL for the map iframe. This causes the content to reload, showing the user the new location. At the same time it also updates the clock and speedometer.
This is the current state of the web interface, it’s functional, but there’s room for improvement! Map Data © OpenStreetMap contributors
Conclusion
The current state of the project is little more than a proof of concept. I do hope to improve this project and make it a permanent installation. This means I don’t have to worry about remembering to fit the hardware to the car each time I need it, and I can potentially use it for my own data analysis, as well as track my car if it’s ever stolen! (it’s a ‘08 Citroën C1 - who’s going to nick that‽)
The next steps for this project are:
- Move everything to a raspberry pi or another internet capable platform (ESP8266?).
- Hide the GPS hardware inside the dashboard.
- Investigate fitting a data modem with external antennas, this should help improve coverage in poor signal areas.
- Spruce up the web interface.
- Look into connecting the system up as an APRS sender, and possibly as a mobile APRS igate.
- Get the compute platform in the car to do all sorts of other stuff!