diff --git a/README.md b/README.md index 213607e..143e556 100644 --- a/README.md +++ b/README.md @@ -91,10 +91,11 @@ At this moment, this library supports the following sentence types: | Proprietary sentence type | Description | |-------------------------------------------------------------|-------------------------------------------------------------------------------------------------| | [PGRME](http://aprs.gids.nl/nmea/#rme) | Estimated Position Error (Garmin proprietary sentence) | -| [PHTRO](#) | Vessel pitch and roll (Xsens IMU/VRU/AHRS) | +| [PHTRO](./phtro.go) | Vessel pitch and roll (Xsens IMU/VRU/AHRS) | | [PMTK](https://www.rhydolabz.com/documents/25/PMTK_A11.pdf) | Messages for setting and reading commands for MediaTek gps modules. | -| [PRDID](#) | Vessel pitch, roll and heading (Xsens IMU/VRU/AHRS) | -| [PSONCMS](#) | Quaternion, acceleration, rate of turn, magnetic field, sensor temperature (Xsens IMU/VRU/AHRS) | +| [PRDID](./prdid.go) | Vessel pitch, roll and heading (Xsens IMU/VRU/AHRS) | +| [PSKPDPT](./pskpdpt.go) | Depth of Water for multiple transducer installation | +| [PSONCMS](./psoncms.go) | Quaternion, acceleration, rate of turn, magnetic field, sensor temperature (Xsens IMU/VRU/AHRS) | If you need to parse a message that contains an unsupported sentence type you can implement and register your own message parser and get yourself unblocked immediately. Check the example below to know how diff --git a/pskpdpt.go b/pskpdpt.go new file mode 100644 index 0000000..d6656e0 --- /dev/null +++ b/pskpdpt.go @@ -0,0 +1,45 @@ +package nmea + +const ( + // TypePSKPDPT type for proprietary Skipper PSKPDPT sentences + TypePSKPDPT = "SKPDPT" +) + +// PSKPDPT - Depth of Water for multiple transducer installation +// https://www.alphatronmarine.com/files/products/120-echonav-skipper-gds101-instoper-manual-12-6-2017_1556099135_47f5f8d1.pdf (page 56, Edition: 2017.06.12) +// https://www.kongsberg.com/globalassets/maritime/km-products/product-documents/164821aa_rd301_instruction_manual_lr.pdf (page 2, 857-164821aa) +// +// Format: $PSKPDPT,x.x,x.x,x.x,xx,xx,c--c*hh +// Example: $PSKPDPT,0002.5,+00.0,0010,10,03,*77 +type PSKPDPT struct { + BaseSentence + // Depth is water depth relative to transducer, meters + Depth float64 + // Offset from transducer, meters + Offset float64 + // RangeScale is Maximum range scale in use, meters + RangeScale float64 + // BottomEchoStrength is Bottom echo strength (0,9) + BottomEchoStrength int64 + // ChannelNumber is Echo sounder channel number (0-99) (1 = 38 kHz. 2 = 50 kHz. 3 = 200 kHz) + ChannelNumber int64 + // TransducerLocation is Transducer location. Text string, indicating transducer position: FWD/AFT/PORT/STB. + // If position is not preset by operator, empty field is provided. + TransducerLocation string +} + +// newPSKPDPT constructor +func newPSKPDPT(s BaseSentence) (PSKPDPT, error) { + p := NewParser(s) + p.AssertType(TypePSKPDPT) + sentence := PSKPDPT{ + BaseSentence: s, + Depth: p.Float64(0, "depth"), + Offset: p.Float64(1, "offset"), + RangeScale: p.Float64(2, "range scale"), + BottomEchoStrength: p.Int64(3, "bottom echo strength"), + ChannelNumber: p.Int64(4, "channel number"), + TransducerLocation: p.String(5, "transducer location"), + } + return sentence, p.Err() +} diff --git a/pskpdpt_test.go b/pskpdpt_test.go new file mode 100644 index 0000000..7789aa1 --- /dev/null +++ b/pskpdpt_test.go @@ -0,0 +1,81 @@ +package nmea + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestPSKPDPT(t *testing.T) { + var testcases = []struct { + name string + raw string + err string + msg PSKPDPT + }{ + { + name: "good sentence, empty location", + raw: "$PSKPDPT,0002.5,+00.0,0010,10,03,*77", + msg: PSKPDPT{ + Depth: 2.5, + Offset: 0, + RangeScale: 10, + BottomEchoStrength: 10, + ChannelNumber: 03, + TransducerLocation: "", + }, + }, + { + name: "good sentence", + raw: "$PSKPDPT,0002.5,-01.1,0010,10,03,AFT*22", + msg: PSKPDPT{ + Depth: 2.5, + Offset: -1.1, + RangeScale: 10, + BottomEchoStrength: 10, + ChannelNumber: 03, + TransducerLocation: "AFT", + }, + }, + { + name: "invalid nmea: Depth", + raw: "$PSKPDPT,x0002.5,+00.0,0010,10,03,*0f", + err: "nmea: PSKPDPT invalid depth: x0002.5", + }, + { + name: "invalid nmea: Offset", + raw: "$PSKPDPT,0002.5,+x00.0,0010,10,03,*0f", + err: "nmea: PSKPDPT invalid offset: +x00.0", + }, + { + name: "invalid nmea: RangeScale", + raw: "$PSKPDPT,0002.5,+00.0,x0010,10,03,*0f", + err: "nmea: PSKPDPT invalid range scale: x0010", + }, + { + name: "invalid nmea: BottomEchoStrength", + raw: "$PSKPDPT,0002.5,+00.0,0010,10x,03,*0f", + err: "nmea: PSKPDPT invalid bottom echo strength: 10x", + }, + { + name: "invalid nmea: ChannelNumber", + raw: "$PSKPDPT,0002.5,+00.0,0010,10,0x3,*0f", + err: "nmea: PSKPDPT invalid channel number: 0x3", + }, + } + + for _, tt := range testcases { + t.Run(tt.name, func(t *testing.T) { + m, err := Parse(tt.raw) + if tt.err != "" { + assert.Error(t, err) + assert.EqualError(t, err, tt.err) + } else { + assert.NoError(t, err) + sentence := m.(PSKPDPT) + sentence.BaseSentence = BaseSentence{} + assert.Equal(t, tt.msg, sentence) + } + }) + } +} diff --git a/sentence.go b/sentence.go index 1b3e6bb..a07f9d0 100644 --- a/sentence.go +++ b/sentence.go @@ -233,6 +233,8 @@ func Parse(raw string) (Sentence, error) { return newPHTRO(s) case TypePRDID: return newPRDID(s) + case TypePSKPDPT: + return newPSKPDPT(s) case TypePSONCMS: return newPSONCMS(s) case TypeGSV: