nmea_plus 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -4
- data/lib/nmea_plus/generated_parser/tokenizer.rb +1 -1
- data/lib/nmea_plus/message/ais/vdm.rb +3 -6
- data/lib/nmea_plus/message/ais/vdm_payload/mmsi_info.rb +393 -0
- data/lib/nmea_plus/message/ais/vdm_payload/payload.rb +13 -13
- data/lib/nmea_plus/message/ais/vdm_payload/sub_area.rb +10 -3
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb +7 -363
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6.rb +5 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f0.rb +17 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f2.rb +16 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f3.rb +15 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f4.rb +24 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f5.rb +34 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg8.rb +1 -0
- data/lib/nmea_plus/message/ais/vdm_payload/vdm_msg8d1f0.rb +17 -0
- data/lib/nmea_plus/message/base.rb +1 -1
- data/lib/nmea_plus/version.rb +1 -1
- data/lib/nmea_plus.rb +41 -19
- metadata +11 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49d631a6794e0a47ff2daef5fb5b4dac87623a5d
|
4
|
+
data.tar.gz: 16636c7450ccb964cedd1a3d76462999af63e967
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5250074e41c49831996adbcc4e9f36990257e157c3980d3bb04b48db678e2c5e7c4bd26563c0a5174854f86605c5db5427b5961e697e35882c8d7afc40cd41bb
|
7
|
+
data.tar.gz: 47e7032aaddbdb141fd4fd8175affc119ece1bd9d961f0434b8b6ff1ee7e7c47c79036187a5db93c262799218da2e37f66397386b8e342b85eab4c56689d2c2e
|
data/README.md
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# NMEA (GPS) and AIS Parser / Decoder for Ruby (nmea_plus)
|
2
2
|
|
3
|
-
[](https://rubygems.org/gems/nmea_plus)
|
4
4
|
[](https://travis-ci.org/ifreecarve/nmea_plus)
|
5
|
-
[](http://www.rubydoc.info/gems/nmea_plus/1.0.
|
5
|
+
[](http://www.rubydoc.info/gems/nmea_plus/1.0.11)
|
6
6
|
|
7
7
|
[NMEA Plus](https://github.com/ifreecarve/nmea_plus) is a Ruby gem for parsing and decoding "GPS" messages: NMEA, AIS, and any other similar formats of short messaging typically used by marine equipment. It provides convenient access (by name) to the fields of each message type, and a stream reader designed for use with Ruby Blocks.
|
8
8
|
|
@@ -101,13 +101,16 @@ Support for proprietary NMEA messages is also possible. PASHR is included as pr
|
|
101
101
|
AIS message type definitions were implemented from the unofficial spec found here:
|
102
102
|
http://catb.org/gpsd/AIVDM.html
|
103
103
|
|
104
|
+
And some binary subtypes from the ITU spec found here:
|
105
|
+
https://www.itu.int/dms_pubrec/itu-r/rec/m/R-REC-M.1371-4-201004-S!!PDF-E.pdf
|
106
|
+
|
104
107
|
The AIS payload can be found in the payload field of a `VDM` message (aka `!AIVDM`, `!ABVDM`, `!SAVDM`). Currently, the following AIS message types are supported:
|
105
108
|
|
106
109
|
> 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 18, 19, 20, 21, 24, 27
|
107
110
|
|
108
|
-
> Type 6 subtypes for DAC/FID: 235/10, 1022/61
|
111
|
+
> Type 6 subtypes for DAC/FID: 1/0, 1/2, 1/3, 1/4, 1/5, 235/10, 1022/61
|
109
112
|
|
110
|
-
> Type 8 subtypes for DAC/FID: 1/22, 1/31, 366/56, 366/57
|
113
|
+
> Type 8 subtypes for DAC/FID: 1/0, 1/22, 1/31, 366/56, 366/57
|
111
114
|
|
112
115
|
|
113
116
|
## Disclaimer
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
|
8
8
|
module NMEAPlus
|
9
|
-
class Decoder < Parser # The source file is in .rex format -- indentation and most yard documentation is impossible.
|
9
|
+
class Decoder < Parser # The source file is in .rex format -- indentation and most yard documentation is impossible. This class does a very basic parse of an input line, calling {NMEAPlus::MessageFactory.create} on the result. In parser.y, this is currently defined to be a {NMEAPlus::NMEAMessageFactory} if the line begins with `$` and {NMEAPlus::AISMessageFactory} if the line begins with `!`. In pratice, you should be using {NMEAPlus::SourceDecoder} (which wraps this class) to parse messages from an IO object; this class can only parse individual strings.
|
10
10
|
require 'strscan'
|
11
11
|
|
12
12
|
class ScanError < StandardError ; end
|
@@ -66,8 +66,9 @@ module NMEAPlus
|
|
66
66
|
ptr = self
|
67
67
|
ret = ""
|
68
68
|
loop do
|
69
|
+
break if ptr.raw_ais_payload.nil? # guard against rare instances of message corruption
|
69
70
|
ret << ptr.raw_ais_payload
|
70
|
-
break if ptr.next_part.nil?
|
71
|
+
break if ptr.next_part.nil? # stop when we run out of messages in the chain
|
71
72
|
ptr = ptr.next_part
|
72
73
|
end
|
73
74
|
ret
|
@@ -105,11 +106,7 @@ module NMEAPlus
|
|
105
106
|
# @return [String] a binary encoded string
|
106
107
|
def _dearmor6b(c, len = 6)
|
107
108
|
val = c.ord
|
108
|
-
|
109
|
-
ret = val - 56
|
110
|
-
else
|
111
|
-
ret = val - 48
|
112
|
-
end
|
109
|
+
ret = val - (val >= 96 ? 56 : 48) # Mapped to 2 separate contiguous blocks of ascii, so choose which
|
113
110
|
ret.to_s(2).rjust(6, "0")[0..(len - 1)]
|
114
111
|
end
|
115
112
|
|
@@ -0,0 +1,393 @@
|
|
1
|
+
|
2
|
+
module NMEAPlus
|
3
|
+
module Message
|
4
|
+
module AIS
|
5
|
+
module VDMPayload
|
6
|
+
|
7
|
+
# A container for MMSI (Maritime Mobile Service Identity) information,
|
8
|
+
# all of which is indicated from the MMSI integer value itself.
|
9
|
+
class MMSIInfo
|
10
|
+
|
11
|
+
# The MMSI
|
12
|
+
# @return [Integer]
|
13
|
+
attr_reader :id
|
14
|
+
|
15
|
+
# @param mmsi [Integer] The MMSI
|
16
|
+
def initialize(mmsi)
|
17
|
+
@id = mmsi
|
18
|
+
end
|
19
|
+
|
20
|
+
# The MMSI category as defined by ITU-R M.585-7
|
21
|
+
# @!parse attr_reader :category
|
22
|
+
# @return [Symbol] The symbol for the MMSI category
|
23
|
+
def category
|
24
|
+
case id.to_s.rjust(9, '0') # formatted as 9 digit string with leading 0s
|
25
|
+
when /[2-7]......../ then :individual_ship
|
26
|
+
when /00...1.../ then :coast_station
|
27
|
+
when /00...2.../ then :harbor_station
|
28
|
+
when /00...3.../ then :pilot_station
|
29
|
+
when /00...4.../ then :ais_repeater_station
|
30
|
+
when /00......./ then :coast_station
|
31
|
+
when /111...1../ then :sar_aircraft_fixed
|
32
|
+
when /111...5../ then :sar_aircraft_helicopter
|
33
|
+
when /1......../ then :sar_aircraft
|
34
|
+
when /8......../ then :handheld
|
35
|
+
when /98......./ then :auxiliary_craft
|
36
|
+
when /970....../ then :sar_transmitter
|
37
|
+
when /972....../ then :man_overboard
|
38
|
+
when /974....../ then :epirb
|
39
|
+
when /99...1.../ then :aton_physical
|
40
|
+
when /99...6.../ then :aton_virtual
|
41
|
+
when /99......./ then :aton
|
42
|
+
else
|
43
|
+
:unknown_mmsi_category
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# The MMSI category as defined by ITU-R M.585-7
|
48
|
+
# @!parse attr_reader :category_description
|
49
|
+
# @return [String] the human-readable description the MMSI category
|
50
|
+
def category_description
|
51
|
+
case category
|
52
|
+
when :individual_ship then "Individual ship"
|
53
|
+
when :coast_station then "Coast station"
|
54
|
+
when :harbor_station then "Harbor station"
|
55
|
+
when :pilot_station then "Pilot station"
|
56
|
+
when :ais_repeater_station then "AIS repeater station"
|
57
|
+
when :sar_aircraft then "SAR aircraft"
|
58
|
+
when :sar_aircraft_fixed then "SAR fixed-wing aircraft"
|
59
|
+
when :sar_aircraft_helicopter then "SAR helicopter"
|
60
|
+
when :aton_physical then "Physical AIS AtoN"
|
61
|
+
when :aton_virtual then "Virtual AIS AtoN"
|
62
|
+
when :aton then "AIS Aid to Navigation"
|
63
|
+
when :auxiliary_craft then "Auxiliary craft"
|
64
|
+
when :handheld then "Handheld transceiver"
|
65
|
+
when :sar_transmitter then "AIS-SART"
|
66
|
+
when :man_overboard then "MOB (Man Overboard)"
|
67
|
+
when :epirb then "EPIRB"
|
68
|
+
else
|
69
|
+
category.to_s
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# The MMSI Maritime Identification Digits (MID), indicating country codes as specified by the ITU.
|
74
|
+
# http://www.itu.int/online/mms/glad/cga_mids.sh
|
75
|
+
# @!parse attr_reader :mid
|
76
|
+
# @return [Integer] the MID
|
77
|
+
def mid
|
78
|
+
range = case category
|
79
|
+
when :individual_ship then 0..2
|
80
|
+
when :coast_station, :harbor_station, :pilot_station, :ais_repeater_station then 2..4
|
81
|
+
when :sar_aircraft, :sar_aircraft_fixed, :sar_aircraft_helicopter then 3..5
|
82
|
+
when :aton_physical, :aton_virtual, :aton then 2..4
|
83
|
+
when :auxiliary_craft then 2..4
|
84
|
+
when :handheld then 1..3
|
85
|
+
when :sar_transmitter, :man_overboard, :epirb then 3..5
|
86
|
+
end
|
87
|
+
return nil if range.nil?
|
88
|
+
id.to_s.rjust(9, '0')[range].to_i
|
89
|
+
end
|
90
|
+
|
91
|
+
# The ISO 3166-1 country ID indicated by the MMSI Maritime Identification Digits (MID)
|
92
|
+
# @!parse attr_reader :country_id
|
93
|
+
# @return [Integer] the MID
|
94
|
+
def country_id
|
95
|
+
# https://github.com/S73417H/MIDs
|
96
|
+
# https://github.com/alexrabarts/iso_country_codes
|
97
|
+
# JSON.parse(IO.read("mids.json")).each {|k, v| puts "when #{k} then #{IsoCountryCodes.find(v[1]).numeric.to_i}" }
|
98
|
+
case mid
|
99
|
+
when 201 then 8
|
100
|
+
when 202 then 20
|
101
|
+
when 203 then 40
|
102
|
+
when 204 then 620
|
103
|
+
when 205 then 56
|
104
|
+
when 206 then 112
|
105
|
+
when 207 then 100
|
106
|
+
when 208 then 336
|
107
|
+
when 209 then 196
|
108
|
+
when 210 then 196
|
109
|
+
when 211 then 276
|
110
|
+
when 212 then 196
|
111
|
+
when 213 then 268
|
112
|
+
when 214 then 498
|
113
|
+
when 215 then 470
|
114
|
+
when 216 then 51
|
115
|
+
when 218 then 276
|
116
|
+
when 219 then 208
|
117
|
+
when 220 then 208
|
118
|
+
when 224 then 724
|
119
|
+
when 225 then 724
|
120
|
+
when 226 then 250
|
121
|
+
when 227 then 250
|
122
|
+
when 228 then 250
|
123
|
+
when 229 then 470
|
124
|
+
when 230 then 246
|
125
|
+
when 231 then 234
|
126
|
+
when 232 then 826
|
127
|
+
when 233 then 826
|
128
|
+
when 234 then 826
|
129
|
+
when 235 then 826
|
130
|
+
when 236 then 292
|
131
|
+
when 237 then 300
|
132
|
+
when 238 then 191
|
133
|
+
when 239 then 300
|
134
|
+
when 240 then 300
|
135
|
+
when 241 then 300
|
136
|
+
when 242 then 504
|
137
|
+
when 243 then 348
|
138
|
+
when 244 then 528
|
139
|
+
when 245 then 528
|
140
|
+
when 246 then 528
|
141
|
+
when 247 then 380
|
142
|
+
when 248 then 470
|
143
|
+
when 250 then 372
|
144
|
+
when 251 then 352
|
145
|
+
when 252 then 438
|
146
|
+
when 253 then 442
|
147
|
+
when 254 then 492
|
148
|
+
when 255 then 620
|
149
|
+
when 256 then 470
|
150
|
+
when 257 then 578
|
151
|
+
when 258 then 578
|
152
|
+
when 259 then 578
|
153
|
+
when 261 then 616
|
154
|
+
when 262 then 499
|
155
|
+
when 263 then 620
|
156
|
+
when 264 then 642
|
157
|
+
when 265 then 752
|
158
|
+
when 266 then 752
|
159
|
+
when 267 then 703
|
160
|
+
when 268 then 674
|
161
|
+
when 269 then 756
|
162
|
+
when 270 then 203
|
163
|
+
when 271 then 792
|
164
|
+
when 272 then 804
|
165
|
+
when 273 then 643
|
166
|
+
when 274 then 807
|
167
|
+
when 275 then 428
|
168
|
+
when 276 then 233
|
169
|
+
when 277 then 440
|
170
|
+
when 278 then 705
|
171
|
+
when 279 then 688
|
172
|
+
when 301 then 660
|
173
|
+
when 303 then 840
|
174
|
+
when 304 then 28
|
175
|
+
when 305 then 28
|
176
|
+
when 306 then 531
|
177
|
+
when 307 then 533
|
178
|
+
when 308 then 44
|
179
|
+
when 309 then 44
|
180
|
+
when 310 then 60
|
181
|
+
when 311 then 60
|
182
|
+
when 312 then 84
|
183
|
+
when 314 then 52
|
184
|
+
when 316 then 124
|
185
|
+
when 319 then 136
|
186
|
+
when 321 then 188
|
187
|
+
when 323 then 192
|
188
|
+
when 325 then 212
|
189
|
+
when 327 then 214
|
190
|
+
when 329 then 312
|
191
|
+
when 330 then 308
|
192
|
+
when 331 then 304
|
193
|
+
when 332 then 320
|
194
|
+
when 335 then 340
|
195
|
+
when 336 then 332
|
196
|
+
when 338 then 840
|
197
|
+
when 339 then 388
|
198
|
+
when 341 then 659
|
199
|
+
when 343 then 662
|
200
|
+
when 345 then 484
|
201
|
+
when 347 then 474
|
202
|
+
when 348 then 500
|
203
|
+
when 350 then 558
|
204
|
+
when 351 then 591
|
205
|
+
when 352 then 591
|
206
|
+
when 353 then 591
|
207
|
+
when 354 then 591
|
208
|
+
when 355 then 591
|
209
|
+
when 356 then 591
|
210
|
+
when 357 then 591
|
211
|
+
when 358 then 630
|
212
|
+
when 359 then 222
|
213
|
+
when 361 then 666
|
214
|
+
when 362 then 780
|
215
|
+
when 364 then 796
|
216
|
+
when 366 then 840
|
217
|
+
when 367 then 840
|
218
|
+
when 368 then 840
|
219
|
+
when 369 then 840
|
220
|
+
when 370 then 591
|
221
|
+
when 371 then 591
|
222
|
+
when 372 then 591
|
223
|
+
when 373 then 591
|
224
|
+
when 375 then 670
|
225
|
+
when 376 then 670
|
226
|
+
when 377 then 670
|
227
|
+
when 378 then 92
|
228
|
+
when 379 then 850
|
229
|
+
when 401 then 4
|
230
|
+
when 403 then 682
|
231
|
+
when 405 then 50
|
232
|
+
when 408 then 48
|
233
|
+
when 410 then 64
|
234
|
+
when 412 then 156
|
235
|
+
when 413 then 156
|
236
|
+
when 414 then 156
|
237
|
+
when 416 then 158
|
238
|
+
when 417 then 144
|
239
|
+
when 419 then 356
|
240
|
+
when 422 then 364
|
241
|
+
when 423 then 31
|
242
|
+
when 425 then 368
|
243
|
+
when 428 then 376
|
244
|
+
when 431 then 392
|
245
|
+
when 432 then 392
|
246
|
+
when 434 then 795
|
247
|
+
when 436 then 398
|
248
|
+
when 437 then 860
|
249
|
+
when 438 then 400
|
250
|
+
when 440 then 410
|
251
|
+
when 441 then 410
|
252
|
+
when 443 then 275
|
253
|
+
when 445 then 408
|
254
|
+
when 447 then 414
|
255
|
+
when 450 then 422
|
256
|
+
when 451 then 417
|
257
|
+
when 453 then 446
|
258
|
+
when 455 then 462
|
259
|
+
when 457 then 496
|
260
|
+
when 459 then 524
|
261
|
+
when 461 then 512
|
262
|
+
when 463 then 586
|
263
|
+
when 466 then 634
|
264
|
+
when 468 then 760
|
265
|
+
when 470 then 784
|
266
|
+
when 472 then 762
|
267
|
+
when 473 then 887
|
268
|
+
when 475 then 887
|
269
|
+
when 477 then 344
|
270
|
+
when 478 then 70
|
271
|
+
when 501 then 250
|
272
|
+
when 503 then 36
|
273
|
+
when 506 then 104
|
274
|
+
when 508 then 96
|
275
|
+
when 510 then 583
|
276
|
+
when 511 then 585
|
277
|
+
when 512 then 554
|
278
|
+
when 514 then 116
|
279
|
+
when 515 then 116
|
280
|
+
when 516 then 162
|
281
|
+
when 518 then 184
|
282
|
+
when 520 then 242
|
283
|
+
when 523 then 166
|
284
|
+
when 525 then 360
|
285
|
+
when 529 then 296
|
286
|
+
when 531 then 418
|
287
|
+
when 533 then 458
|
288
|
+
when 536 then 580
|
289
|
+
when 538 then 584
|
290
|
+
when 540 then 540
|
291
|
+
when 542 then 570
|
292
|
+
when 544 then 520
|
293
|
+
when 546 then 258
|
294
|
+
when 548 then 608
|
295
|
+
when 553 then 598
|
296
|
+
when 555 then 612
|
297
|
+
when 557 then 90
|
298
|
+
when 559 then 16
|
299
|
+
when 561 then 882
|
300
|
+
when 563 then 702
|
301
|
+
when 564 then 702
|
302
|
+
when 565 then 702
|
303
|
+
when 566 then 702
|
304
|
+
when 567 then 764
|
305
|
+
when 570 then 776
|
306
|
+
when 572 then 798
|
307
|
+
when 574 then 704
|
308
|
+
when 576 then 548
|
309
|
+
when 577 then 548
|
310
|
+
when 578 then 876
|
311
|
+
when 601 then 710
|
312
|
+
when 603 then 24
|
313
|
+
when 605 then 12
|
314
|
+
when 607 then 250
|
315
|
+
when 608 then 826
|
316
|
+
when 609 then 108
|
317
|
+
when 610 then 204
|
318
|
+
when 611 then 72
|
319
|
+
when 621 then 262
|
320
|
+
when 613 then 120
|
321
|
+
when 615 then 178
|
322
|
+
when 616 then 174
|
323
|
+
when 617 then 132
|
324
|
+
when 618 then 250
|
325
|
+
when 619 then 384
|
326
|
+
when 620 then 174
|
327
|
+
when 622 then 818
|
328
|
+
when 624 then 231
|
329
|
+
when 625 then 232
|
330
|
+
when 626 then 266
|
331
|
+
when 627 then 288
|
332
|
+
when 629 then 270
|
333
|
+
when 630 then 624
|
334
|
+
when 631 then 226
|
335
|
+
when 632 then 324
|
336
|
+
when 633 then 854
|
337
|
+
when 634 then 404
|
338
|
+
when 635 then 250
|
339
|
+
when 636 then 430
|
340
|
+
when 637 then 430
|
341
|
+
when 638 then 728
|
342
|
+
when 642 then 434
|
343
|
+
when 644 then 426
|
344
|
+
when 645 then 480
|
345
|
+
when 647 then 450
|
346
|
+
when 649 then 466
|
347
|
+
when 650 then 508
|
348
|
+
when 654 then 478
|
349
|
+
when 655 then 454
|
350
|
+
when 656 then 566
|
351
|
+
when 659 then 516
|
352
|
+
when 660 then 638
|
353
|
+
when 661 then 646
|
354
|
+
when 662 then 729
|
355
|
+
when 663 then 686
|
356
|
+
when 664 then 690
|
357
|
+
when 665 then 654
|
358
|
+
when 666 then 706
|
359
|
+
when 667 then 694
|
360
|
+
when 668 then 678
|
361
|
+
when 669 then 748
|
362
|
+
when 670 then 148
|
363
|
+
when 671 then 768
|
364
|
+
when 672 then 788
|
365
|
+
when 674 then 834
|
366
|
+
when 675 then 800
|
367
|
+
when 676 then 180
|
368
|
+
when 677 then 834
|
369
|
+
when 678 then 894
|
370
|
+
when 679 then 716
|
371
|
+
when 701 then 32
|
372
|
+
when 710 then 76
|
373
|
+
when 720 then 68
|
374
|
+
when 725 then 152
|
375
|
+
when 730 then 170
|
376
|
+
when 735 then 218
|
377
|
+
when 740 then 238
|
378
|
+
when 745 then 254
|
379
|
+
when 750 then 328
|
380
|
+
when 755 then 600
|
381
|
+
when 760 then 604
|
382
|
+
when 765 then 740
|
383
|
+
when 770 then 858
|
384
|
+
when 775 then 862
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
end
|
389
|
+
|
390
|
+
end
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
@@ -216,19 +216,19 @@ module NMEAPlus
|
|
216
216
|
end
|
217
217
|
|
218
218
|
# use shorthand for data types as defined in http://catb.org/gpsd/AIVDM.html
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
219
|
+
alias _u _6b_unsigned_integer
|
220
|
+
alias _U _6b_unsigned_integer_scaled
|
221
|
+
alias _i _6b_integer
|
222
|
+
alias _I _6b_integer_scaled
|
223
|
+
alias _b _6b_boolean
|
224
|
+
alias _nb _6b_negated_boolean
|
225
|
+
alias _e _6b_unsigned_integer
|
226
|
+
alias _t _6b_string_nullterminated
|
227
|
+
alias _tt _6b_string
|
228
|
+
alias _T _8b_data_string
|
229
|
+
alias _d _2b_data_string
|
230
|
+
alias _UU _6b_unsigned_integer_scaled_shifted
|
231
|
+
alias _II _6b_integer_scaled_shifted
|
232
232
|
|
233
233
|
end
|
234
234
|
end
|
@@ -102,14 +102,21 @@ module NMEAPlus
|
|
102
102
|
payload_reader :bearing4, 65, 10, :_u, 720
|
103
103
|
payload_reader :distance4, 75, 10, :_u
|
104
104
|
|
105
|
+
# Container for bearing / distance
|
105
106
|
class ShapePoint
|
106
107
|
attr_accessor :bearing
|
107
108
|
attr_accessor :distance
|
108
|
-
attr_accessor :
|
109
|
+
attr_accessor :scale_factor
|
110
|
+
|
111
|
+
# @!parse attr_reader :distance_meters
|
112
|
+
# @return [Integer] The scaled distance in meters
|
113
|
+
def distance_meters
|
114
|
+
distance * (10**scale_factor)
|
115
|
+
end
|
109
116
|
end
|
110
117
|
|
111
118
|
# @!parse attr_reader :points
|
112
|
-
# @return [Array] Array of
|
119
|
+
# @return [Array] Array of {ShapePoint} objects
|
113
120
|
def points
|
114
121
|
ret = []
|
115
122
|
|
@@ -119,7 +126,7 @@ module NMEAPlus
|
|
119
126
|
sp = ShapePoint.new
|
120
127
|
sp.bearing = send("bearing#{i}")
|
121
128
|
sp.distance = d
|
122
|
-
sp.
|
129
|
+
sp.scale_factor = scale_Factor
|
123
130
|
ret << sp
|
124
131
|
end
|
125
132
|
ret
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require_relative "payload"
|
2
|
+
require_relative "mmsi_info"
|
2
3
|
|
3
4
|
module NMEAPlus
|
4
5
|
module Message
|
@@ -12,368 +13,11 @@ module NMEAPlus
|
|
12
13
|
payload_reader :repeat_indicator, 6, 2, :_u
|
13
14
|
payload_reader :source_mmsi, 8, 30, :_u
|
14
15
|
|
15
|
-
#
|
16
|
-
# @!parse attr_reader :
|
17
|
-
# @return [
|
18
|
-
def
|
19
|
-
|
20
|
-
when /[2-7]......../ then :individual_ship
|
21
|
-
when /00...1.../ then :coast_station
|
22
|
-
when /00...2.../ then :harbor_station
|
23
|
-
when /00...3.../ then :pilot_station
|
24
|
-
when /00...4.../ then :ais_repeater_station
|
25
|
-
when /00......./ then :coast_station
|
26
|
-
when /111...1../ then :sar_aircraft_fixed
|
27
|
-
when /111...5../ then :sar_aircraft_helicopter
|
28
|
-
when /1......../ then :sar_aircraft
|
29
|
-
when /8......../ then :handheld
|
30
|
-
when /98......./ then :auxiliary_craft
|
31
|
-
when /970....../ then :sar_transmitter
|
32
|
-
when /972....../ then :man_overboard
|
33
|
-
when /974....../ then :epirb
|
34
|
-
when /99...1.../ then :aton_physical
|
35
|
-
when /99...6.../ then :aton_virtual
|
36
|
-
when /99......./ then :aton
|
37
|
-
else
|
38
|
-
:unknown_mmsi_category
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# The MMSI Maritime Identification Digits (MID)
|
43
|
-
# @!parse attr_reader :mid
|
44
|
-
# @return [Integer] the MID
|
45
|
-
def mid
|
46
|
-
range = case mmsi_category
|
47
|
-
when :individual_ship then 0..2
|
48
|
-
when :coast_station, :harbor_station, :pilot_station, :ais_repeater_station then 2..4
|
49
|
-
when :sar_aircraft, :sar_aircraft_fixed, :sar_aircraft_helicopter then 3..5
|
50
|
-
when :aton_physical, :aton_virtual, :aton then 2..4
|
51
|
-
when :auxiliary_craft then 2..4
|
52
|
-
when :handheld then 1..3
|
53
|
-
when :sar_transmitter, :man_overboard, :epirb then 3..5
|
54
|
-
end
|
55
|
-
return nil if range.nil?
|
56
|
-
source_mmsi.to_s.rjust(9, '0')[range].to_i
|
57
|
-
end
|
58
|
-
|
59
|
-
# The ISO 3166-1 indicated by the MMSI Maritime Identification Digits (MID)
|
60
|
-
# @!parse attr_reader :mid_country
|
61
|
-
# @return [Integer] the MID
|
62
|
-
def mid_country
|
63
|
-
# https://github.com/S73417H/MIDs
|
64
|
-
# https://github.com/alexrabarts/iso_country_codes
|
65
|
-
# JSON.parse(IO.read("mids.json")).each {|k, v| puts "when #{k} then #{IsoCountryCodes.find(v[1]).numeric.to_i}" }
|
66
|
-
case mid
|
67
|
-
when 201 then 8
|
68
|
-
when 202 then 20
|
69
|
-
when 203 then 40
|
70
|
-
when 204 then 620
|
71
|
-
when 205 then 56
|
72
|
-
when 206 then 112
|
73
|
-
when 207 then 100
|
74
|
-
when 208 then 336
|
75
|
-
when 209 then 196
|
76
|
-
when 210 then 196
|
77
|
-
when 211 then 276
|
78
|
-
when 212 then 196
|
79
|
-
when 213 then 268
|
80
|
-
when 214 then 498
|
81
|
-
when 215 then 470
|
82
|
-
when 216 then 51
|
83
|
-
when 218 then 276
|
84
|
-
when 219 then 208
|
85
|
-
when 220 then 208
|
86
|
-
when 224 then 724
|
87
|
-
when 225 then 724
|
88
|
-
when 226 then 250
|
89
|
-
when 227 then 250
|
90
|
-
when 228 then 250
|
91
|
-
when 229 then 470
|
92
|
-
when 230 then 246
|
93
|
-
when 231 then 234
|
94
|
-
when 232 then 826
|
95
|
-
when 233 then 826
|
96
|
-
when 234 then 826
|
97
|
-
when 235 then 826
|
98
|
-
when 236 then 292
|
99
|
-
when 237 then 300
|
100
|
-
when 238 then 191
|
101
|
-
when 239 then 300
|
102
|
-
when 240 then 300
|
103
|
-
when 241 then 300
|
104
|
-
when 242 then 504
|
105
|
-
when 243 then 348
|
106
|
-
when 244 then 528
|
107
|
-
when 245 then 528
|
108
|
-
when 246 then 528
|
109
|
-
when 247 then 380
|
110
|
-
when 248 then 470
|
111
|
-
when 250 then 372
|
112
|
-
when 251 then 352
|
113
|
-
when 252 then 438
|
114
|
-
when 253 then 442
|
115
|
-
when 254 then 492
|
116
|
-
when 255 then 620
|
117
|
-
when 256 then 470
|
118
|
-
when 257 then 578
|
119
|
-
when 258 then 578
|
120
|
-
when 259 then 578
|
121
|
-
when 261 then 616
|
122
|
-
when 262 then 499
|
123
|
-
when 263 then 620
|
124
|
-
when 264 then 642
|
125
|
-
when 265 then 752
|
126
|
-
when 266 then 752
|
127
|
-
when 267 then 703
|
128
|
-
when 268 then 674
|
129
|
-
when 269 then 756
|
130
|
-
when 270 then 203
|
131
|
-
when 271 then 792
|
132
|
-
when 272 then 804
|
133
|
-
when 273 then 643
|
134
|
-
when 274 then 807
|
135
|
-
when 275 then 428
|
136
|
-
when 276 then 233
|
137
|
-
when 277 then 440
|
138
|
-
when 278 then 705
|
139
|
-
when 279 then 688
|
140
|
-
when 301 then 660
|
141
|
-
when 303 then 840
|
142
|
-
when 304 then 28
|
143
|
-
when 305 then 28
|
144
|
-
when 306 then 531
|
145
|
-
when 307 then 533
|
146
|
-
when 308 then 44
|
147
|
-
when 309 then 44
|
148
|
-
when 310 then 60
|
149
|
-
when 311 then 60
|
150
|
-
when 312 then 84
|
151
|
-
when 314 then 52
|
152
|
-
when 316 then 124
|
153
|
-
when 319 then 136
|
154
|
-
when 321 then 188
|
155
|
-
when 323 then 192
|
156
|
-
when 325 then 212
|
157
|
-
when 327 then 214
|
158
|
-
when 329 then 312
|
159
|
-
when 330 then 308
|
160
|
-
when 331 then 304
|
161
|
-
when 332 then 320
|
162
|
-
when 335 then 340
|
163
|
-
when 336 then 332
|
164
|
-
when 338 then 840
|
165
|
-
when 339 then 388
|
166
|
-
when 341 then 659
|
167
|
-
when 343 then 662
|
168
|
-
when 345 then 484
|
169
|
-
when 347 then 474
|
170
|
-
when 348 then 500
|
171
|
-
when 350 then 558
|
172
|
-
when 351 then 591
|
173
|
-
when 352 then 591
|
174
|
-
when 353 then 591
|
175
|
-
when 354 then 591
|
176
|
-
when 358 then 630
|
177
|
-
when 359 then 222
|
178
|
-
when 361 then 666
|
179
|
-
when 362 then 780
|
180
|
-
when 364 then 796
|
181
|
-
when 366 then 840
|
182
|
-
when 367 then 840
|
183
|
-
when 368 then 840
|
184
|
-
when 369 then 840
|
185
|
-
when 370 then 591
|
186
|
-
when 371 then 591
|
187
|
-
when 372 then 591
|
188
|
-
when 373 then 591
|
189
|
-
when 375 then 670
|
190
|
-
when 376 then 670
|
191
|
-
when 377 then 670
|
192
|
-
when 378 then 92
|
193
|
-
when 379 then 850
|
194
|
-
when 401 then 4
|
195
|
-
when 403 then 682
|
196
|
-
when 405 then 50
|
197
|
-
when 408 then 48
|
198
|
-
when 410 then 64
|
199
|
-
when 412 then 156
|
200
|
-
when 413 then 156
|
201
|
-
when 414 then 156
|
202
|
-
when 416 then 158
|
203
|
-
when 417 then 144
|
204
|
-
when 419 then 356
|
205
|
-
when 422 then 364
|
206
|
-
when 423 then 31
|
207
|
-
when 425 then 368
|
208
|
-
when 428 then 376
|
209
|
-
when 431 then 392
|
210
|
-
when 432 then 392
|
211
|
-
when 434 then 795
|
212
|
-
when 436 then 398
|
213
|
-
when 437 then 860
|
214
|
-
when 438 then 400
|
215
|
-
when 440 then 410
|
216
|
-
when 441 then 410
|
217
|
-
when 443 then 275
|
218
|
-
when 445 then 408
|
219
|
-
when 447 then 414
|
220
|
-
when 450 then 422
|
221
|
-
when 451 then 417
|
222
|
-
when 453 then 446
|
223
|
-
when 455 then 462
|
224
|
-
when 457 then 496
|
225
|
-
when 459 then 524
|
226
|
-
when 461 then 512
|
227
|
-
when 463 then 586
|
228
|
-
when 466 then 634
|
229
|
-
when 468 then 760
|
230
|
-
when 470 then 784
|
231
|
-
when 472 then 762
|
232
|
-
when 473 then 887
|
233
|
-
when 475 then 887
|
234
|
-
when 477 then 344
|
235
|
-
when 478 then 70
|
236
|
-
when 501 then 250
|
237
|
-
when 503 then 36
|
238
|
-
when 506 then 104
|
239
|
-
when 508 then 96
|
240
|
-
when 510 then 583
|
241
|
-
when 511 then 585
|
242
|
-
when 512 then 554
|
243
|
-
when 514 then 116
|
244
|
-
when 515 then 116
|
245
|
-
when 516 then 162
|
246
|
-
when 518 then 184
|
247
|
-
when 520 then 242
|
248
|
-
when 523 then 166
|
249
|
-
when 525 then 360
|
250
|
-
when 529 then 296
|
251
|
-
when 531 then 418
|
252
|
-
when 533 then 458
|
253
|
-
when 536 then 580
|
254
|
-
when 538 then 584
|
255
|
-
when 540 then 540
|
256
|
-
when 542 then 570
|
257
|
-
when 544 then 520
|
258
|
-
when 546 then 258
|
259
|
-
when 548 then 608
|
260
|
-
when 553 then 598
|
261
|
-
when 555 then 612
|
262
|
-
when 557 then 90
|
263
|
-
when 559 then 16
|
264
|
-
when 561 then 882
|
265
|
-
when 563 then 702
|
266
|
-
when 564 then 702
|
267
|
-
when 565 then 702
|
268
|
-
when 566 then 702
|
269
|
-
when 567 then 764
|
270
|
-
when 570 then 776
|
271
|
-
when 572 then 798
|
272
|
-
when 574 then 704
|
273
|
-
when 576 then 548
|
274
|
-
when 577 then 548
|
275
|
-
when 578 then 876
|
276
|
-
when 601 then 710
|
277
|
-
when 603 then 24
|
278
|
-
when 605 then 12
|
279
|
-
when 607 then 250
|
280
|
-
when 608 then 826
|
281
|
-
when 609 then 108
|
282
|
-
when 610 then 204
|
283
|
-
when 611 then 72
|
284
|
-
when 621 then 262
|
285
|
-
when 613 then 120
|
286
|
-
when 615 then 178
|
287
|
-
when 616 then 174
|
288
|
-
when 617 then 132
|
289
|
-
when 618 then 250
|
290
|
-
when 619 then 384
|
291
|
-
when 620 then 174
|
292
|
-
when 622 then 818
|
293
|
-
when 624 then 231
|
294
|
-
when 625 then 232
|
295
|
-
when 626 then 266
|
296
|
-
when 627 then 288
|
297
|
-
when 629 then 270
|
298
|
-
when 630 then 624
|
299
|
-
when 631 then 226
|
300
|
-
when 632 then 324
|
301
|
-
when 633 then 854
|
302
|
-
when 634 then 404
|
303
|
-
when 635 then 250
|
304
|
-
when 636 then 430
|
305
|
-
when 637 then 430
|
306
|
-
when 638 then 728
|
307
|
-
when 642 then 434
|
308
|
-
when 644 then 426
|
309
|
-
when 645 then 480
|
310
|
-
when 647 then 450
|
311
|
-
when 649 then 466
|
312
|
-
when 650 then 508
|
313
|
-
when 654 then 478
|
314
|
-
when 655 then 454
|
315
|
-
when 656 then 566
|
316
|
-
when 659 then 516
|
317
|
-
when 660 then 638
|
318
|
-
when 661 then 646
|
319
|
-
when 662 then 729
|
320
|
-
when 663 then 686
|
321
|
-
when 664 then 690
|
322
|
-
when 665 then 654
|
323
|
-
when 666 then 706
|
324
|
-
when 667 then 694
|
325
|
-
when 668 then 678
|
326
|
-
when 669 then 748
|
327
|
-
when 670 then 148
|
328
|
-
when 671 then 768
|
329
|
-
when 672 then 788
|
330
|
-
when 674 then 834
|
331
|
-
when 675 then 800
|
332
|
-
when 676 then 180
|
333
|
-
when 677 then 834
|
334
|
-
when 678 then 894
|
335
|
-
when 679 then 716
|
336
|
-
when 701 then 32
|
337
|
-
when 710 then 76
|
338
|
-
when 720 then 68
|
339
|
-
when 725 then 152
|
340
|
-
when 730 then 170
|
341
|
-
when 735 then 218
|
342
|
-
when 740 then 238
|
343
|
-
when 745 then 254
|
344
|
-
when 750 then 328
|
345
|
-
when 755 then 600
|
346
|
-
when 760 then 604
|
347
|
-
when 765 then 740
|
348
|
-
when 770 then 858
|
349
|
-
when 775 then 862
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
# The MMSI category as defined by ITU-R M.585-7
|
354
|
-
# @!parse attr_reader :mmsi_category_description
|
355
|
-
# @return [String] the human-readable description the MMSI category
|
356
|
-
def mmsi_category_description
|
357
|
-
case mmsi_category
|
358
|
-
when :individual_ship then "Individual ship"
|
359
|
-
when :coast_station then "Coast station"
|
360
|
-
when :harbor_station then "Harbor station"
|
361
|
-
when :pilot_station then "Pilot station"
|
362
|
-
when :ais_repeater_station then "AIS repeater station"
|
363
|
-
when :sar_aircraft then "SAR aircraft"
|
364
|
-
when :sar_aircraft_fixed then "SAR fixed-wing aircraft"
|
365
|
-
when :sar_aircraft_helicopter then "SAR helicopter"
|
366
|
-
when :aton_physical then "Physical AIS AtoN"
|
367
|
-
when :aton_virtual then "Virtual AIS AtoN"
|
368
|
-
when :aton then "AIS Aid to Navigation"
|
369
|
-
when :auxiliary_craft then "Auxiliary craft"
|
370
|
-
when :handheld then "Handheld transceiver"
|
371
|
-
when :sar_transmitter then "AIS-SART"
|
372
|
-
when :man_overboard then "MOB (Man Overboard)"
|
373
|
-
when :epirb then "EPIRB"
|
374
|
-
else
|
375
|
-
mmsi_category.to_s
|
376
|
-
end
|
16
|
+
# Detailed information produced from the MMSI
|
17
|
+
# @!parse attr_reader :source_mmsi_info
|
18
|
+
# @return [MMSIInfo] MMSI information structure
|
19
|
+
def source_mmsi_info
|
20
|
+
MMSIInfo.new(source_mmsi)
|
377
21
|
end
|
378
22
|
|
379
23
|
# The ship cargo type description lookup table
|
@@ -447,7 +91,7 @@ module NMEAPlus
|
|
447
91
|
|
448
92
|
# An MMSI is associated with an auxiliary craft when it is of the form 98XXXYYYY
|
449
93
|
def auxiliary_craft?
|
450
|
-
|
94
|
+
source_mmsi_info.category == :auxiliary_craft
|
451
95
|
end
|
452
96
|
|
453
97
|
# @param code [Integer] The navigational status id
|
@@ -1,4 +1,9 @@
|
|
1
1
|
require_relative 'vdm_msg'
|
2
|
+
require_relative 'vdm_msg6d1f0'
|
3
|
+
require_relative 'vdm_msg6d1f2'
|
4
|
+
require_relative 'vdm_msg6d1f3'
|
5
|
+
require_relative 'vdm_msg6d1f4'
|
6
|
+
require_relative 'vdm_msg6d1f5'
|
2
7
|
require_relative 'vdm_msg6d235f10'
|
3
8
|
require_relative 'vdm_msg6d1022f61'
|
4
9
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'vdm_msg6_dynamic_payload'
|
2
|
+
|
3
|
+
module NMEAPlus
|
4
|
+
module Message
|
5
|
+
module AIS
|
6
|
+
module VDMPayload
|
7
|
+
|
8
|
+
# Type 6: Binary Addressed Message Subtype: IFM 0: Text using 6-bit ASCII
|
9
|
+
class VDMMsg6d1f0 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg6DynamicPayload
|
10
|
+
payload_reader :acknowledge_required?, 88, 1, :_b
|
11
|
+
payload_reader :sequence_number, 89, 11, :_u
|
12
|
+
payload_reader :text, 100, 906, :_t
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require_relative 'vdm_msg6_dynamic_payload'
|
2
|
+
|
3
|
+
module NMEAPlus
|
4
|
+
module Message
|
5
|
+
module AIS
|
6
|
+
module VDMPayload
|
7
|
+
|
8
|
+
# Type 6: Binary Addressed Message Subtype: IFM 2: Interrogation for a specific FM
|
9
|
+
class VDMMsg6d1f2 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg6DynamicPayload
|
10
|
+
payload_reader :requested_dac, 88, 10, :_u
|
11
|
+
payload_reader :requested_fid, 98, 6, :_u
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require_relative 'vdm_msg6_dynamic_payload'
|
2
|
+
|
3
|
+
module NMEAPlus
|
4
|
+
module Message
|
5
|
+
module AIS
|
6
|
+
module VDMPayload
|
7
|
+
|
8
|
+
# Type 6: Binary Addressed Message Subtype: IFM 3: Capability interrogation
|
9
|
+
class VDMMsg6d1f3 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg6DynamicPayload
|
10
|
+
payload_reader :requested_dac, 88, 10, :_u
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'vdm_msg6_dynamic_payload'
|
2
|
+
|
3
|
+
module NMEAPlus
|
4
|
+
module Message
|
5
|
+
module AIS
|
6
|
+
module VDMPayload
|
7
|
+
|
8
|
+
# Type 6: Binary Addressed Message Subtype: IFM 4: Capability reply
|
9
|
+
class VDMMsg6d1f4 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg6DynamicPayload
|
10
|
+
|
11
|
+
# The availibility table for functional IDs; there are 64 boolean entries
|
12
|
+
# @!parse attr_reader :fid_availability
|
13
|
+
# @return [Array] An array of booleans
|
14
|
+
def fid_availability
|
15
|
+
(0...128).step(2).to_a.map do |pos|
|
16
|
+
_6b_boolean(88 + pos, 1)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require_relative 'vdm_msg6_dynamic_payload'
|
2
|
+
|
3
|
+
module NMEAPlus
|
4
|
+
module Message
|
5
|
+
module AIS
|
6
|
+
module VDMPayload
|
7
|
+
|
8
|
+
# Type 6: Binary Addressed Message Subtype: IFM 5: Application acknowledgement to an addressed binary message
|
9
|
+
class VDMMsg6d1f5 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg6DynamicPayload
|
10
|
+
payload_reader :received_fm_dac, 88, 10, :_u
|
11
|
+
payload_reader :received_fm_fid, 98, 6, :_u
|
12
|
+
payload_reader :sequence_number, 104, 11, :_u
|
13
|
+
payload_reader :ai_available?, 115, 1, :_b
|
14
|
+
payload_reader :ai_response, 116, 3, :_e
|
15
|
+
|
16
|
+
# The AI response description
|
17
|
+
# @!parse attr_reader :ai_response_description
|
18
|
+
# @return [String] The description of the AI response
|
19
|
+
def ai_response_description
|
20
|
+
case ai_response
|
21
|
+
when 0 then "Unable to respond"
|
22
|
+
when 1 then "Reception acknowledged"
|
23
|
+
when 2 then "Response to follow"
|
24
|
+
when 3 then "Able to respond but currently inhibited"
|
25
|
+
else
|
26
|
+
"Reserved for future use"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative 'vdm_msg8_dynamic_payload'
|
2
|
+
|
3
|
+
module NMEAPlus
|
4
|
+
module Message
|
5
|
+
module AIS
|
6
|
+
module VDMPayload
|
7
|
+
|
8
|
+
# Type 8: Binary Addressed Message Subtype: IFM 0: Text using 6-bit ASCII
|
9
|
+
class VDMMsg8d1f0 < NMEAPlus::Message::AIS::VDMPayload::VDMMsg8DynamicPayload
|
10
|
+
payload_reader :acknowledge_required?, 56, 1, :_b
|
11
|
+
payload_reader :sequence_number, 57, 11, :_u
|
12
|
+
payload_reader :text, 68, 906, :_t
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -63,7 +63,7 @@ module NMEAPlus
|
|
63
63
|
|
64
64
|
# @return [bool] Whether the checksum calculated from the payload matches the checksum given in the message
|
65
65
|
def checksum_ok?
|
66
|
-
|
66
|
+
0 == calculated_checksum.casecmp(checksum)
|
67
67
|
end
|
68
68
|
|
69
69
|
# return [bool] Whether the checksums for all available message parts are OK
|
data/lib/nmea_plus/version.rb
CHANGED
data/lib/nmea_plus.rb
CHANGED
@@ -3,14 +3,16 @@ require 'nmea_plus/version'
|
|
3
3
|
require 'nmea_plus/generated_parser/parser'
|
4
4
|
require 'nmea_plus/generated_parser/tokenizer'
|
5
5
|
|
6
|
-
# NMEAPlus contains classes for parsing and decoding NMEA and AIS messages
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# NMEAPlus contains classes for parsing and decoding NMEA and AIS messages, of which the {NMEAPlus::SourceDecoder}
|
7
|
+
# is most relevant. Parsed messages extend from the {Message::NMEA::NMEAMessage} object, and any binary
|
8
|
+
# AIS playloads are decoded into objects that extend from {Message::AIS::AISMessage}.
|
9
9
|
# @author Ian Katz
|
10
10
|
module NMEAPlus
|
11
11
|
|
12
|
-
# The
|
13
|
-
#
|
12
|
+
# The SourceDecoder is meant as the primary entry point into the {NMEAPlus} module.
|
13
|
+
# It wraps a {Decoder} object and an IO object, converting IO's #each_line functionality
|
14
|
+
# to {#each_message} and/or {#each_complete_message},
|
15
|
+
# which yield {NMEAPlus::Message} objects representing the parsed data.
|
14
16
|
class SourceDecoder
|
15
17
|
# False by default.
|
16
18
|
# @return [bool] whether to throw an exception on lines that don't properly parse
|
@@ -30,9 +32,20 @@ module NMEAPlus
|
|
30
32
|
@decoder = NMEAPlus::Decoder.new
|
31
33
|
end
|
32
34
|
|
33
|
-
# Executes the block for every valid NMEA message in the source stream
|
35
|
+
# Executes the block for every valid NMEA message in the source stream.
|
36
|
+
# In practice, you should use {#each_complete_message} unless you have a very compelling reason not to.
|
34
37
|
# @yield [NMEAPlus::Message] A parsed message
|
35
38
|
# @return [void]
|
39
|
+
# @example
|
40
|
+
# input = "$GPGGA,123519,4807.038,N,01131.000,W,1,08,0.9,545.4,M,46.9,M,2.2,123*4b"
|
41
|
+
# io_source = StringIO.new(input) # source decoder works on any IO object
|
42
|
+
# source_decoder = NMEAPlus::SourceDecoder.new(io_source)
|
43
|
+
# source_decoder.each_message do |message|
|
44
|
+
# if "GGA" == message.interpreted_data_type
|
45
|
+
# puts "Latitude: #{message.latitude} / Longitude: #{message.longtitude}"
|
46
|
+
# # prints "Latitude: 48.1173 / Longitude: -11.516666666666666666"
|
47
|
+
# end
|
48
|
+
# end
|
36
49
|
def each_message
|
37
50
|
@source.each_line do |line|
|
38
51
|
if @throw_on_parse_fail
|
@@ -49,25 +62,34 @@ module NMEAPlus
|
|
49
62
|
end
|
50
63
|
end
|
51
64
|
|
52
|
-
#
|
53
|
-
#
|
65
|
+
# Attempts to group multipart NMEA messages into chains, and executes the block once for every complete chain.
|
66
|
+
#
|
54
67
|
# @yield [NMEAPlus::Message] A parsed message that may contain subsequent parts
|
55
68
|
# @return [void]
|
69
|
+
# @example
|
70
|
+
# input1 = "!AIVDM,2,1,0,A,58wt8Ui`g??r21`7S=:22058<v05Htp000000015>8OA;0sk,0*7B"
|
71
|
+
# input2 = "!AIVDM,2,2,0,A,eQ8823mDm3kP00000000000,2*5D"
|
72
|
+
# io_source = StringIO.new("#{input1}\n#{input2}") # source decoder works on any IO object
|
73
|
+
# source_decoder = NMEAPlus::SourceDecoder.new(io_source)
|
74
|
+
# source_decoder.each_complete_message do |message|
|
75
|
+
# if message.ais && message.ais.message_type == 5
|
76
|
+
# ais = message.ais # ais payload shortcut
|
77
|
+
# puts "Ship with MMSI #{ais.source_mmsi} (#{ais.name.strip}) is going to #{ais.destination.strip}"
|
78
|
+
# # prints "Ship with MMSI 603916439 (ARCO AVON) is going to HOUSTON"
|
79
|
+
# end
|
80
|
+
# end
|
56
81
|
def each_complete_message
|
57
|
-
partials = {}
|
82
|
+
partials = {} # hash of message type to message-chain-in-progress
|
58
83
|
each_message do |msg|
|
59
|
-
slot = msg.data_type
|
84
|
+
slot = msg.data_type # the slot in the hash
|
60
85
|
|
61
|
-
if partials[slot].nil?
|
86
|
+
if partials[slot].nil? # no message in there
|
62
87
|
partials[slot] = msg
|
63
|
-
|
64
|
-
#
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
else
|
69
|
-
partials[slot].add_message_part(msg)
|
70
|
-
end
|
88
|
+
elsif 1 != (msg.message_number - partials[slot].message_number) # broken sequence
|
89
|
+
# error! just overwrite what was there
|
90
|
+
partials[slot] = msg
|
91
|
+
else # chain on to what's there
|
92
|
+
partials[slot].add_message_part(msg)
|
71
93
|
end
|
72
94
|
|
73
95
|
# take action if we've completed the chain
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nmea_plus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Katz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: racc
|
@@ -70,7 +70,7 @@ dependencies:
|
|
70
70
|
requirements:
|
71
71
|
- - ~>
|
72
72
|
- !ruby/object:Gem::Version
|
73
|
-
version: '0.
|
73
|
+
version: '0.36'
|
74
74
|
- - '>='
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
version: 0.31.0
|
@@ -80,7 +80,7 @@ dependencies:
|
|
80
80
|
requirements:
|
81
81
|
- - ~>
|
82
82
|
- !ruby/object:Gem::Version
|
83
|
-
version: '0.
|
83
|
+
version: '0.36'
|
84
84
|
- - '>='
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: 0.31.0
|
@@ -196,6 +196,7 @@ files:
|
|
196
196
|
- lib/nmea_plus/generated_parser/tokenizer.rb
|
197
197
|
- lib/nmea_plus/message/ais/base_ais.rb
|
198
198
|
- lib/nmea_plus/message/ais/vdm.rb
|
199
|
+
- lib/nmea_plus/message/ais/vdm_payload/mmsi_info.rb
|
199
200
|
- lib/nmea_plus/message/ais/vdm_payload/payload.rb
|
200
201
|
- lib/nmea_plus/message/ais/vdm_payload/sub_area.rb
|
201
202
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg.rb
|
@@ -212,10 +213,16 @@ files:
|
|
212
213
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6.rb
|
213
214
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6_dynamic_payload.rb
|
214
215
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1022f61.rb
|
216
|
+
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f0.rb
|
217
|
+
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f2.rb
|
218
|
+
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f3.rb
|
219
|
+
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f4.rb
|
220
|
+
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d1f5.rb
|
215
221
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg6d235f10.rb
|
216
222
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg7.rb
|
217
223
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg8.rb
|
218
224
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg8_dynamic_payload.rb
|
225
|
+
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg8d1f0.rb
|
219
226
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg8d1f22.rb
|
220
227
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg8d1f31.rb
|
221
228
|
- lib/nmea_plus/message/ais/vdm_payload/vdm_msg8d366f56.rb
|