diff --git a/Nasal/FMGC/SimbriefParser.nas b/Nasal/FMGC/SimbriefParser.nas index 4141153e..093c5d8e 100644 --- a/Nasal/FMGC/SimbriefParser.nas +++ b/Nasal/FMGC/SimbriefParser.nas @@ -14,7 +14,14 @@ var SimbriefParser = { var stamp = systime(); http.save("https://www.simbrief.com/api/xml.fetcher.php?username=" ~ username, getprop('/sim/fg-home') ~ "/Export/A320-family-simbrief.xml") .fail(func me.failure(i)) - .done(func me.read(getprop('/sim/fg-home') ~ "/Export/A320-family-simbrief.xml", i)); + .done(func { + var errs = []; + call(me.read, [(getprop('/sim/fg-home') ~ "/Export/A320-family-simbrief.xml"),i], SimbriefParser, {}, errs); + if (size(errs) > 0) { + debug.printerror(errs); + me.failure(i); + } + }); }, failure: func(i) { mcdu.mcdu_message(i, "SIMBRIEF DOWNLOAD FAILED"); @@ -25,141 +32,162 @@ var SimbriefParser = { if (data != nil) { if (data.getChild("OFP") == nil) { print("XML file " ~ xml ~ " not a valid Simbrief file"); + me.failure(i); + return; } else { me.node = data; - me.parseOFP(); - mcdu.mcdu_message(i, "AOC ACT F-PLN UPLINK"); + if (me.parseOFP() == nil) { + print("Failure to parse Simbrief OFP"); + me.failure(i); + } else { + mcdu.mcdu_message(i, "AOC ACT F-PLN UPLINK"); + } } } else { print("Error reading " ~ xml); + me.failure(i); } }, + tryFindByCoord: func(coords, id, type) { + var result = nil; + if (type == "nav") { + result = findNavaidsByID(id); + } elsif (type == "fix") { + result = findFixesByID(id); + } else { + return nil; + } + + if (size(result) == 0) { return nil; } + foreach (var test; result) { + if (math.abs(test.lat - coords.lat()) < 0.01666666666 and math.abs(test.lon - coords.lon()) < 0.01666666666) { + return test; + } + } + return nil; + }, + buildFlightplan: func() { + # Flightplan stuff + fmgc.flightPlanController.flightplans[3] = createFlightplan(); + fmgc.flightPlanController.flightplans[3].cleanPlan(); + + # INITA + var departureID = me.OFP.getNode("origin/icao_code").getValue(); + var departures = findAirportsByICAO(departureID); + var destinationID = me.OFP.getNode("destination/icao_code").getValue(); + var destinations = findAirportsByICAO(destinationID); + + if (departures != nil and size(departures) != 0 and destinations != nil and size(destinations) != 0) { + fmgc.flightPlanController.flightplans[3].departure = departures[0]; + fmgc.flightPlanController.flightplans[3].destination = destinations[0]; + fmgc.FMGCInternal.arrApt = destinationID; + fmgc.FMGCInternal.depApt = departureID; + + fmgc.FMGCInternal.toFromSet = 1; + fmgc.FMGCNodes.toFromSet.setValue(1); + + fmgc.updateArptLatLon(); + fmgc.updateARPT(); + } else { + me.cleanupInvalid(); + return nil; + } + + var runwayStore = departures[0].runways[me.OFP.getNode("origin/plan_rwy").getValue()]; + if (runwayStore != nil) { + fmgc.flightPlanController.flightplans[3].departure_runway = runwayStore; + } + + runwayStore = destinations[0].runways[me.OFP.getNode("destination/plan_rwy").getValue()]; + if (runwayStore != nil) { + fmgc.flightPlanController.flightplans[3].destination_runway = runwayStore; + } + + var alternateID = me.OFP.getNode("alternate/icao_code").getValue(); + var alternates = findAirportsByICAO(alternateID); + if (alternates != nil and size(alternates) != 0) { + fmgc.FMGCInternal.altAirport = alternateID; + fmgc.FMGCInternal.altAirportSet = 1; + } + + var wps = []; + var ofpNavlog = me.OFP.getNode("navlog"); + var ofpFixes = ofpNavlog.getChildren("fix"); + var ident = ""; + var coords = nil; + var wp = nil; + + foreach (var ofpFix; ofpFixes) { + if (ofpFix.getNode("is_sid_star").getBoolValue()) { + # continue; + } + + ident = ofpFix.getNode("ident").getValue(); + if (find(departureID, ident) != -1 or find(destinationID, ident) != -1) { + continue; + } + + if (ident == "TOC" or ident == "TOD") { + continue; + } + + coords = geo.Coord.new(); + coords.set_latlon( + ofpFix.getNode("pos_lat").getValue(), + ofpFix.getNode("pos_long").getValue()); + + wp = me.tryFindByCoord(coords,ident,"fix"); + wp = me.tryFindByCoord(coords,ident,"nav"); + if (wp == nil) { + wp = createWP(coords, ident); + } + + append(wps, wp); + } + + fmgc.flightPlanController.flightplans[3].insertWaypoints(wps, 1); + fmgc.flightPlanController.destroyTemporaryFlightPlan(3, 1); + fmgc.windController.updatePlans(); + fmgc.updateRouteManagerAlt(); + + return 1; + }, parseOFP: func() { me.OFP = me.node.getChild("OFP"); - me.store1 = nil; - me.store2 = nil; - - me.store1 = me.OFP.getChild("params"); - var units = me.store1.getChild("units").getValue(); - - me.store1 = me.OFP.getChild("general"); - me.store2 = me.OFP.getChild("alternate"); - fmgc.FMGCInternal.flightNum = (me.store1.getChild("icao_airline").getValue() or "") ~ (me.store1.getChild("flight_number").getValue() or ""); + if (me.buildFlightplan() == nil) { + return nil; + } + fmgc.FMGCInternal.flightNum = (me.OFP.getNode("general/icao_airline").getValue() or "") ~ (me.OFP.getNode("general/flight_number").getValue() or ""); fmgc.FMGCInternal.flightNumSet = 1; - fmgc.FMGCInternal.costIndex = me.store1.getChild("costindex").getValue(); + fmgc.FMGCInternal.costIndex = me.OFP.getNode("general/costindex").getValue(); fmgc.FMGCInternal.costIndexSet = 1; fmgc.FMGCNodes.costIndex.setValue(fmgc.FMGCInternal.costIndex); - fmgc.FMGCInternal.tropo = me.store1.getChild("avg_tropopause").getValue(); + fmgc.FMGCInternal.tropo = me.OFP.getNode("general/avg_tropopause").getValue(); fmgc.FMGCInternal.tropoSet = 1; - fmgc.FMGCInternal.crzFt = me.store1.getChild("initial_altitude").getValue(); - fmgc.FMGCInternal.crzFl = me.store1.getChild("initial_altitude").getValue() / 100; - fmgc.altvert(); - fmgc.FMGCInternal.crzSet = 1; + + # Set cruise altitude + fmgc.FMGCInternal.crzFt = me.OFP.getNode("general/initial_altitude").getValue(); + fmgc.FMGCInternal.crzFl = fmgc.FMGCInternal.crzFt / 100; + fmgc.FMGCInternal.crzTemp = (((fmgc.FMGCInternal.crzFt / 1000) * -2) + 15) + me.OFP.getNode("general/avg_temp_dev").getValue(); + fmgc.FMGCInternal.crzProg = fmgc.FMGCInternal.crzFt / 100; mcdu.updateCrzLvlCallback(); - fmgc.FMGCInternal.crzTemp = (((me.store1.getChild("initial_altitude").getValue() / 1000) * -2) + 15) + me.store1.getChild("avg_temp_dev").getValue(); fmgc.FMGCInternal.crzTempSet = 1; - fmgc.FMGCInternal.crzProg = me.store1.getChild("initial_altitude").getValue() / 100; - if (num(me.store1.getChild("avg_wind_comp").getValue()) >= 0) { - fmgc.FMGCInternal.tripWind = "TL" ~ abs(me.store1.getChild("avg_wind_comp").getValue()); + fmgc.FMGCInternal.crzSet = 1; + fmgc.altvert(); + + var windComp = me.OFP.getNode("general/avg_wind_comp").getValue(); + if (num(windComp) >= 0) { + fmgc.FMGCInternal.tripWind = "TL" ~ abs(windComp); } else { - fmgc.FMGCInternal.tripWind = "HD" ~ abs(me.store1.getChild("avg_wind_comp").getValue()); + fmgc.FMGCInternal.tripWind = "HD" ~ abs(windComp); } - fmgc.FMGCInternal.tripWindValue = abs(me.store1.getChild("avg_wind_comp").getValue()); - - fmgc.FMGCInternal.altAirport = me.store2.getChild("icao_code").getValue(); - fmgc.FMGCInternal.altAirportSet = 1; - - # Flightplan stuff - fmgc.flightPlanController.flightplans[3] = createFlightplan(); - - # INITA - me.store1 = me.OFP.getChild("origin"); - me.store2 = me.OFP.getChild("destination"); - - fmgc.FMGCInternal.depApt = me.store1.getChild("icao_code").getValue(); - fmgc.FMGCInternal.arrApt = me.store2.getChild("icao_code").getValue(); - fmgc.FMGCInternal.toFromSet = 1; - fmgc.FMGCNodes.toFromSet.setValue(1); - fmgc.flightPlanController.flightplans[3].departure = airportinfo(fmgc.FMGCInternal.depApt); - fmgc.flightPlanController.flightplans[3].destination = airportinfo(fmgc.FMGCInternal.arrApt); - fmgc.FMGCInternal.altSelected = 0; - fmgc.updateArptLatLon(); - fmgc.updateARPT(); - call(func() { - fmgc.flightPlanController.flightplans[3].departure_runway = airportinfo(fmgc.FMGCInternal.depApt).runways[me.store1.getChild("plan_rwy").getValue()]; - fmgc.flightPlanController.flightplans[3].destination_runway = airportinfo(fmgc.FMGCInternal.arrApt).runways[me.store2.getChild("plan_rwy").getValue()]; - }); - - me.store1 = me.OFP.getChild("navlog").getChildren(); - if (size(me.store1) != 0) { - var firstIsSID = 0; - var SIDID = ""; - if (me.store1[0].getChild("is_sid_star").getValue() == 1) { - if (fmgc.flightPlanController.flightplans[3].departure.getSid(me.store1[0].getChild("via_airway").getValue()) != nil) { - firstIsSID = 1; - SIDID = me.store1[0].getChild("via_airway").getValue(); - } - } - var lastIsSTAR = 0; - var STARID = ""; - if (me.store1[-1].getChild("is_sid_star").getValue() == 1) { - if (fmgc.flightPlanController.flightplans[3].destination.getStar(me.store1[-1].getChild("via_airway").getValue()) != nil) { - lastIsSTAR = 1; - STARID = me.store1[-1].getChild("via_airway").getValue(); - } - } - - var lastSIDIndex = -999; - var firstSTARIndex = -999; - var TOCinSIDflag = 0; - var TODinSTARflag = 0; - for (var i = 0; i < size(me.store1); i = i + 1) { - if (firstIsSID) { - if (me.store1[i].getChild("is_sid_star").getValue() == 0 or me.store1[i].getChild("via_airway").getValue() != SIDID) { - lastSIDIndex = i - 1; - break; - } - } - } - - for (var i = lastSIDIndex == -999 ? 0 : lastSIDIndex; i < size(me.store1); i = i + 1) { - if (STARID != "") { - if (me.store1[i].getChild("is_sid_star").getValue() == 1 and me.store1[i].getChild("via_airway").getValue() == STARID) { - firstSTARIndex = i; - break; - } - } - } - - var max = firstSTARIndex == -999 ? size(me.store1) - 1 : firstSTARIndex - 1; - for (var i = lastSIDIndex == -999 ? 0 : lastSIDIndex + 2; i < max; i = i + 1) { - if (me.store1[i].getChild("ident").getValue() == "TOC" or me.store1[i].getChild("ident").getValue() == "TOD") { continue; } - var coord = geo.Coord.new(); - coord.set_latlon(me.store1[i].getChild("pos_lat").getValue(), me.store1[i].getChild("pos_long").getValue()); - var fixes = findFixesByID(coord, me.store1[i].getChild("ident").getValue()); - var navaids = findNavaidsByID(coord, me.store1[i].getChild("ident").getValue()); - if (size(fixes) > 0) { - fmgc.flightPlanController.flightplans[3].appendWP(createWPFrom(fixes[0])); - } else if (size(navaids) > 0) { - fmgc.flightPlanController.flightplans[3].appendWP(createWPFrom(navaids[0])); - } else { - var WP = createWP(coord, me.store1[i].getChild("ident").getValue()); - fmgc.flightPlanController.flightplans[3].appendWP(WP); - } - } - fmgc.flightPlanController.flightplans[3].sid = fmgc.flightPlanController.flightplans[3].departure.getSid(SIDID); - fmgc.flightPlanController.flightplans[3].star = fmgc.flightPlanController.flightplans[3].destination.getStar(STARID); - } - fmgc.flightPlanController.destroyTemporaryFlightPlan(3, 1); - - fmgc.windController.updatePlans(); - fmgc.updateRouteManagerAlt(); + fmgc.FMGCInternal.tripWindValue = abs(windComp); # INITB me.store1 = me.OFP.getChild("fuel"); me.store2 = me.OFP.getChild("weights"); - if (units == "lbs") { + if (me.OFP.getNode("params/units").getValue() == "lbs") { fmgc.FMGCInternal.taxiFuel = me.store1.getChild("taxi").getValue() / 1000; fmgc.FMGCInternal.taxiFuelSet = 1; fmgc.FMGCInternal.altFuel = me.store1.getChild("alternate_burn").getValue() / 1000; @@ -206,5 +234,7 @@ var SimbriefParser = { fmgc.FMGCInternal.blockCalculating = 0; fmgc.blockCalculating.setValue(0); fmgc.FMGCInternal.blockConfirmed = 1; + + return 1; }, }; \ No newline at end of file