diff --git a/Models/Instruments/DCDU/DCDU.nas b/Models/Instruments/DCDU/DCDU.nas index dae9ce1a..f84c7c23 100644 --- a/Models/Instruments/DCDU/DCDU.nas +++ b/Models/Instruments/DCDU/DCDU.nas @@ -97,15 +97,22 @@ var canvas_DCDU_base = { }, }; +var CPDLCstatusNode = props.globals.getNode("/network/cpdlc/link/status"); +var CPDLCauthority = props.globals.getNode("/network/cpdlc/link/data-authority"); + var canvas_DCDU = { new: func(canvas_group, file) { var m = {parents: [canvas_DCDU, canvas_DCDU_base]}; m.init(canvas_group, file); + m.updateActiveATC(); return m; }, getKeys: func() { return ["ActiveATC","MessageTimeStamp","ADSConnection","RecallMode","LinkLost","Recall","Close"]; }, + cache: { + adsCount: 0, + }, update: func() { me["MessageTimeStamp"].hide(); me["RecallMode"].hide(); @@ -113,22 +120,39 @@ var canvas_DCDU = { me["Recall"].hide(); me["Close"].hide(); - if (atsu.ADS.state == 2) { - me["ADSConnection"].setText("ADS CONNECTED(" ~ atsu.ADS.getCount() ~ ")"); - me["ADSConnection"].show(); - } else { - me["ADSConnection"].hide(); + if (atsu.ADS.getCount() != me.cache.adsCount) { + me.cache.adsCount = atsu.ADS.getCount(); + # FANS A+: status of ADS seems to be independent of connection to CPDLC: confirm in GTG document + if (atsu.ADS.state == 2) { + me["ADSConnection"].setText("ADS CONNECTED(" ~ atsu.ADS.getCount() ~ ")"); + me["ADSConnection"].show(); + } else { + me["ADSConnection"].hide(); + } } - - if (atsu.notificationSystem.notifyAirport != nil and atsu.notificationSystem.hasNotified) { - me["ActiveATC"].setText("ACTIVE ATC : " ~ atsu.notificationSystem.notifyAirport ~ " CTL"); + }, + updateActiveATC: func() { + if (CPDLCstatusNode.getValue() == 2) { + me["ActiveATC"].setText("ACTIVE ATC : " ~ CPDLCauthority.getValue() ~ " CTL"); me["ActiveATC"].show(); } else { me["ActiveATC"].hide(); } - } + }, }; +setlistener("/network/cpdlc/link/status", func() { + if (DCDU != nil) { + DCDU.updateActiveATC(); + } +}, 0, 0); + +setlistener("/network/cpdlc/link/data-authority", func() { + if (DCDU != nil) { + DCDU.updateActiveATC(); + } +}, 0, 0); + var canvas_DCDU_test = { init: func(canvas_group, file) { var font_mapper = func(family, weight) { @@ -180,10 +204,10 @@ setlistener("sim/signals/fdm-initialized", func { }); var rateApply = func { - DCDU_update.restart(0.05 * dcdu_rate.getValue()); + DCDU_update.restart(0.15 * dcdu_rate.getValue()); } -var DCDU_update = maketimer(0.05, func { +var DCDU_update = maketimer(0.15, func { canvas_DCDU_base.update(); }); diff --git a/Models/Instruments/MCDU/MCDU.nas b/Models/Instruments/MCDU/MCDU.nas index 37877a24..b44bdaae 100644 --- a/Models/Instruments/MCDU/MCDU.nas +++ b/Models/Instruments/MCDU/MCDU.nas @@ -1426,7 +1426,6 @@ var canvas_MCDU_base = { me["Simple_L2S"].setText("NEXT ATC"); me["Simple_L2"].setText("----"); me["Simple_C1"].setText("------------- "); - me["Simple_R1"].setText("NOTIFIED "); me["Simple_R3S"].setText("MAX UPLINK DELAY"); me["Simple_R3"].setText("NONE"); @@ -1438,9 +1437,19 @@ var canvas_MCDU_base = { pageSwitch[i].setBoolValue(1); } + if (canvas_dcdu.CPDLCstatusNode.getValue() == 2) { + me["Simple_R1"].setText("DISCONNECT "); + me["Simple_C1"].setText("---------- "); + } else { + me["Simple_R1"].setText("NOTIFIED "); + me["Simple_C1"].setText("------------- "); + } + if (atsu.notificationSystem.notifyAirport != nil) { if (atsu.notificationSystem.hasNotified) { me["Simple_L1"].setText(atsu.notificationSystem.notifyAirport); + me["Simple_C1"].show(); + me["Simple_R1"].show(); } else { me["Simple_L1"].setText("----"); me["Simple_C1"].hide(); diff --git a/Nasal/MCDU/MCDU.nas b/Nasal/MCDU/MCDU.nas index f4bfac92..2a222b81 100644 --- a/Nasal/MCDU/MCDU.nas +++ b/Nasal/MCDU/MCDU.nas @@ -966,6 +966,13 @@ var rskbutton = func(btn, i) { } else if (page == "MCDUTEXT") { atsu.freeTexts[i].selection = 3; atsu.freeTexts[i].changed = 1; + } else if (page == "CONNECTSTATUS") { + if (canvas_dcdu.CPDLCstatusNode.getValue() == 2) { + atsu.notificationSystem.hasNotified = 0; + fgcommand("cpdlc-disconnect"); + } else { + mcdu_message(i, "NOT ALLOWED"); + } } else { mcdu_message(i, "NOT ALLOWED"); } diff --git a/Nasal/Systems/Comm/CPDLC.nas b/Nasal/Systems/Comm/CPDLC.nas index be29fce8..e411cc98 100644 --- a/Nasal/Systems/Comm/CPDLC.nas +++ b/Nasal/Systems/Comm/CPDLC.nas @@ -12,43 +12,89 @@ var CPDLCmessage = { }; var CPDLCnewMsgFlag = props.globals.getNode("/network/cpdlc/rx/new-message"); +var CPDLCnewMsgAlert = props.globals.initNode("/network/cpdlc/new-message-ringtone", 0, "BOOL"); +var CPDLCnewMsgLight = props.globals.initNode("/network/cpdlc/new-message-light", 0, "BOOL"); setlistener("/network/cpdlc/rx/new-message", func() { - if (CPDLCnewMsgflag.getBoolValue()) { - # add to DCDU message buffer - # make alert on DCDU - # add DCDU prompts (wilco, etc) + if (CPDLCnewMsgFlag.getBoolValue()) { + # add to DCDU message buffer to display + + ATCMSGRingCancel = 0; + ATCMSGRing(); + ATCMsgFlashCancel = 0; + ATCMSGFlash(); + # ATC MSG pushbutton: flashes, ringtone after 15 secs, therafter every 15 secs + # add DCDU prompts (wilco, etc) associated to message --> so the CPDLC message object must store the correct response for the actual message CPDLCnewMsgFlag.setBoolValue(0); } }, 0, 0); +var ATCMSGRingCancel = 0; +var ATCMSGRing = func() { + CPDLCnewMsgAlert.setBoolValue(0); + settimer(func() { + if (!ATCMSGRingCancel) { + CPDLCnewMsgAlert.setBoolValue(1); + ATCMSGRing(); + } + }, 15); +}; + +var ATCMsgFlashCancel = 0; +var ATCMSGFlash = func() { + CPDLCnewMsgLight.setBoolValue(!CPDLCnewMsgLight.getBoolValue()); + settimer(func() { + if (!ATCMsgFlashCancel) { + ATCMSGFlash(); + } + }, 0.2); +}; + # issue fgcommand with cpdlc message to send +var prefixes = { + acPerf: "DUE TO A/C PERFORMANCE", + weather: "DUE TO WEATHER", + turbulence: "DUE TO TURBULENCE", + medical: "DUE TO MEDICAL", + technical: "DUE TO TECHNICAL", + discretion: "AT PILOTS DISCRETION", +}; + +var responses = { + w: "WILCO", + u: "UNABLE", + a: "AFFIRM", + n: "NEGATIVE", + r: "ROGER", + s: "STBY", + #o: "none?", + #y: "any?", +}; + var freeText = { - new: func(index) { - var freeTextObj = {parents: [freeText]}; - freeTextObj.index = index; - return freeTextObj; + new: func() { + return {parents: [freeText]}; }, selection: 9, changed: 0, getText: func() { if (me.selection == 0) { - return "DUE TO A/C PERFORMANCE"; + return prefixes["acPerf"]; } elsif (me.selection == 1) { - return "DUE TO WEATHER"; + return prefixes["weather"]; } elsif (me.selection == 2) { - return "DUE TO TURBULENCE"; + return prefixes["turbulence"]; } elsif (me.selection == 3) { - return "DUE TO MEDICAL"; + return prefixes["medical"]; } elsif (me.selection == 4) { - return "DUE TO TECHNICAL"; + return prefixes["technical"]; } elsif (me.selection == 5) { - return "AT PILOTS DISCRETION"; + return prefixes["discretion"]; } else { - return nil; + return ""; } } }; -var freeTexts = [freeText.new(0), freeText.new(1)]; \ No newline at end of file +var freeTexts = [freeText.new(), freeText.new()]; \ No newline at end of file