Files
xplane-cockpit/server/config.js
T
karim b2fab0c374 G1000 MFD EIS: real two-bus volts, alternator/battery amps, engine hours
- electrical readout now shows M (main) and E (essential) bus volts from
  bus_volts[0]/[1], M (alternator generator_amps) and S (battery_amps) separately,
  and ENG hours from flight time — replacing the hardcoded duplicate volts / +0.0
  amps / 0.0 HRS placeholders (manual S.54 C172 layout)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 12:15:34 +02:00

189 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Central configuration: which X-Plane datarefs/commands the cockpit needs.
//
// These are *universal* datarefs that work on virtually every aircraft.
// To add a G1000- or aircraft-specific instrument, just add its dataref name
// here under DATAREFS (read) and/or WRITABLE_DATAREFS / COMMANDS (interact).
export const CONFIG = {
// Where X-Plane's built-in web server listens (on the same PC). X-Plane 12.1.1+.
xplaneHost: process.env.XPLANE_HOST || 'localhost',
xplanePort: Number(process.env.XPLANE_PORT || 8086),
xplaneApiBase: '/api/v3',
// Where THIS bridge serves the UI + relays data. 0.0.0.0 => reachable from the LAN.
bridgeHost: process.env.BRIDGE_HOST || '0.0.0.0',
bridgePort: Number(process.env.BRIDGE_PORT || 8080),
// How often X-Plane pushes value updates (it caps near 1020 Hz anyway).
updateHz: Number(process.env.UPDATE_HZ || 20),
};
// Datarefs we SUBSCRIBE to and stream to every client. Keyed by a short alias
// the frontend uses, so the long sim/... names live in exactly one place.
export const DATAREFS = {
// --- primary flight data ---
airspeed: 'sim/cockpit2/gauges/indicators/airspeed_kts_pilot',
altitude: 'sim/cockpit2/gauges/indicators/altitude_ft_pilot',
vspeed: 'sim/cockpit2/gauges/indicators/vvi_fpm_pilot',
pitch: 'sim/cockpit2/gauges/indicators/pitch_AHARS_deg_pilot',
roll: 'sim/cockpit2/gauges/indicators/roll_AHARS_deg_pilot',
heading: 'sim/cockpit2/gauges/indicators/heading_AHARS_deg_mag_pilot',
slip: 'sim/cockpit2/gauges/indicators/slip_deg',
gForce: 'sim/flightmodel/forces/g_nrml',
// --- position / navigation (for the moving map) ---
lat: 'sim/flightmodel/position/latitude',
lon: 'sim/flightmodel/position/longitude',
groundspeed: 'sim/flightmodel/position/groundspeed', // m/s
track: 'sim/cockpit2/gauges/indicators/ground_track_mag_pilot', // deg
gpsDistNm: 'sim/cockpit2/radios/indicators/gps_dme_distance_nm',
gpsBearing: 'sim/cockpit2/radios/indicators/gps_bearing_deg_mag',
// --- engine / misc (handy on an MFD) ---
fuelTotal: 'sim/cockpit2/fuel/fuel_quantity', // array
oat: 'sim/cockpit2/temperature/outside_air_temp_degc',
// --- G1000 PFD: radios (NAV/COM active + standby) ---
nav1: 'sim/cockpit2/radios/actuators/nav1_frequency_hz',
nav1Sb: 'sim/cockpit2/radios/actuators/nav1_standby_frequency_hz',
nav2: 'sim/cockpit2/radios/actuators/nav2_frequency_hz',
nav2Sb: 'sim/cockpit2/radios/actuators/nav2_standby_frequency_hz',
com1: 'sim/cockpit2/radios/actuators/com1_frequency_hz',
com1Sb: 'sim/cockpit2/radios/actuators/com1_standby_frequency_hz',
com2: 'sim/cockpit2/radios/actuators/com2_frequency_hz',
com2Sb: 'sim/cockpit2/radios/actuators/com2_standby_frequency_hz',
// --- G1000 PFD: HSI / CDI ---
obsCrs: 'sim/cockpit2/radios/actuators/nav1_obs_deg_mag_pilot',
gsDef: 'sim/cockpit/radios/nav1_vdef', // glideslope vertical deflection (dots)
hsiDef: 'sim/cockpit2/radios/indicators/hsi_hdef_dots_pilot',
hsiToFrom: 'sim/cockpit2/radios/indicators/hsi_flag_from_to_pilot',
navBearing: 'sim/cockpit2/radios/indicators/hsi_bearing_deg_mag_pilot',
// --- bearing pointers (BRG1/BRG2) + DME + marker beacons ---
nav1Brg: 'sim/cockpit2/radios/indicators/nav1_bearing_deg_mag',
nav2Brg: 'sim/cockpit2/radios/indicators/nav2_bearing_deg_mag',
nav1Dme: 'sim/cockpit2/radios/indicators/nav1_dme_distance_nm',
nav2Dme: 'sim/cockpit2/radios/indicators/nav2_dme_distance_nm',
mkrOuter: 'sim/cockpit2/radios/indicators/outer_marker_lit',
mkrMiddle: 'sim/cockpit2/radios/indicators/middle_marker_lit',
mkrInner: 'sim/cockpit2/radios/indicators/inner_marker_lit',
// --- G1000 UI state (for display sync with the in-sim G1000) ---
// CDI/HSI source: 0 = NAV1/VLOC1, 1 = NAV2/VLOC2, 2 = GPS (standard dataref).
cdiSrc: 'sim/cockpit2/radios/actuators/HSI_source_select_pilot',
// The rest are G1000-internal, so the FlyWithLua companion (ui-sync.lua)
// publishes them as custom datarefs. Absent until the plugin runs -> the web
// G1000 just keeps its own local UI state (graceful).
uiMfdPage: 'glasscockpit/ui/mfd_page', // 0 map, 1 fpl, 2 nrst
uiMapRange: 'glasscockpit/ui/map_range_nm', // active map range, NM
uiInset: 'glasscockpit/ui/inset', // PFD inset map on/off (0/1)
// --- G1000 PFD: data fields ---
baro: 'sim/cockpit2/gauges/actuators/barometer_setting_in_hg_pilot',
tas: 'sim/cockpit2/gauges/indicators/true_airspeed_kts_pilot',
windSpd: 'sim/cockpit2/gauges/indicators/wind_speed_kts',
windDir: 'sim/cockpit2/gauges/indicators/wind_heading_deg_mag',
xpdrCode: 'sim/cockpit2/radios/actuators/transponder_code',
xpdrMode: 'sim/cockpit2/radios/actuators/transponder_mode',
fdPitch: 'sim/cockpit2/autopilot/flight_director_pitch_deg',
fdRoll: 'sim/cockpit2/autopilot/flight_director_roll_deg',
// --- G1000 MFD: engine strip (arrays — UI reads index 0/1) ---
engRpm: 'sim/cockpit2/engine/indicators/engine_speed_rpm',
fuelFlow: 'sim/cockpit2/engine/indicators/fuel_flow_kg_sec',
oilTemp: 'sim/cockpit2/engine/indicators/oil_temperature_deg_C',
oilPress: 'sim/cockpit2/engine/indicators/oil_pressure_psi',
egt: 'sim/cockpit2/engine/indicators/EGT_deg_C',
fuelQty: 'sim/cockpit2/fuel/fuel_quantity',
volts: 'sim/cockpit2/electrical/bus_volts', // array: [0]=main bus, [1]=essential
amps: 'sim/cockpit2/electrical/battery_amps', // battery (S) amps
genAmps: 'sim/cockpit2/electrical/generator_amps', // alternator (M) amps
engHrs: 'sim/time/total_flight_time_sec', // proxy for engine/tach hours
// --- autopilot readouts (live values, so the panel reflects reality) ---
apState: 'sim/cockpit2/autopilot/autopilot_state', // bitfield of active modes
apHdgBug: 'sim/cockpit2/autopilot/heading_dial_deg_mag_pilot',
apAltBug: 'sim/cockpit2/autopilot/altitude_dial_ft_pilot',
apVsBug: 'sim/cockpit2/autopilot/vvi_dial_fpm',
apSpdBug: 'sim/cockpit2/autopilot/airspeed_dial_kts_mach',
apEngaged: 'sim/cockpit2/autopilot/servos_on',
navHdef: 'sim/cockpit2/radios/indicators/hsi_relative_bearing_vor_pilot',
// --- AFCS mode annunciation (the green/white mode strip on a real G1000) ---
// X-Plane's per-mode status datarefs: 0 = off, 1 = armed, 2 = active/captured.
// These mean the AFCS bar mirrors the sim exactly, no Lua needed.
apMode: 'sim/cockpit2/autopilot/autopilot_mode', // 0 off, 1 FD, 2 AP
hdgStatus: 'sim/cockpit2/autopilot/hdg_status',
navStatus: 'sim/cockpit2/autopilot/nav_status',
gpssStatus: 'sim/cockpit2/autopilot/gpss_status',
aprStatus: 'sim/cockpit2/autopilot/approach_status',
bcStatus: 'sim/cockpit2/autopilot/backcourse_status',
altStatus: 'sim/cockpit2/autopilot/alt_hold_status',
vsStatus: 'sim/cockpit2/autopilot/vvi_status',
flcStatus: 'sim/cockpit2/autopilot/speed_status',
gsStatus: 'sim/cockpit2/autopilot/glideslope_status',
vnavStatus: 'sim/cockpit2/autopilot/vnav_status',
};
// Datarefs the frontend may WRITE (e.g. turning the heading bug knob).
export const WRITABLE_DATAREFS = {
apHdgBug: 'sim/cockpit2/autopilot/heading_dial_deg_mag_pilot',
apAltBug: 'sim/cockpit2/autopilot/altitude_dial_ft_pilot',
apVsBug: 'sim/cockpit2/autopilot/vvi_dial_fpm',
apSpdBug: 'sim/cockpit2/autopilot/airspeed_dial_kts_mach',
xpdrMode: 'sim/cockpit2/radios/actuators/transponder_mode', // 0 off,1 stby,2 on,3 alt
xpdrCode: 'sim/cockpit2/radios/actuators/transponder_code', // 4-digit squawk
};
// Commands the frontend may TRIGGER (autopilot mode buttons etc.).
export const COMMANDS = {
apToggle: 'sim/autopilot/servos_toggle',
fdToggle: 'sim/autopilot/fdir_toggle',
hdg: 'sim/autopilot/heading',
nav: 'sim/autopilot/NAV',
apr: 'sim/autopilot/approach',
altHold: 'sim/autopilot/altitude_hold',
vs: 'sim/autopilot/vertical_speed',
flc: 'sim/autopilot/level_change',
vnav: 'sim/autopilot/vnav',
backCourse:'sim/autopilot/back_course',
noseUp: 'sim/autopilot/nose_up',
noseDown: 'sim/autopilot/nose_down',
altUp: 'sim/autopilot/altitude_up',
altDown: 'sim/autopilot/altitude_down',
hdgUp: 'sim/autopilot/heading_up',
hdgDown: 'sim/autopilot/heading_down',
xpdrIdent: 'sim/transponder/transponder_ident',
};
// Per-radio standby tuning (coarse = MHz, fine = kHz) + active/standby flip.
// These work regardless of the dataref's frequency units, so the web tuner just
// fires them — no risky raw frequency writes.
for (const r of ['nav1', 'nav2', 'com1', 'com2']) {
COMMANDS[`${r}CoarseUp`] = `sim/radios/stby_${r}_coarse_up`;
COMMANDS[`${r}CoarseDown`] = `sim/radios/stby_${r}_coarse_down`;
COMMANDS[`${r}FineUp`] = `sim/radios/stby_${r}_fine_up`;
COMMANDS[`${r}FineDown`] = `sim/radios/stby_${r}_fine_down`;
COMMANDS[`${r}Swap`] = `sim/radios/${r}_standby_flip`;
}
// Every clickable G1000 bezel control maps to a real X-Plane command. The PFD
// is unit n1, the MFD is unit n3 (the default C172 layout). Aliases are
// prefixed pfd_/mfd_ so the frontend just says e.g. command('mfd_fpl').
const G1000_KEYS = [
...Array.from({ length: 12 }, (_, i) => `softkey${i + 1}`),
'direct', 'menu', 'fpl', 'proc', 'clr', 'ent', 'cursor',
'fms_outer_up', 'fms_outer_down', 'fms_inner_up', 'fms_inner_down',
'range_up', 'range_down', 'pan_push', 'pan_up', 'pan_down', 'pan_left', 'pan_right',
'hdg_up', 'hdg_down', 'hdg_sync',
'alt_outer_up', 'alt_outer_down', 'alt_inner_up', 'alt_inner_down',
'crs_up', 'crs_down', 'crs_sync', 'baro_up', 'baro_down',
'nav_outer_up', 'nav_outer_down', 'nav_inner_up', 'nav_inner_down', 'nav12', 'nvol_up', 'nvol_dn',
'com_outer_up', 'com_outer_down', 'com_inner_up', 'com_inner_down', 'com12', 'cvol_up', 'cvol_dn',
'ap', 'fd', 'hdg', 'alt', 'nav', 'vnv', 'apr', 'bc', 'vs', 'flc', 'nose_up', 'nose_down',
];
for (const [unit, prefix] of [['n1', 'pfd'], ['n3', 'mfd']]) {
for (const k of G1000_KEYS) COMMANDS[`${prefix}_${k}`] = `sim/GPS/g1000${unit}_${k}`;
}