G1000: two-way sim sync, more PFD/MFD fidelity, authentic dialogs
Sync (FlyWithLua companions in plugins/ + server/fmssync.js): - FMS flight-plan two-way sync (App <-> in-sim FMS) via fms-sync.lua - G1000 UI-state publish (page/range/inset) via ui-sync.lua + CDI source, baro, map-range follow - Terrain awareness: elevation grid probe (terrain-probe.lua) -> red/yellow MFD overlay vs aircraft altitude PFD: - AFCS mode annunciation bar from autopilot _status datarefs - CDI source GPS/VLOC colouring, BRG1/BRG2 pointers + DME windows, marker beacons - magenta speed/altitude trend vectors, selected-altitude alerting - time-based (frame-rate-independent) smoothing for attitude/heading/tapes MFD: - nav data bar (DTK/ETE/active leg), airways overlay from earth_awy.dat, compass rose anchored to the ownship Dialogs (NEAREST/FLIGHTPLAN/DIRECT-TO/PROCEDURES): - flat, square, embedded G1000 look (no shadow/rounded/transparency) - compact lower-right placement, no close X (softkey toggles), single window - NEAREST 2-line entries (ILS/VFR, COM freq, runway length), PROC action menu Service worker: network-first HTML so reloads pick up new builds (cache v2). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,7 @@ import { useEffect, useRef, useState, useCallback } from 'react';
|
||||
export function useXplane() {
|
||||
const [values, setValues] = useState({});
|
||||
const [flightPlan, setFlightPlan] = useState({ name: 'ACTIVE', waypoints: [] });
|
||||
const [terrain, setTerrain] = useState(null); // elevation grid for terrain awareness
|
||||
const [exportMsg, setExportMsg] = useState(null);
|
||||
const [connected, setConnected] = useState(false); // socket to bridge
|
||||
const [xpConnected, setXpConnected] = useState(false); // bridge <-> X-Plane
|
||||
@@ -37,6 +38,7 @@ export function useXplane() {
|
||||
}
|
||||
else if (msg.type === 'status') setXpConnected(!!msg.xpConnected);
|
||||
else if (msg.type === 'flightplan') setFlightPlan(msg.data);
|
||||
else if (msg.type === 'terrain') setTerrain(msg.data);
|
||||
else if (msg.type === 'fp_export_result') setExportMsg(msg);
|
||||
};
|
||||
ws.onclose = () => {
|
||||
@@ -68,9 +70,16 @@ export function useXplane() {
|
||||
clear: () => send({ type: 'fp_clear' }),
|
||||
set: (plan) => send({ type: 'fp_set', plan }),
|
||||
export: (name) => send({ type: 'fp_export', name }),
|
||||
load: (name) => send({ type: 'fp_load', name }),
|
||||
};
|
||||
|
||||
return { values, flightPlan, exportMsg, connected, xpConnected, command, setDataref, fp };
|
||||
return { values, flightPlan, terrain, exportMsg, connected, xpConnected, command, setDataref, fp };
|
||||
}
|
||||
|
||||
// List saved .fms flight plans (X-Plane's Output/FMS plans) via the bridge.
|
||||
export async function fmsList() {
|
||||
try { const r = await fetch('/api/fms/list'); return r.ok ? r.json() : []; }
|
||||
catch { return []; }
|
||||
}
|
||||
|
||||
// Search X-Plane's nav database (waypoints/VOR/NDB/airports) via the bridge.
|
||||
@@ -86,3 +95,21 @@ export async function navSearch(q) {
|
||||
|
||||
// Convenience: read a numeric value with a fallback.
|
||||
export const num = (v, d = 0) => (typeof v === 'number' && isFinite(v) ? v : d);
|
||||
const v0 = (x) => (Array.isArray(x) ? num(x[0]) : num(x));
|
||||
|
||||
// System alerts/annunciations derived from live datarefs — drives the PFD
|
||||
// CAUTION softkey + the ALERTS window. Each: { t: text, warn: bool (red vs amber) }.
|
||||
export function systemAlerts(V = {}) {
|
||||
const out = [];
|
||||
const rpm = v0(V.engRpm);
|
||||
const running = rpm > 400;
|
||||
const oilP = v0(V.oilPress);
|
||||
const oilT = v0(V.oilTemp); const oilF = oilT > 150 ? oilT : oilT * 9 / 5 + 32;
|
||||
const volts = v0(V.volts);
|
||||
const fuelGal = (Array.isArray(V.fuelQty) ? V.fuelQty.reduce((a, b) => a + num(b), 0) : num(V.fuelQty)) / 2.72;
|
||||
if (running && oilP < 20) out.push({ t: 'OIL PRESSURE', warn: true });
|
||||
if (oilF > 245) out.push({ t: 'OIL TEMP HIGH', warn: true });
|
||||
if (Array.isArray(V.fuelQty) && fuelGal < 5) out.push({ t: 'FUEL LOW TOTAL', warn: fuelGal < 2.5 });
|
||||
if (volts > 1 && volts < 24.5) out.push({ t: 'LOW VOLTS', warn: false });
|
||||
return out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user