# AOC Flight Log system # Basic OOOI system implementation var OOOIReport = { new: func(state,time=0,fob="") { var report = {parents:[OOOIReport]}; report.state = state; report.fob = (fob != "") ? fob : fmgc.FMGCInternal.fob; if (time != 0) { report.time = formatSecToHHMM(time); report.elapsed = time; } else { report.time = sprintf("%02d.%02d", getprop("/sim/time/utc/hour"), getprop("/sim/time/utc/minute")); report.elapsed = int(getprop("/sim/time/elapsed-sec")); } report.gmt = getprop("/sim/time/gmt-string"); report.date = getprop("/sim/time/utc/day"); report.fltnum = (fmgc.FMGCInternal.flightNumSet == 1) ? fmgc.FMGCInternal.flightNum : "----"; report.tofrom = (fmgc.FMGCInternal.toFromSet) ? fmgc.FMGCInternal.depApt ~ "-" ~ fmgc.FMGCInternal.arrApt : "----/----"; return report; }, }; # Flight phase states: RESET, BEGIN, WPUSH, OUT, OFF, ON, END var OOOIReportPage = { new: func(index) { var page = {parents:[OOOIReportPage]}; page.index = index; page.fltstate = ""; #UNDEF state RESET/BEGIN/WPUSH page.fltnum = (fmgc.FMGCInternal.flightNumSet == 1) ? fmgc.FMGCInternal.flightNum : ""; page.date = getprop("/sim/time/utc/day"); page.tofrom = (fmgc.FMGCInternal.toFromSet) ? fmgc.FMGCInternal.depApt ~ "-" ~ fmgc.FMGCInternal.arrApt : ""; page.fltstart = 0; page.blkstart = 0; page.flttime = "--.--"; page.blktime = "--.--"; return page; }, }; var formatSecToHHMM = func(sec) { var mn = int(sec / 60); return sprintf("%02d.%02d",int(mn/60),math.mod(mn,60)); } var FlightLogDatabase = { database: std.Vector.new(), pages: std.Vector.new(), currpageindex: 0, addReport: func(report) { if (report.state == 0 or me.getPageSize()==0) me.addPage(); me.database.append(report); var pg = me.pages.vector[me.pages.size()-1]; if (report.state < 3) { # IN states (3/4) don't update page data if (report.fltnum != "") pg.fltnum = report.fltnum; if (report.tofrom != "") pg.tofrom = report.tofrom; } if (report.state == 0) { pg.fltstate = "OUT"; pg.blkstart = report.elapsed; } else if (report.state == 1) { pg.fltstate = "OFF"; pg.fltstart = report.elapsed; } else if (report.state == 2) { pg.fltstate = "ON"; if (pg.fltstart > 0) pg.flttime = formatSecToHHMM(report.elapsed - pg.fltstart); } else if (report.state > 2) { pg.fltstate = "END"; if (pg.blkstart > 0) pg.blktime = formatSecToHHMM(report.elapsed - pg.blkstart); } }, reset: func() { #Actually reset occurs before IN state - I have no solution for this #if (me.getPageSize()>0 and me.currpageindex < me.getSize()) me.addPage(); }, getSize: func() { return me.database.size(); }, getPageSize: func() { return me.pages.size(); }, clearDatabase: func() { me.database.clear(); me.pages.clear(); }, getLogs: func() { var lst = []; foreach (var log; me.database) { append(lst,log); } return lst; }, addPage: func() { me.currpageindex = me.getSize(); me.pages.append( OOOIReportPage.new(me.getSize()) ); }, getPage: func(pg) { return (pg<=me.getPageSize()) ? me.pages.vector[pg-1] : OOOIReportPage.new(0); }, getLogByPage: func(no) { var lst = [nil,nil,nil,nil]; if (me.getPageSize() == 0) return lst; var i = (me.getPageSize()>=no) ? me.pages.vector[no-1].index : 0; var len = me.getSize(); var v = 0; var p = 0; while (i 9) { # imho - it's useful few speed tollerance, 10kts min speed on taxiways - CHECKME - better with pushback detection? FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState)); expectedOOOIState = 1; } } } else if (expectedOOOIState == 1) { # OFF if (!gear0) { FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState)); expectedOOOIState = 2; } else if (gs < 1) { # RETURN-IN ?? - rejected takeoff, A/C back to apron - CHECKME if (doorL1_pos.getValue()>0 or doorR1_pos.getValue()>0 or doorL4_pos.getValue()>0 or doorR4_pos.getValue()>0) { FlightLogDatabase.addReport(OOOIReport.new(4)); # RETURN-IN expectedOOOIState = 0; } } } else if (expectedOOOIState == 2) { # ON if (gear0 and (phase == 7 or phase == 0)) { #done or preflight FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState)); expectedOOOIState = 3; lastgs0 = 0; lastgsrestart = 0; } } else if (expectedOOOIState == 3) { # IN if (gear0 and gs < 1) { if (lastgs0 == 0) { lastgs0 = int(getprop("/sim/time/elapsed-sec")); lastgsrestart = 0; } if (doorL1_pos.getValue()>0 or doorR1_pos.getValue()>0 or doorL4_pos.getValue()>0 or doorR4_pos.getValue()>0) { FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState)); expectedOOOIState = 0; } } else if (!gear0) { # OFF without IN -> TO without stop and opening doors if (lastgs0>0) FlightLogDatabase.addReport(OOOIReport.new(expectedOOOIState,lastgs0)); # IN (estimated) FlightLogDatabase.addPage(); if (lastgsrestart>0) FlightLogDatabase.addReport(OOOIReport.new(0,lastgsrestart)); # OUT (estimated) expectedOOOIState = 1; # go on to OFF state } else if (gs > 9 and lastgsrestart == 0) { # try to detect OFF without IN lastgsrestart = int(getprop("/sim/time/elapsed-sec")); } } }); var engine_one_chk_OOOI = setlistener("/engines/engine[0]/state", func { if (getprop("/engines/engine[0]/state") == 3) { removelistener(engine_one_chk_OOOI); waitingOOOIChange.start(); } },0,0);