// 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 10–20 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', fuelTot: 'sim/cockpit2/fuel/fuel_totalizer_sum_kg', // pilot-set fuel totalizer (remaining, kg) fuelMax: 'sim/aircraft/weight/acf_m_fuel_tot', // max fuel capacity (kg) — for RST FUEL 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', // ==================================================================== // CESSNA CITATION X (model 750) — twin Rolls-Royce AE3007C turbofans. // Honeywell Primus 2000 suite: PFD / MFD / EICAS / dual CDU. // All of these are universal sim datarefs, streamed live with no Lua; // only the FMS flight-plan needs the FlyWithLua bridge (fms-sync.lua). // ==================================================================== // --- engine (arrays index 0 = LH, 1 = RH) --- n1: 'sim/cockpit2/engine/indicators/N1_percent', // Fan RPM % (EICAS FAN%) n2: 'sim/cockpit2/engine/indicators/N2_percent', // Core RPM % (standby panel) itt: 'sim/cockpit2/engine/indicators/ITT_deg_C', // Interstage Turbine Temp °C fuelPress: 'sim/cockpit2/engine/indicators/fuel_pressure_psi', throttle: 'sim/cockpit2/engine/actuators/throttle_ratio', // per-engine commanded thrust // --- Citation PFD extras --- radioAlt: 'sim/cockpit2/gauges/indicators/radio_altimeter_height_ft_pilot', // RA (<2500 ft AGL) mach: 'sim/cockpit2/gauges/indicators/mach_pilot', // PFD Mach / FLC target aoa: 'sim/flightmodel/position/alpha', // angle of attack (deg) → normalised adf1Brg: 'sim/cockpit2/radios/indicators/adf1_relative_bearing_deg', adf2Brg: 'sim/cockpit2/radios/indicators/adf2_relative_bearing_deg', adf1: 'sim/cockpit2/radios/actuators/adf1_frequency_hz', adf2: 'sim/cockpit2/radios/actuators/adf2_frequency_hz', // --- EICAS systems --- hydPress: 'sim/cockpit2/hydraulics/indicators/hydraulic_pressure_psi', // array A/B (PSI) elevTrim: 'sim/cockpit2/controls/elevator_trim', // -1..1 → STAB deg flapRatio: 'sim/cockpit2/controls/flap_ratio', // 0..1 → SLAT/5/15/FULL flapDeploy: 'sim/flightmodel2/controls/flap1_deploy_ratio', // actual trailing-edge flap slatRatio: 'sim/flightmodel2/controls/slat_ratio', // leading-edge slat status gearHandle: 'sim/cockpit2/controls/gear_handle_down', // 0 up / 1 down gearDeploy: 'sim/flightmodel2/gear/deploy_ratio', // array: per-gear 0..1 speedbrake: 'sim/cockpit2/controls/speedbrake_ratio', parkBrake: 'sim/cockpit2/controls/parking_brake_ratio', // control-position graphic (CTRL POS page): commanded surface ratios -1..1 ailDefl: 'sim/cockpit2/controls/yoke_roll_ratio', elevDefl: 'sim/cockpit2/controls/yoke_pitch_ratio', rudDefl: 'sim/cockpit2/controls/yoke_heading_ratio', battVolt: 'sim/cockpit2/electrical/battery_voltage', // array per battery battTemp: 'sim/cockpit2/electrical/battery_temp_C', // ELEC page (append) // --- yaw damper / mach-trim annunciation (Citation AP YD / M TRIM) --- ydOn: 'sim/cockpit2/switches/yaw_damper_on', }; // 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 cdiSrc: 'sim/cockpit2/radios/actuators/HSI_source_select_pilot', // 0 NAV1 · 1 NAV2 · 2 GPS (CDI softkey cycles it) fuelTot: 'sim/cockpit2/fuel/fuel_totalizer_sum_kg', // SYSTEM → DEC/INC/RST FUEL adjusts the totalizer // NRST page: load a selected airport's tower/CTAF into COM standby, or a VOR into NAV standby. com1Sb: 'sim/cockpit2/radios/actuators/com1_standby_frequency_hz', com2Sb: 'sim/cockpit2/radios/actuators/com2_standby_frequency_hz', nav1Sb: 'sim/cockpit2/radios/actuators/nav1_standby_frequency_hz', nav2Sb: 'sim/cockpit2/radios/actuators/nav2_standby_frequency_hz', }; // 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', // --- Citation X autopilot (Honeywell Primus) extras --- // The mode buttons reuse the universal AP commands above (hdg/nav/apr/bc/ // altHold/flc/vs/vnav). These add the Citation-specific master functions. yawDamper: 'sim/systems/yaw_damper_toggle', // YD button (engages w/ AP too) apStby: 'sim/autopilot/control_wheel_steer', // STBY → basic pitch/roll (CWS), drops modes spdUp: 'sim/autopilot/airspeed_up', // pitch wheel in FLC = target IAS/Mach spdDown: 'sim/autopilot/airspeed_down', vsUp: 'sim/autopilot/vertical_speed_up', // pitch wheel in V/S = target fpm vsDown: 'sim/autopilot/vertical_speed_down', }; // 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}`; }