Skip to content

Instantly share code, notes, and snippets.

Created February 1, 2016 13:41
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 anonymous/96cea6c8d068d44719c7 to your computer and use it in GitHub Desktop.
Save anonymous/96cea6c8d068d44719c7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'socket'
Socket.const_set :AF_BLUETOOTH, 31
Socket.const_set :BTPROTO_RFCOMM, 3
module Bluetooth
refine Socket.singleton_class do
def bt_sockaddr bdaddr, channel
[Socket::AF_BLUETOOTH, 0, *bdaddr.scan(/\h\h/).reverse_each.map(&:hex), channel, 0].pack('C*')
end
end
end
class GPS
using Bluetooth
def initialize bdaddr, channel
@bdaddr = bdaddr
@channel = channel
@file = "coordinates.gps"
@parser = GPSParser.new
end
def run
@socket = Socket.new Socket::AF_BLUETOOTH, :SOCK_STREAM, Socket::BTPROTO_RFCOMM
@socket.connect Socket.bt_sockaddr @bdaddr, @channel
loop do
gps_data = @socket.gets
puts gps_data
if gps_data.start_with?("$GPGGA") && gps_data.size == 62
parsed_data = @parser.parse_gps_data(gps_data).join(',')<<$/
File.write(@file, parsed_data, mode: 'a') # create KML file with coords ???
end
end
ensure
@socket.close if @socket
end
end
class GPSParser
def parse_gps_data gps_data
lat, lon = gps_data = gps_data.split(',').values_at(2..5).each_slice(2).to_a
lat_degrees = parse_latitude(*lat)
lon_degrees = parse_longitude(*lon)
[lat_degrees, lon_degrees]
end
def parse_latitude lat, heading
degrees = lat[0,2].to_f + (lat[2,lat.size].to_f / 60.0)
heading == 'N' ? degrees : -degrees
end
def parse_longitude lon, heading
degrees = lon[0,3].to_f + (lon[3,lon.size].to_f / 60.0)
heading == 'E' ? degrees : -degrees
end
end
bdaddr = "60:BE:B5:FE:1D:61"
channel = 5
gps = GPS.new bdaddr, channel
gps.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment