Module: MmGPS

Defined in:
lib/mm_gps/mm_gps_module.rb,
lib/mm_gps.rb,
lib/mm_gps/version.rb,
lib/mm_gps/mm_gps_beacon.rb,
lib/mm_gps/mm_gps_buffer.rb,
ext/mm_gps/mm_gps.c

Overview

Manage connection and data decoding with a MarvelMind beacon or hedgehog.

Defined Under Namespace

Classes: Beacon, Buffer

Constant Summary collapse

VERSION =
"0.2.1"

Class Method Summary collapse

Class Method Details

.append_crc16(buf) ⇒ String

Appends a CRC16 checksum to a string

Parameters:

  • buf (String)

    the starting string

Returns:

  • (String)

    the original string plus its CRC16



52
53
54
55
56
57
58
59
60
61
62
# File 'ext/mm_gps/mm_gps.c', line 52

static VALUE mm_gps_add_CRC16(VALUE klass, VALUE str)
{
  union {
    ushort u;
    char   s[2];
  } crc;
  
  Check_Type(str, T_STRING);
  crc.u = CRC16(RSTRING_PTR(str), RSTRING_LEN(str));  
  return rb_str_buf_cat(str, crc.s, 2);
}

.crc16(buf) ⇒ Fixnum

Calculate CRC16 checksum of a string

Parameters:

  • buf (String)

    the string to be checksummed

Returns:

  • (Fixnum)

    the CRC16 value



40
41
42
43
44
# File 'ext/mm_gps/mm_gps.c', line 40

static VALUE mm_gps_CRC16(VALUE klass, VALUE str)
{
  Check_Type(str, T_STRING);
  return rb_fix_new(CRC16(RSTRING_PTR(str), RSTRING_LEN(str)));
}

.hexify(buf) ⇒ String

Returns a HEX description of a binary buffer

Parameters:

  • buf (String)

    the input buffer

Returns:

  • (String)

    the HEX description



39
40
41
42
43
44
# File 'lib/mm_gps/mm_gps_module.rb', line 39

def self.hexify(buf)
  len = buf.length
  return (("%02X " * len) % buf.unpack("C#{len}")).chop
rescue NoMethodError
  return '--'
end

.parse_packet(buf) ⇒ Hash|Array

Parse the given buffer according to the MarvelMind protocol. See www.marvelmind.com/pics/marvelmind_beacon_interfaces_v2016_03_07a.pdf

Parameters:

  • buf (String)

    the String buffer to be parsed

Returns:

  • (Hash|Array)

    if the system is running, return a Hash with timestamp, coordinates, and error code (data code 0x0001). Otherwise returns an Array of Hashes for beacons status (data code 0x0002).



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/mm_gps/mm_gps_module.rb', line 52

def self.parse_packet(buf)
  unless valid_crc16?(buf) then
    raise MmGPSError.new("Invalid CRC", {reason: :nocrc, packet:buf, crc:("%04X" % crc16(buf[0...-2]))}) 
  end
  header = buf[0..5].unpack('CCS<C')
  if header[2] == 1 then # Regular GPS Data
    result = {}
    payload = buf[5...16].unpack('L<s<3C')
    result = %I(ts x y z f).zip(payload).to_h
    result[:ts] /= 64.0
    %I(x y z).each {|k| result[k] /= 100.0}
  elsif header[2] == 2 then # Frozen
    len = buf[5].unpack('C')[0]
    result = []
    len.times do |i|
      offset = 6 + i * 8
      payload = buf[offset...(offset + 8)].unpack('Cs<3C')
      result << %I(address x y z reserved).zip(payload).to_h
      %I(x y z).each {|k| result.last[k] /= 100.0}
    end
  else
    unless valid_crc16?(buf) then
      raise MmGPSError.new("Unexpected packet type #{header[2]}",
        {reason: :notype, packet:buf, crc:("%04X" % crc16(buf[0...-2])), type:header[2]}) 
    end
  end
  return result
end

.valid_crc16?(str) ⇒ Bool

Checks a sbuffer for valid CRC16.

Parameters:

  • str (String)

    the buffer to be checked

Returns:

  • (Bool)

    true if the buffer is self-consistent



31
32
33
# File 'lib/mm_gps/mm_gps_module.rb', line 31

def self.valid_crc16?(str)
  crc16(str) == 0
end