SB persist

Options page for GSX Sync
This commit is contained in:
Kilian Hofmann 2025-06-18 23:57:46 +02:00
parent 4b60f8eec2
commit 390edd29b8
16 changed files with 316 additions and 135 deletions

View File

@ -1,14 +1,9 @@
import { FC, useEffect, useRef, useState } from 'react'; import { FC, useEffect, useRef, useState } from 'react';
import { import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
GSX_SERVICE_CALLED,
GSX_SERVICE_FINISHED,
} from '../../constants';
import { WASMDataF } from '../../types/WASMData'; import { WASMDataF } from '../../types/WASMData';
import { LoadingState } from '../../types/general'; import { LoadingState, SimBrief } from '../../types/general';
import { ImportFlightPlan } from '../../utils/TFDISBImport'; import { ImportFlightPlan } from '../../utils/TFDISBImport';
import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallSBEntryF, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
@ -23,8 +18,7 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoadi
const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget); const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget);
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
const [fuelEnabled, setFuelEnabled] = useState(true); const [fuelEnabled, setFuelEnabled] = useState(true);
//eslint-disable-next-line @typescript-eslint/no-explicit-any const [SBPlan, setSBPlan] = useState<SimBrief>();
const [SBPlan, setSBPlan] = useState<any>();
const [SBInFlight, setSBInFlight] = useState(false); const [SBInFlight, setSBInFlight] = useState(false);
const cargo = useRef(0); const cargo = useRef(0);
@ -83,7 +77,7 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoadi
cargo.current = parseFloat(SBResponse.message.cargo) ?? 0; cargo.current = parseFloat(SBResponse.message.cargo) ?? 0;
updateData(); updateData(undefined, SBResponse.message);
setSBPlan(SBResponse.message); setSBPlan(SBResponse.message);
setFuel(parseFloat(SBResponse.message.fuel) ?? 0); setFuel(parseFloat(SBResponse.message.fuel) ?? 0);
@ -102,16 +96,8 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoadi
setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel)); setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel));
}, [WASMData.livePayload.fuel]); }, [WASMData.livePayload.fuel]);
const updateData = (_CGTarget?: number) => { const updateData = (_CGTarget?: number, _SBPlan?: SimBrief) => {
Coherent.call( CoherentCallSBEntryF(cargo.current ?? 0, _CGTarget ?? CGTarget, _SBPlan ?? SBPlan);
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: 0,
cargo: cargo.current ?? 0,
CGTarget: _CGTarget ?? CGTarget,
})
);
}; };
return ( return (
@ -153,7 +139,7 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoadi
type="text" type="text"
placeholder="" placeholder=""
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600" className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
value={SBPlan?.plannedZFW ?? 0} value={SBPlan?.plannedZFW ?? WASMData.sbPlanned.ZFW}
disabled disabled
/> />
</div> </div>
@ -163,7 +149,7 @@ const SBEntryF: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoadi
type="text" type="text"
placeholder="" placeholder=""
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600" className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
value={SBPlan?.plannedGW ?? 0} value={SBPlan?.plannedGW ?? WASMData.sbPlanned.GW}
disabled disabled
/> />
</div> </div>

View File

@ -1,14 +1,9 @@
import { FC, useEffect, useRef, useState } from 'react'; import { FC, useEffect, useRef, useState } from 'react';
import { import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
GSX_SERVICE_CALLED,
GSX_SERVICE_FINISHED,
} from '../../constants';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { LoadingState } from '../../types/general'; import { LoadingState, SimBrief } from '../../types/general';
import { ImportFlightPlan } from '../../utils/TFDISBImport'; import { ImportFlightPlan } from '../../utils/TFDISBImport';
import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallSBEntryPax, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
@ -23,8 +18,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget); const [CGTarget, setCGTarget] = useState(WASMData.targetPayload.CGTarget);
const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel)); const [fuel, setFuel] = useState(Math.round(WASMData.livePayload.fuel));
const [fuelEnabled, setFuelEnabled] = useState(true); const [fuelEnabled, setFuelEnabled] = useState(true);
//eslint-disable-next-line @typescript-eslint/no-explicit-any const [SBPlan, setSBPlan] = useState<SimBrief>();
const [SBPlan, setSBPlan] = useState<any>();
const [SBInFlight, setSBInFlight] = useState(false); const [SBInFlight, setSBInFlight] = useState(false);
const numPax = useRef(0); const numPax = useRef(0);
@ -85,7 +79,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
cargo.current = parseFloat(SBResponse.message.cargo) ?? 0; cargo.current = parseFloat(SBResponse.message.cargo) ?? 0;
numPax.current = parseInt(SBResponse.message.pax) ?? 0; numPax.current = parseInt(SBResponse.message.pax) ?? 0;
updateData(); updateData(SBResponse.message);
setSBPlan(SBResponse.message); setSBPlan(SBResponse.message);
setFuel(parseFloat(SBResponse.message.fuel) ?? 0); setFuel(parseFloat(SBResponse.message.fuel) ?? 0);
@ -104,17 +98,8 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel)); setFuelEnabled(inRangeOf(Math.round(WASMData.livePayload.fuel), fuel));
}, [WASMData.livePayload.fuel]); }, [WASMData.livePayload.fuel]);
const updateData = (_CGTarget?: number) => { const updateData = (_CGTarget?: number, _SBPlan?: SimBrief) => {
Coherent.call( CoherentCallSBEntryPax(cargo.current ?? 0, numPax.current ?? 0, _CGTarget ?? CGTarget, _SBPlan ?? SBPlan);
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: 0,
cargo: cargo.current ?? 0,
numPax: numPax.current ?? 0,
CGTarget: _CGTarget ?? CGTarget,
})
);
}; };
return ( return (
@ -156,7 +141,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
type="text" type="text"
placeholder="" placeholder=""
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600" className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
value={SBPlan?.plannedZFW ?? 0} value={SBPlan?.plannedZFW ?? WASMData.sbPlanned.ZFW}
disabled disabled
/> />
</div> </div>
@ -166,7 +151,7 @@ const SBEntryPax: FC<SBEntryProps> = ({ WASMData, loadingState, username, setLoa
type="text" type="text"
placeholder="" placeholder=""
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600" className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
value={SBPlan?.plannedGW ?? 0} value={SBPlan?.plannedGW ?? WASMData.sbPlanned.GW}
disabled disabled
/> />
</div> </div>

View File

@ -0,0 +1,42 @@
import { FC } from 'react';
import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
import { LoadingState } from '../../types/general';
import { WASMDataPax } from '../../types/WASMData';
import { CoherentCallOptionsSet } from '../../utils/utils';
import ToggleComponent from '../toggleComponent/ToggleComponent';
interface OptionsPaxProps {
WASMData: WASMDataPax;
loadingState: LoadingState;
}
const OptionsPax: FC<OptionsPaxProps> = ({ WASMData, loadingState }) => {
const GSXActive = () => {
return (
(WASMData.GSX.boardingState >= GSX_SERVICE_CALLED || WASMData.GSX.deboardingState >= GSX_SERVICE_CALLED) &&
WASMData.GSX.deboardingState !== GSX_SERVICE_FINISHED
);
};
return (
<>
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
<ToggleComponent
optionName="GSX Sync"
value={WASMData.options.GSXSync}
leftLabel={{ value: true }}
rightLabel={{ value: false }}
backgroundColor="bg-zinc-700"
setValue={(value) => {
CoherentCallOptionsSet(value);
}}
disabled={loadingState !== 'preview' || GSXActive()}
/>
</div>
</div>
</>
);
};
export default OptionsPax;

View File

@ -2,6 +2,7 @@ import { FC, useState } from 'react';
import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants'; import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import OptionsPax from '../options/OptionsPax';
import Profile from '../profile/Profile'; import Profile from '../profile/Profile';
import SBEntryPax from '../SBEntry/SBEntryPax'; import SBEntryPax from '../SBEntry/SBEntryPax';
import StationEntryPax from '../stationEntry/StationEntryPax'; import StationEntryPax from '../stationEntry/StationEntryPax';
@ -125,6 +126,9 @@ const Pax: FC<PaxProps> = ({ WASMData, username }) => {
{((username && selectedTab === 2) || (!username && selectedTab === 1)) && ( {((username && selectedTab === 2) || (!username && selectedTab === 1)) && (
<StationEntryPax WASMData={WASMData} loadingState={loadingState} setLoadingState={setLoadingState} /> <StationEntryPax WASMData={WASMData} loadingState={loadingState} setLoadingState={setLoadingState} />
)} )}
{((username && selectedTab === 3) || (!username && selectedTab === 2)) && (
<OptionsPax WASMData={WASMData} loadingState={loadingState} />
)}
</> </>
); );
}; };

View File

@ -1,13 +1,8 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
GSX_SERVICE_CALLED,
GSX_SERVICE_FINISHED,
} from '../../constants';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataF } from '../../types/WASMData'; import { WASMDataF } from '../../types/WASMData';
import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallStationEntryF, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
interface StationEntryProps { interface StationEntryProps {
@ -76,19 +71,7 @@ const StationEntryF: FC<StationEntryProps> = ({ WASMData, loadingState, setLoadi
}, [WASMData.livePayload.fuel]); }, [WASMData.livePayload.fuel]);
const updateData = () => { const updateData = () => {
Coherent.call( CoherentCallStationEntryF(upper1, upper2, upper3, upper4, lowerForward, lowerRear);
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: 2,
business1: upper1,
business2: upper2,
economy1: upper3,
economy2: upper4,
forwardCargo: lowerForward,
rearCargo: lowerRear,
})
);
}; };
return ( return (

View File

@ -1,13 +1,8 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
GSX_SERVICE_CALLED,
GSX_SERVICE_FINISHED,
} from '../../constants';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallStationEntryPax, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
interface StationEntryProps { interface StationEntryProps {
@ -76,19 +71,7 @@ const StationEntryPax: FC<StationEntryProps> = ({ WASMData, loadingState, setLoa
}, [WASMData.livePayload.fuel]); }, [WASMData.livePayload.fuel]);
const updateData = () => { const updateData = () => {
Coherent.call( CoherentCallStationEntryPax(business1, business2, economy1, economy2, forwardCargo, rearCargo);
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: 2,
business1,
business2,
economy1,
economy2,
forwardCargo,
rearCargo,
})
);
}; };
return ( return (

View File

@ -0,0 +1,51 @@
interface ToggleComponentProps<T> {
optionName: string;
value: T;
leftLabel: {
value: T;
label?: string;
};
rightLabel: {
value: T;
label?: string;
};
backgroundColor: string;
disabled?: boolean;
setValue: (value: T) => void;
}
const ToggleComponent = <T,>({
optionName,
value,
leftLabel,
rightLabel,
backgroundColor,
disabled,
setValue,
}: ToggleComponentProps<T>) => {
return (
<div className="flex w-full items-center justify-between text-xs">
<span>{optionName}</span>
<div className="inline-flex w-1/2 rounded-md shadow-sm">
<button
type="button"
className={`${value === leftLabel.value ? 'bg-green-700' : backgroundColor} w-1/2 rounded-l-lg border border-white px-4 py-2 text-white disabled:pointer-events-none disabled:opacity-50`}
onClick={() => setValue(leftLabel.value)}
disabled={disabled}
>
{leftLabel.label || 'Enabled'}
</button>
<button
type="button"
className={`${value === rightLabel.value ? 'bg-green-700' : backgroundColor} w-1/2 rounded-r-md border border-white px-4 py-2 text-white disabled:pointer-events-none disabled:opacity-50`}
onClick={() => setValue(rightLabel.value)}
disabled={disabled}
>
{rightLabel.label || 'Disabled'}
</button>
</div>
</div>
);
};
export default ToggleComponent;

View File

@ -1,13 +1,8 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
GSX_SERVICE_CALLED,
GSX_SERVICE_FINISHED,
} from '../../constants';
import { WASMDataF } from '../../types/WASMData'; import { WASMDataF } from '../../types/WASMData';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallZFWEntry, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
@ -99,15 +94,7 @@ const ZFWEntryF: FC<ZFWEntryProps> = ({ WASMData, loadingState, setLoadingState
}, [WASMData.livePayload.fuel]); }, [WASMData.livePayload.fuel]);
const updateData = (_ZFWTarget?: number, _CGTarget?: number) => { const updateData = (_ZFWTarget?: number, _CGTarget?: number) => {
Coherent.call( CoherentCallZFWEntry(_ZFWTarget ?? ZFWTarget, _CGTarget ?? CGTarget);
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: 1,
ZFWTarget: _ZFWTarget ?? ZFWTarget,
CGTarget: _CGTarget ?? CGTarget,
})
);
}; };
return ( return (

View File

@ -1,13 +1,8 @@
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { import { GSX_SERVICE_CALLED, GSX_SERVICE_FINISHED } from '../../constants';
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
GSX_SERVICE_CALLED,
GSX_SERVICE_FINISHED,
} from '../../constants';
import { WASMDataPax } from '../../types/WASMData'; import { WASMDataPax } from '../../types/WASMData';
import { LoadingState } from '../../types/general'; import { LoadingState } from '../../types/general';
import { inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils'; import { CoherentCallZFWEntry, inRangeOf, loadAircraft, unloadAircraft } from '../../utils/utils';
import CGSelect from '../CGSelect/CGSelect'; import CGSelect from '../CGSelect/CGSelect';
import ActionBar from '../actionbar/ActionBar'; import ActionBar from '../actionbar/ActionBar';
@ -99,15 +94,7 @@ const ZFWEntryPax: FC<ZFWEntryProps> = ({ WASMData, loadingState, setLoadingStat
}, [WASMData.livePayload.fuel]); }, [WASMData.livePayload.fuel]);
const updateData = (_ZFWTarget?: number, _CGTarget?: number) => { const updateData = (_ZFWTarget?: number, _CGTarget?: number) => {
Coherent.call( CoherentCallZFWEntry(_ZFWTarget ?? ZFWTarget, _CGTarget ?? CGTarget);
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: 1,
ZFWTarget: _ZFWTarget ?? ZFWTarget,
CGTarget: _CGTarget ?? CGTarget,
})
);
}; };
return ( return (

View File

@ -11,3 +11,10 @@ export const CG_ADJUST = 0.05;
export const GSX_SERVICE_CALLED = 4; export const GSX_SERVICE_CALLED = 4;
export const GSX_SERVICE_ACTIVE = 5; export const GSX_SERVICE_ACTIVE = 5;
export const GSX_SERVICE_FINISHED = 6; export const GSX_SERVICE_FINISHED = 6;
export const MODE_SB_SET = 0;
export const MODE_ZFW_SET = 1;
export const MODE_STATION_SET = 2;
export const MODE_LOAD_SET = 3;
export const MODE_UNLOAD_SET = 4;
export const MODE_OPTIONS_SET = 5;

View File

@ -1,19 +1,23 @@
export interface WASMDataPax { interface WASMData {
livePayload: LivePayloadPax;
targetPayload: TargetPayloadPax;
GSX: GSX; GSX: GSX;
userData: UserData; userData: UserData;
limits: LimitsPax;
options: Options; options: Options;
sbPlanned: {
ZFW: number;
GW: number;
};
} }
export interface WASMDataF { export interface WASMDataPax extends WASMData {
livePayload: LivePayloadPax;
targetPayload: TargetPayloadPax;
limits: LimitsPax;
}
export interface WASMDataF extends WASMData {
livePayload: LivePayloadF; livePayload: LivePayloadF;
targetPayload: TargetPayloadF; targetPayload: TargetPayloadF;
GSX: GSX;
userData: UserData;
limits: LimitsF; limits: LimitsF;
options: Options;
} }
interface TargetPayload { interface TargetPayload {

View File

@ -1 +1,9 @@
export type LoadingState = 'preview' | 'loaded'; export type LoadingState = 'preview' | 'loaded';
export interface SimBrief {
plannedZFW: number;
plannedGW: number;
pax: number;
cargo: number;
fuel: number;
}

View File

@ -1,11 +1,21 @@
import { COHERENT_COMM_BUS_WASM_CALL, COMM_BUS_UPDATE_TARGET_EVENT } from '../constants'; import {
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
MODE_LOAD_SET,
MODE_OPTIONS_SET,
MODE_SB_SET,
MODE_STATION_SET,
MODE_UNLOAD_SET,
MODE_ZFW_SET,
} from '../constants';
import { SimBrief } from '../types/general';
export const loadAircraft = () => { export const loadAircraft = () => {
Coherent.call( Coherent.call(
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT, COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({ JSON.stringify({
mode: 3, mode: MODE_LOAD_SET,
}) })
); );
}; };
@ -15,7 +25,7 @@ export const unloadAircraft = () => {
COHERENT_COMM_BUS_WASM_CALL, COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT, COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({ JSON.stringify({
mode: 4, mode: MODE_UNLOAD_SET,
}) })
); );
}; };
@ -23,3 +33,103 @@ export const unloadAircraft = () => {
export const inRangeOf = (value: number, target: number, tolerance: number = 10) => { export const inRangeOf = (value: number, target: number, tolerance: number = 10) => {
return Math.abs(value - target) < tolerance; return Math.abs(value - target) < tolerance;
}; };
export const CoherentCallZFWEntry = (ZFWTarget: number, CGTarget: number) => {
Coherent.call(
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: MODE_ZFW_SET,
ZFWTarget: ZFWTarget,
CGTarget: CGTarget,
})
);
};
export const CoherentCallStationEntryPax = (
business1: number,
business2: number,
economy1: number,
economy2: number,
forwardCargo: number,
rearCargo: number
) => {
Coherent.call(
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: MODE_STATION_SET,
business1,
business2,
economy1,
economy2,
forwardCargo,
rearCargo,
})
);
};
export const CoherentCallStationEntryF = (
upper1: number,
upper2: number,
upper3: number,
upper4: number,
lowerForward: number,
lowerRear: number
) => {
Coherent.call(
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: MODE_STATION_SET,
upper1,
upper2,
upper3,
upper4,
lowerForward,
lowerRear,
})
);
};
export const CoherentCallSBEntryPax = (cargo: number, numPax: number, CGTarget: number, SBPlan?: SimBrief) => {
Coherent.call(
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: MODE_SB_SET,
cargo: cargo,
numPax: numPax,
CGTarget: CGTarget,
plannedZFW: SBPlan?.plannedZFW ?? 0,
plannedGW: SBPlan?.plannedGW ?? 0,
})
);
};
export const CoherentCallSBEntryF = (cargo: number, CGTarget: number, SBPlan?: SimBrief) => {
Coherent.call(
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: MODE_SB_SET,
cargo: cargo,
CGTarget: CGTarget,
plannedZFW: SBPlan?.plannedZFW ?? 0,
plannedGW: SBPlan?.plannedGW ?? 0,
})
);
};
export const CoherentCallOptionsSet = (GSXSync?: boolean, paxWeight?: number, bagWeight?: number) => {
Coherent.call(
COHERENT_COMM_BUS_WASM_CALL,
COMM_BUS_UPDATE_TARGET_EVENT,
JSON.stringify({
mode: MODE_OPTIONS_SET,
GSXSync,
paxWeight,
bagWeight,
})
);
};

