From 487ed3f589bf6b5f26dcb122d03f84fd33303426 Mon Sep 17 00:00:00 2001 From: Kilian Hofmann Date: Fri, 13 Feb 2026 21:34:56 +0100 Subject: [PATCH] GSX synced loading of fuel --- EFB/efb-html.patch | 3 +- EFB/efb-js.patch | 4 +- PackageSources/js-bundle/package.json | 2 +- .../js-bundle/src/components/input/Input.tsx | 19 ++++++++ .../stationEntry/StationEntryPax.tsx | 2 +- PackageSources/wasm-module/load-manager.cpp | 48 ++++++++++++------- PackageSources/wasm-module/load-manager.h | 2 +- PackageSources/wasm-module/shared.h | 4 +- TODO.md | 3 -- insert-efb.js | 43 ++++++++--------- 10 files changed, 78 insertions(+), 52 deletions(-) diff --git a/EFB/efb-html.patch b/EFB/efb-html.patch index 547fda8..8515c50 100644 --- a/EFB/efb-html.patch +++ b/EFB/efb-html.patch @@ -10,6 +10,5 @@ Index: EFB.html - + -- -+ + + diff --git a/EFB/efb-js.patch b/EFB/efb-js.patch index 527d1f8..c2de99d 100644 --- a/EFB/efb-js.patch +++ b/EFB/efb-js.patch @@ -2,7 +2,7 @@ Index: EFB.js =================================================================== --- EFB.js +++ EFB.js -@@ -40265,11 +40265,11 @@ +@@ -50827,11 +50827,11 @@ ), /* @__PURE__ */ (0, import_jsx_runtime13.jsx)( "button", @@ -16,7 +16,7 @@ Index: EFB.js ), /* @__PURE__ */ (0, import_jsx_runtime13.jsx)( "button", -@@ -40767,8 +40767,27 @@ +@@ -51337,8 +51337,27 @@ ] }) ] }) }) }); } diff --git a/PackageSources/js-bundle/package.json b/PackageSources/js-bundle/package.json index 3e99c18..b589443 100644 --- a/PackageSources/js-bundle/package.json +++ b/PackageSources/js-bundle/package.json @@ -1,6 +1,6 @@ { "name": "tfdidesign-md11-load-manager", - "version": "0.2.10", + "version": "0.2.17", "description": "", "main": "index.js", "type": "module", diff --git a/PackageSources/js-bundle/src/components/input/Input.tsx b/PackageSources/js-bundle/src/components/input/Input.tsx index 10bb390..437d862 100644 --- a/PackageSources/js-bundle/src/components/input/Input.tsx +++ b/PackageSources/js-bundle/src/components/input/Input.tsx @@ -21,14 +21,28 @@ export default function Input(props: { const blurRef = useRef(false); const [isFocused, setFocused] = useState(false); const [showKeyboard, setShowKeyboard] = useState(false); + const [unfocusTimer, setUnfocusTimer] = useState(null); useEffect(() => { + if (unfocusTimer) { + clearTimeout(unfocusTimer); + setUnfocusTimer(null); + } + if (isFocused) { + setUnfocusTimer(setTimeout(() => ref.current?.blur(), 5e3)); Coherent.trigger('FOCUS_INPUT_FIELD', guid, '', '', '', false); } else { console.log('UNFOCUS_INPUT_FIELD'); Coherent.trigger('UNFOCUS_INPUT_FIELD', guid); } + + return () => { + if (unfocusTimer) { + clearTimeout(unfocusTimer); + setUnfocusTimer(null); + } + }; }, [isFocused, guid]); return ( @@ -60,6 +74,11 @@ export default function Input(props: { }} onChange={(e) => { if (props.onChange) props.onChange(e.target.value); + if (unfocusTimer) { + clearTimeout(unfocusTimer); + setUnfocusTimer(null); + } + if (isFocused) setUnfocusTimer(setTimeout(() => ref.current?.blur(), 5e3)); }} value={props.value} className={props.className} diff --git a/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx b/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx index 3ff2768..3547565 100644 --- a/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx +++ b/PackageSources/js-bundle/src/components/stationEntry/StationEntryPax.tsx @@ -26,7 +26,7 @@ const StationEntryPax: FC = ({ const [economy2, setEconomy2] = useState(WASMData.targetPayload.economy2); const [forwardCargo, setForwardCargo] = useState(WASMData.targetPayload.forwardCargo); const [rearCargo, setRearCargo] = useState(WASMData.targetPayload.rearCargo); - const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); + const [fuel, setFuel] = useState(Math.round(WASMData.targetPayload.fuel)); const ZFW = () => { if (loadingState !== 'loaded' && !gsxActive) return Math.round(WASMData.targetPayload.total); diff --git a/PackageSources/wasm-module/load-manager.cpp b/PackageSources/wasm-module/load-manager.cpp index cf50454..6f84e03 100644 --- a/PackageSources/wasm-module/load-manager.cpp +++ b/PackageSources/wasm-module/load-manager.cpp @@ -453,6 +453,12 @@ extern "C" MSFS_CALLBACK void module_init(void) { log(stderr, "Could not add L:FSDT_GSX_DEBOARDING_CARGO_PERCENT to data definition, terminating.\n"); return; } + hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_GSX, "L:FSDT_GSX_FUELHOSE_CONNECTED", "number", + SIMCONNECT_DATATYPE_FLOAT64); + if (hr != S_OK) { + log(stderr, "Could not add L:FSDT_GSX_FUELHOSE_CONNECTED to data definition, terminating.\n"); + return; + } // User LVars hr = SimConnect_AddToDataDefinition(simConnect, DATA_DEFINITION_USER_DATA, "L:MD11_EFB_IS_CARGO", "bool", SIMCONNECT_DATATYPE_FLOAT64); @@ -619,28 +625,30 @@ extern "C" MSFS_CALLBACK bool Load_Manager_gauge_callback(FsContext ctx, int ser lookup_var(&tick18); if (fmod(tick18.var_value.n, 3) == 0) sendData(); - if (GSXData->fuelingState == FUELING_STATE_FUELING && abs(liveFuelData->total - targetFuelData->total) < 0.1) { - GSXData->fuelingState = FUELING_STATE_FUELD; + // Terminate + if (GSXData->fuelingState == FUELING_STATE_FUELING && abs(liveFuelData->total - targetFuelData->total) < 1) { + GSXData->fuelingState = FUELING_STATE_FUELED; fuel(targetFuelData, simConnect); } - dTime += d->dt; + FuelData_t toSet = {}; - if (GSXData->fuelingState == FUELING_STATE_FUELING && dTime >= 0.5) { + // Force set to lower before connection + if (GSXData->fuelingState == FUELING_STATE_CALLED && targetFuelData->total <= liveFuelData->total) { + distribute(&toSet, max(0, targetFuelData->total - 10000), true, UserData->isER); - FuelData_t toSet = {}; + fuel(&toSet, simConnect); + } + // Fuel + else if (GSXData->fuelingState == FUELING_STATE_FUELING && GSXData->fuelConnected > 0) { + dTime += d->dt; - if (targetFuelData->total > liveFuelData->total) { - distribute(&toSet, - min(targetFuelData->total, - liveFuelData->total + min(max(targetFuelData->total - liveFuelData->total, 1), FUELING_RATE) * dTime), - true, UserData->isER); - } else { - distribute(&toSet, - max(targetFuelData->total, - liveFuelData->total + max(min(targetFuelData->total - liveFuelData->total, -1), -FUELING_RATE) * dTime), - true, UserData->isER); - } + if (dTime < 0.5) break; + + distribute(&toSet, + min(targetFuelData->total, + liveFuelData->total + min(max(targetFuelData->total - liveFuelData->total, 1), FUELING_RATE) * dTime), + true, UserData->isER); dTime = 0; @@ -1167,6 +1175,7 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContex GSXData->passengersDeboarded = data->passengersDeboarded; GSXData->cargoBoarded = data->cargoBoarded; GSXData->cargoDeboarded = data->cargoDeboarded; + GSXData->fuelConnected = data->fuelConnected; if (UserOptions->GSXSync && GSXData->couatlStarted == 1) { switch ((char)GSXData->boardingState) { @@ -1325,13 +1334,18 @@ void CALLBACK MyDispatchProc(SIMCONNECT_RECV *pData, DWORD cbData, void *pContex break; } + case GSX_SERVICE_CALLED: { + GSXData->fuelingState = FUELING_STATE_CALLED; + + break; + } case GSX_SERVICE_ACTIVE: { GSXData->fuelingState = FUELING_STATE_FUELING; break; } case GSX_SERVICE_FINISHED: { - GSXData->fuelingState = FUELING_STATE_FUELD; + GSXData->fuelingState = FUELING_STATE_FUELED; fuel(targetFuelData, simConnect); break; diff --git a/PackageSources/wasm-module/load-manager.h b/PackageSources/wasm-module/load-manager.h index b5b5d7a..b1dcf5d 100644 --- a/PackageSources/wasm-module/load-manager.h +++ b/PackageSources/wasm-module/load-manager.h @@ -34,7 +34,7 @@ /******************************** Constants ********************************/ // Module identification #define MODULE_NAME "[KHOFMANN TFDi MD-11 Load Manager] " -#define VERSION_STRING "2.12-beta" +#define VERSION_STRING "2.19" // COMM BUS #define COMM_BUS_LIVE_DATA_EVENT "khofmann_tfdi_md-11_load_manager_live_data" #define COMM_BUS_UPDATE_TARGET_EVENT "khofmann_tfdi_md-11_load_manager_update_target" diff --git a/PackageSources/wasm-module/shared.h b/PackageSources/wasm-module/shared.h index 4221d98..5dd513f 100644 --- a/PackageSources/wasm-module/shared.h +++ b/PackageSources/wasm-module/shared.h @@ -46,6 +46,7 @@ #define CG_TOLERANCE 0.05 // GSX States #define GSX_SERVICE_IDLE 1 +#define GSX_SERVICE_CALLED 4 #define GSX_SERVICE_ACTIVE 5 #define GSX_SERVICE_FINISHED 6 @@ -85,7 +86,7 @@ enum LOADING_STATES { LOADING_STATE_DEBOARDED, }; -enum FUELING_STATES { FUELING_STATE_IDLE, FUELING_STATE_FUELING, FUELING_STATE_FUELD }; +enum FUELING_STATES { FUELING_STATE_IDLE, FUELING_STATE_CALLED, FUELING_STATE_FUELING, FUELING_STATE_FUELED }; enum CALL_MODES { CALL_MODE_SB_SET, @@ -114,6 +115,7 @@ typedef struct { double passengersDeboarded; // Num pax double cargoBoarded; // In percent double cargoDeboarded; // In percent + double fuelConnected; // boolean // Additional properties enum LOADING_STATES loadingState; diff --git a/TODO.md b/TODO.md index c261bc8..e69de29 100644 --- a/TODO.md +++ b/TODO.md @@ -1,3 +0,0 @@ -TEST progressive fueling -TEST progressive loading/unloading ZFWCG -Implement minimum fuel in tank (i.e. unusable) \ No newline at end of file diff --git a/insert-efb.js b/insert-efb.js index 1543f9c..59d6cdb 100644 --- a/insert-efb.js +++ b/insert-efb.js @@ -1,45 +1,40 @@ -const { applyPatch } = require("diff"); -const fs = require("fs"); -const util = require("node:util"); -const exec = util.promisify(require("node:child_process").exec); -const readline = require("readline"); +const { applyPatch } = require('diff'); +const fs = require('fs'); +const readline = require('readline'); -const outPath = - "./PackageSources/html_ui/Pages/VCockpit/Instruments/aircraft_efb/KH_TFDi_MD11_efb"; +const outPath = './PackageSources/html_ui/Pages/VCockpit/Instruments/aircraft_efb/KH_TFDi_MD11_efb'; -fs.copyFileSync("./EFB/efb.css", `${outPath}/efb.css`); - -let file1Contents = fs.readFileSync("./EFB/efb.js").toString(); -let patch = fs.readFileSync("./EFB/efb-js.patch").toString(); +let file1Contents = fs.readFileSync('./EFB/efb.js').toString(); +let patch = fs.readFileSync('./EFB/efb-js.patch').toString(); let patchedFile = applyPatch(file1Contents, patch); fs.writeFileSync(`${outPath}/efb.js`, patchedFile); -file1Contents = fs.readFileSync("./EFB/efb.index.js").toString(); -patch = fs.readFileSync("./EFB/efb-index-js.patch").toString(); +file1Contents = fs.readFileSync('./EFB/efb.index.js').toString(); +patch = fs.readFileSync('./EFB/efb-index-js.patch').toString(); patchedFile = applyPatch(file1Contents, patch); fs.writeFileSync(`${outPath}/efb.index.js`, patchedFile); -file1Contents = fs.readFileSync("./EFB/efb.html").toString(); -patch = fs.readFileSync("./EFB/efb-html.patch").toString(); +file1Contents = fs.readFileSync('./EFB/efb.html').toString(); +patch = fs.readFileSync('./EFB/efb-html.patch').toString(); patchedFile = applyPatch(file1Contents, patch); fs.writeFileSync(`${outPath}/efb.html`, patchedFile); -var output = ""; +var output = ''; var lineReader = readline.createInterface({ input: fs.createReadStream(`${outPath}/App.js`), }); -lineReader.on("line", (line) => { - if (line.startsWith("import")) { - output += "// " + line + "\n"; - } else if (line.startsWith("export")) { - output += "window.KH_LM = App;\n"; +lineReader.on('line', (line) => { + if (line.startsWith('import')) { + output += '// ' + line + '\n'; + } else if (line.startsWith('export')) { + output += 'window.KH_LM = App;\n'; } else { - output += line + "\n"; + output += line + '\n'; } }); -lineReader.on("close", () => { +lineReader.on('close', () => { fs.writeFile(`${outPath}/App.js`, output, (err) => { if (err) console.log(err); - console.log("Import/Export removed."); + console.log('Import/Export removed.'); }); });