feat: 导入 NMEA-0183 GPS 协议解析库(node-nmea)
Some checks failed
Node.js CI / build (10.x) (push) Has been cancelled
Node.js CI / build (12.x) (push) Has been cancelled
Node.js CI / build (14.x) (push) Has been cancelled
Node.js CI / build (15.x) (push) Has been cancelled

NMEA-0183 语句解析器,含 21 个语句类型 codec 与配套单元测试。

- codecs/:APB/BWC/DBT/GGA/GLL/GRMT/GSA/GSV/HDG/HDM/HDT/MWV/RDID/
  RMB/RMC/ROT/RSA/TXT/VTG/VWR/ZDA
- test/:各 codec 对应的 mocha 用例
- .github/workflows/:node与 npm-publish 流水线

许可证:MIT(原作者 James Penn)
This commit is contained in:
hyzl
2026-10-19 09:54:44 +08:00
commit b0a1993169
50 changed files with 1951 additions and 0 deletions

58
codecs/APB.js Normal file
View File

@@ -0,0 +1,58 @@
exports.ID = 'APB';
exports.TYPE = 'autopilot-b';
exports.decode = function(fields) {
/*
=== APB - Autopilot Sentence "B" ===
13 15
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12| 14|
| | | | | | | | | | | | | | |
$--APB,A,A,x.x,a,N,A,A,x.x,a,c--c,x.x,a,x.x,a*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Status
V = LORAN-C Blink or SNR warning
V = general warning flag or other navigation systems when a reliable
fix is not available
2. Status
V = Loran-C Cycle Lock warning flag
A = OK or not used
3. Cross Track Error Magnitude
4. Direction to steer, L or R
5. Cross Track Units, N = Nautical Miles
6. Status
A = Arrival Circle Entered
7. Status
A = Perpendicular passed at waypoint
8. Bearing origin to destination
9. M = Magnetic, T = True
10. Destination Waypoint ID
11. Bearing, present position to Destination
12. M = Magnetic, T = True
13. Heading to steer to destination waypoint
14. M = Magnetic, T = True
15. Checksum
*/
return {
sentence: exports.ID,
type: exports.TYPE,
status1 : fields[1],
status2 : fields[2],
xteMagn : +fields[3],
steerDir : fields[4],
xteUnit : fields[5],
arrivalCircleStatus : fields[6],
arrivalPerpendicularStatus : fields[7],
bearingOrig2Dest : +fields[8],
bearingOrig2DestType : fields[9],
waypoint : fields[10],
bearing2Dest : +fields[11],
bearingDestType : fields[12],
heading2steer : +fields[13],
headingDestType : fields[14]
}
}

42
codecs/BWC.js Normal file
View File

@@ -0,0 +1,42 @@
/*
=== BWC - Bearing & Distance to Waypoint - Great Circle ===
------------------------------------------------------------------------------
12
1 2 3 4 5 6 7 8 9 10 11| 13 14
| | | | | | | | | | | | | |
$--BEC,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x.x,T,x.x,M,x.x,N,c--c,m,*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. UTCTime
2. Waypoint Latitude
3. N = North, S = South
4. Waypoint Longitude
5. E = East, W = West
6. Bearing, True
7. T = True
8. Bearing, Magnetic
9. M = Magnetic
10. Nautical Miles
11. N = Nautical Miles
12. Waypoint ID
13. FAA mode indicator (NMEA 2.3 and later, optional)
14. Checksum
*/
exports.ID = 'BWC';
exports.TYPE = '2waypoint';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
lat: +fields[2],
latPole: fields[3],
lon: +fields[4],
lonPole: fields[5],
bearingtrue: +fields[6],
bearingmag: +fields[8],
distance: +fields[10],
id: fields[12]
}
}

45
codecs/DBT.js Normal file
View File

@@ -0,0 +1,45 @@
var helpers = require("../helpers.js")
/*
=== DBT - Depth below transducer ===
------------------------------------------------------------------------------
*******1 2 3 4 5 6 7
*******| | | | | | |
$--DBT,x.x,f,x.x,M,x.x,F*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Depth, feet
2. f = feet
3. Depth, meters
4. M = meters
5. Depth, Fathoms
6. F = Fathoms
7. Checksum
*/
exports.TYPE = 'depth-transducer';
exports.ID = 'DBT';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
depthMeters: +fields[3],
depthFeet: +fields[1]
}
}
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeFixed(msg.depthFeet,2));
result.push('f');
result.push(helpers.encodeFixed(msg.depthMeters, 2));
result.push('M');
result.push(helpers.encodeFixed(msg.depthFathoms, 2));
result.push('F');
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
}

72
codecs/GGA.js Normal file
View File

@@ -0,0 +1,72 @@
var helpers = require("../helpers.js")
exports.TYPE = 'fix';
exports.ID = 'GGA';
/*
11
1 2 3 4 5 6 7 8 9 10 | 12 13 14 15
| | | | | | | | | | | | | | |
$--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh
1) Time (UTC)
2) Latitude
3) N or S (North or South)
4) Longitude
5) E or W (East or West)
6) GPS Quality Indicator,
0 - fix not available,
1 - GPS fix,
2 - Differential GPS fix
7) Number of satellites in view, 00 - 12
8) Horizontal Dilution of precision
9) Antenna Altitude above/below mean-sea-level (geoid)
10) Units of antenna altitude, meters
11) Geoidal separation, the difference between the WGS-84 earth
ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
12) Units of geoidal separation, meters
13) Age of differential GPS data, time in seconds since last SC104
type 1 or 9 update, null field when DGPS is not used
14) Differential reference station ID, 0000-1023
15) Checksum
*/
var FIX_TYPE = ['none', 'fix', 'delta','pps','rtk','frtk','estimated','manual','simulation'];
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
timestamp: fields[1],
lat: fields[2],
latPole: fields[3],
lon: fields[4],
lonPole: fields[5],
fixType: FIX_TYPE[+fields[6]],
numSat: +fields[7],
horDilution: +fields[8],
alt: +fields[9],
altUnit: fields[10],
geoidalSep: +fields[11],
geoidalSepUnit: fields[12],
differentialAge: +fields[13],
differentialRefStn: fields[14]
};
}
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeTime(msg.timestamp));
result.push(helpers.encodeDegrees(msg.lat));
result.push(msg.latPole);
result.push(helpers.encodeDegrees(msg.lon));
result.push(msg.lonPole);
result.push(FIX_TYPE.indexOf(msg.fixType));
result.push(helpers.encodeValue(msg.numSat));
result.push(helpers.encodeFixed(msg.horDilution, 1));
result.push(helpers.encodeAltitude(msg.alt));
result.push(helpers.encodeGeoidalSeperation(msg.geoidalSep));
result.push(helpers.encodeFixed(msg.differentialAge, 2));
result.push(msg.differentialRefStn);
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
}

52
codecs/GLL.js Normal file
View File

@@ -0,0 +1,52 @@
var helpers = require("../helpers.js")
/*
=== GLL - Geographic Position - Latitude/Longitude ===
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8
| | | | | | | |
$--GLL,llll.ll,a,yyyyy.yy,a,hhmmss.ss,a,m,*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Latitude
2. N or S (North or South)
3. Longitude
4. E or W (East or West)
5. Universal Time Coordinated (UTC)
6. Status A - Data Valid, V - Data Invalid
7. FAA mode indicator (NMEA 2.3 and later)
8. Checksum
*/
exports.TYPE = 'geo-position';
exports.ID = 'GLL';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: 'geo-position',
timestamp: fields[5],
lat: fields[1],
latPole: fields[2],
lon: fields[3],
lonPole: fields[4],
timestamp: fields[5],
status: fields[6] == 'A' ? 'valid' : 'invalid'
};
}
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeDegrees(msg.lat));
result.push(msg.latPole);
result.push(helpers.encodeDegrees(msg.lon));
result.push(msg.lonPole);
result.push(helpers.encodeTime(msg.timestamp));
result.push('A');
result.push('D');
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
}