View File

@ -502,12 +502,14 @@ int receiveData(const char* buf) {
switch(mode) { switch(mode) {
// SB Entry // SB Entry
case 0: { case 0: {
if (!document.HasMember("cargo") || !document.HasMember("CGTarget")) return -1; if (!document.HasMember("cargo") || !document.HasMember("CGTarget") || !document.HasMember("plannedZFW") || !document.HasMember("plannedGW")) return -1;
unsigned int cargo = document["cargo"].GetInt(); unsigned int cargo = document["cargo"].GetInt();
double CGTarget = document["CGTarget"].GetDouble(); double CGTarget = document["CGTarget"].GetDouble();
if (UserData->isCargo) { if (UserData->isCargo) {
targetFPayloadData->CGTarget = CGTarget; targetFPayloadData->CGTarget = CGTarget;
targetFPayloadData->sbPlanned.ZFW = document["plannedZFW"].GetDouble();
targetFPayloadData->sbPlanned.GW = document["plannedGW"].GetDouble();
distribute(targetFPayloadData, liveFuelData, cargo, UserData->isImperial, UserData->isER); distribute(targetFPayloadData, liveFuelData, cargo, UserData->isImperial, UserData->isER);
} }
@ -516,6 +518,9 @@ int receiveData(const char* buf) {
unsigned short numPax = document["numPax"].GetInt(); unsigned short numPax = document["numPax"].GetInt();
targetPaxPayloadData->CGTarget = CGTarget; targetPaxPayloadData->CGTarget = CGTarget;
targetPaxPayloadData->sbPlanned.ZFW = document["plannedZFW"].GetDouble();
targetPaxPayloadData->sbPlanned.GW = document["plannedGW"].GetDouble();
distribute(targetPaxPayloadData, liveFuelData, numPax, cargo, UserData->isImperial, UserData->isER); distribute(targetPaxPayloadData, liveFuelData, numPax, cargo, UserData->isImperial, UserData->isER);
} }
break; break;
@ -588,6 +593,32 @@ int receiveData(const char* buf) {
break; break;
} }
// Option set
case 5: {
if (document.HasMember("GSXSync")) {
UserOptions->GSXSync = document["GSXSync"].GetBool();
}
rapidjson::Document optionsDoc;
rapidjson::Document::AllocatorType& allocator = optionsDoc.GetAllocator();
optionsDoc.SetObject();
optionsDoc.AddMember("GSXSync", UserOptions->GSXSync, allocator);
optionsDoc.AddMember("paxWeightKG", UserOptions->paxWeightKG, allocator);
optionsDoc.AddMember("bagWeightKG", UserOptions->bagWeightKG, allocator);
optionsDoc.AddMember("paxWeightLBS", UserOptions->paxWeightLBS, allocator);
optionsDoc.AddMember("bagWeightLBS", UserOptions->bagWeightLBS, allocator);
FILE* optionsFile = fopen("\\work\\options.json", "wb");
if (optionsFile != NULL) {
char writeBuffer[256];
rapidjson::FileWriteStream os(optionsFile, writeBuffer, sizeof(writeBuffer));
rapidjson::Writer<rapidjson::FileWriteStream> writer(os);
optionsDoc.Accept(writer);
fclose(optionsFile);
log(stdout, MODULE_NAME"Options written.\n");
}
break;
}
default: default:
break; break;
} }
@ -619,6 +650,8 @@ void sendData () {
limits.SetObject(); limits.SetObject();
rapidjson::Value options; rapidjson::Value options;
options.SetObject(); options.SetObject();
rapidjson::Value sbPlanned;
sbPlanned.SetObject();
rapidjson::StringBuffer strbuf; rapidjson::StringBuffer strbuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf); rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
@ -773,6 +806,10 @@ void sendData () {
options.AddMember("paxWeight", UserData->isImperial ? UserOptions->paxWeightLBS : UserOptions->paxWeightKG, allocator); options.AddMember("paxWeight", UserData->isImperial ? UserOptions->paxWeightLBS : UserOptions->paxWeightKG, allocator);
options.AddMember("bagWeight", UserData->isImperial ? UserOptions->bagWeightLBS : UserOptions->bagWeightKG, allocator); options.AddMember("bagWeight", UserData->isImperial ? UserOptions->bagWeightLBS : UserOptions->bagWeightKG, allocator);
// SB Planned
sbPlanned.AddMember("ZFW", UserData->isCargo ? targetFPayloadData->sbPlanned.ZFW: targetPaxPayloadData->sbPlanned.ZFW, allocator);
sbPlanned.AddMember("GW", UserData->isCargo ? targetFPayloadData->sbPlanned.GW : targetPaxPayloadData->sbPlanned.GW, allocator);
// Construct document // Construct document
document.AddMember("livePayload", livePayload.Move(), allocator); document.AddMember("livePayload", livePayload.Move(), allocator);
document.AddMember("targetPayload", targetPayload.Move(), allocator); document.AddMember("targetPayload", targetPayload.Move(), allocator);
@ -780,6 +817,7 @@ void sendData () {
document.AddMember("userData", userData.Move(), allocator); document.AddMember("userData", userData.Move(), allocator);
document.AddMember("limits", limits.Move(), allocator); document.AddMember("limits", limits.Move(), allocator);
document.AddMember("options", options.Move(), allocator); document.AddMember("options", options.Move(), allocator);
document.AddMember("sbPlanned", sbPlanned.Move(), allocator);
// Write to CommBus // Write to CommBus
document.Accept(writer); document.Accept(writer);

View File

@ -18,7 +18,7 @@
//PMC pallet due to 104in door //PMC pallet due to 104in door
#define MAX_FRONT_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.0 * 15000.0) : (6.0 * 6804.0)) #define MAX_FRONT_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.0 * 15000.0) : (6.0 * 6804.0))
#define MAX_UPPER_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.5 * 15000.0) : (6.5 * 6804.0)) #define MAX_UPPER_CARGO(IS_IMPERIAL) ((IS_IMPERIAL) ? (6.5 * 15000.0) : (6.5 * 6804.0))
//LD3s due to 70in door //LD3s due to 70in door, ER option takes up two slots
#define MAX_REAR_CARGO(IS_IMPERIAL, IS_ER) ((IS_IMPERIAL) ? ((IS_ER ? 12.0 : 14.0) * 3500.0) : ((IS_ER ? 12.0 : 14.0) * 1588.0)) #define MAX_REAR_CARGO(IS_IMPERIAL, IS_ER) ((IS_IMPERIAL) ? ((IS_ER ? 12.0 : 14.0) * 3500.0) : ((IS_ER ? 12.0 : 14.0) * 1588.0))
// All actual Business seats // All actual Business seats
@ -187,6 +187,10 @@ typedef struct {
unsigned char economy2; unsigned char economy2;
unsigned short total; unsigned short total;
} paxCount; } paxCount;
struct sbPlanned {
double ZFW;
double GW;
} sbPlanned;
} paxPayloadData_t; } paxPayloadData_t;
typedef struct { typedef struct {
double pilot; double pilot;
@ -243,6 +247,10 @@ typedef struct {
unsigned int upper4; unsigned int upper4;
unsigned int total; unsigned int total;
} stations; } stations;
struct sbPlanned {
double ZFW;
double GW;
} sbPlanned;
} fPayloadData_t; } fPayloadData_t;
typedef struct { typedef struct {
// SimConnect mapped // SimConnect mapped

View File

@ -18,8 +18,6 @@ TODO:
- Add to EFB.js and EFB.html - Add to EFB.js and EFB.html
- Automate this? - Automate this?
- JS - JS
- Persist SB data across page changes - Options (pax/bag weights)
- Options (GSX sync, pax/bag weights)
- Types for SB plan (only what I need)
- WASM - WASM
- Custom pax/bag weights - Custom pax/bag weights