public async Task <string> GetToken(CancellationToken cancellationToken) { await _lock.WaitAsync(cancellationToken); try { if (_settings.TokenResponse.IsValidForAuth()) { return(_settings.TokenResponse.AccessToken); } if (_settings.TokenResponse.CanBeRefreshed()) { try { await _messagesService.AddMessageAsync("Refreshing AA access token."); return(await RefreshAccessToken(cancellationToken)); } catch (Exception) { // Ignore and try asking user } } await _messagesService.AddMessageAsync("Asking user for AA access token."); return(await AskUserForAccessToken(cancellationToken)); } finally { _lock.Release(); } }
private async Task SendTelemetry(Models.FlightData flightData) { if (_settings.CurrentFlightId == null) { await _messagesService.AddMessageAsync( new Message("Not sending telemetry as no current flight ID is set.")); return; } try { var lat = (float)flightData.CurrentPosition.Latitude; var lon = (float)flightData.CurrentPosition.Longitude; var alt = (ushort)flightData.CurrentPosition.Altitude; var courseInRadians = flightData.CurrentPosition.Course / 180 * Math.PI; var xVel = (float)(Math.Sin(courseInRadians) * flightData.CurrentPosition.Speed); var yVel = (float)(Math.Cos(courseInRadians) * flightData.CurrentPosition.Speed); var zVel = flightData.CurrentPosition.VerticalSpeed; // Create dataStructure var udpMessage = new UavPositionReport { GpsTimestamp = DateTime.UtcNow, Pos = new Position(lat, lon, 0), Alt = new Altitude(alt, AltitudeDatum.Agl, 1), Velocity = new Velocity(xVel, yVel, zVel, 1), IsAirborne = AirborneStatus.Airborne, SatellitesVisible = 3 }; var telemetryId = Guid.Parse(_settings.CurrentTelemetryId); var telemetry = new TelemetryEvent <UavPositionReport>(telemetryId, udpMessage) { SequenceNumber = _sequenceNumber }; var message = string.Format($"Sending Telemetry {flightData.CurrentPosition.Latitude}, {flightData.CurrentPosition.Longitude}, {flightData.CurrentPosition.Altitude}"); await _messagesService.AddMessageAsync(new Message(message)); _client.SendTelemetry(telemetry, _settings.TelemetryHostName, _settings.TelemetryPortNumber, _settings.EncryptionKey); _sequenceNumber += 1; } catch (Exception) { await _messagesService.AddMessageAsync(new Message("ERROR: Sending telemetry failed.")); } }
public async Task SignInAsync() { if (!_settings.CheckEnableAltitudeAngel) { return; } try { // Load the user's profile, will trigger auth CurrentUser = await _client.GetUserProfile(); IsSignedIn.Value = true; await UpdateMapData(_missionPlanner.FlightDataMap, CancellationToken.None); await UpdateMapData(_missionPlanner.FlightPlanningMap, CancellationToken.None); } catch (Exception) { await _messagesService.AddMessageAsync("There was a problem signing you in."); } }
private async Task OnMessage(byte[] bytes) { await _messagesService.AddMessageAsync(new Message($"INFO: Received notification message of {bytes.Length} bytes.")); var notification = new NotificationMessage(); try { var msg = Encoding.UTF8.GetString(bytes); notification = JsonConvert.DeserializeObject <NotificationMessage>(msg); if (notification.Acknowledge) { await SendAck(_aaClientWebSocket, notification.Id); } } catch (Exception e) { await _messagesService.AddMessageAsync(new Message($"ERROR: Failed to deserialize and acknowledge notification message. {e}")); } await _messagesService.AddMessageAsync(new Message($"INFO: Processing {notification.Type} notification message.")); try { switch (notification.Type) { case OutboundNotifsCommands.Land: LandNotificationProperties landProps = notification.Properties.ToObject <LandNotificationProperties>(); await _missionPlanner.CommandDroneToLand((float)landProps.Latitude, (float)landProps.Longitude); break; case OutboundNotifsCommands.Loiter: LoiterNotificationProperties loiterProps = notification.Properties.ToObject <LoiterNotificationProperties>(); await _missionPlanner.CommandDroneToLoiter((float)loiterProps.Latitude, (float)loiterProps.Longitude, (float)loiterProps.Altitude.Meters); break; case OutboundNotifsCommands.AllClear: await _missionPlanner.CommandDroneAllClear(); break; case OutboundNotifsCommands.ReturnToBase: await _missionPlanner.CommandDroneToReturnToBase(); break; case OutboundNotifsCommands.PermissionUpdate: var permissionProperties = notification.Properties.ToObject <PermissionNotificationProperties>(); await _messagesService.AddMessageAsync(new Message($"Flight permissions updated: {permissionProperties.PermissionState}") { TimeToLive = TimeSpan.FromSeconds(10) }); break; case OutboundNotifsCommands.ConflictInformation: var conflictProperties = notification.Properties.ToObject <ConflictInformationProperties>(); await _missionPlanner.NotifyConflict(conflictProperties.Message); break; case OutboundNotifsCommands.ConflictClearedInformation: var conflictClearedProperties = notification.Properties.ToObject <ConflictClearedNotificationProperties>(); await _missionPlanner.NotifyConflictResolved(conflictClearedProperties.Message); break; case OutboundNotifsCommands.Instruction: var instructionProperties = notification.Properties.ToObject <InstructionNotificationProperties>(); if (await _missionPlanner.ShowYesNoMessageBox( $"You have been sent the following instruction:\r\n\r\n\"{instructionProperties.Instruction}\"\r\n\r\nDo you wish to accept and follow the instruction?", "Instruction")) { await _flightServiceClient.AcceptInstruction(instructionProperties.InstructionId); if (instructionProperties.Instruction.IndexOf("hold", StringComparison.InvariantCultureIgnoreCase) >= 0) { await _missionPlanner.CommandDroneToLoiter((float)_missionPlannerState.Latitude, (float)_missionPlannerState.Longitude, _missionPlannerState.Altitude); break; } if (instructionProperties.Instruction.IndexOf("resume", StringComparison.InvariantCultureIgnoreCase) >= 0) { await _missionPlanner.CommandDroneAllClear(); break; } if (instructionProperties.Instruction.IndexOf("land", StringComparison.InvariantCultureIgnoreCase) >= 0) { await _missionPlanner.CommandDroneToLand((float)_missionPlannerState.Latitude, (float)_missionPlannerState.Longitude); break; } if (instructionProperties.Instruction.IndexOf("return", StringComparison.InvariantCultureIgnoreCase) >= 0) { await _missionPlanner.CommandDroneToReturnToBase(); } } else { await _flightServiceClient.RejectInstruction(instructionProperties.InstructionId); } break; default: await _messagesService.AddMessageAsync(new Message($"WARN: Unknown notification message type '{notification.Type}'.")); break; } } catch (Exception e) { await _messagesService.AddMessageAsync(new Message($"ERROR: Failed to process {notification.Type} notification message. {e}")); } }
private async Task StartTelemetryFlight(FlightPlan flightPlan) { if (flightPlan == null) { return; } if (_settings.CurrentFlightId != null) { // Complete flight if starting one before the previous ends. await CompleteFlight(); } // TODO somehow prevent Arming of UAV until the following try statement has been completed, so telemetry isnt sent late. PBI 8490 try { CurrentUser = await _client.GetUserProfile(); Guid?flightPlanId; if (_settings.UseExistingFlightPlanId) { flightPlanId = _settings.ExistingFlightPlanId; } else { await _messagesService.AddMessageAsync(new Message("Creating flight plan...") { TimeToLive = TimeSpan.FromSeconds(10) }); var createPlanResponse = await _client.CreateFlightPlan(flightPlan, CurrentUser); if (createPlanResponse.Outcome == StrategicSeverity.DirectConflict) { await _messagesService.AddMessageAsync(new Message("Conflict detected; flight cancelled.") { TimeToLive = TimeSpan.FromSeconds(10) }); await _missionPlanner.Disarm(); return; } flightPlanId = createPlanResponse.FlightPlanId; } // Check flight plan id is valid if (flightPlanId == null || flightPlanId == Guid.Empty) { await _messagesService.AddMessageAsync(new Message("Flight plan not available; flight cancelled.") { TimeToLive = TimeSpan.FromSeconds(10) }); await _missionPlanner.Disarm(); return; } _settings.CurrentFlightReportId = flightPlanId.ToString(); await _messagesService.AddMessageAsync(new Message($"Flight plan {flightPlanId} in use.") { TimeToLive = TimeSpan.FromSeconds(10) }); // Flight being rejected will throw, and cause a disarm await _messagesService.AddMessageAsync(new Message("Starting flight...") { TimeToLive = TimeSpan.FromSeconds(10) }); var startFlightResponse = await _client.StartFlight(flightPlanId.Value.ToString("D")); _settings.CurrentFlightId = startFlightResponse.Id; var tacticalSettings = startFlightResponse.ServiceResponses.First(); var notificationSettings = (WebsocketNotificationProtocolConfiguration)tacticalSettings.Properties.NotificationProtocols.First(); _settings.OutboundNotifsEndpointUrl = notificationSettings.Properties.Endpoints.First(); var telemetrySettings = (UdpTelemetryProtocolConfiguration)tacticalSettings.Properties.TelemetryProtocols.First(); _settings.CurrentTelemetryId = telemetrySettings.Id; _settings.EncryptionKey = telemetrySettings.Properties.EncryptionKey; var telemetryEndPoint = telemetrySettings.Properties.Endpoints.First(); _settings.TelemetryHostName = telemetryEndPoint.Split(':')[0]; _settings.TelemetryPortNumber = int.Parse(telemetryEndPoint.Split(':')[1]); _settings.TransmissionRateInMilliseconds = telemetrySettings.Properties.TransmissionRateInMilliseconds; var task = _notificationsService.StartWebSocket(); await _messagesService.AddMessageAsync(new Message($"Flight {startFlightResponse.Id} approved and underway.") { TimeToLive = TimeSpan.FromSeconds(10) }); await task; } catch (Exception) { await _missionPlanner.Disarm(); await _messagesService.AddMessageAsync(new Message($"Flight create failed.")); } }