48
codecs/GRMT.js Normal file
View File

@@ -0,0 +1,48 @@
exports.ID = 'GRMT';
exports.TYPE = 'sensor-information';
exports.decode = function(fields) {
/*
=== PGRMT - Garmin Proprietary Sensor Status Information ===
The Garmin Proprietary sentence $PGRMT gives information concerning the status of a GPS sensor. This
sentence is transmitted once per minute regardless of the selected baud rate.
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9
| | | | | | | | |
$PGRMT,GPS19x-HVS Software Version 2.20,P,P,R,R,P,C,15,R*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Product, model and software version (variable length field, e.g., “GPS 10 SW VER 2.01 BT VER 1.27 764”)
2. ROM checksum test, P = pass, F = fail
3. Receiver failure discrete, P = pass, F = fail
4. Stored data lost, R = retained, L = lost
5. Real time clock lost, R = retained, L = lost
6. Oscillator drift discrete, P = pass, F = excessive drift detected
7. Data collection discrete, C = collecting, null if not collecting
8. GPS sensor temperature in degrees C
9. GPS sensor configuration data, R = retained, L = lost
Note: Some sensors have been seen to not provide all information above, in some cases just the product
model during boot. Example:
$PGRMT,GPS19x-HVS Software Version 2.20,,,,,,,,*6F
*/
return {
sentence: exports.ID,
type: exports.TYPE,
product : fields[1],
rom_checksum : fields[2],
receiver_failure : fields[3],
stored_data_lost : fields[4],
rtc_lost: fields[5],
oscillator_drift: fields[6],
data_collection: fields[7],
sensor_temperature: fields[8],
sensor_configuration: fields[9]
}
}

44
codecs/GSA.js Normal file
View File

@@ -0,0 +1,44 @@
/*
=== GSA - GPS DOP and active satellites ===
This is one of the sentences commonly emitted by GPS units.
------------------------------------------------------------------------------
1 2 3 4 14 15 16 17 18
| | | | | | | | |
$--GSA,a,a,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x.x,x.x,x.x*hh
------------------------------------------------------------------------------
Field Number:
1) Selection mode
2) Mode
3) ID of 1st satellite used for fix
4) ID of 2nd satellite used for fix
...
14) ID of 12th satellite used for fix
15) PDOP in meters
16) HDOP in meters
17) VDOP in meters
18) Checksum
*/
exports.TYPE = 'active-satellites';
exports.ID = 'GSA';
exports.decode = function(fields) {
// $GPGSA,A,3,12,05,25,29,,,,,,,,,9.4,7.6,5.6
var sats = [];
for (var i=1; i < 13; i++) {
if (fields[i+2]) sats.push(+fields[i+2]);
};
return {
sentence: exports.ID,
type: exports.TYPE,
selectionMode: fields[1],
mode: +fields[2],
satellites: sats,
PDOP: +fields[15],
HDOP: +fields[16],
VDOP: +fields[17]
};
}

23
codecs/GSV.js Normal file
View File

@@ -0,0 +1,23 @@
exports.ID = 'GSV';
exports.TYPE = 'satellite-list-partial';
exports.decode = function(fields) {
// $GPGSV,3,1,12, 05,58,322,36, 02,55,032,, 26,50,173,, 04,31,085,
var numRecords = (fields.length - 4) / 4,
sats = [];
for (var i=0; i < numRecords; i++) {
var offset = i * 4 + 4;
sats.push({id: fields[offset],
elevationDeg: +fields[offset+1],
azimuthTrue: +fields[offset+2],
SNRdB: +fields[offset+3]});
};
return {
sentence: exports.ID,
type: exports.TYPE,
numMsgs: +fields[1],
msgNum: +fields[2],
satsInView: +fields[3],
satellites: sats
};
}

36
codecs/HDG.js Normal file
View File

