• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

davewalker5 / ADS-B-BaseStationReader / 17804934237

17 Sep 2025 04:40PM UTC coverage: 89.917% (-3.8%) from 93.692%
17804934237

push

github

web-flow
Merge pull request #41 from davewalker5/filtered-tracking

Filtered tracking

381 of 461 branches covered (82.65%)

Branch coverage included in aggregate %.

1465 of 1592 new or added lines in 52 files covered. (92.02%)

1465 of 1592 relevant lines covered (92.02%)

38.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.49
/src/BaseStationReader.BusinessLogic/Tracking/NotificationSender.cs
1
using BaseStationReader.Entities.Events;
2
using BaseStationReader.Entities.Interfaces;
3
using BaseStationReader.Entities.Tracking;
4

5
namespace BaseStationReader.BusinessLogic.Tracking
6
{
7
    public class NotificationSender : INotificationSender
8
    {
9
        private readonly ITrackerLogger _logger;
10
        private readonly int? _maximumDistance;
11
        private readonly int? _maximumAltitude;
12
        private readonly IEnumerable<AircraftBehaviour> _behaviours;
13

14
        public NotificationSender(
1✔
15
            ITrackerLogger logger,
1✔
16
            IEnumerable<AircraftBehaviour> behaviours,
1✔
17
            int? maximumDistance,
1✔
18
            int? maximumAltitude)
1✔
19
        {
1✔
20
            _logger = logger;
1✔
21
            _maximumDistance = maximumDistance;
1✔
22
            _maximumAltitude = maximumAltitude;
1✔
23
            _behaviours = behaviours;
1✔
24
        }
1✔
25

26
        /// <summary>
27
        /// Send an "aircraft added" notification to the subscribers to the specified handler
28
        /// </summary>
29
        /// <param name="aircraft"></param>
30
        /// <param name="sender"></param>
31
        /// <param name="handler"></param>
32
        /// <param name="type"></param>
33
        /// <param name="previousLatitude"></param>
34
        /// <param name="previousLongitude"></param>
35
        public void SendAddedNotification(
36
            Aircraft aircraft,
37
            object sender,
38
            EventHandler<AircraftNotificationEventArgs> handler)
39
        {
1✔
40
            if (NotificationRequired(aircraft))
1✔
41
            {
1✔
42
                SendNotification(aircraft, null, sender, handler, AircraftNotificationType.Added);
1✔
43
            }
1✔
44
        }
1✔
45

46
        /// <summary>
47
        /// Send an "aircraft updated" notification to the subscribers to the specified handler
48
        /// </summary>
49
        /// <param name="aircraft"></param>
50
        /// <param name="sender"></param>
51
        /// <param name="handler"></param>
52
        /// <param name="type"></param>
53
        /// <param name="previousLatitude"></param>
54
        /// <param name="previousLongitude"></param>
55
        public void SendUpdatedNotification(
56
            Aircraft aircraft,
57
            object sender,
58
            EventHandler<AircraftNotificationEventArgs> handler,
59
            decimal? previousLatitude,
60
            decimal? previousLongitude)
61
        {
1✔
62
            if (NotificationRequired(aircraft))
1✔
63
            {
1✔
64
                // If the position's changed, create a position object to attach to the event arguments
65
                AircraftPosition position = null;
1✔
66
                if ((aircraft.Latitude != previousLatitude) || (aircraft.Longitude != previousLongitude))
1!
NEW
67
                {
×
NEW
68
                    position = CreateAircraftPosition(aircraft);
×
NEW
69
                }
×
70

71
                // Send the notification
72
                SendNotification(aircraft, position, sender, handler, AircraftNotificationType.Updated);
1✔
73
            }
1✔
74
        }
1✔
75

76
        /// <summary>
77
        /// Send a "stale aircraft" notification to the subscribers to the specified handler
78
        /// </summary>
79
        /// <param name="aircraft"></param>
80
        /// <param name="sender"></param>
81
        /// <param name="handler"></param>
82
        public void SendStaleNotification(
83
            Aircraft aircraft,
84
            object sender,
85
            EventHandler<AircraftNotificationEventArgs> handler)
86
        {
20✔
87
            if (NotificationRequired(aircraft))
20✔
88
            {
20✔
89
                SendNotification(aircraft, null, sender, handler, AircraftNotificationType.Stale);
20✔
90
            }
20✔
91
        }
20✔
92

93
        /// <summary>
94
        /// Send an "inactive aircraft" notification to the subscribers to the specified handler
95
        /// </summary>
96
        /// <param name="aircraft"></param>
97
        /// <param name="sender"></param>
98
        /// <param name="handler"></param>
99
        public void SendInactiveNotification(
100
            Aircraft aircraft,
101
            object sender,
102
            EventHandler<AircraftNotificationEventArgs> handler)
103
        {
10✔
104
            if (NotificationRequired(aircraft))
10✔
105
            {
10✔
106
                SendNotification(aircraft, null, sender, handler, AircraftNotificationType.Recent);
10✔
107
            }
10✔
108
        }
10✔
109

110
        /// <summary>
111
        /// Send an "aircraft removed" notification to the subscribers to the specified handler
112
        /// </summary>
113
        /// <param name="aircraft"></param>
114
        /// <param name="sender"></param>
115
        /// <param name="handler"></param>
116
        public void SendRemovedNotification(
117
            Aircraft aircraft,
118
            object sender,
119
            EventHandler<AircraftNotificationEventArgs> handler)
120
        {
1✔
121
            if (NotificationRequired(aircraft))
1✔
122
            {
1✔
123
                SendNotification(aircraft, null, sender, handler, AircraftNotificationType.Removed);
1✔
124
            }
1✔
125
        }
1✔
126

127
        /// <summary>
128
        /// Return true if an aircraft meets the criteria for notifications to be sent
129
        /// </summary>
130
        /// <param name="aircraft"></param>
131
        /// <returns></returns>
132
        private bool NotificationRequired(Aircraft aircraft)
133
            => _behaviours.Contains(aircraft.Behaviour) &&
33!
134
               ((_maximumDistance == null) || (aircraft.Distance <= _maximumDistance)) &&
33✔
135
               ((_maximumAltitude == null) || (aircraft.Altitude <= _maximumAltitude));
33✔
136

137
        /// <summary>
138
        /// Send a notification of the specified type to the subscribers to the specified handler
139
        /// </summary>
140
        /// <param name="aircraft"></param>
141
        /// <param name="sender"></param>
142
        /// <param name="handler"></param>
143
        /// <param name="type"></param>
144
        /// <param name="previousLatitude"></param>
145
        /// <param name="previousLongitude"></param>
146
        private void SendNotification(
147
            Aircraft aircraft,
148
            AircraftPosition position,
149
            object sender,
150
            EventHandler<AircraftNotificationEventArgs> handler,
151
            AircraftNotificationType type)
152
        {
33✔
153
            try
154
            {
33✔
155
                // Send the notification to subscribers
156
                handler?.Invoke(sender, new AircraftNotificationEventArgs
33✔
157
                {
33✔
158
                    Aircraft = aircraft,
33✔
159
                    Position = position,
33✔
160
                    NotificationType = type
33✔
161
                });
33✔
162
            }
33✔
NEW
163
            catch (Exception ex)
×
NEW
164
            {
×
165
                // Log and sink the exception. The tracker has to be protected from errors in the
166
                // subscriber callbacks or the application will stop updating
NEW
167
                _logger.LogException(ex);
×
NEW
168
            }
×
169
        }
33✔
170

171
        /// <summary>
172
        /// Create and return aircraft position if the specified aircraft has valid latitude and longitude
173
        /// </summary>
174
        /// <param name="aircraft"></param>
175
        /// <returns></returns>
176
        private static AircraftPosition CreateAircraftPosition(Aircraft aircraft)
NEW
177
        {
×
NEW
178
            AircraftPosition position = null;
×
179

NEW
180
            if (aircraft.Altitude != null && aircraft.Latitude != null && aircraft.Longitude != null)
×
NEW
181
            {
×
182
                // Note that both the address and ID of the aircraft are added to the position. The address
183
                // isn't persisted, but is used to map a position to an existing aircraft in cases where a
184
                // new aircraft is detected and its position is pushed to the queue in the same batch as the
185
                // aircraft itself
NEW
186
                position = new AircraftPosition
×
NEW
187
                {
×
NEW
188
                    Id = aircraft.Id,
×
NEW
189
                    Address = aircraft.Address,
×
NEW
190
                    Altitude = aircraft.Altitude ?? 0M,
×
NEW
191
                    Latitude = aircraft.Latitude ?? 0M,
×
NEW
192
                    Longitude = aircraft.Longitude ?? 0M,
×
NEW
193
                    Timestamp = aircraft.LastSeen
×
NEW
194
                };
×
NEW
195
            }
×
196

NEW
197
            return position;
×
NEW
198
        }
×
199
    }
200
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc