Skip to content

Commit cd0f55b

Browse files
authored
add support for Garmin sensor status information (#117)
1 parent af41c6a commit cd0f55b

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ on [IEC 61162-1:2016 (Edition 5.0 2016-08)](https://webstore.iec.ch/publication/
170170
| [PNG](./pgn.go) | Transfer NMEA2000 frame as NMEA0183 sentence (ShipModul MiniPlex-3) | [1](https://opencpn.org/wiki/dokuwiki/lib/exe/fetch.php?media=opencpn:software:mxpgn_sentence.pdf) |
171171
| [PCDIN](./pcdin.go) | Transfer NMEA2000 frame as NMEA0183 sentence (SeaSmart.Net Protocol) | [1](http://www.seasmart.net/pdf/SeaSmart_HTTP_Protocol_RevG_043012.pdf) |
172172
| [PGRME](./pgrme.go) | Estimated Position Error (Garmin proprietary sentence) | [1](http://aprs.gids.nl/nmea/#rme) |
173+
| [PGRMT](./pgrmt.go) | Sensor Status Information (Garmin proprietary sentence) | [1#2.2.6](https://developer.garmin.com/downloads/legacy/uploads/2015/08/190-00684-00.pdf) |
173174
| [PHTRO](./phtro.go) | Vessel pitch and roll (Xsens IMU/VRU/AHRS) | |
174175
| [PMTK001](./pmtk.go) | Acknowledgement of previously sent command/packet | [1](https://www.rhydolabz.com/documents/25/PMTK_A11.pdf) |
175176
| [PRDID](./prdid.go) | Vessel pitch, roll and heading (Xsens IMU/VRU/AHRS) | |

pgrmt.go

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package nmea
2+
3+
const (
4+
// TypePGRMT type for PGRMT sentences
5+
TypePGRMT = "GRMT"
6+
// PassPGRMT Self-Test Passed
7+
PassPGRMT = "P"
8+
// FailPGRMT Self-Test Failed
9+
FailPGRMT = "F"
10+
// DataRetainedPGRMT Data Retained
11+
DataRetainedPGRMT = "R"
12+
// DataLostPGRMT Data Lost
13+
DataLostPGRMT = "L"
14+
// DataCollectingPGRMT Data Collecting
15+
DataCollectingPGRMT = "C"
16+
)
17+
18+
// PGRMT is Sensor Status Information (Garmin proprietary sentence)
19+
// https://developer.garmin.com/downloads/legacy/uploads/2015/08/190-00684-00.pdf
20+
// $PGRMT,<0>,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>*hh<CR><LF>
21+
// Format: $PGRMT,xxxxxxxxxx,A,A,A,A,A,A,N,A*hh<CR><LF>
22+
// Example: $PGRMT,GPS24xd-HVS VER 2.30,,,,,,,,*10
23+
type PGRMT struct {
24+
BaseSentence
25+
ModelAndFirmwareVersion string
26+
ROMChecksumTest string // "P" = pass, "F" = fail
27+
ReceiverFailureDiscrete string // "P" = pass, "F" = fail
28+
StoredDataLost string // "R" = retained, "L" = lost
29+
RealtimeClockLost string // "R" = retained, "L" = lost
30+
OscillatorDriftDiscrete string // "P" = pass, "F" = fail
31+
DataCollectionDiscrete string // "C" = collecting, "" = not collecting
32+
SensorTemperature float64 // Degrees C
33+
SensorConfigurationData string // "R" = retained, "L" = lost
34+
}
35+
36+
// newPGRMT constructor
37+
func newPGRMT(s BaseSentence) (Sentence, error) {
38+
p := NewParser(s)
39+
p.AssertType(TypePGRMT)
40+
41+
return PGRMT{
42+
BaseSentence: s,
43+
ModelAndFirmwareVersion: p.String(0, "product, model and software version"),
44+
ROMChecksumTest: p.EnumString(1, "rom checksum test", PassPGRMT, FailPGRMT),
45+
ReceiverFailureDiscrete: p.EnumString(2, "receiver failure discrete", PassPGRMT, FailPGRMT),
46+
StoredDataLost: p.EnumString(3, "stored data lost", DataRetainedPGRMT, DataLostPGRMT),
47+
RealtimeClockLost: p.EnumString(4, "realtime clock lost", DataRetainedPGRMT, DataLostPGRMT),
48+
OscillatorDriftDiscrete: p.EnumString(5, "oscillator drift discrete", PassPGRMT, FailPGRMT),
49+
DataCollectionDiscrete: p.EnumString(6, "data collection discrete", DataCollectingPGRMT),
50+
SensorTemperature: p.Float64(7, "sensor temperature in degrees celsius"),
51+
SensorConfigurationData: p.EnumString(8, "sensor configuration data", DataRetainedPGRMT, DataLostPGRMT),
52+
}, p.Err()
53+
}

pgrmt_test.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package nmea
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
var pgrmttests = []struct {
10+
name string
11+
raw string
12+
err string
13+
msg PGRMT
14+
}{
15+
{
16+
name: "typical sentence",
17+
raw: "$PGRMT,GPS24xd-HVS VER 2.30,,,,,,,,*10",
18+
msg: PGRMT{
19+
ModelAndFirmwareVersion: "GPS24xd-HVS VER 2.30",
20+
},
21+
},
22+
{
23+
name: "all good",
24+
raw: "$PGRMT,GOOD GPS VER 1.0,P,P,R,R,P,C,32,R*39",
25+
msg: PGRMT{
26+
ModelAndFirmwareVersion: "GOOD GPS VER 1.0",
27+
ROMChecksumTest: PassPGRMT,
28+
ReceiverFailureDiscrete: PassPGRMT,
29+
StoredDataLost: DataRetainedPGRMT,
30+
RealtimeClockLost: DataRetainedPGRMT,
31+
OscillatorDriftDiscrete: PassPGRMT,
32+
DataCollectionDiscrete: DataCollectingPGRMT,
33+
SensorTemperature: 32,
34+
SensorConfigurationData: DataRetainedPGRMT,
35+
},
36+
},
37+
{
38+
name: "all bad",
39+
raw: "$PGRMT,BAD GPS VER 1.0,F,F,L,L,F,,-64,L*18",
40+
msg: PGRMT{
41+
ModelAndFirmwareVersion: "BAD GPS VER 1.0",
42+
ROMChecksumTest: FailPGRMT,
43+
ReceiverFailureDiscrete: FailPGRMT,
44+
StoredDataLost: DataLostPGRMT,
45+
RealtimeClockLost: DataLostPGRMT,
46+
OscillatorDriftDiscrete: FailPGRMT,
47+
SensorTemperature: -64,
48+
SensorConfigurationData: DataLostPGRMT,
49+
},
50+
},
51+
}
52+
53+
func TestPGRMT(t *testing.T) {
54+
for _, tt := range pgrmttests {
55+
t.Run(tt.name, func(t *testing.T) {
56+
m, err := Parse(tt.raw)
57+
if tt.err != "" {
58+
assert.Error(t, err)
59+
assert.EqualError(t, err, tt.err)
60+
} else {
61+
assert.NoError(t, err)
62+
pgrmt := m.(PGRMT)
63+
pgrmt.BaseSentence = BaseSentence{}
64+
assert.Equal(t, tt.msg, pgrmt)
65+
}
66+
})
67+
}
68+
}

sentence.go

+2
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,8 @@ func (p *SentenceParser) Parse(raw string) (Sentence, error) {
339339
return newPCDIN(s)
340340
case TypePGRME:
341341
return newPGRME(s)
342+
case TypePGRMT:
343+
return newPGRMT(s)
342344
case TypePHTRO:
343345
return newPHTRO(s)
344346
case TypePMTK001:

0 commit comments

Comments
 (0)