forked from adrianmo/go-nmea
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mwv.go
98 lines (86 loc) · 2.83 KB
/
mwv.go
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
package nmea
import (
"fmt"
"github.com/martinlindhe/unit"
)
const (
// TypeMWV type for MWV sentences
TypeMWV = "MWV"
ReferenceRelative = "R"
ReferenceTrue = "T"
WindSpeedUnitKPH = "K"
WindSpeedUnitKnots = "N"
WindSpeedUnitMPS = "M"
WindSpeedUnitMPH = "S"
ValidMWV = "A"
InvalidMWV = "V"
)
// Sentence info:
// 1 Wind angle, 0.0 to 359.9 degrees, in relation to the vessel’s bow/centerline, to the nearest 0.1 degree. If the data for this field is not valid, the field will be blank.
// 2 Reference:
// R: Relative (apparent wind, as felt when standing on the moving ship)
// T: Theoretical (calculated actual wind, as though the vessel were stationary)
// 3 Wind speed, to the nearest tenth of a unit. If the data for this field is not valid, the field will be blank.
// 4 Wind speed units:
// K: km/hr
// M: m/s
// N: knots
// S: statute miles/hr
// 5 Status:
// A: data valid
// V: data invalid
// MWV - Wind Speed and Angle
type MWV struct {
BaseSentence
Angle Float64
Reference String
WindSpeed Float64
WindSpeedUnit String
Status String
}
// newMWV constructor
func newMWV(s BaseSentence) (MWV, error) {
p := NewParser(s)
p.AssertType(TypeMWV)
m := MWV{
BaseSentence: s,
Angle: p.Float64(0, "Angle"),
Reference: p.EnumString(1, "Reference", ReferenceRelative, ReferenceTrue),
WindSpeed: p.Float64(2, "WindSpeed"),
WindSpeedUnit: p.EnumString(3, "WindSpeedUnit", WindSpeedUnitKPH, WindSpeedUnitKnots, WindSpeedUnitMPS, WindSpeedUnitMPH),
Status: p.EnumString(4, "Status", ValidMWV, InvalidMWV),
}
return m, p.Err()
}
// GetTrueWindDirection retrieves the true wind direction from the sentence
func (s MWV) GetTrueWindDirection() (float64, error) {
if s.Status.Value == ValidMWV && s.Reference.Value == ReferenceTrue {
if v, err := s.Angle.GetValue(); err == nil {
return (unit.Angle(v) * unit.Degree).Radians(), nil
}
}
return 0, fmt.Errorf("value is unavailable")
}
// GetRelativeWindDirection retrieves the relative wind direction from the sentence
func (s MWV) GetRelativeWindDirection() (float64, error) {
if s.Status.Value == ValidMWV && s.Reference.Value == ReferenceRelative {
if v, err := s.Angle.GetValue(); err == nil {
return (unit.Angle(v) * unit.Degree).Radians(), nil
}
}
return 0, fmt.Errorf("value is unavailable")
}
// GetWindSpeed retrieves wind speed from the sentence
func (s MWV) GetWindSpeed() (float64, error) {
if v, err := s.WindSpeed.GetValue(); err == nil && s.Status.Value == ValidMWV {
switch s.WindSpeedUnit.Value {
case WindSpeedUnitMPS:
return v, nil
case WindSpeedUnitKPH:
return (unit.Speed(v) * unit.KilometersPerHour).MetersPerSecond(), nil
case WindSpeedUnitKnots:
return (unit.Speed(v) * unit.Knot).MetersPerSecond(), nil
}
}
return 0, fmt.Errorf("value is unavailable")
}