Repository navigation
Expand file tree
/
Copy pathAuxDataProvider.cs
More file actions
182 lines (154 loc) · 6.34 KB
/
Copy pathAuxDataProvider.cs
File metadata and controls
182 lines (154 loc) · 6.34 KB
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
170
171
172
173
174
175
176
177
178
179
180
181
182
// AZMLib/AuxDataProvider.cs
using UCNLDrivers;
using UCNLDrivers.uAux;
namespace AZMLib
{
/// <summary>
/// Агрегирует данные от всех зарегистрированных IAuxSource.
/// Знает про конкретные типы: uAuxGNSSPort, uAuxBPPort,
/// uAuxRadantPort.
/// Предоставляет единые свойства для AZMCombiner.
/// </summary>
public class AuxDataProvider
{
private readonly AuxManager _auxManager;
// ======== АГРЕГИРОВАННЫЕ ДАННЫЕ ========
public double? Latitude { get; private set; }
public double? Longitude { get; private set; }
public double? Heading { get; private set; }
public bool? IsHeadingTrue { get; private set; }
public double? Course { get; private set; }
public double? Speed { get; private set; }
public double? Depth { get; private set; }
public double? CurrentRotatorAngle { get; private set; }
public bool RotatorBusy { get; private set; }
public DateTime LastUpdate { get; private set; } = DateTime.MinValue;
public bool HasValidPosition =>
Latitude.HasValue && Longitude.HasValue;
// ======== СОБЫТИЯ ========
public event EventHandler? OnDataUpdated;
public event EventHandler? OnRotatorUpdated;
// ======== КОНСТРУКТОР ========
public AuxDataProvider(AuxManager auxManager)
{
_auxManager = auxManager ?? throw new ArgumentNullException(nameof(auxManager));
_auxManager.OnSourceStatusChanged += OnSourceStatusChanged;
}
// ======== ПОДПИСКА НА ИСТОЧНИКИ ========
private void OnSourceStatusChanged(object? sender, AuxSourceStatusEventArgs e)
{
// Подписываемся только когда источник стал Detected
if (e.Info.Status != AuxStatus.Detected) return;
var source = _auxManager.GetSource(e.Info.Id);
if (source == null) return;
SubscribeToSource(source);
}
/// <summary>
/// Можно вызвать принудительно для уже активных источников.
/// </summary>
public void SubscribeAll()
{
foreach (var info in _auxManager.GetAllSources())
{
if (info.Status == AuxStatus.Detected)
{
var source = _auxManager.GetSource(info.Id);
if (source != null)
SubscribeToSource(source);
}
}
}
private void SubscribeToSource(IAuxSource source)
{
switch (source)
{
case uAuxGNSSPort gnss:
gnss.HeadingUpdated += (_, _) => UpdateFromGNSS(gnss);
gnss.LocationUpdated += (_, _) => UpdateFromGNSS(gnss);
UpdateFromGNSS(gnss); // сразу взять текущие
break;
case uAuxBPPort bp:
bp.LocationUpdated += (_, _) => UpdateFromBP(bp);
UpdateFromBP(bp);
break;
case uAuxRadantPort radant:
radant.CurrentAngleChanged += (_, _) => UpdateFromRadant(radant);
radant.BusyChanged += (_, _) => UpdateFromRadant(radant);
UpdateFromRadant(radant);
break;
}
}
// ======== ОБРАБОТЧИКИ ДАННЫХ ========
private void UpdateFromGNSS(uAuxGNSSPort gnss)
{
if (!double.IsNaN(gnss.Heading))
{
Heading = gnss.Heading;
IsHeadingTrue = gnss.IsHeadingTrue;
}
if (!double.IsNaN(gnss.Latitude) && !double.IsNaN(gnss.Longitude))
{
Latitude = gnss.Latitude;
Longitude = gnss.Longitude;
}
if (!double.IsNaN(gnss.CourseOverGround))
Course = gnss.CourseOverGround;
if (!double.IsNaN(gnss.GroundSpeed))
Speed = gnss.GroundSpeed;
LastUpdate = DateTime.UtcNow;
OnDataUpdated?.Invoke(this, EventArgs.Empty);
}
private void UpdateFromBP(uAuxBPPort bp)
{
if (!double.IsNaN(bp.Latitude) && !double.IsNaN(bp.Longitude))
{
Latitude = bp.Latitude;
Longitude = bp.Longitude;
}
if (!double.IsNaN(bp.CourseOverGround))
Course = bp.CourseOverGround;
if (!double.IsNaN(bp.GroundSpeed))
Speed = bp.GroundSpeed;
LastUpdate = DateTime.UtcNow;
OnDataUpdated?.Invoke(this, EventArgs.Empty);
}
private void UpdateFromRadant(uAuxRadantPort radant)
{
if (!double.IsNaN(radant.CurrentAngle))
CurrentRotatorAngle = radant.CurrentAngle;
RotatorBusy = radant.Busy;
OnRotatorUpdated?.Invoke(this, EventArgs.Empty);
}
// ======== ДОСТУП К ИСТОЧНИКАМ ========
public uAuxGNSSPort? FindGNSSPort()
{
foreach (var info in _auxManager.GetAllSources())
{
var source = _auxManager.GetSource(info.Id);
if (source is uAuxGNSSPort gnss)
return gnss;
}
return null;
}
public uAuxBPPort? FindBPPort()
{
foreach (var info in _auxManager.GetAllSources())
{
var source = _auxManager.GetSource(info.Id);
if (source is uAuxBPPort bp)
return bp;
}
return null;
}
public uAuxRadantPort? FindRadantPort()
{
foreach (var info in _auxManager.GetAllSources())
{
var source = _auxManager.GetSource(info.Id);
if (source is uAuxRadantPort radant)
return radant;
}
return null;
}
}
}