@@ -0,0 +1,36 @@
var helpers = require("../helpers.js")
/*
=== HDG - Magnetic heading, deviation, variation ===
------------------------------------------------------------------------------
1 2 3 4 5 6
| | | | | |
$--HDG,x.x,x.x,a,x.x,a*hh
------------------------------------------------------------------------------
Field Number:
1) Magnetic Sensor heading in degrees
2) Magnetic Deviation, degrees
3) Magnetic Deviation direction, E = Easterly, W = Westerly
4) Magnetic Variation degrees
5) Magnetic Variation direction, E = Easterly, W = Westerly
6) Checksum
*/
exports.TYPE = 'heading-deviation-variation';
exports.ID = 'HDG';
exports.decode = function (fields) {
console.log(fields);
return {
sentence: exports.ID,
type: 'heading-deviation-variation',
heading: +fields[1],
deviation: +fields[2],
deviationDirection: fields[3],
variation: +fields[4],
variationDirection: fields[5]
}
};

34
codecs/HDM.js Normal file
View File

@@ -0,0 +1,34 @@
var helpers = require("../helpers.js")
/*
=== HDM - Heading - Magnetic ===
------------------------------------------------------------------------------
1 2 3
| | |
$--HDM,x.x,M*hh
------------------------------------------------------------------------------
Field Number:
1) Heading Degrees, magnetic
2) M = Magnetic
3) Checksum
*/
exports.TYPE = 'heading-info-magnetic';
exports.ID = 'HDM';
exports.decode = function (fields) {
return {
sentence: exports.ID,
type: 'heading-info-magnetic',
heading: +fields[1]
}
};
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeFixed(msg.heading, 1));
result.push('M');
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
};

34
codecs/HDT.js Normal file
View File

@@ -0,0 +1,34 @@
var helpers = require("../helpers.js")
/*
=== HDT - Heading - True ===
------------------------------------------------------------------------------
1 2 3
| | |
$--HDT,x.x,T*hh
------------------------------------------------------------------------------
Field Number:
1) Heading Degrees, true
2) T = True
3) Checksum
*/
exports.TYPE = 'heading-info';
exports.ID = 'HDT';
exports.decode = function (fields) {
return {
sentence: exports.ID,
type: 'heading-info',
heading: +fields[1]
}
};
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeFixed(msg.heading, 1));
result.push('T');
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
};

44
codecs/MWV.js Normal file
View File

@@ -0,0 +1,44 @@
var helpers = require("../helpers.js")
/*
=== MWV - Wind Speed and Angle ===
------------------------------------------------------------------------------
*******1 2 3 4 5
*******| | | | |
$--MWV,x.x,a,x.x,a*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Wind Angle, 0 to 360 degrees
2. Reference, R = Relative, T = True
3. Wind Speed
4. Wind Speed Units, K/M/N
5. Status, A = Data Valid
6. Checksum
*/
exports.TYPE = 'wind';
exports.ID = 'MWV';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
angle: +fields[1],
reference: fields[2],
speed: +fields[3],
units: fields[4],
status: fields[5]
}
}
exports.encode = function(talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeDegrees(msg.angle));
result.push(msg.reference);
result.push(helpers.encodeFixed(msg.speed, 2));
result.push(msg.units);
result.push(typeof msg.status === undefined ? 'A' : msg.status);
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
}

29
codecs/RDID.js Normal file
View File

@@ -0,0 +1,29 @@
exports.ID = 'RDID';
exports.TYPE = 'gyro';
exports.decode = function(fields) {
/*
=== PRDID - RDI Proprietary Heading, Pitch, Roll ===
------------------------------------------------------------------------------
1 2 3 4
| | | |
$PRDID,-2.06,4.81,37.62*6D<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Roll
2. Pitch
3. Heading
4. Checksum
*/
return {
sentence: exports.ID,
type: exports.TYPE,
roll : +fields[1],
pitch : +fields[2],
heading : +fields[3],
}
}

