private void SendDeleteAircraft(FDP2.FDR fdr) { if (Instance?.connected == true) { Instance?.SendData($"D{fdr.Callsign}"); } }
public static void UpdateFDR(FDP2.FDR fdr) { if (Instance?.connected == true) { Instance.SendAircraftMetadata(fdr); } }
private bool isSSRCodeValid(FDP2.FDR flightDataRecord, NetworkPilot actualAircraft) { // Allow Non-Discrete codes if (actualAircraft.TransponderCode == 0640) { return(true); // 1200 } if (actualAircraft.TransponderCode == 1024) { return(true); // 2000 } if (actualAircraft.TransponderCode == 3968) { return(true); // 7600 } if (actualAircraft.TransponderCode == 4032) { return(true); // 7700 } if (actualAircraft.TransponderCode != flightDataRecord.AssignedSSRCode) { return(false); } return(true); }
/// vatSys calls this function when it encounters a custom label item (defined in Labels.xml) during the label rendering. /// itemType is the value of the Type attribute in Labels.xml /// If it's not our item being called (another plugins, for example), return null. /// As a general rule, don't do processing in here as you'll slow down the ASD refresh. In the case of parsing a level to a string though, that's fine. public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { if (flightDataRecord == null) { return(null); } switch (itemType) { case LABEL_ITEM_LEVEL: int level = radarTrack == null ? flightDataRecord.PRL / 100 : radarTrack.CorrectedAltitude / 100; string sLevel = level.ToString("D3"); if (level > RDP.TRANSITION_ALTITUDE) //then flight level { sLevel = "F" + sLevel; } else { sLevel = "A" + sLevel; } return(new CustomLabelItem() { Text = sLevel }); default: return(null); } }
/// First we check if the itemType is our custom Label Item, and a flight data record exists (since we need a callsign) /// Then we get the previously calculated character from our dictionary and display it by returning a custom label item. /// Note we change the items colour from the default colour if it is a 'Z' char. public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { if (flightDataRecord == null) { return(null); } if (itemType != LABEL_ITEM) { return(null); } // Check if the SSR is valid. Otherwise return the "Dupe" tag. ssrCodeValues.TryGetValue(flightDataRecord.Callsign, out bool isCodeValid); if (isCodeValid) { return(null); } return(new CustomLabelItem() { Type = itemType, ForeColourIdentity = Colours.Identities.Default, Text = "Dupe" }); }
public static void RemoveFDR(FDP2.FDR fdr) { if (Instance?.connected == true) { Instance.SendDeleteAircraft(fdr); Instance.vStripsAssignedHeadings.TryRemove(fdr.Callsign, out _); } }
private void SendRemarks(FDP2.FDR fdr) { string rmks = $"P{fdr.Callsign}:{fdr.Remarks}"; if (Instance?.connected == true) { Instance?.SendData(rmks); } }
public void OnFDRUpdate(FDP2.FDR updated) { if (FDP2.GetFDRIndex(updated.Callsign) == -1)//removed { updated.PropertyChanged -= FDR_PropertyChanged; vStripsConnector.RemoveFDR(updated); } else { updated.PropertyChanged -= FDR_PropertyChanged; updated.PropertyChanged += FDR_PropertyChanged; } }
/// This is called each time a flight data record is updated /// Here we are updating the eastbound callsigns dictionary with each flight data record public void OnFDRUpdate(FDP2.FDR updated) { if (FDP2.GetFDRIndex(updated.Callsign) == -1) //FDR was removed (that's what triggered the update) { eastboundCallsigns.TryRemove(updated.Callsign, out _); } else { if (updated.ParsedRoute.Count > 1) { //calculate track from first route point to last (Departure point to destination point) var rte = updated.ParsedRoute; double trk = Conversions.CalculateTrack(rte.First().Intersection.LatLong, rte.Last().Intersection.LatLong); bool east = trk >= 0 && trk < 180; eastboundCallsigns.AddOrUpdate(updated.Callsign, east, (c, e) => east); } } }
public void OnFDRUpdate(FDP2.FDR updated) { if (FDP2.GetFDRIndex(updated.Callsign) == -1) { pbnValues.TryRemove(updated.Callsign, out _); } else { Match pbn = Regex.Match(updated.Remarks, @"PBN\/\w+\s"); bool rnp10 = Regex.IsMatch(pbn.Value, @"A\d"); bool rnp5 = Regex.IsMatch(pbn.Value, @"B\d"); bool rnp4 = Regex.IsMatch(pbn.Value, @"L\d"); bool rnp2 = updated.Remarks.Contains("NAV/RNP2") || updated.Remarks.Contains("NAV/GLS RNP2"); // TODO: Find a better way char cap = 'P'; if (rnp2 && (rnp10 || rnp4)) { cap = '\0'; } else if (rnp2) { cap = '\0'; } else if (rnp4) { cap = '\0'; } else if (rnp5) { cap = '\0'; } else if (rnp10) { cap = '\0'; } pbnValues.AddOrUpdate(updated.Callsign, cap, (k, v) => cap); } }
/// First we check if the itemType is our custom Label Item, and a flight data record exists (since we need a callsign) /// Then we get the previously calculated character from our dictionary and display it by returning a custom label item. /// Note we change the items colour from the default colour if it is a 'Z' char. public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { if (flightDataRecord == null) { return(null); } if (itemType != LABEL_ITEM) { return(null); } char val = 'P'; pbnValues.TryGetValue(flightDataRecord.Callsign, out val); return(new CustomLabelItem() { Type = itemType, ForeColourIdentity = Colours.Identities.Default, Text = val.ToString() }); }
private void ProcessData(string packet) { if (packet.Length == 0) { return; } string msg = packet.Substring(1); string[] msg_fields = msg.Split(':'); FDP2.FDR fdr = null; if (msg_fields.Length > 0) { fdr = FDP2.GetFDRs.FirstOrDefault(f => f.Callsign == msg_fields[0]); } switch (packet[0]) { case 'U': if (!connected) { OnConnected(); } SendControllerInfo(); break; case 'r': // Runway request if (Airport?.ICAOName != msg) // || setRunways == false) // Commented out as part of runway supression { getMetar(msg); // Call before we update 'Airport' Airport = Airspace2.GetAirport(msg); setRunways = false; //vStripsPlugin.ShowSetupWindow(); // Commented out to stop popup JMG } else { //SendRunways(); Airport = Airspace2.GetAirport(msg); } break; case 'S': // State if (msg_fields.Length > 1 && fdr != null) { switch (msg_fields[1]) { case "TAXI": MMI.EstFDR(fdr); break; } } break; /* * JMG * vStrips doesn't send Arrival Runway, so we use Dep runway in vStrips for Arrival runway allocation. * We need to keep an eye out when Route changes received that have a Dep runway and reassign to Arr runway. * */ case 'R': // Route if (msg_fields.Length > 3 && fdr != null) { if (fdr.DepAirport == msg_fields[1] && fdr.DesAirport == msg_fields[2]) { string rte = msg_fields[3]; string[] rte_fields = rte.Split(' '); // parse route on space if (rte_fields[0].Contains('/')) // If the first field has a slash, it's a Dep runway assignment. { string[] start_fields = rte_fields[0].Split('/'); String NewRwy = start_fields[1]; // get the runway if (fdr.CoupledTrack?.OnGround == false) // if we're airborne apply the runway to Arrivals { FDP2.SetArrivalRunway(fdr, Airspace2.GetRunway(fdr.DesAirport, NewRwy)); } else // Apply the Route change, or Dep runway change { string temprwy = ""; if (fdr.DepartureRunway != null) { temprwy = fdr.DepartureRunway.ToString(); } if (temprwy != NewRwy) // if the Dep runway has changed { FDP2.SetDepartureRunway(fdr, Airspace2.GetRunway(fdr.DepAirport, NewRwy)); } else // Not a runway change, so update the route { FDP2.ModifyRoute(fdr, rte); } } } } else { FDP2.ModifyFDR(fdr, fdr.Callsign, fdr.FlightRules, msg_fields[1], msg_fields[2], msg_fields[3], fdr.Remarks, fdr.AircraftCount.ToString(), fdr.AircraftType, fdr.AircraftWake, fdr.AircraftEquip, fdr.AircraftSurvEquip, fdr.TAS.ToString(), fdr.RFL.ToString(), fdr.ETD.ToString("HHmm"), fdr.EET.ToString("HHmm")); } } break; case 'H': // Heading if (msg_fields.Length > 1 && fdr != null) { vStripsAssignedHeadings.AddOrUpdate(fdr.Callsign, int.Parse(msg_fields[1]), (s, i) => int.Parse(msg_fields[1])); if (!string.IsNullOrEmpty(msg_fields[1]) && msg_fields[1] != "0") { FDP2.SetGlobalOps(fdr, $"H{msg_fields[1]}"); } if (msg_fields.Length > 2 && msg_fields[2] != "0") { FDP2.SetCFL(fdr, FDP2.FDR.LEVEL_NONE, int.Parse(msg_fields[2]), false); } } break; case '>': // Select Callsign // Edited JMG to ensure when strip is selected in vStrips, track is selected in vatSys if (fdr != null) { var currentSelection = MMI.SelectedTrack; // Deselect old if (MMI.SelectedTrack != null) { MMI.SelectOrDeselectTrack(currentSelection); } var trk = MMI.FindTrack(fdr); if (trk != null) { MMI.SelectOrDeselectTrack(trk); } } break; } PacketReceived?.Invoke(this, new PacketReceivedEventArgs(packet)); Console.WriteLine(packet); }
/** * Construct Aircraft data * * string[] strArray = msg.Split(':'); * this.callsign = strArray[0]; * this.upDown = this.callsign[0]; * this.callsign = this.callsign.Substring(1); * this.origin = strArray[1]; * this.dest = strArray[2]; * this.squawk = string.IsNullOrEmpty(strArray[3]) ? (string)null : strArray[3]; * this.sentSquawk = string.IsNullOrEmpty(strArray[4]) ? (string)null : strArray[4]; * this.groundState = strArray[5][0]; * this.altitude = int.Parse(strArray[6]); * this.heading = int.Parse(strArray[7]); * this.gone = int.Parse(strArray[8]); * this.toGo = int.Parse(strArray[9]); * this.aircraftType = strArray[10]; * this.sidName = string.IsNullOrEmpty(strArray[11]) ? (string)null : strArray[11]; * this.runway = string.IsNullOrEmpty(strArray[12]) ? (string)null : strArray[12]; * this.fpRules = strArray[13][0] == 'V' ? FltRules.VFR : FltRules.IFR; * this.rfl = int.Parse(strArray[14]); * this.estDepTime = strArray[15]; * this.spd = strArray[16]; * this.groundspeed = int.Parse(strArray[17]); * this.route = strArray[18]; * this.distanceFromMe = int.Parse(strArray[19]); * this.commsType = strArray[20][0]; * try * { * this.lat = double.Parse(strArray[21]); * this.lon = double.Parse(strArray[22]); * } * catch * { * } * if (!(Presenter.CurrentAirfield == "EGLL") && !(Presenter.CurrentAirfield == "EGCC")) * return; * this.scratchpad = strArray[23]; * */ private void SendAircraftMetadata(FDP2.FDR fdr) { if (fdr == null) { return; } if (fdr.PredictedPosition.Location == null) { return; } RDP.RadarTrack radTrack = fdr.CoupledTrack; if (radTrack == null) { radTrack = RDP.RadarTracks.FirstOrDefault(r => r.ASMGCSCoupledFDR == fdr); } string gone = "0"; string togo = "0"; string tome = "0"; if (fdr.ParsedRoute?.Count > 0) { gone = Conversions.CalculateDistance(fdr.ParsedRoute.First().Intersection.LatLong, fdr.PredictedPosition.Location).ToString("0"); togo = Conversions.CalculateDistance(fdr.ParsedRoute.Last().Intersection.LatLong, fdr.PredictedPosition.Location).ToString("0"); tome = Conversions.CalculateDistance(Airport == null ? Network.Me.Position : Airport.LatLong, fdr.PredictedPosition.Location).ToString("0"); } string upDown = "U"; if (radTrack?.OnGround == true || fdr.ATD == DateTime.MaxValue) { upDown = "D"; } string gndState = " "; if (fdr.DepAirport == Airport?.ICAOName && fdr.State == FDP2.FDR.FDRStates.STATE_COORDINATED) { gndState = "T"; } int ahdg = 0; vStripsAssignedHeadings.TryGetValue(fdr.Callsign, out ahdg); string meta = string.Join(":", upDown + fdr.Callsign, fdr.DepAirport, fdr.DesAirport, fdr.AssignedSSRCode == -1 ? "" : Convert.ToString(fdr.AssignedSSRCode, 8), radTrack != null ? Convert.ToString(radTrack.ActualAircraft.TransponderCode, 8): "", gndState, fdr.CFLUpper <= FDP2.FDR.LEVEL_VSA ? 0 : fdr.CFLUpper, ahdg, gone, togo, fdr.AircraftType + "/" + fdr.AircraftWake, (fdr.DepAirport == Airport?.ICAOName ? fdr.SIDSTARString:""), // modified JMG - Inhibit STAR population for airborne fdr.RunwayString, fdr.FlightRules, fdr.RFL, fdr.ETD.ToString("HHmm"), 0, fdr.PredictedPosition.Groundspeed.ToString("0"), fdr.Route, tome, fdr.TextOnly ? "T" : fdr.ReceiveOnly ? "R" : "V", fdr.PredictedPosition.Location.Latitude, fdr.PredictedPosition.Location.Longitude, fdr.LabelOpData); Instance?.SendData("M" + meta); SendRemarks(fdr); }
public CustomLabelItem GetCustomLabelItem(string itemType, Track track, FDP2.FDR flightDataRecord, RDP.RadarTrack radarTrack) { return(null); }
// Not needed for this plugin. public void OnFDRUpdate(FDP2.FDR updated) { }