File: xdr.go

package info (click to toggle)
golang-github-adrianmo-go-nmea 1.10.0-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 900 kB
  • sloc: makefile: 15
file content (169 lines) | stat: -rw-r--r-- 4,533 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package nmea

import "errors"

const (
	// TypeXDR type of XDR sentence for Transducer Measurement
	TypeXDR = "XDR"
)

const (
	// TransducerAngularDisplacementXDR is transducer type for Angular displacement
	TransducerAngularDisplacementXDR = "A"
	// TransducerTemperatureXDR is transducer type for Temperature
	TransducerTemperatureXDR = "C"
	// TransducerDepthXDR is transducer type for Depth
	TransducerDepthXDR = "D"
	// TransducerFrequencyXDR is transducer type for Frequency
	TransducerFrequencyXDR = "F"
	// TransducerHumidityXDR is transducer type for Humidity
	TransducerHumidityXDR = "H"
	// TransducerForceXDR is transducer type for Force
	TransducerForceXDR = "N"
	// TransducerPressureXDR is transducer type for Pressure
	TransducerPressureXDR = "P"
	// TransducerFlowXDR is transducer type for Flow
	TransducerFlowXDR = "R"
	// TransducerAbsoluteHumidityXDR is transducer type for Absolute humidity
	TransducerAbsoluteHumidityXDR = "B"
	// TransducerGenericXDR is transducer type for Generic
	TransducerGenericXDR = "G"
	// TransducerCurrentXDR is transducer type for Current
	TransducerCurrentXDR = "I"
	// TransducerSalinityXDR is transducer type for Salinity
	TransducerSalinityXDR = "L"
	// TransducerSwitchValveXDR is transducer type for Switch, valve
	TransducerSwitchValveXDR = "S"
	// TransducerTachometerXDR is transducer type for Tachometer
	TransducerTachometerXDR = "T"
	// TransducerVoltageXDR is transducer type for Voltage
	TransducerVoltageXDR = "U"
	// TransducerVolumeXDR is transducer type for Volume
	TransducerVolumeXDR = "V"
)

// XDR - Transducer Measurement
// https://gpsd.gitlab.io/gpsd/NMEA.html#_xdr_transducer_measurement
// https://www.eye4software.com/hydromagic/documentation/articles-and-howtos/handling-nmea0183-xdr/
//
// Format: $--XDR,a,x.x,a,c--c, ..... *hh<CR><LF>
// Example: $HCXDR,A,171,D,PITCH,A,-37,D,ROLL,G,367,,MAGX,G,2420,,MAGY,G,-8984,,MAGZ*41
//			$SDXDR,C,23.15,C,WTHI*70
type XDR struct {
	BaseSentence
	Measurements []XDRMeasurement
}

// XDRMeasurement is measurement recorded by transducer
type XDRMeasurement struct {
	// TransducerType is type of transducer
	// * A - Angular displacement
	// * C - Temperature
	// * D - Depth
	// * F - Frequency
	// * H - Humidity
	// * N - Force
	// * P - Pressure
	// * R - Flow
	// * B - Absolute humidity
	// * G - Generic
	// * I - Current
	// * L - Salinity
	// * S - Switch, valve
	// * T - Tachometer
	// * U - Voltage
	// * V - Volume
	// could be more
	TransducerType string

	// Value of measurement
	Value float64

	// Unit of measurement
	// * "" - could be empty!
	// * A - Amperes
	// * B - Bars | Binary
	// * C - Celsius
	// * D - Degrees
	// * H - Hertz
	// * I - liters/second
	// * K - Kelvin | Density, kg/m3 kilogram per cubic metre
	// * M - Meters | Cubic Meters (m3)
	// * N - Newton
	// * P - percent of full range | Pascal
	// * R - RPM
	// * S - Parts per thousand
	// * V - Volts
	// could be more
	Unit string

	// TransducerName is name of transducer where measurement was recorded
	TransducerName string
}

// newXDR constructor
func newXDR(s BaseSentence) (Sentence, error) {
	p := NewParser(s)
	p.AssertType(TypeXDR)

	xdr := XDR{
		BaseSentence: s,
		Measurements: nil,
	}

	if len(p.Fields)%4 != 0 {
		return xdr, errors.New("XDR field count is not exactly dividable by 4")
	}

	xdr.Measurements = make([]XDRMeasurement, 0, len(s.Fields)/4)
	for i := 0; i < len(s.Fields); {
		tmp := XDRMeasurement{
			TransducerType: p.EnumString(
				i,
				"transducer type",
				TransducerAngularDisplacementXDR,
				TransducerTemperatureXDR,
				TransducerDepthXDR,
				TransducerFrequencyXDR,
				TransducerHumidityXDR,
				TransducerForceXDR,
				TransducerPressureXDR,
				TransducerFlowXDR,
				TransducerAbsoluteHumidityXDR,
				TransducerGenericXDR,
				TransducerCurrentXDR,
				TransducerSalinityXDR,
				TransducerSwitchValveXDR,
				TransducerTachometerXDR,
				TransducerVoltageXDR,
				TransducerVolumeXDR,
			),
			Value: p.Float64(i+1, "measurement value"),
			Unit: p.EnumString(
				i+2,
				"measurement unit",
				UnitAmpere,
				UnitBars,
				UnitBinary,
				UnitCelsius,
				UnitDegrees,
				UnitHertz,
				UnitLitresPerSecond,
				UnitKelvin,
				UnitKilogramPerCubicMetre,
				UnitNewtons,
				UnitMeters,
				UnitCubicMeters,
				UnitRevolutionsPerMinute,
				UnitPercent,
				UnitPascal,
				UnitPartsPerThousand,
				UnitVolts,
			),
			TransducerName: p.String(i+3, "transducer name"),
		}
		xdr.Measurements = append(xdr.Measurements, tmp)
		i += 4
	}
	return xdr, p.Err()
}