51
codecs/RMB.js Normal file
View File

@@ -0,0 +1,51 @@
/*
=== RMB Recommended Minimum Navigation Information ===
To be sent by a navigation receiver when a destination waypoint is active.
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| | | | | | | | | | | | | |
$--RMB,A,x.x,a,c--c,c--c,llll.ll,a,yyyyy.yy,a,x.x,x.x,x.x,A*hh
------------------------------------------------------------------------------
Field Number:
1) Status, V = Navigation receiver warning
2) Cross Track error - nautical miles
3) Direction to Steer, Left or Right
4) FROM Waypoint ID
5) TO Waypoint ID
6) Destination Waypoint Latitude
7) N or S
8) Destination Waypoint Longitude
9) E or W
10) Range to destination in nautical miles
11) Bearing to destination in degrees True
12) Destination closing velocity in knots
13) Arrival Status, A = Arrival Circle Entered
14) Checksum
*/
exports.TYPE = 'nav-info-waypoint';
exports.ID = 'RMB';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
status: fields[1] == 'V' ? 'warning' : 'valid',
crossTrackError: +fields[2],
steer: fields[3],
fromWaypoint: fields[4],
toWaypoint: fields[5],
lat: fields[6],
latPole: fields[7],
lon: fields[8],
lonPole: fields[9],
range: +fields[10],
bearing: +fields[11],
vmg: +fields[12],
arrived: fields[13] == 'A' ? true : false
};
}

46
codecs/RMC.js Normal file
View File

@@ -0,0 +1,46 @@
/*
=== RMC - Recommended Minimum Navigation Information ===
This is one of the sentences commonly emitted by GPS units.
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10 11 12
| | | | | | | | | | | |
$--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a*hh
------------------------------------------------------------------------------
Field Number:
1) Time (UTC)
2) Status, V = Navigation receiver warning
3) Latitude
4) N or S
5) Longitude
6) E or W
7) Speed over ground, knots
8) Track made good, degrees true
9) Date, ddmmyy
10) Magnetic Variation, degrees
11) E or W
12) Checksum
*/
exports.TYPE = 'nav-info';
exports.ID = 'RMC';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
timestamp: fields[1],
status: fields[2] == 'V' ? 'warning' : 'valid',
lat: fields[3],
latPole: fields[4],
lon: fields[5],
lonPole: fields[6],
speedKnots: +fields[7],
trackTrue: +fields[8],
date: fields[9],
variation: +fields[10],
variationPole: fields[11]
};
}

35
codecs/ROT.js Normal file
View File

@@ -0,0 +1,35 @@
var helpers = require("../helpers.js")
/*
=== ROT - Rate Of Turn ===
------------------------------------------------------------------------------
1 2 3
| | |
$--ROT,x.x,A*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Rate Of Turn, degrees per minute, "-" means bow turns to port
2. Status, "A" means data is valid
3. Checksum
*/
exports.TYPE = 'rate-of-turn';
exports.ID = 'ROT';
exports.decode = function (fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
rateOfTurn: +fields[1],
valid: fields[2] === "A",
}
};
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeFixed(msg.rateOfTurn, 2));
result.push('A');
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
}

28
codecs/RSA.js Normal file
View File

@@ -0,0 +1,28 @@
/*
=== RSA - Rudder Angle ===
------------------------------------------------------------------------------
1 2 3
| | |
$--RSA,x.x,A,,*0B
------------------------------------------------------------------------------
Field Number:
1. Rudder Angle
2. Always A
3. Checksum
*/
exports.TYPE = 'rudder';
exports.ID = 'RSA';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
angle: +fields[1]
}
}

25
codecs/TXT.js Normal file
View File

@@ -0,0 +1,25 @@
/*
ZDA product info
1 2 3 4 5
| | | | |
$GPTXT,xx,yy,zz,info*hh
1) The total number of statements in the current message, 01 to 99
2) Statement number, 01 to 99
3) Text identifier
4) Text information
5) Checksum
*/
exports.ID = 'TXT';
exports.TYPE = 'product-info';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
xx: fields[1],
yy: fields[2],
zz: fields[3],
info: fields[4]
};
}

70
codecs/VTG.js Normal file
View File

@@ -0,0 +1,70 @@
var helpers = require("../helpers.js")
/*
=== VTG - Track made good and Ground speed ===
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10
| | | | | | | | | |
$--VTG,x.x,T,x.x,M,x.x,N,x.x,K,m,*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Track Degrees
2. T = True
3. Track Degrees
4. M = Magnetic
5. Speed Knots
6. N = Knots
7. Speed Kilometers Per Hour
8. K = Kilometers Per Hour
9. FAA mode indicator (NMEA 2.3 and later)
10. Checksum=== VTG - Track made good and Ground speed ===
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9 10
| | | | | | | | | |
$--VTG,x.x,T,x.x,M,x.x,N,x.x,K,m,*hh<CR><LF>
------------------------------------------------------------------------------
Field Number:
1. Track Degrees
2. T = True
3. Track Degrees
4. M = Magnetic
5. Speed Knots
6. N = Knots
7. Speed Kilometers Per Hour
8. K = Kilometers Per Hour
9. FAA mode indicator (NMEA 2.3 and later)
10. Checksum
*/
exports.TYPE = 'track-info';
exports.ID = 'VTG';
exports.decode = function (fields) {
return {
sentence: exports.ID,
type: 'track-info',
trackTrue: +fields[1],
trackMagnetic: +fields[3],
speedKnots: +fields[5],
speedKmph: +fields[7]
}
};
exports.encode = function (talker, msg) {
var result = ['$' + talker + exports.ID];
result.push(helpers.encodeDegrees(msg.trackTrue));
result.push('T');
result.push(helpers.encodeDegrees(msg.trackMagnetic));
result.push('M');
result.push(helpers.encodeFixed(msg.speedKnots, 2));
result.push('N');
result.push('');
result.push('');
result.push('A');
var resultMsg = result.join(',');
return resultMsg + helpers.computeChecksum(resultMsg);
}

39
codecs/VWR.js Normal file
View File

@@ -0,0 +1,39 @@
var helpers = require("../helpers.js")
/*
=== VWR Relative Wind Speed and Angle ===
Note: This is no longer a sentence that is recommended by the NMEA 0183 Standard Committee
for new designs, however it does exist in a lot of equipment.
------------------------------------------------------------------------------
1 2 3 4 5 6 7 8 9
| | | | | | | | |
$--VWR,x.x,a,x.x,N,x.x,M,x.x,K*hh
------------------------------------------------------------------------------
Field Number:
1) Wind direction magnitude in degrees
2) Wind direction Left/Right of bow
3) Speed
4) N
5) Speed
6) M = Meters Per Second
7) Speed
8) K = Kilometers Per Hour
9) Checksum
*/
exports.TYPE = 'wind-relative';
exports.ID = 'VWR';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
angle: +fields[1],
direction: fields[2],
speedKnots: +fields[3],
speedMs: +fields[5],
speedKmph: +fields[7]
}
}

29
codecs/ZDA.js Normal file
View File

@@ -0,0 +1,29 @@
/*
ZDA Time & Date – UTC, Day, Month, Year and Local Time Zone
1 2 3 4 5 6 7
| | | | | | |
$--ZDA,hhmmss.ss,xx,xx,xxxx,xx,xx*hh
1) Local zone minutes description, same sign as local hours
2) Local zone description, 00 to +/- 13 hours
3) Year
4) Month, 01 to 12
5) Day, 01 to 31
6) Time (UTC)
7) Checksum
*/
exports.ID = 'ZDA';
exports.TYPE = 'time-zone';
exports.decode = function(fields) {
return {
sentence: exports.ID,
type: exports.TYPE,
timestamp: fields[1],
day: fields[2],
month: fields[3],
year: fields[4],
ltzh: fields[5],
ltzn: fields[6]
};
}