diff --git a/FlightStreamDeck.AddOn/App.xaml.cs b/FlightStreamDeck.AddOn/App.xaml.cs index 0871fb0..1104ce8 100644 --- a/FlightStreamDeck.AddOn/App.xaml.cs +++ b/FlightStreamDeck.AddOn/App.xaml.cs @@ -1,5 +1,4 @@ -using FlightStreamDeck.Core; -using FlightStreamDeck.Logics; +using FlightStreamDeck.Logics; using FlightStreamDeck.Logics.Actions; using FlightStreamDeck.SimConnectFSX; using Microsoft.AppCenter; @@ -109,9 +108,9 @@ private void ConfigureServices(ServiceCollection services) services.AddTransient(typeof(MainWindow)); services.AddSingleton(); services.AddTransient(); - services.AddTransient(); services.AddSingleton(); + services.AddSingleton(); services.AddTransient(services => services.GetRequiredService()); services.AddTransient(services => services.GetRequiredService()); diff --git a/FlightStreamDeck.Core/EnumConverter.cs b/FlightStreamDeck.Core/EnumConverter.cs deleted file mode 100644 index 87b351c..0000000 --- a/FlightStreamDeck.Core/EnumConverter.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; - -namespace FlightStreamDeck.Core -{ - public class EnumConverter - { - public TOGGLE_VALUE? GetVariableEnum(string? value) - { - if (value != null && !float.TryParse(value, out _) - && Enum.TryParse(value.Trim().Replace(":", "__").Replace(" ", "_"), true, out TOGGLE_VALUE result)) - { - return result; - } - - return null; - } - - public (uint? number, TOGGLE_VALUE? variable) GetUIntOrVariable(string value) - { - if (uint.TryParse(value, out var result)) - { - return (result, null); - } - else if (int.TryParse(value, out var intResult)) - { - return (unchecked((uint)intResult), null); - } - else - { - var variable = GetVariableEnum(value); - return (null, variable); - } - } - } -} diff --git a/FlightStreamDeck.Core/EventValueLibrary.cs b/FlightStreamDeck.Core/EventValueLibrary.cs deleted file mode 100644 index 56bb81b..0000000 --- a/FlightStreamDeck.Core/EventValueLibrary.cs +++ /dev/null @@ -1,453 +0,0 @@ -using System.Collections.Generic; - -namespace FlightStreamDeck.Core -{ - public static class EventValueLibrary - { - struct ValueEntry - { - public ValueEntry(string unit, short decimals) - { - Unit = unit; - Decimals = decimals; - } - - public string Unit; - public int Decimals; - } - - const string DEFAULT_UNIT = "number"; - const int DEFAULT_DECIMALS = 0; - - static Dictionary availableValues = new Dictionary() - { - { TOGGLE_VALUE.THROTTLE_LOWER_LIMIT, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_RPM__1, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.GENERAL_ENG_RPM__2, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.GENERAL_ENG_RPM__3, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.GENERAL_ENG_RPM__4, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.GENERAL_ENG_THROTTLE_LEVER_POSITION__1, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_THROTTLE_LEVER_POSITION__2, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_THROTTLE_LEVER_POSITION__3, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_THROTTLE_LEVER_POSITION__4, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_MIXTURE_LEVER_POSITION__1, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_MIXTURE_LEVER_POSITION__2, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_MIXTURE_LEVER_POSITION__3, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_MIXTURE_LEVER_POSITION__4, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_PROPELLER_LEVER_POSITION__1, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_PROPELLER_LEVER_POSITION__2, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_PROPELLER_LEVER_POSITION__3, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_PROPELLER_LEVER_POSITION__4, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_MAX_RPM, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.GENERAL_ENG_FUEL_PRESSURE__1, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_FUEL_PRESSURE__2, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_FUEL_PRESSURE__3, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_FUEL_PRESSURE__4, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_FUEL_USED_SINCE_START, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N1__1, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N1__2, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N1__3, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N1__4, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N2__1, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N2__2, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N2__3, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_CORRECTED_N2__4, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_ITT__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.TURB_ENG_ITT__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.TURB_ENG_ITT__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.TURB_ENG_ITT__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.TURB_ENG_AFTERBURNER_PCT_ACTIVE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_GPH__1, new ValueEntry("Gallons per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_GPH__2, new ValueEntry("Gallons per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_GPH__3, new ValueEntry("Gallons per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_GPH__4, new ValueEntry("Gallons per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_PPH__1, new ValueEntry("Pounds per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_PPH__2, new ValueEntry("Pounds per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_PPH__3, new ValueEntry("Pounds per hour", 0) }, - { TOGGLE_VALUE.ENG_FUEL_FLOW_PPH__4, new ValueEntry("Pounds per hour", 0) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER2_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER3_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_MAIN_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_AUX_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_TIP_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_MAIN_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_AUX_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_TIP_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_EXTERNAL1_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_EXTERNAL2_LEVEL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER2_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER3_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_MAIN_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_AUX_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_TIP_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_MAIN_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_AUX_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_TIP_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_EXTERNAL1_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_EXTERNAL2_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_LEFT_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_RIGHT_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER2_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_CENTER3_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_MAIN_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_AUX_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_LEFT_TIP_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_MAIN_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_AUX_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_RIGHT_TIP_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_EXTERNAL1_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TANK_EXTERNAL2_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_LEFT_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_RIGHT_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TOTAL_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_WEIGHT_PER_GALLON, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.FUEL_TOTAL_CAPACITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_SELECTED_QUANTITY_PERCENT, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.FUEL_SELECTED_QUANTITY, new ValueEntry("Gallons", 2) }, - { TOGGLE_VALUE.FUEL_TOTAL_QUANTITY_WEIGHT, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.ESTIMATED_FUEL_FLOW, new ValueEntry("Pounds per hour", 2) }, - { TOGGLE_VALUE.GROUND_VELOCITY, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.TOTAL_WORLD_VELOCITY, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.VELOCITY_BODY_Z, new ValueEntry("meter per second", 0) }, - { TOGGLE_VALUE.VELOCITY_BODY_X, new ValueEntry("meter per second", 0) }, - { TOGGLE_VALUE.VELOCITY_BODY_Y, new ValueEntry("meter per second", 0) }, - { TOGGLE_VALUE.VELOCITY_WORLD_Z, new ValueEntry("meter per second", 0) }, - { TOGGLE_VALUE.VELOCITY_WORLD_X, new ValueEntry("meter per second", 0) }, - { TOGGLE_VALUE.VELOCITY_WORLD_Y, new ValueEntry("meter per second", 0) }, - { TOGGLE_VALUE.ACCELERATION_WORLD_X, new ValueEntry("meter per second squared", 2) }, - { TOGGLE_VALUE.ACCELERATION_WORLD_Y, new ValueEntry("meter per second squared", 2) }, - { TOGGLE_VALUE.ACCELERATION_WORLD_Z, new ValueEntry("meter per second squared", 2) }, - { TOGGLE_VALUE.ACCELERATION_BODY_X, new ValueEntry("meter per second squared", 2) }, - { TOGGLE_VALUE.ACCELERATION_BODY_Y, new ValueEntry("meter per second squared", 2) }, - { TOGGLE_VALUE.ACCELERATION_BODY_Z, new ValueEntry("meter per second squared", 2) }, - { TOGGLE_VALUE.ROTATION_VELOCITY_BODY_X, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.ROTATION_VELOCITY_BODY_Y, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.ROTATION_VELOCITY_BODY_Z, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.RELATIVE_WIND_VELOCITY_BODY_X, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.RELATIVE_WIND_VELOCITY_BODY_Y, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.RELATIVE_WIND_VELOCITY_BODY_Z, new ValueEntry("meter per second", 2) }, - { TOGGLE_VALUE.PLANE_ALT_ABOVE_GROUND, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.PLANE_ALTITUDE, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.MAGVAR, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.GROUND_ALTITUDE, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.AIRSPEED_TRUE, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AIRSPEED_INDICATED, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AIRSPEED_TRUE_CALIBRATE, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.AIRSPEED_BARBER_POLE, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AIRSPEED_MACH, new ValueEntry("Mach", 2) }, - { TOGGLE_VALUE.VERTICAL_SPEED, new ValueEntry("Feet per minute", 0) }, - { TOGGLE_VALUE.MACH_MAX_OPERATE, new ValueEntry("Mach", 2) }, - { TOGGLE_VALUE.BARBER_POLE_MACH, new ValueEntry("Mach", 2) }, - { TOGGLE_VALUE.INDICATED_ALTITUDE, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.KOHLSMAN_SETTING_MB, new ValueEntry("Millibars", 0) }, - { TOGGLE_VALUE.KOHLSMAN_SETTING_HG, new ValueEntry("inHg", 2) }, - { TOGGLE_VALUE.ATTITUDE_BARS_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WISKEY_COMPASS_INDICATION_DEGREES, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.RADIO_HEIGHT, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.MAX_G_FORCE, new ValueEntry("Gforce", 2) }, - { TOGGLE_VALUE.MIN_G_FORCE, new ValueEntry("Gforce", 2) }, - { TOGGLE_VALUE.SUCTION_PRESSURE, new ValueEntry("inHg", 2) }, - { TOGGLE_VALUE.ADF_CARD, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.HSI_BEARING, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.HSI_SPEED, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.HSI_DISTANCE, new ValueEntry("Nautical miles", 2) }, - { TOGGLE_VALUE.GPS_POSITION_LAT, new ValueEntry("Degrees", 10) }, - { TOGGLE_VALUE.GPS_POSITION_LON, new ValueEntry("Degrees", 10) }, - { TOGGLE_VALUE.GPS_POSITION_ALT, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.GPS_GROUND_SPEED, new ValueEntry("Meters per second", 2) }, - { TOGGLE_VALUE.GPS_WP_DISTANCE, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.GPS_WP_CROSS_TRK, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.GPS_WP_VERTICAL_SPEED, new ValueEntry("Meters per second", 2) }, - { TOGGLE_VALUE.GPS_ETE, new ValueEntry("Seconds", 0) }, - { TOGGLE_VALUE.GPS_ETA, new ValueEntry("Seconds", 0) }, - { TOGGLE_VALUE.GPS_WP_NEXT_LAT, new ValueEntry("Degrees", 10) }, - { TOGGLE_VALUE.GPS_WP_NEXT_LON, new ValueEntry("Degrees", 10) }, - { TOGGLE_VALUE.GPS_WP_NEXT_ALT, new ValueEntry("Meters", 0) }, - { TOGGLE_VALUE.GPS_WP_PREV_LAT, new ValueEntry("Degrees", 10) }, - { TOGGLE_VALUE.GPS_WP_PREV_LON, new ValueEntry("Degrees", 10) }, - { TOGGLE_VALUE.GPS_WP_PREV_ALT, new ValueEntry("Meters", 0) }, - { TOGGLE_VALUE.GPS_WP_ETE, new ValueEntry("Seconds", 0) }, - { TOGGLE_VALUE.GPS_WP_ETA, new ValueEntry("Seconds", 0) }, - { TOGGLE_VALUE.GPS_APPROACH_TIMEZONE_DEVIATION, new ValueEntry("Seconds", 0) }, - { TOGGLE_VALUE.GPS_TARGET_DISTANCE, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.GPS_TARGET_ALTITUDE, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.ELEVATOR_TRIM_POSITION, new ValueEntry("Radians", 2) }, - { TOGGLE_VALUE.ELEVATOR_TRIM_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.SPOILERS_HANDLE_POSITION, new ValueEntry("Position", 2) }, - { TOGGLE_VALUE.SPOILERS_LEFT_POSITION, new ValueEntry("Position", 2) }, - { TOGGLE_VALUE.SPOILERS_RIGHT_POSITION, new ValueEntry("Position", 2) }, - { TOGGLE_VALUE.FLAPS_HANDLE_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TRAILING_EDGE_FLAPS_LEFT_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TRAILING_EDGE_FLAPS_RIGHT_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.LEADING_EDGE_FLAPS_LEFT_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.LEADING_EDGE_FLAPS_RIGHT_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.AILERON_LEFT_DEFLECTION_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.AILERON_RIGHT_DEFLECTION_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.AILERON_TRIM, new ValueEntry("Radians", 2) }, - { TOGGLE_VALUE.AILERON_TRIM_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.RUDDER_DEFLECTION_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.RUDDER_TRIM_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ELEVATOR_DEFLECTION_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.AUTOPILOT_HEADING_LOCK_DIR, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.AUTOPILOT_HEADING_LOCK_DIR__1, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.AUTOPILOT_ALTITUDE_LOCK_VAR, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.AUTOPILOT_ALTITUDE_LOCK_VAR__1, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.AUTOPILOT_ALTITUDE_LOCK_VAR__2, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.AUTOPILOT_ALTITUDE_LOCK_VAR__3, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.AUTOPILOT_VERTICAL_HOLD_VAR, new ValueEntry("Feet/minute", 0) }, - { TOGGLE_VALUE.AUTOPILOT_VERTICAL_HOLD_VAR__1, new ValueEntry("Feet/minute", 0) }, - { TOGGLE_VALUE.AUTOPILOT_VERTICAL_HOLD_VAR__2, new ValueEntry("Feet/minute", 0) }, - { TOGGLE_VALUE.AUTOPILOT_VERTICAL_HOLD_VAR__3, new ValueEntry("Feet/minute", 0) }, - { TOGGLE_VALUE.AUTOPILOT_AIRSPEED_HOLD_VAR, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AUTOPILOT_AIRSPEED_HOLD_VAR__1, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AUTOPILOT_AIRSPEED_HOLD_VAR__2, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.GEAR_HYDRAULIC_PRESSURE, new ValueEntry("Pound force per square foot (psf)", 2) }, - { TOGGLE_VALUE.GEAR_CENTER_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_LEFT_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_RIGHT_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_TAIL_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_AUX_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_TOTAL_PCT_EXTENDED, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WATER_RUDDER_HANDLE_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WATER_LEFT_RUDDER_EXTENDED, new ValueEntry("Percentage", 0) }, - { TOGGLE_VALUE.WATER_RIGHT_RUDDER_EXTENDED, new ValueEntry("Percentage", 0) }, - { TOGGLE_VALUE.GEAR_CENTER_STEER_ANGLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_LEFT_STEER_ANGLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_RIGHT_STEER_ANGLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_AUX_STEER_ANGLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WATER_LEFT_RUDDER_STEER_ANGLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WATER_RIGHT_RUDDER_STEER_ANGLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_CENTER_STEER_ANGLE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_LEFT_STEER_ANGLE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_RIGHT_STEER_ANGLE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GEAR_AUX_STEER_ANGLE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WATER_LEFT_RUDDER_STEER_ANGLE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.WATER_RIGHT_RUDDER_STEER_ANGLE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.CENTER_WHEEL_RPM, new ValueEntry("Rpm", 0) }, - { TOGGLE_VALUE.LEFT_WHEEL_RPM, new ValueEntry("Rpm", 0) }, - { TOGGLE_VALUE.RIGHT_WHEEL_RPM, new ValueEntry("Rpm", 0) }, - { TOGGLE_VALUE.AUX_WHEEL_RPM, new ValueEntry("Rpm", 0) }, - { TOGGLE_VALUE.RETRACT_LEFT_FLOAT_EXTENDED, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.RETRACT_RIGHT_FLOAT_EXTENDED, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.STEER_INPUT_CONTROL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.AMBIENT_DENSITY, new ValueEntry("Slugs per cubic feet", 0) }, - { TOGGLE_VALUE.AMBIENT_TEMPERATURE, new ValueEntry("Celsius", 2) }, - { TOGGLE_VALUE.AMBIENT_PRESSURE, new ValueEntry("inHg", 2) }, - { TOGGLE_VALUE.AMBIENT_WIND_VELOCITY, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AMBIENT_WIND_DIRECTION, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.AMBIENT_WIND_X, new ValueEntry("Meters per second", 0) }, - { TOGGLE_VALUE.AMBIENT_WIND_Y, new ValueEntry("Meters per second", 0) }, - { TOGGLE_VALUE.AMBIENT_WIND_Z, new ValueEntry("Meters per second", 0) }, - { TOGGLE_VALUE.STRUCT_AMBIENT_WIND, new ValueEntry("Feet_per_second", 0) }, - { TOGGLE_VALUE.AIRCRAFT_WIND_X, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AIRCRAFT_WIND_Y, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.AIRCRAFT_WIND_Z, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.BAROMETER_PRESSURE, new ValueEntry("Millibars", 0) }, - { TOGGLE_VALUE.SEA_LEVEL_PRESSURE, new ValueEntry("Millibars", 0) }, - { TOGGLE_VALUE.TOTAL_AIR_TEMPERATURE, new ValueEntry("Celsius", 2) }, - { TOGGLE_VALUE.AMBIENT_VISIBILITY, new ValueEntry("Meters", 0) }, - { TOGGLE_VALUE.STANDARD_ATM_TEMPERATURE, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.FOLDING_WING_LEFT_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.FOLDING_WING_RIGHT_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.CANOPY_OPEN, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TAILHOOK_POSITION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ELECTRICAL_TOTAL_LOAD_AMPS, new ValueEntry("Amperes", 2) }, - { TOGGLE_VALUE.ELECTRICAL_BATTERY_LOAD, new ValueEntry("Amperes", 2) }, - { TOGGLE_VALUE.ELECTRICAL_BATTERY_VOLTAGE, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.ELECTRICAL_MAIN_BUS_VOLTAGE, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.ELECTRICAL_MAIN_BUS_AMPS, new ValueEntry("Amperes", 2) }, - { TOGGLE_VALUE.ELECTRICAL_AVIONICS_BUS_VOLTAGE, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.ELECTRICAL_AVIONICS_BUS_AMPS, new ValueEntry("Amperes", 2) }, - { TOGGLE_VALUE.ELECTRICAL_HOT_BATTERY_BUS_VOLTAGE, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.ELECTRICAL_HOT_BATTERY_BUS_AMPS, new ValueEntry("Amperes", 2) }, - { TOGGLE_VALUE.ELECTRICAL_BATTERY_BUS_VOLTAGE, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.ELECTRICAL_BATTERY_BUS_AMPS, new ValueEntry("Amperes", 2) }, - { TOGGLE_VALUE.ELECTRICAL_BATTERY_BUS_CONTACT_SWITCH, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.HYDRAULIC_SYSTEM_INTEGRITY, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TOTAL_WEIGHT, new ValueEntry("Pounds", 0) }, - { TOGGLE_VALUE.MAX_GROSS_WEIGHT, new ValueEntry("Pounds", 0) }, - { TOGGLE_VALUE.EMPTY_WEIGHT, new ValueEntry("Pounds", 0) }, - { TOGGLE_VALUE.G_FORCE, new ValueEntry("GForce", 2) }, - { TOGGLE_VALUE.DESIGN_SPEED_VS0, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.DESIGN_SPEED_VS1, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.DESIGN_SPEED_VC, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.MIN_DRAG_VELOCITY, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.ESTIMATED_CRUISE_SPEED, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.CG_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.CG_PERCENT_LATERAL, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ATC_SUGGESTED_MIN_RWY_TAKEOFF, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.ATC_SUGGESTED_MIN_RWY_LANDING, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.TYPICAL_DESCENT_RATE, new ValueEntry("Feet per minute", 0) }, - { TOGGLE_VALUE.VISUAL_MODEL_RADIUS, new ValueEntry("Meters", 2) }, - { TOGGLE_VALUE.DYNAMIC_PRESSURE, new ValueEntry("Pounds per square foot", 0) }, - { TOGGLE_VALUE.TOTAL_VELOCITY, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.AIRSPEED_SELECT_INDICATED_OR_TRUE, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.VARIOMETER_RATE, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.PRESSURE_ALTITUDE, new ValueEntry("Meters", 0) }, - { TOGGLE_VALUE.MAGNETIC_COMPASS, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.BRAKE_DEPENDENT_HYDRAULIC_PRESSURE, new ValueEntry("Pounds per square foot", 2) }, - { TOGGLE_VALUE.WING_AREA, new ValueEntry("Square feet", 2) }, - { TOGGLE_VALUE.WING_SPAN, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.LINEAR_CL_ALPHA, new ValueEntry("Per radian", 2) }, - { TOGGLE_VALUE.CG_AFT_LIMIT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.CG_FWD_LIMIT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.CG_MAX_MACH, new ValueEntry("Machs", 2) }, - { TOGGLE_VALUE.CG_MIN_MACH, new ValueEntry("Machs", 2) }, - { TOGGLE_VALUE.EXIT_POSX, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.EXIT_POSY, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.EXIT_POSZ, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.DECISION_HEIGHT, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.DECISION_ALTITUDE_MSL, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.EMPTY_WEIGHT_PITCH_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.EMPTY_WEIGHT_ROLL_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.EMPTY_WEIGHT_YAW_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.EMPTY_WEIGHT_CROSS_COUPLED_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.TOTAL_WEIGHT_PITCH_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.TOTAL_WEIGHT_ROLL_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.TOTAL_WEIGHT_YAW_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.TOTAL_WEIGHT_CROSS_COUPLED_MOI, new ValueEntry("Slugs per feet squared", 2) }, - { TOGGLE_VALUE.MAX_RATED_ENGINE_RPM, new ValueEntry("Rpm", 0) }, - { TOGGLE_VALUE.MANUAL_FUEL_PUMP_HANDLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ELECTRICAL_OLD_CHARGING_AMPS, new ValueEntry("Amps", 2) }, - { TOGGLE_VALUE.CONCORDE_VISOR_POSITION_PERCENT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.PITOT_ICE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.SIMULATED_RADIUS, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.STRUCTURAL_ICE_PCT, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ARTIFICIAL_GROUND_ELEVATION, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.PUSHBACK_CONTACTX, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.PUSHBACK_CONTACTY, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.PUSHBACK_CONTACTZ, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.YAW_STRING_PCT_EXTENDED, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.INDUCTOR_COMPASS_PERCENT_DEVIATION, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.ANEMOMETER_PCT_RPM, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.NAV_VOR_LLAF64, new ValueEntry("LLA structure", 0) }, - { TOGGLE_VALUE.NAV_GS_LLAF64, new ValueEntry("LLA structure", 0) }, - { TOGGLE_VALUE.STATIC_CG_TO_GROUND, new ValueEntry("Feet", 2) }, - { TOGGLE_VALUE.TOW_RELEASE_HANDLE, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.APU_PCT_RPM, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.APU_PCT_STARTER, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.APU_VOLTS, new ValueEntry("Volts", 2) }, - { TOGGLE_VALUE.PRESSURIZATION_CABIN_ALTITUDE, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.PRESSURIZATION_CABIN_ALTITUDE_GOAL, new ValueEntry("Feet", 0) }, - { TOGGLE_VALUE.PRESSURIZATION_CABIN_ALTITUDE_RATE, new ValueEntry("Feet per second", 0) }, - { TOGGLE_VALUE.PRESSURIZATION_PRESSURE_DIFFERENTIAL, new ValueEntry("Pounds per square foot", 0) }, - { TOGGLE_VALUE.NAV_ACTIVE_FREQUENCY__1, new ValueEntry("MHz", 2) }, - { TOGGLE_VALUE.NAV_STANDBY_FREQUENCY__1, new ValueEntry("MHz", 2) }, - { TOGGLE_VALUE.NAV_ACTIVE_FREQUENCY__2, new ValueEntry("MHz", 2) }, - { TOGGLE_VALUE.NAV_STANDBY_FREQUENCY__2, new ValueEntry("MHz", 2) }, - { TOGGLE_VALUE.COM_ACTIVE_FREQUENCY__1, new ValueEntry("MHz", 3) }, - { TOGGLE_VALUE.COM_STANDBY_FREQUENCY__1, new ValueEntry("MHz", 3) }, - { TOGGLE_VALUE.COM_ACTIVE_FREQUENCY__2, new ValueEntry("MHz", 3) }, - { TOGGLE_VALUE.COM_STANDBY_FREQUENCY__2, new ValueEntry("MHz", 3) }, - { TOGGLE_VALUE.ADF_ACTIVE_FREQUENCY__1, new ValueEntry("MHz", 0) }, - { TOGGLE_VALUE.ADF_STANDBY_FREQUENCY__1, new ValueEntry("MHz", 0) }, - { TOGGLE_VALUE.ADF_ACTIVE_FREQUENCY__2, new ValueEntry("MHz", 0) }, - { TOGGLE_VALUE.ADF_STANDBY_FREQUENCY__2, new ValueEntry("MHz", 0) }, - { TOGGLE_VALUE.PLANE_PITCH_DEGREES, new ValueEntry("Degrees", 2) }, - { TOGGLE_VALUE.PLANE_BANK_DEGREES, new ValueEntry("Degrees", 2) }, - { TOGGLE_VALUE.PLANE_HEADING_DEGREES_TRUE, new ValueEntry("Degrees", 2) }, - { TOGGLE_VALUE.PLANE_HEADING_DEGREES_MAGNETIC, new ValueEntry("Degrees", 2) }, - { TOGGLE_VALUE.TURB_ENG_MAX_TORQUE_PERCENT__1, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_MAX_TORQUE_PERCENT__2, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_MAX_TORQUE_PERCENT__3, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_MAX_TORQUE_PERCENT__4, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_PCT_MAX_RPM__1, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_PCT_MAX_RPM__2, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_PCT_MAX_RPM__3, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_PCT_MAX_RPM__4, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_PRIMARY_NOZZLE_PERCENT__1, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_PRIMARY_NOZZLE_PERCENT__2, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_PRIMARY_NOZZLE_PERCENT__3, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.TURB_ENG_PRIMARY_NOZZLE_PERCENT__4, new ValueEntry("Percent", 0) }, - { TOGGLE_VALUE.NAV_OBS__1, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.NAV_OBS__2, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.NAV_DME__1, new ValueEntry("Nautical miles", 1) }, - { TOGGLE_VALUE.NAV_DME__2, new ValueEntry("Nautical miles", 1) }, - { TOGGLE_VALUE.NAV_DMESPEED__1, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.NAV_DMESPEED__2, new ValueEntry("Knots", 0) }, - { TOGGLE_VALUE.RECIP_ENG_COWL_FLAP_POSITION__1, new ValueEntry("Percent", 2) }, - { TOGGLE_VALUE.TURN_COORDINATOR_BALL, new ValueEntry("Position 128", 0) }, - { TOGGLE_VALUE.RECIP_ENG_MANIFOLD_PRESSURE__1, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.RECIP_ENG_MANIFOLD_PRESSURE__2, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.RECIP_ENG_MANIFOLD_PRESSURE__3, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.RECIP_ENG_MANIFOLD_PRESSURE__4, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.TURB_ENG_JET_THRUST__1, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.TURB_ENG_JET_THRUST__2, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.TURB_ENG_JET_THRUST__3, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.TURB_ENG_JET_THRUST__4, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.PROP_THRUST__1, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.PROP_THRUST__2, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.PROP_THRUST__3, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.PROP_THRUST__4, new ValueEntry("Pounds", 2) }, - { TOGGLE_VALUE.PROP_RPM__1, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.PROP_RPM__2, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.PROP_RPM__3, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.PROP_RPM__4, new ValueEntry("Rpm", 1) }, - { TOGGLE_VALUE.ENG_CYLINDER_HEAD_TEMPERATURE__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_CYLINDER_HEAD_TEMPERATURE__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_CYLINDER_HEAD_TEMPERATURE__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_CYLINDER_HEAD_TEMPERATURE__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_OIL_TEMPERATURE__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_OIL_TEMPERATURE__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_OIL_TEMPERATURE__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_OIL_TEMPERATURE__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_TEMPERATURE__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_TEMPERATURE__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_TEMPERATURE__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_TEMPERATURE__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.ENG_OIL_PRESSURE__1, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.ENG_OIL_PRESSURE__2, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.ENG_OIL_PRESSURE__3, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.ENG_OIL_PRESSURE__4, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_PRESSURE__1, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_PRESSURE__2, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_PRESSURE__3, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.GENERAL_ENG_OIL_PRESSURE__4, new ValueEntry("Psi", 0) }, - { TOGGLE_VALUE.RECIP_CARBURETOR_TEMPERATURE__1, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_CARBURETOR_TEMPERATURE__2, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_CARBURETOR_TEMPERATURE__3, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.RECIP_CARBURETOR_TEMPERATURE__4, new ValueEntry("Celsius", 0) }, - { TOGGLE_VALUE.GYRO_DRIFT_ERROR, new ValueEntry("Degrees", 0) }, - { TOGGLE_VALUE.HEADING_INDICATOR, new ValueEntry("Degrees", 0) }, - }; - - public static string GetUnit(this TOGGLE_VALUE value, string? unit) - { - if (!string.IsNullOrEmpty(unit)) - { - // TODO: add some validation - return unit; - } - else if (availableValues.ContainsKey(value)) - { - return availableValues[value].Unit; - } - return DEFAULT_UNIT; - } - - public static int GetDecimals(this TOGGLE_VALUE value, int? decimals = null) - { - if (decimals.HasValue) - { - return decimals.Value; - } - else if (availableValues.ContainsKey(value)) - { - return availableValues[value].Decimals; - } - - return DEFAULT_DECIMALS; - } - } -} diff --git a/FlightStreamDeck.Core/TOGGLE_VALUE.cs b/FlightStreamDeck.Core/TOGGLE_VALUE.cs deleted file mode 100644 index ed0e560..0000000 --- a/FlightStreamDeck.Core/TOGGLE_VALUE.cs +++ /dev/null @@ -1,700 +0,0 @@ -namespace FlightStreamDeck.Core -{ - public enum TOGGLE_VALUE - { - NUMBER_OF_ENGINES = 100, - THROTTLE_LOWER_LIMIT, - MASTER_IGNITION_SWITCH, - ENG_COMBUSTION, - GENERAL_ENG_COMBUSTION__1, - GENERAL_ENG_COMBUSTION__2, - GENERAL_ENG_COMBUSTION__3, - GENERAL_ENG_COMBUSTION__4, - GENERAL_ENG_MASTER_ALTERNATOR__1, - GENERAL_ENG_MASTER_ALTERNATOR__2, - GENERAL_ENG_FUEL_PUMP_SWITCH__1, - GENERAL_ENG_FUEL_PUMP_SWITCH__2, - GENERAL_ENG_FUEL_PUMP_SWITCH__3, - GENERAL_ENG_FUEL_PUMP_SWITCH__4, - GENERAL_ENG_FUEL_PUMP_SWITCH_EX1__1, - GENERAL_ENG_FUEL_PUMP_SWITCH_EX1__2, - GENERAL_ENG_FUEL_PUMP_SWITCH_EX1__3, - GENERAL_ENG_FUEL_PUMP_SWITCH_EX1__4, - GENERAL_ENG_FUEL_PUMP_ON__1, - GENERAL_ENG_FUEL_PUMP_ON__2, - GENERAL_ENG_FUEL_PUMP_ON__3, - GENERAL_ENG_FUEL_PUMP_ON__4, - GENERAL_ENG_FUEL_PRESSURE__1, - GENERAL_ENG_FUEL_PRESSURE__2, - GENERAL_ENG_FUEL_PRESSURE__3, - GENERAL_ENG_FUEL_PRESSURE__4, - GENERAL_ENG_RPM__1, - GENERAL_ENG_RPM__2, - GENERAL_ENG_RPM__3, - GENERAL_ENG_RPM__4, - GENERAL_ENG_STARTER__1, - GENERAL_ENG_STARTER__2, - GENERAL_ENG_STARTER__3, - GENERAL_ENG_STARTER__4, - GENERAL_ENG_THROTTLE_LEVER_POSITION__1, - GENERAL_ENG_THROTTLE_LEVER_POSITION__2, - GENERAL_ENG_THROTTLE_LEVER_POSITION__3, - GENERAL_ENG_THROTTLE_LEVER_POSITION__4, - GENERAL_ENG_MIXTURE_LEVER_POSITION__1, - GENERAL_ENG_MIXTURE_LEVER_POSITION__2, - GENERAL_ENG_MIXTURE_LEVER_POSITION__3, - GENERAL_ENG_MIXTURE_LEVER_POSITION__4, - GENERAL_ENG_PROPELLER_LEVER_POSITION__1, - GENERAL_ENG_PROPELLER_LEVER_POSITION__2, - GENERAL_ENG_PROPELLER_LEVER_POSITION__3, - GENERAL_ENG_PROPELLER_LEVER_POSITION__4, - GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__1, - GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__2, - GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__3, - GENERAL_ENG_EXHAUST_GAS_TEMPERATURE__4, - GENERAL_ENG_GENERATOR_SWITCH__1, - GENERAL_ENG_GENERATOR_SWITCH__2, - GENERAL_ENG_GENERATOR_SWITCH__3, - GENERAL_ENG_GENERATOR_SWITCH__4, - GENERAL_ENG_GENERATOR_ACTIVE__1, - GENERAL_ENG_GENERATOR_ACTIVE__2, - GENERAL_ENG_GENERATOR_ACTIVE__3, - GENERAL_ENG_GENERATOR_ACTIVE__4, - GENERAL_ENG_ANTI_ICE_POSITION__1, - GENERAL_ENG_ANTI_ICE_POSITION__2, - GENERAL_ENG_ANTI_ICE_POSITION__3, - GENERAL_ENG_ANTI_ICE_POSITION__4, - GENERAL_ENG_FUEL_VALVE__1, - GENERAL_ENG_FUEL_VALVE__2, - GENERAL_ENG_FUEL_VALVE__3, - GENERAL_ENG_FUEL_VALVE__4, - ENG_MAX_RPM, - GENERAL_ENG_STARTER_ACTIVE, - GENERAL_ENG_FUEL_USED_SINCE_START, - TURB_ENG_IGNITION_ON, - TURB_ENG_MASTER_STARTER_SWITCH, - TURB_ENG_CORRECTED_N1__1, - TURB_ENG_CORRECTED_N1__2, - TURB_ENG_CORRECTED_N1__3, - TURB_ENG_CORRECTED_N1__4, - TURB_ENG_CORRECTED_N2__1, - TURB_ENG_CORRECTED_N2__2, - TURB_ENG_CORRECTED_N2__3, - TURB_ENG_CORRECTED_N2__4, - TURB_ENG_ITT__1, - TURB_ENG_ITT__2, - TURB_ENG_ITT__3, - TURB_ENG_ITT__4, - TURB_ENG_AFTERBURNER_STAGE_ACTIVE, - TURB_ENG_AFTERBURNER_PCT_ACTIVE, - ENG_FUEL_FLOW_GPH__1, - ENG_FUEL_FLOW_GPH__2, - ENG_FUEL_FLOW_GPH__3, - ENG_FUEL_FLOW_GPH__4, - ENG_FUEL_FLOW_PPH__1, - ENG_FUEL_FLOW_PPH__2, - ENG_FUEL_FLOW_PPH__3, - ENG_FUEL_FLOW_PPH__4, - FUEL_TANK_SELECTOR__1, - FUEL_TANK_SELECTOR__2, - FUEL_TANK_SELECTOR__3, - FUEL_TANK_SELECTOR__4, - FUEL_TANK_CENTER_LEVEL, - FUEL_TANK_CENTER2_LEVEL, - FUEL_TANK_CENTER3_LEVEL, - FUEL_TANK_LEFT_MAIN_LEVEL, - FUEL_TANK_LEFT_AUX_LEVEL, - FUEL_TANK_LEFT_TIP_LEVEL, - FUEL_TANK_RIGHT_MAIN_LEVEL, - FUEL_TANK_RIGHT_AUX_LEVEL, - FUEL_TANK_RIGHT_TIP_LEVEL, - FUEL_TANK_EXTERNAL1_LEVEL, - FUEL_TANK_EXTERNAL2_LEVEL, - FUEL_TANK_CENTER_CAPACITY, - FUEL_TANK_CENTER2_CAPACITY, - FUEL_TANK_CENTER3_CAPACITY, - FUEL_TANK_LEFT_MAIN_CAPACITY, - FUEL_TANK_LEFT_AUX_CAPACITY, - FUEL_TANK_LEFT_TIP_CAPACITY, - FUEL_TANK_RIGHT_MAIN_CAPACITY, - FUEL_TANK_RIGHT_AUX_CAPACITY, - FUEL_TANK_RIGHT_TIP_CAPACITY, - FUEL_TANK_EXTERNAL1_CAPACITY, - FUEL_TANK_EXTERNAL2_CAPACITY, - FUEL_LEFT_CAPACITY, - FUEL_RIGHT_CAPACITY, - FUEL_TANK_CENTER_QUANTITY, - FUEL_TANK_CENTER2_QUANTITY, - FUEL_TANK_CENTER3_QUANTITY, - FUEL_TANK_LEFT_MAIN_QUANTITY, - FUEL_TANK_LEFT_AUX_QUANTITY, - FUEL_TANK_LEFT_TIP_QUANTITY, - FUEL_TANK_RIGHT_MAIN_QUANTITY, - FUEL_TANK_RIGHT_AUX_QUANTITY, - FUEL_TANK_RIGHT_TIP_QUANTITY, - FUEL_TANK_EXTERNAL1_QUANTITY, - FUEL_TANK_EXTERNAL2_QUANTITY, - FUEL_LEFT_QUANTITY, - FUEL_RIGHT_QUANTITY, - FUEL_TOTAL_QUANTITY, - FUEL_WEIGHT_PER_GALLON, - FUEL_TOTAL_CAPACITY, - FUEL_SELECTED_QUANTITY_PERCENT, - FUEL_SELECTED_QUANTITY, - FUEL_TOTAL_QUANTITY_WEIGHT, - FUEL_TRANSFER_PUMP_ON__1, - FUEL_TRANSFER_PUMP_ON__2, - FUEL_TRANSFER_PUMP_ON__3, - FUEL_TRANSFER_PUMP_ON__4, - NUM_FUEL_SELECTORS, - UNLIMITED_FUEL, - ESTIMATED_FUEL_FLOW, - LIGHT_STROBE, - LIGHT_PANEL, - LIGHT_LANDING, - LIGHT_TAXI, - LIGHT_BEACON, - LIGHT_NAV, - LIGHT_LOGO, - LIGHT_WING, - LIGHT_RECOGNITION, - LIGHT_CABIN, - LIGHT_TAXI_ON, - LIGHT_STROBE_ON, - LIGHT_PANEL_ON, - LIGHT_RECOGNITION_ON, - LIGHT_WING_ON, - LIGHT_LOGO_ON, - LIGHT_CABIN_ON, - LIGHT_CABIN_ON__1, - LIGHT_CABIN_ON__2, - LIGHT_CABIN_ON__3, - LIGHT_CABIN_ON__4, - LIGHT_HEAD_ON, - LIGHT_BRAKE_ON, - LIGHT_NAV_ON, - LIGHT_BEACON_ON, - LIGHT_LANDING_ON, - LIGHT_PANEL_POWER_SETTING__1, - LIGHT_PANEL_POWER_SETTING__2, - LIGHT_PANEL_POWER_SETTING__3, - LIGHT_PANEL_POWER_SETTING__4, - LIGHT_CABIN_POWER_SETTING__1, - LIGHT_CABIN_POWER_SETTING__2, - LIGHT_CABIN_POWER_SETTING__3, - LIGHT_CABIN_POWER_SETTING__4, - GROUND_VELOCITY, - TOTAL_WORLD_VELOCITY, - VELOCITY_BODY_Z, - VELOCITY_BODY_X, - VELOCITY_BODY_Y, - VELOCITY_WORLD_Z, - VELOCITY_WORLD_X, - VELOCITY_WORLD_Y, - ACCELERATION_WORLD_X, - ACCELERATION_WORLD_Y, - ACCELERATION_WORLD_Z, - ACCELERATION_BODY_X, - ACCELERATION_BODY_Y, - ACCELERATION_BODY_Z, - ROTATION_VELOCITY_BODY_X, - ROTATION_VELOCITY_BODY_Y, - ROTATION_VELOCITY_BODY_Z, - RELATIVE_WIND_VELOCITY_BODY_X, - RELATIVE_WIND_VELOCITY_BODY_Y, - RELATIVE_WIND_VELOCITY_BODY_Z, - PLANE_ALT_ABOVE_GROUND, - PLANE_PITCH_DEGREES, - PLANE_BANK_DEGREES, - PLANE_HEADING_DEGREES_TRUE, - PLANE_HEADING_DEGREES_MAGNETIC, - PLANE_ALTITUDE, - PROP_DEICE_SWITCH__1, - PROP_DEICE_SWITCH__2, - PROP_DEICE_SWITCH__3, - PROP_DEICE_SWITCH__4, - MAGVAR, - GROUND_ALTITUDE, - SIM_ON_GROUND, - AIRSPEED_TRUE, - AIRSPEED_INDICATED, - AIRSPEED_TRUE_CALIBRATE, - AIRSPEED_BARBER_POLE, - AIRSPEED_MACH, - VERTICAL_SPEED, - MACH_MAX_OPERATE, - STALL_WARNING, - OVERSPEED_WARNING, - BARBER_POLE_MACH, - INDICATED_ALTITUDE, - KOHLSMAN_SETTING_MB, - KOHLSMAN_SETTING_HG, - ATTITUDE_BARS_POSITION, - ATTITUDE_CAGE, - WISKEY_COMPASS_INDICATION_DEGREES, - RADIO_HEIGHT, - MAX_G_FORCE, - MIN_G_FORCE, - SUCTION_PRESSURE, - AVIONICS_MASTER_SWITCH, - DME_SOUND, - TACAN_DME_SOUND, - MARKER_SOUND, - INNER_MARKER, - MIDDLE_MARKER, - OUTER_MARKER, - ADF_CARD, - HSI_CDI_NEEDLE, - HSI_GSI_NEEDLE, - HSI_CDI_NEEDLE_VALID, - HSI_GSI_NEEDLE_VALID, - HSI_BEARING_VALID, - HSI_BEARING, - HSI_HAS_LOCALIZER, - HSI_SPEED, - HSI_DISTANCE, - GPS_POSITION_LAT, - GPS_POSITION_LON, - GPS_POSITION_ALT, - GPS_IS_ACTIVE_FLIGHT_PLAN, - GPS_IS_ACTIVE_WAY_POINT, - GPS_IS_ARRIVED, - GPS_IS_DIRECTTO_FLIGHTPLAN, - GPS_GROUND_SPEED, - GPS_WP_DISTANCE, - GPS_WP_CROSS_TRK, - GPS_WP_VERTICAL_SPEED, - GPS_ETE, - GPS_ETA, - GPS_WP_NEXT_LAT, - GPS_WP_NEXT_LON, - GPS_WP_NEXT_ALT, - GPS_WP_PREV_VALID, - GPS_WP_PREV_LAT, - GPS_WP_PREV_LON, - GPS_WP_PREV_ALT, - GPS_WP_ETE, - GPS_WP_ETA, - GPS_FLIGHT_PLAN_WP_INDEX, - GPS_FLIGHT_PLAN_WP_COUNT, - GPS_IS_ACTIVE_WP_LOCKED, - GPS_IS_APPROACH_LOADED, - GPS_IS_APPROACH_ACTIVE, - GPS_APPROACH_IS_WP_RUNWAY, - GPS_APPROACH_APPROACH_INDEX, - GPS_APPROACH_TRANSITION_INDEX, - GPS_APPROACH_IS_FINAL, - GPS_APPROACH_IS_MISSED, - GPS_APPROACH_TIMEZONE_DEVIATION, - GPS_APPROACH_WP_INDEX, - GPS_APPROACH_WP_COUNT, - GPS_DRIVES_NAV1, - COM_RECIEVE_ALL, - COM_RECEIVE_ALL, - COM_TRANSMIT__1, - COM_TRANSMIT__2, - COM_STATUS__1, - COM_STATUS__2, - COM_AVAILABLE, - COM_TEST__1, - COM_TEST__2, - ADF_IDENT, - ADF_NAME, - NAV_IDENT, - NAV_NAME, - TACAN_IDENT, - TACAN_NAME, - NAV_GLIDE_SLOPE, - SELECTED_DME, - GPS_WP_NEXT_ID, - GPS_WP_PREV_ID, - GPS_TARGET_DISTANCE, - GPS_TARGET_ALTITUDE, - ELEVATOR_TRIM_POSITION, - ELEVATOR_TRIM_PCT, - BRAKE_PARKING_POSITION, - BRAKE_PARKING_INDICATOR, - SPOILERS_ARMED, - SPOILERS_HANDLE_POSITION, - SPOILERS_LEFT_POSITION, - SPOILERS_RIGHT_POSITION, - FLAPS_HANDLE_PERCENT, - FLAPS_HANDLE_INDEX, - FLAPS_NUM_HANDLE_POSITIONS, - TRAILING_EDGE_FLAPS_LEFT_PERCENT, - TRAILING_EDGE_FLAPS_RIGHT_PERCENT, - LEADING_EDGE_FLAPS_LEFT_PERCENT, - LEADING_EDGE_FLAPS_RIGHT_PERCENT, - AILERON_LEFT_DEFLECTION_PCT, - AILERON_RIGHT_DEFLECTION_PCT, - AILERON_TRIM, - AILERON_TRIM_PCT, - RUDDER_DEFLECTION_PCT, - RUDDER_TRIM_PCT, - FLAP_DAMAGE_BY_SPEED, - FLAP_SPEED_EXCEEDED, - ELEVATOR_DEFLECTION_PCT, - ALTERNATE_STATIC_SOURCE_OPEN, - FOLDING_WING_HANDLE_POSITION, - FUEL_DUMP_SWITCH, - AUTOPILOT_AVAILABLE, - AUTOPILOT_MASTER, - AUTOPILOT_DISENGAGED, - AUTOPILOT_NAV_SELECTED, - AUTOPILOT_WING_LEVELER, - AUTOPILOT_NAV1_LOCK, - AUTOPILOT_HEADING_LOCK, - AUTOPILOT_HEADING_LOCK_DIR, - AUTOPILOT_HEADING_LOCK_DIR__1, - AUTOPILOT_HEADING_SLOT_INDEX, - AUTOPILOT_ALTITUDE_LOCK, - AUTOPILOT_ALTITUDE_LOCK_VAR, - AUTOPILOT_ALTITUDE_LOCK_VAR__1, - AUTOPILOT_ALTITUDE_LOCK_VAR__2, - AUTOPILOT_ALTITUDE_LOCK_VAR__3, - AUTOPILOT_ALTITUDE_SLOT_INDEX, - AUTOPILOT_ATTITUDE_HOLD, - AUTOPILOT_GLIDESLOPE_HOLD, - AUTOPILOT_APPROACH_HOLD, - AUTOPILOT_BACKCOURSE_HOLD, - AUTOPILOT_VERTICAL_HOLD_VAR, - AUTOPILOT_VERTICAL_HOLD_VAR__1, - AUTOPILOT_VERTICAL_HOLD_VAR__2, - AUTOPILOT_VERTICAL_HOLD_VAR__3, - AUTOPILOT_PITCH_HOLD, - AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE, - AUTOPILOT_AIRSPEED_HOLD, - AUTOPILOT_AIRSPEED_HOLD_VAR, - AUTOPILOT_AIRSPEED_HOLD_VAR__1, - AUTOPILOT_AIRSPEED_HOLD_VAR__2, - AUTOPILOT_SPEED_SLOT_INDEX, - AUTOPILOT_FLIGHT_LEVEL_CHANGE, - AUTOPILOT_MACH_HOLD, - AUTOPILOT_MACH_HOLD_VAR, - AUTOPILOT_YAW_DAMPER, - AUTOPILOT_RPM_HOLD_VAR, - AUTOPILOT_THROTTLE_ARM, - AUTOPILOT_TAKEOFF_POWER_ACTIVE, - AUTOTHROTTLE_ACTIVE, - AUTOPILOT_VERTICAL_HOLD, - AUTOPILOT_RPM_HOLD, - FLY_BY_WIRE_ELAC_SWITCH, - FLY_BY_WIRE_FAC_SWITCH, - FLY_BY_WIRE_SEC_SWITCH, - FLY_BY_WIRE_ELAC_FAILED, - FLY_BY_WIRE_FAC_FAILED, - FLY_BY_WIRE_SEC_FAILED, - IS_GEAR_RETRACTABLE, - IS_GEAR_SKIS, - IS_GEAR_FLOATS, - IS_GEAR_SKIDS, - IS_GEAR_WHEELS, - GEAR_HANDLE_POSITION, - GEAR_HYDRAULIC_PRESSURE, - TAILWHEEL_LOCK_ON, - GEAR_CENTER_POSITION, - GEAR_LEFT_POSITION, - GEAR_RIGHT_POSITION, - GEAR_TAIL_POSITION, - GEAR_AUX_POSITION, - GEAR_TOTAL_PCT_EXTENDED, - AUTO_BRAKE_SWITCH_CB, - WATER_RUDDER_HANDLE_POSITION, - WATER_LEFT_RUDDER_EXTENDED, - WATER_RIGHT_RUDDER_EXTENDED, - GEAR_CENTER_STEER_ANGLE, - GEAR_LEFT_STEER_ANGLE, - GEAR_RIGHT_STEER_ANGLE, - GEAR_AUX_STEER_ANGLE, - WATER_LEFT_RUDDER_STEER_ANGLE, - WATER_RIGHT_RUDDER_STEER_ANGLE, - GEAR_CENTER_STEER_ANGLE_PCT, - GEAR_LEFT_STEER_ANGLE_PCT, - GEAR_RIGHT_STEER_ANGLE_PCT, - GEAR_AUX_STEER_ANGLE_PCT, - WATER_LEFT_RUDDER_STEER_ANGLE_PCT, - WATER_RIGHT_RUDDER_STEER_ANGLE_PCT, - CENTER_WHEEL_RPM, - LEFT_WHEEL_RPM, - RIGHT_WHEEL_RPM, - AUX_WHEEL_RPM, - GEAR_EMERGENCY_HANDLE_POSITION, - ANTISKID_BRAKES_ACTIVE, - RETRACT_FLOAT_SWITCH, - RETRACT_LEFT_FLOAT_EXTENDED, - RETRACT_RIGHT_FLOAT_EXTENDED, - STEER_INPUT_CONTROL, - GEAR_DAMAGE_BY_SPEED, - GEAR_SPEED_EXCEEDED, - NOSEWHEEL_LOCK_ON, - AMBIENT_DENSITY, - AMBIENT_TEMPERATURE, - AMBIENT_PRESSURE, - AMBIENT_WIND_VELOCITY, - AMBIENT_WIND_DIRECTION, - AMBIENT_WIND_X, - AMBIENT_WIND_Y, - AMBIENT_WIND_Z, - STRUCT_AMBIENT_WIND, - AIRCRAFT_WIND_X, - AIRCRAFT_WIND_Y, - AIRCRAFT_WIND_Z, - BAROMETER_PRESSURE, - SEA_LEVEL_PRESSURE, - TOTAL_AIR_TEMPERATURE, - AMBIENT_IN_CLOUD, - AMBIENT_VISIBILITY, - STANDARD_ATM_TEMPERATURE, - SMOKE_ENABLE, - PITOT_HEAT, - FOLDING_WING_LEFT_PERCENT, - FOLDING_WING_RIGHT_PERCENT, - CANOPY_OPEN, - TAILHOOK_POSITION, - IS_TAIL_DRAGGER, - ELECTRICAL_MASTER_BATTERY, - ELECTRICAL_MASTER_BATTERY__1, - ELECTRICAL_MASTER_BATTERY__2, - ELECTRICAL_TOTAL_LOAD_AMPS, - ELECTRICAL_BATTERY_LOAD, - ELECTRICAL_BATTERY_VOLTAGE, - //ELECTRICAL_BATTERY_IS_CHARGING, - ELECTRICAL_MAIN_BUS_VOLTAGE, - ELECTRICAL_MAIN_BUS_AMPS, - ELECTRICAL_AVIONICS_BUS_VOLTAGE, - ELECTRICAL_AVIONICS_BUS_AMPS, - ELECTRICAL_HOT_BATTERY_BUS_VOLTAGE, - ELECTRICAL_HOT_BATTERY_BUS_AMPS, - ELECTRICAL_BATTERY_BUS_VOLTAGE, - ELECTRICAL_BATTERY_BUS_AMPS, - ELECTRICAL_BATTERY_BUS_CONTACT_SWITCH, - ELECTRIC_GPU_ACTIVE, - ELECTRIC_GPU_SWITCH, - CIRCUIT_GENERAL_PANEL_ON, - CIRCUIT_FLAP_MOTOR_ON, - CIRCUIT_GEAR_MOTOR_ON, - CIRCUIT_AUTOPILOT_ON, - CIRCUIT_AVIONICS_ON, - CIRCUIT_PITOT_HEAT_ON, - CIRCUIT_PROP_SYNC_ON, - CIRCUIT_AUTO_FEATHER_ON, - CIRCUIT_AUTO_BRAKES_ON, - CIRCUIT_STANDY_VACUUM_ON, - CIRCUIT_MARKER_BEACON_ON, - CIRCUIT_GEAR_WARNING_ON, - CIRCUIT_HYDRAULIC_PUMP_ON, - HYDRAULIC_SYSTEM_INTEGRITY, - STRUCTURAL_DEICE_SWITCH, - APPLY_HEAT_TO_SYSTEMS, - TOTAL_WEIGHT, - MAX_GROSS_WEIGHT, - EMPTY_WEIGHT, - IS_USER_SIM, - LABEL_SUPPORTED, - SIM_DISABLED, - G_FORCE, - ATC_HEAVY, - AUTO_COORDINATION, - REALISM, - TRUE_AIRSPEED_SELECTED, - DESIGN_SPEED_VS0, - DESIGN_SPEED_VS1, - DESIGN_SPEED_VC, - MIN_DRAG_VELOCITY, - ESTIMATED_CRUISE_SPEED, - CG_PERCENT, - CG_PERCENT_LATERAL, - IS_SLEW_ACTIVE, - IS_SLEW_ALLOWED, - ATC_SUGGESTED_MIN_RWY_TAKEOFF, - ATC_SUGGESTED_MIN_RWY_LANDING, - PAYLOAD_STATION_COUNT, - USER_INPUT_ENABLED, - TYPICAL_DESCENT_RATE, - VISUAL_MODEL_RADIUS, - CATEGORY, - SIGMA_SQRT, - DYNAMIC_PRESSURE, - TOTAL_VELOCITY, - AIRSPEED_SELECT_INDICATED_OR_TRUE, - VARIOMETER_RATE, - VARIOMETER_SWITCH, - PRESSURE_ALTITUDE, - MAGNETIC_COMPASS, - TURN_INDICATOR_SWITCH, - BRAKE_DEPENDENT_HYDRAULIC_PRESSURE, - PANEL_ANTI_ICE_SWITCH, - WING_AREA, - WING_SPAN, - LINEAR_CL_ALPHA, - CG_AFT_LIMIT, - CG_FWD_LIMIT, - CG_MAX_MACH, - CG_MIN_MACH, - PAYLOAD_STATION_NAME, - EXIT_POSX, - EXIT_POSY, - EXIT_POSZ, - DECISION_HEIGHT, - DECISION_ALTITUDE_MSL, - EMPTY_WEIGHT_PITCH_MOI, - EMPTY_WEIGHT_ROLL_MOI, - EMPTY_WEIGHT_YAW_MOI, - EMPTY_WEIGHT_CROSS_COUPLED_MOI, - TOTAL_WEIGHT_PITCH_MOI, - TOTAL_WEIGHT_ROLL_MOI, - TOTAL_WEIGHT_YAW_MOI, - TOTAL_WEIGHT_CROSS_COUPLED_MOI, - WATER_BALLAST_VALVE, - MAX_RATED_ENGINE_RPM, - FULL_THROTTLE_THRUST_TO_WEIGHT_RATIO, - PROP_AUTO_CRUISE_ACTIVE, - DROPPABLE_OBJECTS_UI_NAME, - MANUAL_FUEL_PUMP_HANDLE, - ELECTRICAL_OLD_CHARGING_AMPS, - HYDRAULIC_SWITCH, - CONCORDE_VISOR_POSITION_PERCENT, - REALISM_CRASH_WITH_OTHERS, - REALISM_CRASH_DETECTION, - MANUAL_INSTRUMENT_LIGHTS, - PITOT_ICE_PCT, - RAD_INS_SWITCH, - SIMULATED_RADIUS, - STRUCTURAL_ICE_PCT, - ARTIFICIAL_GROUND_ELEVATION, - SURFACE_INFO_VALID, - PUSHBACK_CONTACTX, - PUSHBACK_CONTACTY, - PUSHBACK_CONTACTZ, - PUSHBACK_WAIT, - YAW_STRING_PCT_EXTENDED, - INDUCTOR_COMPASS_PERCENT_DEVIATION, - ANEMOMETER_PCT_RPM, - NAV_VOR_LLAF64, - NAV_GS_LLAF64, - STATIC_CG_TO_GROUND, - TOW_RELEASE_HANDLE, - TOW_CONNECTION, - APU_PCT_RPM, - APU_PCT_STARTER, - APU_VOLTS, - APU_GENERATOR_SWITCH, - APU_GENERATOR_ACTIVE, - APU_ON_FIRE_DETECTED, - PRESSURIZATION_CABIN_ALTITUDE, - PRESSURIZATION_CABIN_ALTITUDE_GOAL, - PRESSURIZATION_CABIN_ALTITUDE_RATE, - PRESSURIZATION_PRESSURE_DIFFERENTIAL, - PRESSURIZATION_DUMP_SWITCH, - FIRE_BOTTLE_SWITCH, - FIRE_BOTTLE_DISCHARGED, - CABIN_NO_SMOKING_ALERT_SWITCH, - CABIN_SEATBELTS_ALERT_SWITCH, - GPWS_WARNING, - GPWS_SYSTEM_ACTIVE, - IS_LATITUDE_LONGITUDE_FREEZE_ON, - IS_ALTITUDE_FREEZE_ON, - IS_ATTITUDE_FREEZE_ON, - NAV_ACTIVE_FREQUENCY__1, - NAV_STANDBY_FREQUENCY__1, - NAV_ACTIVE_FREQUENCY__2, - NAV_STANDBY_FREQUENCY__2, - COM_ACTIVE_FREQUENCY__1, - COM_STANDBY_FREQUENCY__1, - COM_ACTIVE_FREQUENCY__2, - COM_STANDBY_FREQUENCY__2, - ENG_TORQUE__1, - ENG_TORQUE__2, - ENG_TORQUE__3, - ENG_TORQUE__4, - TURB_ENG_MAX_TORQUE_PERCENT__1, - TURB_ENG_MAX_TORQUE_PERCENT__2, - TURB_ENG_MAX_TORQUE_PERCENT__3, - TURB_ENG_MAX_TORQUE_PERCENT__4, - TURB_ENG_FREE_TURBINE_TORQUE__1, - TURB_ENG_FREE_TURBINE_TORQUE__2, - TURB_ENG_FREE_TURBINE_TORQUE__3, - TURB_ENG_FREE_TURBINE_TORQUE__4, - GENERAL_ENG_PCT_MAX_RPM__1, - GENERAL_ENG_PCT_MAX_RPM__2, - GENERAL_ENG_PCT_MAX_RPM__3, - GENERAL_ENG_PCT_MAX_RPM__4, - TURB_ENG_PRIMARY_NOZZLE_PERCENT__1, - TURB_ENG_PRIMARY_NOZZLE_PERCENT__2, - TURB_ENG_PRIMARY_NOZZLE_PERCENT__3, - TURB_ENG_PRIMARY_NOZZLE_PERCENT__4, - TRANSPONDER_CODE__1, - TRANSPONDER_STATE__1, - NAV_SOUND__1, - NAV_SOUND__2, - SIMULATION_RATE, - NAV_OBS__1, - NAV_OBS__2, - NAV_DME__1, - NAV_DME__2, - NAV_DMESPEED__1, - NAV_DMESPEED__2, - RECIP_ENG_COWL_FLAP_POSITION__1, - TURN_COORDINATOR_BALL, - RECIP_ENG_MANIFOLD_PRESSURE__1, - RECIP_ENG_MANIFOLD_PRESSURE__2, - RECIP_ENG_MANIFOLD_PRESSURE__3, - RECIP_ENG_MANIFOLD_PRESSURE__4, - TURB_ENG_JET_THRUST__1, - TURB_ENG_JET_THRUST__2, - TURB_ENG_JET_THRUST__3, - TURB_ENG_JET_THRUST__4, - PROP_THRUST__1, - PROP_THRUST__2, - PROP_THRUST__3, - PROP_THRUST__4, - PROP_RPM__1, - PROP_RPM__2, - PROP_RPM__3, - PROP_RPM__4, - COM_SPACING_MODE, - ADF_ACTIVE_FREQUENCY__1, - ADF_STANDBY_FREQUENCY__1, - ADF_ACTIVE_FREQUENCY__2, - ADF_STANDBY_FREQUENCY__2, - ABSOLUTE_TIME, - ZULU_TIME, - LOCAL_TIME, - ENG_CYLINDER_HEAD_TEMPERATURE__1, - ENG_CYLINDER_HEAD_TEMPERATURE__2, - ENG_CYLINDER_HEAD_TEMPERATURE__3, - ENG_CYLINDER_HEAD_TEMPERATURE__4, - RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__1, - RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__2, - RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__3, - RECIP_ENG_CYLINDER_HEAD_TEMPERATURE__4, - ENG_OIL_TEMPERATURE__1, - ENG_OIL_TEMPERATURE__2, - ENG_OIL_TEMPERATURE__3, - ENG_OIL_TEMPERATURE__4, - GENERAL_ENG_OIL_TEMPERATURE__1, - GENERAL_ENG_OIL_TEMPERATURE__2, - GENERAL_ENG_OIL_TEMPERATURE__3, - GENERAL_ENG_OIL_TEMPERATURE__4, - ENG_OIL_PRESSURE__1, - ENG_OIL_PRESSURE__2, - ENG_OIL_PRESSURE__3, - ENG_OIL_PRESSURE__4, - GENERAL_ENG_OIL_PRESSURE__1, - GENERAL_ENG_OIL_PRESSURE__2, - GENERAL_ENG_OIL_PRESSURE__3, - GENERAL_ENG_OIL_PRESSURE__4, - RECIP_CARBURETOR_TEMPERATURE__1, - RECIP_CARBURETOR_TEMPERATURE__2, - RECIP_CARBURETOR_TEMPERATURE__3, - RECIP_CARBURETOR_TEMPERATURE__4, - ANGLE_OF_ATTACK_INDICATOR, - GYRO_DRIFT_ERROR, - HEADING_INDICATOR, - PLANE_IN_PARKING_STATE, - MASTER_CAUTION_ACTIVE, - MASTER_WARNING_ACTIVE, - MASTER_CAUTION_ACKNOWLEDGED, - MASTER_WARNING_ACKNOWLEDGED, - } -} diff --git a/FlightStreamDeck.Logics/Actions/GenericGaugeAction.cs b/FlightStreamDeck.Logics/Actions/GenericGaugeAction.cs index 7cb22b1..00b2993 100644 --- a/FlightStreamDeck.Logics/Actions/GenericGaugeAction.cs +++ b/FlightStreamDeck.Logics/Actions/GenericGaugeAction.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using EnumConverter = FlightStreamDeck.Core.EnumConverter; namespace FlightStreamDeck.Logics.Actions; @@ -58,15 +57,14 @@ public class GenericGaugeAction : BaseAction private readonly IImageLogic imageLogic; private readonly IEventRegistrar eventRegistrar; private readonly IEventDispatcher eventDispatcher; - private readonly EnumConverter enumConverter; + private readonly SimVarManager simVarManager; private string? toggleEvent = null; - private TOGGLE_VALUE? displayValue = null; - private TOGGLE_VALUE? subDisplayValue = null; - private TOGGLE_VALUE? displayValueBottom = null; - private TOGGLE_VALUE? minValue = null; - private TOGGLE_VALUE? maxValue = null; - private string? customUnit = null; + private SimVarRegistration? displayValue = null; + private SimVarRegistration? subDisplayValue = null; + private SimVarRegistration? displayValueBottom = null; + private SimVarRegistration? minValue = null; + private SimVarRegistration? maxValue = null; private int? customDecimals = null; private double currentValue = 0; @@ -84,7 +82,7 @@ public class GenericGaugeAction : BaseAction ChartThicknessValue = "13", ChartChevronSizeValue = "3", Header = "L", - DisplayValue = TOGGLE_VALUE.FUEL_LEFT_QUANTITY.ToString(), + DisplayValue = "FUEL LEFT QUANTITY", HeaderBottom = string.Empty, DisplayValueBottom = string.Empty, MinValue = "0", @@ -102,7 +100,7 @@ public GenericGaugeAction( IImageLogic imageLogic, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - EnumConverter enumConverter) + SimVarManager simVarManager) { this.settings = DefaultSettings; this.logger = logger; @@ -110,7 +108,7 @@ public GenericGaugeAction( this.imageLogic = imageLogic; this.eventRegistrar = eventRegistrar; this.eventDispatcher = eventDispatcher; - this.enumConverter = enumConverter; + this.simVarManager = simVarManager; } protected override async Task OnWillAppear(ActionEventArgs args) @@ -162,12 +160,12 @@ public override async Task InitializeSettingsAsync(GenericGaugeSettings? setting } var newToggleEvent = settings.ToggleValue; - TOGGLE_VALUE? newDisplayValue = enumConverter.GetVariableEnum(settings.DisplayValue); - TOGGLE_VALUE? newSubDisplayValue = enumConverter.GetVariableEnum(settings.SubDisplayValue); - TOGGLE_VALUE? newDisplayValueBottom = enumConverter.GetVariableEnum(settings.DisplayValueBottom); + var newDisplayValue = simVarManager.GetRegistration(settings.DisplayValue, settings.ValueUnit); + var newSubDisplayValue = simVarManager.GetRegistration(settings.SubDisplayValue, settings.ValueUnit); + var newDisplayValueBottom = simVarManager.GetRegistration(settings.DisplayValueBottom, settings.ValueUnit); - TOGGLE_VALUE? newMinValue = enumConverter.GetVariableEnum(settings.MinValue); - TOGGLE_VALUE? newMaxValue = enumConverter.GetVariableEnum(settings.MaxValue); + var newMinValue = simVarManager.GetRegistration(settings.MinValue); + var newMaxValue = simVarManager.GetRegistration(settings.MaxValue); if (double.TryParse(string.IsNullOrWhiteSpace(settings.MinValue) ? DefaultSettings.MinValue : settings.MinValue, out var min)) { @@ -187,18 +185,14 @@ public override async Task InitializeSettingsAsync(GenericGaugeSettings? setting customDecimals = null; } - var newUnit = settings.ValueUnit?.Trim(); - if (string.IsNullOrWhiteSpace(newUnit)) newUnit = null; - if (newDisplayValue != displayValue || newDisplayValueBottom != displayValueBottom || newSubDisplayValue != subDisplayValue || - newMinValue != minValue || newMaxValue != maxValue || newUnit != customUnit) + newMinValue != minValue || newMaxValue != maxValue) { DeRegisterValues(); } toggleEvent = newToggleEvent; displayValue = newDisplayValue; - customUnit = newUnit; subDisplayValue = newSubDisplayValue; displayValueBottom = newDisplayValueBottom; minValue = newMinValue; @@ -212,15 +206,14 @@ private async Task UpdatePropertyInspector() await SendToPropertyInspectorAsync(this.settings); } - private bool SetFromGenericValueStatus(Dictionary<(TOGGLE_VALUE variable, string? unit), double> genericValueStatus, TOGGLE_VALUE? variable, string? unit, ref double currentValue) + private bool SetFromGenericValueStatus(Dictionary genericValueStatus, SimVarRegistration? variable, ref double currentValue) { bool isUpdated = false; - if (variable.HasValue) + if (variable != null) { - var tuple = (variable.Value, unit); - if (genericValueStatus.ContainsKey(tuple)) + if (genericValueStatus.ContainsKey(variable)) { - var newValue = genericValueStatus[tuple]; + var newValue = genericValueStatus[variable]; isUpdated = currentValue != newValue; currentValue = newValue; } @@ -234,17 +227,17 @@ private async void FlightConnector_GenericValuesUpdated(object? sender, ToggleVa bool isUpdated = false; - isUpdated |= SetFromGenericValueStatus(e.GenericValueStatus, displayValue, customUnit, ref currentValue); - isUpdated |= SetFromGenericValueStatus(e.GenericValueStatus, displayValueBottom, customUnit, ref currentValueBottom); - isUpdated |= SetFromGenericValueStatus(e.GenericValueStatus, subDisplayValue, null, ref currentSubValue); + isUpdated |= SetFromGenericValueStatus(e.GenericValueStatus, displayValue, ref currentValue); + isUpdated |= SetFromGenericValueStatus(e.GenericValueStatus, displayValueBottom, ref currentValueBottom); + isUpdated |= SetFromGenericValueStatus(e.GenericValueStatus, subDisplayValue, ref currentSubValue); double min = 0; - if (SetFromGenericValueStatus(e.GenericValueStatus, minValue, null, ref min)) + if (SetFromGenericValueStatus(e.GenericValueStatus, minValue, ref min)) { currentMinValue = min; isUpdated = true; } double max = 0; - if (SetFromGenericValueStatus(e.GenericValueStatus, maxValue, null, ref max)) + if (SetFromGenericValueStatus(e.GenericValueStatus, maxValue, ref max)) { currentMaxValue = max; isUpdated = true; @@ -260,31 +253,31 @@ private void RegisterValues() { eventRegistrar.RegisterEvent(toggleEvent); - var values = new List<(TOGGLE_VALUE variables, string? unit)>(); - if (displayValue.HasValue) values.Add((displayValue.Value, customUnit)); - if (subDisplayValue.HasValue) values.Add((subDisplayValue.Value, customUnit)); - if (displayValueBottom.HasValue) values.Add((displayValueBottom.Value, customUnit)); - if (minValue.HasValue) values.Add((minValue.Value, null)); - if (maxValue.HasValue) values.Add((maxValue.Value, null)); + var values = new List(); + if (displayValue != null) values.Add(displayValue); + if (subDisplayValue != null) values.Add(subDisplayValue); + if (displayValueBottom != null) values.Add(displayValueBottom); + if (minValue != null) values.Add(minValue); + if (maxValue != null) values.Add(maxValue); if (values.Count > 0) { - flightConnector.RegisterSimValues(values.ToArray()); + simVarManager.RegisterSimValues(values.ToArray()); } } private void DeRegisterValues() { - var values = new List<(TOGGLE_VALUE variables, string? unit)>(); - if (displayValue.HasValue) values.Add((displayValue.Value, customUnit)); - if (subDisplayValue.HasValue) values.Add((subDisplayValue.Value, customUnit)); - if (displayValueBottom.HasValue) values.Add((displayValueBottom.Value, customUnit)); - if (minValue.HasValue) values.Add((minValue.Value, null)); - if (maxValue.HasValue) values.Add((maxValue.Value, null)); + var values = new List(); + if (displayValue != null) values.Add(displayValue); + if (subDisplayValue != null) values.Add(subDisplayValue); + if (displayValueBottom != null) values.Add(displayValueBottom); + if (minValue != null) values.Add(minValue); + if (maxValue != null) values.Add(maxValue); if (values.Count > 0) { - flightConnector.DeRegisterSimValues(values.ToArray()); + simVarManager.DeRegisterSimValues(values.ToArray()); } currentValue = 0; @@ -300,10 +293,10 @@ private async Task UpdateImage() switch (settings.Type) { case "Custom": - if (displayValue.HasValue || displayValueBottom.HasValue) + if (displayValue != null || displayValueBottom != null) { var chartSplit = string.IsNullOrEmpty(settings.ChartSplitValue) ? DefaultSettings.ChartSplitValue : settings.ChartSplitValue; - var numberFormat = $"F{EventValueLibrary.GetDecimals(displayValue ?? displayValueBottom.Value, customDecimals)}"; + var numberFormat = $"F{KnownVariables.GetDecimals(displayValue?.variableName ?? displayValueBottom?.variableName, customDecimals)}"; bool.TryParse(settings.AbsValText, out bool absValueText); @@ -332,10 +325,10 @@ await SetImageSafeAsync( } break; default: - if (displayValue.HasValue || displayValueBottom.HasValue) + if (displayValue != null || displayValueBottom != null) { - var numberFormat = "F" + (displayValue.HasValue ? EventValueLibrary.GetDecimals(displayValue.Value, customDecimals) : 2); - var subValueText = subDisplayValue.HasValue ? currentSubValue.ToString("F" + EventValueLibrary.GetDecimals(subDisplayValue.Value)) : null; + var numberFormat = "F" + (displayValue != null ? displayValue.variableName.GetDecimals(customDecimals) : 2); + var subValueText = subDisplayValue != null ? currentSubValue.ToString("F" + subDisplayValue.variableName.GetDecimals()) : null; int? fontSize = null; if (int.TryParse(settings.FontSize, out var size)) { diff --git a/FlightStreamDeck.Logics/Actions/GenericToggleAction.cs b/FlightStreamDeck.Logics/Actions/GenericToggleAction.cs index d001e7f..fef5bac 100644 --- a/FlightStreamDeck.Logics/Actions/GenericToggleAction.cs +++ b/FlightStreamDeck.Logics/Actions/GenericToggleAction.cs @@ -3,6 +3,7 @@ using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Timers; @@ -59,24 +60,24 @@ public class GenericToggleAction : BaseAction, EmbedLinkL private readonly IEvaluator evaluator; private readonly IEventRegistrar eventRegistrar; private readonly IEventDispatcher eventDispatcher; - private readonly EnumConverter enumConverter; + private readonly SimVarManager simVarManager; private readonly EmbedLinkLogic embedLinkLogic; private Timer? timer = null; private string? toggleEvent = null; private uint? toggleEventDataUInt = null; - private TOGGLE_VALUE? toggleEventDataVariable = null; + private SimVarRegistration? toggleEventDataVariable = null; private double? toggleEventDataVariableValue = null; + private string? holdEvent = null; private uint? holdEventDataUInt = null; - private TOGGLE_VALUE? holdEventDataVariable = null; + private SimVarRegistration? holdEventDataVariable = null; private double? holdEventDataVariableValue = null; - private IEnumerable feedbackVariables = new List(); + private IEnumerable feedbackVariables = new List(); private IExpression? expression; - private TOGGLE_VALUE? displayValue = null; + private SimVarRegistration? displayVariable = null; - private string? customUnit = null; private int? customDecimals = null; private double? currentValue = null; @@ -92,7 +93,7 @@ public GenericToggleAction( IEvaluator evaluator, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - EnumConverter enumConverter) + SimVarManager simVarManager) { this.logger = logger; this.flightConnector = flightConnector; @@ -100,7 +101,7 @@ public GenericToggleAction( this.evaluator = evaluator; this.eventRegistrar = eventRegistrar; this.eventDispatcher = eventDispatcher; - this.enumConverter = enumConverter; + this.simVarManager = simVarManager; this.embedLinkLogic = new EmbedLinkLogic(this); } @@ -120,22 +121,20 @@ public override Task InitializeSettingsAsync(GenericToggleSettings? settings) if (settings == null) return Task.CompletedTask; var newToggleEvent = settings.ToggleValue; - (var newToggleEventDataUInt, var newToggleEventDataVariable) = enumConverter.GetUIntOrVariable(settings.ToggleValueData); + (var newToggleEventDataUInt, var newToggleEventDataVariable) = GetUIntOrVariable(settings.ToggleValueData); var newHoldEvent = settings.HoldValue; - (var newHoldEventDataUInt, var newHoldEventDataVariable) = enumConverter.GetUIntOrVariable(settings.HoldValueData); + (var newHoldEventDataUInt, var newHoldEventDataVariable) = GetUIntOrVariable(settings.HoldValueData); (var newFeedbackVariables, var newExpression) = evaluator.Parse(settings.FeedbackValue); - TOGGLE_VALUE? newDisplayValue = enumConverter.GetVariableEnum(settings.DisplayValue); + var newDisplayValue = simVarManager.GetRegistration(settings.DisplayValue, settings.DisplayValueUnit); if (int.TryParse(settings.DisplayValuePrecision, out int decimals)) { customDecimals = decimals; } - var newUnit = settings.DisplayValueUnit?.Trim(); - if (string.IsNullOrWhiteSpace(newUnit)) newUnit = null; - if (!newFeedbackVariables.SequenceEqual(feedbackVariables) || newDisplayValue != displayValue - || newUnit != customUnit + if (!newFeedbackVariables.SequenceEqual(feedbackVariables) + || newDisplayValue != displayVariable || newToggleEventDataVariable != toggleEventDataVariable || newHoldEventDataVariable != holdEventDataVariable ) @@ -151,31 +150,60 @@ public override Task InitializeSettingsAsync(GenericToggleSettings? settings) holdEventDataVariable = newHoldEventDataVariable; feedbackVariables = newFeedbackVariables; expression = newExpression; - displayValue = newDisplayValue; - customUnit = newUnit; + displayVariable = newDisplayValue; RegisterValues(); return Task.CompletedTask; } + private (uint? number, SimVarRegistration? variable) GetUIntOrVariable(string? value) + { + if (uint.TryParse(value, out var result)) + { + return (result, null); + } + else if (int.TryParse(value, out var intResult)) + { + return (unchecked((uint)intResult), null); + } + else if (value != null) + { + var variable = simVarManager.GetRegistration(value, null); + return (null, variable); + } + else + { + return (null, null); + } + } + private async void FlightConnector_GenericValuesUpdated(object? sender, ToggleValueUpdatedEventArgs e) { if (StreamDeck == null) return; - var valuesWithDefaultUnits = e.GenericValueStatus.Where(o => o.Key.unit == null).ToDictionary(o => o.Key.variable, o => o.Value); - var newStatus = expression != null && evaluator.Evaluate(valuesWithDefaultUnits, expression); + var newStatus = expression != null && expression.Evaluate(e.GenericValueStatus); var isUpdated = newStatus != currentStatus; currentStatus = newStatus; - if (displayValue.HasValue && e.GenericValueStatus.ContainsKey((displayValue.Value, customUnit))) + bool TryGetValue([NotNullWhen(true)] SimVarRegistration? variable, out double value) + { + if (variable != null && e.GenericValueStatus.ContainsKey(variable)) + { + value = e.GenericValueStatus[variable]; + return true; + } + value = 0; + return false; + } + + if (TryGetValue(displayVariable, out var newValue)) { - var newValue = e.GenericValueStatus[(displayValue.Value, customUnit)]; isUpdated |= newValue != currentValue; currentValue = newValue; - if (displayValue.Value == TOGGLE_VALUE.ZULU_TIME - || displayValue.Value == TOGGLE_VALUE.LOCAL_TIME) + if (displayVariable.variableName == "ZULU TIME" + || displayVariable.variableName == "LOCAL TIME") { string hours = Math.Floor(newValue / 3600).ToString().PadLeft(2, '0'); newValue = newValue % 3600; @@ -188,29 +216,29 @@ private async void FlightConnector_GenericValuesUpdated(object? sender, ToggleVa switch (customDecimals) { case 0: //HH:MM:SS - currentValueTime = $"{hours}:{minutes}:{seconds}{(displayValue.Value == TOGGLE_VALUE.ZULU_TIME ? "Z" : String.Empty)}"; - currentValue = e.GenericValueStatus[(displayValue.Value, customUnit)]; + currentValueTime = $"{hours}:{minutes}:{seconds}{(displayVariable.variableName == "ZULU TIME" ? "Z" : String.Empty)}"; + currentValue = e.GenericValueStatus[displayVariable]; break; case 1: //HH:MM - currentValueTime = $"{hours}:{minutes}{(displayValue.Value == TOGGLE_VALUE.ZULU_TIME ? "Z" : String.Empty)}"; - currentValue = e.GenericValueStatus[(displayValue.Value, customUnit)]; + currentValueTime = $"{hours}:{minutes}{(displayVariable.variableName == "ZULU TIME" ? "Z" : String.Empty)}"; + currentValue = e.GenericValueStatus[displayVariable]; break; default: currentValueTime = string.Empty; - currentValue = e.GenericValueStatus[(displayValue.Value, customUnit)]; + currentValue = e.GenericValueStatus[displayVariable]; break; } } } - if (toggleEventDataVariable.HasValue && e.GenericValueStatus.ContainsKey((toggleEventDataVariable.Value, null))) + if (TryGetValue(toggleEventDataVariable, out var newToggleValue)) { - toggleEventDataVariableValue = e.GenericValueStatus[(toggleEventDataVariable.Value, null)]; + toggleEventDataVariableValue = newToggleValue; } - if (holdEventDataVariable.HasValue && e.GenericValueStatus.ContainsKey((holdEventDataVariable.Value, null))) + if (TryGetValue(holdEventDataVariable, out var newHoldValue)) { - holdEventDataVariableValue = e.GenericValueStatus[(holdEventDataVariable.Value, null)]; + holdEventDataVariableValue = newHoldValue; } if (isUpdated) @@ -250,29 +278,30 @@ private void RegisterValues() eventRegistrar.RegisterEvent(toggleEvent); eventRegistrar.RegisterEvent(holdEvent); - var values = new List<(TOGGLE_VALUE variables, string? unit)>(); - foreach (var feedbackVariable in feedbackVariables) values.Add((feedbackVariable, null)); - if (displayValue.HasValue) values.Add((displayValue.Value, customUnit)); - if (toggleEventDataVariable.HasValue) values.Add((toggleEventDataVariable.Value, null)); - if (holdEventDataVariable.HasValue) values.Add((holdEventDataVariable.Value, null)); + var variables = new List(); + foreach (var feedbackVariable in feedbackVariables) variables.Add(feedbackVariable); + + if (displayVariable != null) variables.Add(displayVariable); + if (toggleEventDataVariable != null) variables.Add(toggleEventDataVariable); + if (holdEventDataVariable != null) variables.Add(holdEventDataVariable); - if (values.Count > 0) + if (variables.Count > 0) { - flightConnector.RegisterSimValues(values.ToArray()); + simVarManager.RegisterSimValues(variables.ToArray()); } } private void DeRegisterValues() { - var values = new List<(TOGGLE_VALUE variables, string? unit)>(); - foreach (var feedbackVariable in feedbackVariables) values.Add((feedbackVariable, null)); - if (displayValue.HasValue) values.Add((displayValue.Value, customUnit)); - if (toggleEventDataVariable.HasValue) values.Add((toggleEventDataVariable.Value, null)); - if (holdEventDataVariable.HasValue) values.Add((holdEventDataVariable.Value, null)); + var variables = new List(); + foreach (var feedbackVariable in feedbackVariables) variables.Add(feedbackVariable); + if (displayVariable != null) variables.Add(displayVariable); + if (toggleEventDataVariable != null) variables.Add(toggleEventDataVariable); + if (holdEventDataVariable != null) variables.Add(holdEventDataVariable); - if (values.Count > 0) + if (variables.Count > 0) { - flightConnector.DeRegisterSimValues(values.ToArray()); + simVarManager.DeRegisterSimValues(variables.ToArray()); } currentValue = null; @@ -346,9 +375,9 @@ private async Task TriggerToggleEventAsync() return result; } - private uint CalculateEventParam(TOGGLE_VALUE? variable, double? variableValue, uint? inputValue) + private uint CalculateEventParam(SimVarRegistration? variable, double? variableValue, uint? inputValue) { - if (variable is not null && variableValue.HasValue) + if (variable != null && variableValue.HasValue) { var rounded = Math.Round(variableValue.Value);// - 360; return rounded < 0 ? unchecked((uint)(int)rounded) : (uint)rounded; @@ -370,7 +399,7 @@ private async Task UpdateImage() var valueToShow = !string.IsNullOrEmpty(currentValueTime) ? currentValueTime : - (displayValue.HasValue && currentValue.HasValue) ? currentValue.Value.ToString("F" + EventValueLibrary.GetDecimals(displayValue.Value, customDecimals)) : ""; + (displayVariable != null && currentValue.HasValue) ? currentValue.Value.ToString("F" + displayVariable.variableName.GetDecimals(customDecimals)) : ""; var image = imageLogic.GetImage(settings.Header, currentStatus, value: valueToShow, diff --git a/FlightStreamDeck.Logics/Actions/HorizonAction.cs b/FlightStreamDeck.Logics/Actions/HorizonAction.cs index 14b44bb..47789e8 100644 --- a/FlightStreamDeck.Logics/Actions/HorizonAction.cs +++ b/FlightStreamDeck.Logics/Actions/HorizonAction.cs @@ -1,6 +1,4 @@ -using FlightStreamDeck.Core; - -namespace FlightStreamDeck.Logics.Actions; +namespace FlightStreamDeck.Logics.Actions; [StreamDeckAction("tech.flighttracker.streamdeck.artificial.horizon")] public class HorizonAction : BaseAction @@ -8,20 +6,19 @@ public class HorizonAction : BaseAction private readonly ILogger logger; private readonly IFlightConnector flightConnector; private readonly IImageLogic imageLogic; + private readonly SimVarManager simVarManager; + private string bankValue = "PLANE BANK DEGREES"; + private string pitchValue = "PLANE PITCH DEGREES"; - private TOGGLE_VALUE bankValue = TOGGLE_VALUE.PLANE_BANK_DEGREES; - private TOGGLE_VALUE pitchValue = TOGGLE_VALUE.PLANE_PITCH_DEGREES; - private TOGGLE_VALUE headingValue = TOGGLE_VALUE.PLANE_HEADING_DEGREES_MAGNETIC; - - private double currentHeadingValue = 0; private double currentBankValue = 0; private double currentPitchValue = 0; - public HorizonAction(ILogger logger, IFlightConnector flightConnector, IImageLogic imageLogic) + public HorizonAction(ILogger logger, IFlightConnector flightConnector, IImageLogic imageLogic, SimVarManager simVarManager) { this.logger = logger; this.flightConnector = flightConnector; this.imageLogic = imageLogic; + this.simVarManager = simVarManager; } protected override async Task OnWillAppear(ActionEventArgs args) @@ -35,21 +32,27 @@ protected override async Task OnWillAppear(ActionEventArgs ar private async void FlightConnector_GenericValuesUpdated(object? sender, ToggleValueUpdatedEventArgs e) { - bool isUpdated = false; - - if (e.GenericValueStatus.ContainsKey((bankValue, null)) && currentBankValue != e.GenericValueStatus[(bankValue, null)]) + bool TryGetNewValue(string variable, double currentValue, out double value) { - currentBankValue = e.GenericValueStatus[(bankValue, null)]; - isUpdated = true; + if (e.GenericValueStatus.TryGetValue(new SimVarRegistration(variable, null), out var newValue) && currentValue != newValue) + { + value = newValue; + return true; + } + value = 0; + return false; } - if (e.GenericValueStatus.ContainsKey((headingValue, null)) && currentHeadingValue != e.GenericValueStatus[(headingValue, null)]) + + bool isUpdated = false; + + if (TryGetNewValue(bankValue, currentBankValue, out var newBank)) { - currentHeadingValue = e.GenericValueStatus[(headingValue, null)]; + currentBankValue = newBank; isUpdated = true; } - if (e.GenericValueStatus.ContainsKey((pitchValue, null)) && currentPitchValue != e.GenericValueStatus[(pitchValue, null)]) + if (TryGetNewValue(pitchValue, currentPitchValue, out var newPitch)) { - currentPitchValue = e.GenericValueStatus[(pitchValue, null)]; + currentPitchValue = newPitch; isUpdated = true; } @@ -68,23 +71,23 @@ protected override Task OnWillDisappear(ActionEventArgs args) private void RegisterValues() { - flightConnector.RegisterSimValues((bankValue, null), (pitchValue, null)); + simVarManager.RegisterSimValues(simVarManager.GetRegistration(bankValue), simVarManager.GetRegistration(pitchValue)); } private void DeRegisterValues() { - flightConnector.DeRegisterSimValues((bankValue, null), (pitchValue, null)); + simVarManager.DeRegisterSimValues(simVarManager.GetRegistration(bankValue), simVarManager.GetRegistration(pitchValue)); } protected override Task OnKeyDown(ActionEventArgs args) { - bankValue = 0; + currentBankValue = 0; _ = UpdateImage(); return Task.CompletedTask; } private async Task UpdateImage() { - await SetImageSafeAsync(imageLogic.GetHorizonImage(currentPitchValue, currentBankValue, currentHeadingValue)); + await SetImageSafeAsync(imageLogic.GetHorizonImage(currentPitchValue, currentBankValue)); } } diff --git a/FlightStreamDeck.Logics/Actions/NavCom/AdfHandler.cs b/FlightStreamDeck.Logics/Actions/NavCom/AdfHandler.cs index 04eac9a..b8811a8 100644 --- a/FlightStreamDeck.Logics/Actions/NavCom/AdfHandler.cs +++ b/FlightStreamDeck.Logics/Actions/NavCom/AdfHandler.cs @@ -1,16 +1,15 @@ -using FlightStreamDeck.Core; -using System; +using System; namespace FlightStreamDeck.Logics.Actions.NavCom; public class AdfHandler : HzHandler { public AdfHandler( - IFlightConnector flightConnector, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - TOGGLE_VALUE active, TOGGLE_VALUE? standby, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? avionicsVariable, - KnownEvents? toggle, KnownEvents? set) : + IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, SimVarManager simVarManager, + string active, string? standby, string? batteryVariable, string? avionicsVariable, + KnownEvents? toggle, KnownEvents? set) : base( - flightConnector, eventRegistrar, eventDispatcher, active, standby, batteryVariable, avionicsVariable, toggle, set, + eventRegistrar, eventDispatcher, simVarManager, active, standby, batteryVariable, avionicsVariable, toggle, set, "0100", "8888", "" ) @@ -26,7 +25,7 @@ protected override string AddDefaultPattern(string value) /// /// Convert from default MHz to kHz /// - protected override string FormatValueForDisplay(double value, TOGGLE_VALUE simvar) + protected override string FormatValueForDisplay(double value, SimVarRegistration simvar) { return ((int)Math.Round(value * 1000)).ToString(); } diff --git a/FlightStreamDeck.Logics/Actions/NavCom/BcdHandler.cs b/FlightStreamDeck.Logics/Actions/NavCom/BcdHandler.cs index 215d416..32ac6fa 100644 --- a/FlightStreamDeck.Logics/Actions/NavCom/BcdHandler.cs +++ b/FlightStreamDeck.Logics/Actions/NavCom/BcdHandler.cs @@ -5,11 +5,11 @@ namespace FlightStreamDeck.Logics.Actions.NavCom; public class BcdHandler : NavComHandler { public BcdHandler( - IFlightConnector flightConnector, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - TOGGLE_VALUE active, TOGGLE_VALUE? standby, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? avionicsVariable, + IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, SimVarManager simVarManager, + string active, string? standby, string? batteryVariable, string? avionicsVariable, KnownEvents? toggle, KnownEvents? set, string minPattern, string maxPattern, string mask) : - base(flightConnector, eventRegistrar, eventDispatcher, active, standby, batteryVariable, avionicsVariable, toggle, set, minPattern, maxPattern, mask) + base(eventRegistrar, eventDispatcher, simVarManager, active, standby, batteryVariable, avionicsVariable, toggle, set, minPattern, maxPattern, mask) { } diff --git a/FlightStreamDeck.Logics/Actions/NavCom/HzHandler.cs b/FlightStreamDeck.Logics/Actions/NavCom/HzHandler.cs index cf4be17..c90f0c8 100644 --- a/FlightStreamDeck.Logics/Actions/NavCom/HzHandler.cs +++ b/FlightStreamDeck.Logics/Actions/NavCom/HzHandler.cs @@ -5,11 +5,11 @@ namespace FlightStreamDeck.Logics.Actions.NavCom; public class HzHandler : NavComHandler { public HzHandler( - IFlightConnector flightConnector, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - TOGGLE_VALUE active, TOGGLE_VALUE? standby, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? avionicsVariable, + IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, SimVarManager simVarManager, + string active, string? standby, string? batteryVariable, string? avionicsVariable, KnownEvents? toggle, KnownEvents? set, string minPattern, string maxPattern, string mask) : - base(flightConnector, eventRegistrar, eventDispatcher, active, standby, batteryVariable, avionicsVariable, toggle, set, minPattern, maxPattern, mask) + base(eventRegistrar, eventDispatcher, simVarManager, active, standby, batteryVariable, avionicsVariable, toggle, set, minPattern, maxPattern, mask) { } diff --git a/FlightStreamDeck.Logics/Actions/NavCom/NavComHandler.cs b/FlightStreamDeck.Logics/Actions/NavCom/NavComHandler.cs index bca01fc..7ffbf92 100644 --- a/FlightStreamDeck.Logics/Actions/NavCom/NavComHandler.cs +++ b/FlightStreamDeck.Logics/Actions/NavCom/NavComHandler.cs @@ -1,17 +1,19 @@ using FlightStreamDeck.Core; +using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace FlightStreamDeck.Logics.Actions.NavCom; public abstract class NavComHandler { - private readonly IFlightConnector flightConnector; private readonly IEventRegistrar eventRegistrar; private readonly IEventDispatcher eventDispatcher; - private readonly TOGGLE_VALUE active; - private readonly TOGGLE_VALUE? standby; - private readonly TOGGLE_VALUE? batteryVariable; - private readonly TOGGLE_VALUE? avionicsVariable; + private readonly SimVarManager simVarManager; + private readonly SimVarRegistration active; + private readonly SimVarRegistration? standby; + private readonly SimVarRegistration? batteryVariable; + private readonly SimVarRegistration? avionicsVariable; private readonly KnownEvents? toggle; private readonly KnownEvents? set; @@ -22,13 +24,13 @@ public abstract class NavComHandler public bool IsSettable => set != null; public NavComHandler( - IFlightConnector flightConnector, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - TOGGLE_VALUE active, - TOGGLE_VALUE? standby, - TOGGLE_VALUE? batteryVariable, - TOGGLE_VALUE? avionicsVariable, + SimVarManager simVarManager, + string active, + string? standby, + string? batteryVariable, + string? avionicsVariable, KnownEvents? toggle, KnownEvents? set, string minPattern, @@ -36,13 +38,13 @@ public NavComHandler( string mask ) { - this.flightConnector = flightConnector; this.eventRegistrar = eventRegistrar; this.eventDispatcher = eventDispatcher; - this.active = active; - this.standby = standby; - this.batteryVariable = batteryVariable; - this.avionicsVariable = avionicsVariable; + this.simVarManager = simVarManager; + this.active = simVarManager.GetRegistration(active) ?? throw new ArgumentException("Invalid Active variable!", "active"); + this.standby = simVarManager.GetRegistration(standby); + this.batteryVariable = simVarManager.GetRegistration(batteryVariable); + this.avionicsVariable = simVarManager.GetRegistration(avionicsVariable); this.toggle = toggle; this.set = set; MinPattern = minPattern; @@ -58,12 +60,12 @@ public void RegisterSimValuesAndEvents() } eventRegistrar.RegisterEvent(set.ToString()); - flightConnector.RegisterSimValues(GetSimVars().ToArray()); + simVarManager.RegisterSimValues(GetSimVars().ToArray()); } public void DeRegisterSimValues() { - flightConnector.DeRegisterSimValues(GetSimVars().ToArray()); + simVarManager.DeRegisterSimValues(GetSimVars().ToArray()); } public async Task TriggerAsync(string value, bool swap) @@ -80,14 +82,25 @@ public async Task TriggerAsync(string value, bool swap) } } - public (string activeString, string standbyString, bool showActiveOnly, bool dependant) GetDisplayValues(Dictionary<(TOGGLE_VALUE variable, string? unit), double> genericValues) + public (string activeString, string standbyString, bool showActiveOnly, bool dependant) GetDisplayValues(Dictionary genericValues) { + bool TryGetValue([NotNullWhen(true)] SimVarRegistration? variable, out double value) + { + if (variable != null && genericValues.TryGetValue(variable, out var newValue)) + { + value = newValue; + return true; + } + value = 0; + return false; + } + bool dependant = true; - if (batteryVariable != null && genericValues.TryGetValue((batteryVariable.Value, null), out var batteryValue)) + if (TryGetValue(batteryVariable, out var batteryValue)) { dependant = dependant && batteryValue != 0; } - if (avionicsVariable != null && genericValues.TryGetValue((avionicsVariable.Value, null), out var avionicsValue)) + if (TryGetValue(avionicsVariable, out var avionicsValue)) { dependant = dependant && avionicsValue != 0; } @@ -96,13 +109,13 @@ public async Task TriggerAsync(string value, bool swap) var value2 = string.Empty; if (dependant) { - if (genericValues.TryGetValue((active, null), out var doubleValue1)) + if (TryGetValue(active, out var doubleValue1)) { value1 = FormatValueForDisplay(doubleValue1, active); } - if (standby != null && genericValues.TryGetValue((standby.Value, null), out var doubleValue2)) + if (TryGetValue(standby, out var doubleValue2)) { - value2 = FormatValueForDisplay(doubleValue2, standby.Value); + value2 = FormatValueForDisplay(doubleValue2, standby); } } return (value1, value2, standby == null, dependant); @@ -128,28 +141,28 @@ protected virtual string AddDefaultPattern(string value) protected abstract uint FormatValueForSimConnect(string value); - protected virtual string FormatValueForDisplay(double value, TOGGLE_VALUE simvar) + protected virtual string FormatValueForDisplay(double value, SimVarRegistration simvar) { - return value.ToString("F" + EventValueLibrary.GetDecimals(simvar)); + return value.ToString("F" + simvar.variableName.GetDecimals()); } - protected virtual List<(TOGGLE_VALUE variable, string? unit)> GetSimVars() + protected virtual List GetSimVars() { - var values = new List<(TOGGLE_VALUE variable, string? unit)> + var values = new List { - (active, null) + active }; if (standby != null) { - values.Add((standby.Value, null)); + values.Add(standby); } if (batteryVariable != null) { - values.Add((batteryVariable.Value, null)); + values.Add(batteryVariable); } if (avionicsVariable != null) { - values.Add((avionicsVariable.Value, null)); + values.Add(avionicsVariable); } return values; diff --git a/FlightStreamDeck.Logics/Actions/NavCom/XpdrHandler.cs b/FlightStreamDeck.Logics/Actions/NavCom/XpdrHandler.cs index ded6b13..ecc251f 100644 --- a/FlightStreamDeck.Logics/Actions/NavCom/XpdrHandler.cs +++ b/FlightStreamDeck.Logics/Actions/NavCom/XpdrHandler.cs @@ -1,15 +1,13 @@ -using FlightStreamDeck.Core; - -namespace FlightStreamDeck.Logics.Actions.NavCom; +namespace FlightStreamDeck.Logics.Actions.NavCom; internal class XpdrHandler : BcdHandler { public XpdrHandler( - IFlightConnector flightConnector, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - TOGGLE_VALUE active, TOGGLE_VALUE? standby, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? avionicsVariable, + IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, SimVarManager simVarManager, + string active, string? standby, string? batteryVariable, string? avionicsVariable, KnownEvents? toggle, KnownEvents? set, - string minPattern, string maxPattern, string mask) : - base(flightConnector, eventRegistrar, eventDispatcher, active, standby, batteryVariable, avionicsVariable, toggle, set, minPattern, maxPattern, mask) + string minPattern, string maxPattern, string mask) : + base(eventRegistrar, eventDispatcher, simVarManager, active, standby, batteryVariable, avionicsVariable, toggle, set, minPattern, maxPattern, mask) { } @@ -24,7 +22,7 @@ protected override uint FormatValueForSimConnect(string value) return data; } - protected override string FormatValueForDisplay(double value, TOGGLE_VALUE simvar) + protected override string FormatValueForDisplay(double value, SimVarRegistration simvar) { var stringValue = base.FormatValueForDisplay(value, simvar); if (stringValue != string.Empty) stringValue = stringValue.PadLeft(4, '0'); diff --git a/FlightStreamDeck.Logics/Actions/NavComAction.cs b/FlightStreamDeck.Logics/Actions/NavComAction.cs index 16ac408..3bb4bbe 100644 --- a/FlightStreamDeck.Logics/Actions/NavComAction.cs +++ b/FlightStreamDeck.Logics/Actions/NavComAction.cs @@ -1,5 +1,4 @@ -using FlightStreamDeck.Core; -using FlightStreamDeck.Logics.Actions.NavCom; +using FlightStreamDeck.Logics.Actions.NavCom; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using SharpDeck.Enums; @@ -37,7 +36,7 @@ public class NavComAction : BaseAction, EmbedLinkLogic.IAction private readonly IFlightConnector flightConnector; private readonly IEventRegistrar eventRegistrar; private readonly IEventDispatcher eventDispatcher; - private readonly EnumConverter enumConverter; + private readonly SimVarManager simVarManager; private readonly RegistrationParameters registrationParameters; private readonly Timer timer; @@ -59,7 +58,7 @@ public NavComAction( IFlightConnector flightConnector, IEventRegistrar eventRegistrar, IEventDispatcher eventDispatcher, - EnumConverter enumConverter, + SimVarManager simVarManager, RegistrationParameters registrationParameters ) { @@ -68,7 +67,7 @@ RegistrationParameters registrationParameters this.flightConnector = flightConnector; this.eventRegistrar = eventRegistrar; this.eventDispatcher = eventDispatcher; - this.enumConverter = enumConverter; + this.simVarManager = simVarManager; this.registrationParameters = registrationParameters; timer = new Timer { Interval = HOLD_DURATION_MILLISECONDS }; timer.Elapsed += Timer_Elapsed; @@ -191,8 +190,8 @@ public override Task InitializeSettingsAsync(NavComSettings? settings) SwitchTo( settings.Type, - enumConverter.GetVariableEnum(settings.BattMasterValue), - enumConverter.GetVariableEnum(settings.AvionicsValue) + settings.BattMasterValue, + settings.AvionicsValue ); return Task.CompletedTask; @@ -229,18 +228,18 @@ private async Task UpdateImage(bool dependant, string value1, string value2, boo private byte[]? GetImageBytes() => settings?.ImageBackground_base64 != null ? Convert.FromBase64String(settings.ImageBackground_base64) : null; - private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? avionicsVariable) + private void SwitchTo(string? type, string? batteryVariable, string? avionicsVariable) { handler?.DeRegisterSimValues(); switch (type) { case "NAV1": handler = new BcdHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.NAV_ACTIVE_FREQUENCY__1, - TOGGLE_VALUE.NAV_STANDBY_FREQUENCY__1, + simVarManager, + "NAV_ACTIVE_FREQUENCY__1", + "NAV_STANDBY_FREQUENCY__1", batteryVariable, avionicsVariable, KnownEvents.NAV1_RADIO_SWAP, @@ -252,11 +251,11 @@ private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? break; case "NAV2": handler = new BcdHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.NAV_ACTIVE_FREQUENCY__2, - TOGGLE_VALUE.NAV_STANDBY_FREQUENCY__2, + simVarManager, + "NAV_ACTIVE_FREQUENCY__2", + "NAV_STANDBY_FREQUENCY__2", batteryVariable, avionicsVariable, KnownEvents.NAV2_RADIO_SWAP, @@ -268,11 +267,11 @@ private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? break; case "COM1": handler = new HzHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.COM_ACTIVE_FREQUENCY__1, - TOGGLE_VALUE.COM_STANDBY_FREQUENCY__1, + simVarManager, + "COM_ACTIVE_FREQUENCY__1", + "COM_STANDBY_FREQUENCY__1", batteryVariable, avionicsVariable, KnownEvents.COM_STBY_RADIO_SWAP, @@ -284,11 +283,11 @@ private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? break; case "COM2": handler = new HzHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.COM_ACTIVE_FREQUENCY__2, - TOGGLE_VALUE.COM_STANDBY_FREQUENCY__2, + simVarManager, + "COM_ACTIVE_FREQUENCY__2", + "COM_STANDBY_FREQUENCY__2", batteryVariable, avionicsVariable, KnownEvents.COM2_RADIO_SWAP, @@ -300,10 +299,10 @@ private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? break; case "XPDR": handler = new XpdrHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.TRANSPONDER_CODE__1, + simVarManager, + "TRANSPONDER_CODE__1", null, batteryVariable, avionicsVariable, @@ -316,11 +315,11 @@ private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? break; case "ADF1": handler = new AdfHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.ADF_ACTIVE_FREQUENCY__1, - TOGGLE_VALUE.ADF_STANDBY_FREQUENCY__1, + simVarManager, + "ADF_ACTIVE_FREQUENCY__1", + "ADF_STANDBY_FREQUENCY__1", batteryVariable, avionicsVariable, KnownEvents.ADF1_RADIO_SWAP, @@ -329,11 +328,11 @@ private void SwitchTo(string? type, TOGGLE_VALUE? batteryVariable, TOGGLE_VALUE? break; case "ADF2": handler = new AdfHandler( - flightConnector, eventRegistrar, eventDispatcher, - TOGGLE_VALUE.ADF_ACTIVE_FREQUENCY__2, - TOGGLE_VALUE.ADF_STANDBY_FREQUENCY__2, + simVarManager, + "ADF_ACTIVE_FREQUENCY__2", + "ADF_STANDBY_FREQUENCY__2", batteryVariable, avionicsVariable, KnownEvents.ADF2_RADIO_SWAP, diff --git a/FlightStreamDeck.Logics/Actions/WindAction.cs b/FlightStreamDeck.Logics/Actions/WindAction.cs index ab88ba0..a259c34 100644 --- a/FlightStreamDeck.Logics/Actions/WindAction.cs +++ b/FlightStreamDeck.Logics/Actions/WindAction.cs @@ -1,6 +1,4 @@ -using FlightStreamDeck.Core; - -namespace FlightStreamDeck.Logics.Actions; +namespace FlightStreamDeck.Logics.Actions; [StreamDeckAction("tech.flighttracker.streamdeck.wind.direction")] public class WindAction : BaseAction @@ -8,21 +6,22 @@ public class WindAction : BaseAction private readonly ILogger logger; private readonly IFlightConnector flightConnector; private readonly IImageLogic imageLogic; + private readonly SimVarManager simVarManager; + private string windDirectionValue = "AMBIENT WIND DIRECTION"; + private string windVelocityValue = "AMBIENT WIND VELOCITY"; + private string headingValue = "PLANE HEADING DEGREES TRUE"; - private TOGGLE_VALUE windDirectionValue = TOGGLE_VALUE.AMBIENT_WIND_DIRECTION; - private TOGGLE_VALUE windVelocityValue = TOGGLE_VALUE.AMBIENT_WIND_VELOCITY; - private TOGGLE_VALUE headingValue = TOGGLE_VALUE.PLANE_HEADING_DEGREES_TRUE; - - private double currentWwindDirectionValue = 0; + private double currentWindDirectionValue = 0; private double currentWindVelocityValue = 0; private double currentHeadingValue = 0; private bool currentRelative = true; - public WindAction(ILogger logger, IFlightConnector flightConnector, IImageLogic imageLogic) + public WindAction(ILogger logger, IFlightConnector flightConnector, IImageLogic imageLogic, SimVarManager simVarManager) { this.logger = logger; this.flightConnector = flightConnector; this.imageLogic = imageLogic; + this.simVarManager = simVarManager; } protected override async Task OnWillAppear(ActionEventArgs args) @@ -36,21 +35,32 @@ protected override async Task OnWillAppear(ActionEventArgs ar private async void FlightConnector_GenericValuesUpdated(object? sender, ToggleValueUpdatedEventArgs e) { + bool TryGetNewValue(string variable, double currentValue, out double value) + { + if (e.GenericValueStatus.TryGetValue(new SimVarRegistration(variable, null), out var newValue) && currentValue != newValue) + { + value = newValue; + return true; + } + value = 0; + return false; + } + bool isUpdated = false; - if (e.GenericValueStatus.ContainsKey((windDirectionValue, null)) && currentWwindDirectionValue != e.GenericValueStatus[(windDirectionValue, null)]) + if (TryGetNewValue(windDirectionValue, currentWindDirectionValue, out var newDirection)) { - currentWwindDirectionValue = e.GenericValueStatus[(windDirectionValue, null)]; + currentWindDirectionValue = newDirection; isUpdated = true; } - if (e.GenericValueStatus.ContainsKey((headingValue, null)) && currentHeadingValue != e.GenericValueStatus[(headingValue, null)]) + if (TryGetNewValue(headingValue, currentHeadingValue, out var newHeading)) { - currentHeadingValue = e.GenericValueStatus[(headingValue, null)]; + currentHeadingValue = newHeading; isUpdated = true; } - if (e.GenericValueStatus.ContainsKey((windVelocityValue, null)) && currentWindVelocityValue != e.GenericValueStatus[(windVelocityValue, null)]) + if (TryGetNewValue(windVelocityValue, currentWindVelocityValue, out var newVelocity)) { - currentWindVelocityValue = e.GenericValueStatus[(windVelocityValue, null)]; + currentWindVelocityValue = newVelocity; isUpdated = true; } @@ -69,12 +79,12 @@ protected override Task OnWillDisappear(ActionEventArgs args) private void RegisterValues() { - flightConnector.RegisterSimValues((windDirectionValue, null), (windVelocityValue, null), (headingValue, null)); + simVarManager.RegisterSimValues(simVarManager.GetRegistration(windDirectionValue), simVarManager.GetRegistration(windVelocityValue), simVarManager.GetRegistration(headingValue)); } private void DeRegisterValues() { - flightConnector.DeRegisterSimValues((windDirectionValue, null), (windVelocityValue, null), (headingValue, null)); + simVarManager.DeRegisterSimValues(simVarManager.GetRegistration(windDirectionValue), simVarManager.GetRegistration(windVelocityValue), simVarManager.GetRegistration(headingValue)); } protected override Task OnKeyDown(ActionEventArgs args) @@ -86,6 +96,6 @@ protected override Task OnKeyDown(ActionEventArgs args) private async Task UpdateImage() { - await SetImageSafeAsync(imageLogic.GetWindImage(currentWwindDirectionValue, currentWindVelocityValue, currentHeadingValue, currentRelative)); + await SetImageSafeAsync(imageLogic.GetWindImage(currentWindDirectionValue, currentWindVelocityValue, currentHeadingValue, currentRelative)); } } diff --git a/FlightStreamDeck.Logics/Evaluators/ComparisonEvaluator.cs b/FlightStreamDeck.Logics/Evaluators/ComparisonEvaluator.cs index 533ea96..8713f0a 100644 --- a/FlightStreamDeck.Logics/Evaluators/ComparisonEvaluator.cs +++ b/FlightStreamDeck.Logics/Evaluators/ComparisonEvaluator.cs @@ -1,151 +1,68 @@ -using FlightStreamDeck.Core; -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -namespace FlightStreamDeck.Logics +namespace FlightStreamDeck.Logics; + +public class ComparisonEvaluator : IEvaluator { - public class ComparisonEvaluator : IEvaluator + public class Expression : IExpression { - public class Expression : IExpression + public Expression(SimVarRegistration? feedbackVariable, SimVarRegistration? feedbackComparisonVariable, string? feedbackComparisonStringValue, string feedbackComparisonOperator) { - public Expression(TOGGLE_VALUE? feedbackVariable, TOGGLE_VALUE? feedbackComparisonVariable, string? feedbackComparisonStringValue, string feedbackComparisonOperator) - { - FeedbackVariable = feedbackVariable; - FeedbackComparisonVariable = feedbackComparisonVariable; - FeedbackComparisonStringValue = feedbackComparisonStringValue; - FeedbackComparisonOperator = feedbackComparisonOperator; - } - - public TOGGLE_VALUE? FeedbackVariable { get; } - public TOGGLE_VALUE? FeedbackComparisonVariable { get; } - public string? FeedbackComparisonStringValue { get; } - public string FeedbackComparisonOperator { get; } - - public double? PreviousFeedbackValue { get; set; } - public double? PreviousFeedbackComparisonValue { get; set; } - public bool PreviousResult { get; set; } + FeedbackVariable = feedbackVariable; + FeedbackComparisonVariable = feedbackComparisonVariable; + FeedbackComparisonStringValue = feedbackComparisonStringValue; + FeedbackComparisonOperator = feedbackComparisonOperator; } - private readonly EnumConverter enumConverter; + public SimVarRegistration? FeedbackVariable { get; } + public SimVarRegistration? FeedbackComparisonVariable { get; } + public string? FeedbackComparisonStringValue { get; } + public string FeedbackComparisonOperator { get; } - public ComparisonEvaluator(EnumConverter enumConverter) - { - this.enumConverter = enumConverter; - } + public double? PreviousFeedbackValue { get; set; } + public double? PreviousFeedbackComparisonValue { get; set; } + public bool PreviousResult { get; set; } - public (IEnumerable, IExpression) Parse(string feedbackValue) + public bool Evaluate(Dictionary values) { - var (feedbackVariable, feedbackComparisonVariable, feedbackComparisonStringValue, feedbackComparisonOperator) = - GetValueValueComparison(feedbackValue); - - var list = new List(); - if (feedbackVariable != null) list.Add(feedbackVariable.Value); - if (feedbackComparisonVariable != null) list.Add(feedbackComparisonVariable.Value); - return (list, new Expression(feedbackVariable, feedbackComparisonVariable, feedbackComparisonStringValue, feedbackComparisonOperator)); - } + double? feedbackValue = null; + double? comparisonFeedbackValue = null; - public bool Evaluate(Dictionary values, IExpression expression) - { - if (expression is Expression compareExpression) + if (FeedbackVariable != null && values.ContainsKey(FeedbackVariable)) { - double? feedbackValue = null; - double? comparisonFeedbackValue = null; - - if (compareExpression.FeedbackVariable.HasValue && values.ContainsKey(compareExpression.FeedbackVariable.Value)) - { - feedbackValue = values[compareExpression.FeedbackVariable.Value]; - } - - if (compareExpression.FeedbackComparisonVariable.HasValue && values.ContainsKey(compareExpression.FeedbackComparisonVariable.Value)) - { - // Compare to a variable - comparisonFeedbackValue = values[compareExpression.FeedbackComparisonVariable.Value]; - } - else - { - // Compare to a number - if (double.TryParse(compareExpression.FeedbackComparisonStringValue, out var number)) - { - comparisonFeedbackValue = number; - } - } - - if (feedbackValue == compareExpression.PreviousFeedbackValue - && comparisonFeedbackValue == compareExpression.PreviousFeedbackComparisonValue) - { - return compareExpression.PreviousResult; - } - - compareExpression.PreviousFeedbackValue = feedbackValue; - compareExpression.PreviousFeedbackComparisonValue = comparisonFeedbackValue; - - if (feedbackValue.HasValue && comparisonFeedbackValue.HasValue) - { - compareExpression.PreviousResult = CompareValues(feedbackValue.Value, comparisonFeedbackValue.Value, compareExpression.FeedbackComparisonOperator); - return compareExpression.PreviousResult; - } - return false; + feedbackValue = values[FeedbackVariable]; } - throw new ArgumentException($"{nameof(expression)} has to be of type {typeof(Expression).FullName}!", nameof(expression)); - } - - public const string OperatorEquals = "=="; - public const string OperatorTruncatedEquals = "~"; - public const string OperatorNotEquals = "!="; - public const string OperatorGreaterOrEquals = ">="; - public const string OperatorLessOrEquals = "<="; - public const string OperatorGreater = ">"; - public const string OperatorLess = "<"; - - public static readonly List AllowedComparisons = new List { - OperatorEquals, - OperatorTruncatedEquals, - OperatorNotEquals, - OperatorGreaterOrEquals, - OperatorLessOrEquals, - OperatorGreater, - OperatorLess - }; - - public (TOGGLE_VALUE? leftEnum, TOGGLE_VALUE? rightEnum, string? rightString, string comparisionOperator) GetValueValueComparison(string value) - { - if (string.IsNullOrEmpty(value)) return (null, null, string.Empty, string.Empty); - TOGGLE_VALUE? result = enumConverter.GetVariableEnum(value); - - if (result != null) + if (FeedbackComparisonVariable != null && values.ContainsKey(FeedbackComparisonVariable)) { - // Old behavior - return (result, null, "0", "!="); + // Compare to a variable + comparisonFeedbackValue = values[FeedbackComparisonVariable]; } else { - var comparisonAttempt = AllowedComparisons.Where((string allowedComp) => value.Contains(allowedComp)); - - if (comparisonAttempt.Any()) + // Compare to a number + if (double.TryParse(FeedbackComparisonStringValue, out var number)) { - var splitInput = value.Split(comparisonAttempt.First()); - var leftSideEnum = enumConverter.GetVariableEnum(splitInput.First()); - var rightSideEnum = int.TryParse(splitInput.Last(), out int temp) ? null : enumConverter.GetVariableEnum(splitInput.Last()); - string? rightSideString = rightSideEnum == null ? splitInput.Last() : null; - - if ( - (leftSideEnum != null && rightSideEnum != null && leftSideEnum != rightSideEnum) || - (leftSideEnum != null && !string.IsNullOrEmpty(rightSideString)) - ) - { - return ( - leftSideEnum, - rightSideEnum, - rightSideString, - comparisonAttempt.First() - ); - } + comparisonFeedbackValue = number; } + } + + if (feedbackValue == PreviousFeedbackValue + && comparisonFeedbackValue == PreviousFeedbackComparisonValue) + { + return PreviousResult; + } - return (null, null, string.Empty, string.Empty); + PreviousFeedbackValue = feedbackValue; + PreviousFeedbackComparisonValue = comparisonFeedbackValue; + + if (feedbackValue.HasValue && comparisonFeedbackValue.HasValue) + { + PreviousResult = CompareValues(feedbackValue.Value, comparisonFeedbackValue.Value, FeedbackComparisonOperator); + return PreviousResult; } + return false; } public bool CompareValues(double currentValue, double comparisonValue, string operatorValue) @@ -180,4 +97,83 @@ public bool CompareValues(double currentValue, double comparisonValue, string op return output; } } + + public const string OperatorEquals = "=="; + public const string OperatorTruncatedEquals = "~"; + public const string OperatorNotEquals = "!="; + public const string OperatorGreaterOrEquals = ">="; + public const string OperatorLessOrEquals = "<="; + public const string OperatorGreater = ">"; + public const string OperatorLess = "<"; + + public static readonly List AllowedComparisons = new List { + OperatorEquals, + OperatorTruncatedEquals, + OperatorNotEquals, + OperatorGreaterOrEquals, + OperatorLessOrEquals, + OperatorGreater, + OperatorLess + }; + + private readonly SimVarManager simVarManager; + + public ComparisonEvaluator(SimVarManager simVarManager) + { + this.simVarManager = simVarManager; + } + + public (IEnumerable, IExpression) Parse(string feedbackValue) + { + var (feedbackVariable, feedbackComparisonVariable, feedbackComparisonStringValue, feedbackComparisonOperator) = + GetValueValueComparison(feedbackValue); + + var list = new List(); + if (feedbackVariable != null) list.Add(feedbackVariable); + if (feedbackComparisonVariable != null) list.Add(feedbackComparisonVariable); + return (list, new Expression(feedbackVariable, feedbackComparisonVariable, feedbackComparisonStringValue, feedbackComparisonOperator)); + } + + private (SimVarRegistration? leftEnum, SimVarRegistration? rightEnum, string? rightString, string comparisionOperator) GetValueValueComparison(string value) + { + if (string.IsNullOrEmpty(value)) return (null, null, string.Empty, string.Empty); + + var comparisonFound = AllowedComparisons.FirstOrDefault(value.Contains); + + if (comparisonFound != null) + { + var splitInput = value.Split(comparisonFound); + + if (splitInput is [var left, var right]) + { + var leftSideEnum = simVarManager.GetRegistration(left, null); + var rightSideEnum = int.TryParse(right, out int temp) ? null : simVarManager.GetRegistration(right, null); + var rightSideString = rightSideEnum == null ? right : null; + + if ( + (leftSideEnum != null && rightSideEnum != null && leftSideEnum != rightSideEnum) || + (leftSideEnum != null && !string.IsNullOrEmpty(rightSideString)) + ) + { + return ( + leftSideEnum, + rightSideEnum, + rightSideString, + comparisonFound + ); + } + } + } + else + { + // Old behavior + var result = simVarManager.GetRegistration(value, null); + if (result != null) + { + return (result, null, "0", "!="); + } + } + + return (null, null, string.Empty, string.Empty); + } } diff --git a/FlightStreamDeck.Logics/Evaluators/IEvaluator.cs b/FlightStreamDeck.Logics/Evaluators/IEvaluator.cs index d239336..8dd9877 100644 --- a/FlightStreamDeck.Logics/Evaluators/IEvaluator.cs +++ b/FlightStreamDeck.Logics/Evaluators/IEvaluator.cs @@ -1,16 +1,13 @@ -using FlightStreamDeck.Core; -using System.Collections.Generic; +using System.Collections.Generic; -namespace FlightStreamDeck.Logics -{ - public interface IExpression - { +namespace FlightStreamDeck.Logics; - } +public interface IExpression +{ + bool Evaluate(Dictionary values); +} - public interface IEvaluator - { - (IEnumerable, IExpression?) Parse(string feedbackValue); - bool Evaluate(Dictionary values, IExpression expression); - } +public interface IEvaluator +{ + (IEnumerable, IExpression?) Parse(string feedbackValue); } diff --git a/FlightStreamDeck.Logics/Evaluators/SimpleEvaluator.cs b/FlightStreamDeck.Logics/Evaluators/SimpleEvaluator.cs deleted file mode 100644 index 636ec5b..0000000 --- a/FlightStreamDeck.Logics/Evaluators/SimpleEvaluator.cs +++ /dev/null @@ -1,49 +0,0 @@ -using FlightStreamDeck.Core; -using System; -using System.Collections.Generic; - -namespace FlightStreamDeck.Logics -{ - /// - /// This evaluator assumes feedbackValue contains only a single SimConnect variable - /// - public class SimpleEvaluator : IEvaluator - { - public class Expression : IExpression - { - public Expression(TOGGLE_VALUE variable) - { - Variable = variable; - } - public TOGGLE_VALUE Variable { get; } - } - - private readonly EnumConverter enumConverter; - - public SimpleEvaluator(EnumConverter enumConverter) - { - this.enumConverter = enumConverter; - } - - public (IEnumerable, IExpression?) Parse(string feedbackValue) - { - var variable = enumConverter.GetVariableEnum(feedbackValue); - if (variable == null) return (new List(), null); - - return (new List { variable.Value }, new Expression(variable.Value)); - } - - public bool Evaluate(Dictionary values, IExpression expression) - { - if (expression is Expression simpleExpression) - { - if (values.ContainsKey(simpleExpression.Variable)) - { - return values[simpleExpression.Variable] != 0; - } - return false; - } - throw new ArgumentException($"{nameof(expression)} has to be of type {typeof(Expression).FullName}!", nameof(expression)); - } - } -} diff --git a/FlightStreamDeck.Logics/IFlightConnector.cs b/FlightStreamDeck.Logics/IFlightConnector.cs index 337bd21..6d74caf 100644 --- a/FlightStreamDeck.Logics/IFlightConnector.cs +++ b/FlightStreamDeck.Logics/IFlightConnector.cs @@ -1,149 +1,152 @@ -using FlightStreamDeck.Core; -using System; +using System; using System.Collections.Generic; -namespace FlightStreamDeck.Logics +namespace FlightStreamDeck.Logics; + +public interface IFlightConnector { - public interface IFlightConnector - { - event EventHandler AircraftStatusUpdated; - event EventHandler GenericValuesUpdated; - event EventHandler InvalidEventRegistered; - - void ApOff(); - void ApOn(); - void ApToggle(); - void ApHdgToggle(); - void ApNavToggle(); - void ApAprToggle(); - void ApAltToggle(); - void ApVsToggle(); - void ApFlcOn(); - void ApFlcOff(); - - /// In Degree - void ApHdgSet(uint heading); - void ApHdgInc(); - void ApHdgDec(); - - /// In Feet - void ApAltSet(uint altitude); - void ApAltInc(); - void ApAltDec(); - - /// In Feet per min - void ApVsSet(uint speed); - - void ApAirSpeedSet(uint speed); - void ApAirSpeedInc(); - void ApAirSpeedDec(); - void QNHSet(uint qnh); - void QNHInc(); - void QNHDec(); - - void AvMasterToggle(uint state); - - void Trigger(Enum eventEnum, uint data); - - uint? RegisterToggleEvent(Enum eventEnum, string eventName); - - void RegisterSimValues(params (TOGGLE_VALUE variables, string? unit)[] simValues); - void DeRegisterSimValues(params (TOGGLE_VALUE variables, string? unit)[] simValues); - } + event EventHandler AircraftStatusUpdated; + event EventHandler GenericValuesUpdated; + event EventHandler InvalidEventRegistered; + + void ApOff(); + void ApOn(); + void ApToggle(); + void ApHdgToggle(); + void ApNavToggle(); + void ApAprToggle(); + void ApAltToggle(); + void ApVsToggle(); + void ApFlcOn(); + void ApFlcOff(); + + /// In Degree + void ApHdgSet(uint heading); + void ApHdgInc(); + void ApHdgDec(); + + /// In Feet + void ApAltSet(uint altitude); + void ApAltInc(); + void ApAltDec(); + + /// In Feet per min + void ApVsSet(uint speed); + + void ApAirSpeedSet(uint speed); + void ApAirSpeedInc(); + void ApAirSpeedDec(); + void QNHSet(uint qnh); + void QNHInc(); + void QNHDec(); + + void AvMasterToggle(uint state); + + void Trigger(Enum eventEnum, uint data); + + uint? RegisterToggleEvent(Enum eventEnum, string eventName); + + void RegisterSimValues(IEnumerable simValues); + void DeRegisterSimValues(IEnumerable simValues); +} - public class AircraftStatusUpdatedEventArgs : EventArgs +public class AircraftStatusUpdatedEventArgs : EventArgs +{ + public AircraftStatusUpdatedEventArgs(AircraftStatus aircraftStatus) { - public AircraftStatusUpdatedEventArgs(AircraftStatus aircraftStatus) - { - AircraftStatus = aircraftStatus; - } - - public AircraftStatus AircraftStatus { get; } + AircraftStatus = aircraftStatus; } - public class ToggleValueUpdatedEventArgs : EventArgs - { - public ToggleValueUpdatedEventArgs(Dictionary<(TOGGLE_VALUE variable, string? unit), double> genericValueStatus) - { - GenericValueStatus = genericValueStatus; - } + public AircraftStatus AircraftStatus { get; } +} - public Dictionary<(TOGGLE_VALUE variable, string? unit), double> GenericValueStatus { get; } +public class ToggleValueUpdatedEventArgs : EventArgs +{ + public ToggleValueUpdatedEventArgs(Dictionary genericValueStatus) + { + GenericValueStatus = genericValueStatus; } - public class InvalidEventRegisteredEventArgs : EventArgs - { - public InvalidEventRegisteredEventArgs(uint sendID) - { - SendID = sendID; - } + public Dictionary GenericValueStatus { get; } +} - public uint SendID { get; } +public class InvalidEventRegisteredEventArgs : EventArgs +{ + public InvalidEventRegisteredEventArgs(uint sendID) + { + SendID = sendID; } - public class AircraftStatus - { - public string Callsign { get; set; } + public uint SendID { get; } +} - public double SimTime { get; set; } - public int? LocalTime { get; set; } - public int? ZuluTime { get; set; } - public long? AbsoluteTime { get; set; } +public class AircraftStatus +{ + public string Callsign { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } - public double Altitude { get; set; } - public double AltitudeAboveGround { get; set; } + public double SimTime { get; set; } + public int? LocalTime { get; set; } + public int? ZuluTime { get; set; } + public long? AbsoluteTime { get; set; } - public double Heading { get; set; } - public double TrueHeading { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } + public double Altitude { get; set; } + public double AltitudeAboveGround { get; set; } - public double WindDirection { get; set; } - public double WindVelocity { get; set; } + public double Heading { get; set; } + public double TrueHeading { get; set; } - public double GroundSpeed { get; set; } - public double IndicatedAirSpeed { get; set; } - public double VerticalSpeed { get; set; } + public double WindDirection { get; set; } + public double WindVelocity { get; set; } - public double FuelTotalQuantity { get; set; } + public double GroundSpeed { get; set; } + public double IndicatedAirSpeed { get; set; } + public double VerticalSpeed { get; set; } - public double Pitch { get; set; } - public double Bank { get; set; } + public double FuelTotalQuantity { get; set; } - public bool IsOnGround { get; set; } - public bool StallWarning { get; set; } - public bool OverspeedWarning { get; set; } + public double Pitch { get; set; } + public double Bank { get; set; } - public bool IsAutopilotOn { get; set; } + public bool IsOnGround { get; set; } + public bool StallWarning { get; set; } + public bool OverspeedWarning { get; set; } - public bool IsApHdgOn { get; set; } - public int ApHeading { get; set; } + public bool IsAutopilotOn { get; set; } - public bool IsApNavOn { get; set; } + public bool IsApHdgOn { get; set; } + public int ApHeading { get; set; } - public bool IsApAprOn { get; set; } + public bool IsApNavOn { get; set; } - public bool IsApAltOn { get; set; } - public int ApAltitude { get; set; } + public bool IsApAprOn { get; set; } - public bool IsApVsOn { get; set; } - public int ApVs { get; set; } + public bool IsApAltOn { get; set; } + public int ApAltitude { get; set; } - public bool IsApFlcOn { get; set; } - public int ApAirspeed { get; set; } + public bool IsApVsOn { get; set; } + public int ApVs { get; set; } - public int QNHMbar { get; set; } + public bool IsApFlcOn { get; set; } + public int ApAirspeed { get; set; } - public string Transponder { get; set; } - public int FreqencyCom1 { get; set; } - public int FreqencyCom2 { get; set; } - public bool IsAvMasterOn { get; set; } - public double Nav1OBS { get; set; } - public double Nav2OBS { get; set; } - public double ADFCard { get; set; } - public int ADFActiveFrequency1 { get; set; } - public int ADFStandbyFrequency1 { get; set; } - public int ADFActiveFrequency2 { get; set; } - public int ADFStandbyFrequency2 { get; set; } - } + public int QNHMbar { get; set; } + + public string Transponder { get; set; } + public int FreqencyCom1 { get; set; } + public int FreqencyCom2 { get; set; } + public bool IsAvMasterOn { get; set; } + public double Nav1OBS { get; set; } + public double Nav2OBS { get; set; } + public double ADFCard { get; set; } + public int ADFActiveFrequency1 { get; set; } + public int ADFStandbyFrequency1 { get; set; } + public int ADFActiveFrequency2 { get; set; } + public int ADFStandbyFrequency2 { get; set; } } + +public record SimVarRegistration( + string variableName, + string? variableUnit +); \ No newline at end of file diff --git a/FlightStreamDeck.Logics/ImageLogic.cs b/FlightStreamDeck.Logics/ImageLogic.cs index f992d8d..78cea2d 100644 --- a/FlightStreamDeck.Logics/ImageLogic.cs +++ b/FlightStreamDeck.Logics/ImageLogic.cs @@ -7,446 +7,445 @@ using System; using System.IO; -namespace FlightStreamDeck.Logics +namespace FlightStreamDeck.Logics; + +public interface IImageLogic { - public interface IImageLogic - { - string GetImage(string text, bool active, string? value = null, int? fontSize = null, string? imageOnFilePath = null, byte[]? imageOnBytes = null, string? imageOffFilePath = null, byte[]? imageOffBytes = null); - string GetNumberImage(int number); - string GetNavComImage(string type, bool dependant, string value1, string value2, bool showMainOnly = false, string? imageOnFilePath = null, byte[]? imageOnBytes = null); - public string GetHorizonImage(double pitchInDegrees, double rollInDegrees, double headingInDegrees); - public string GetGenericGaugeImage(string text, double value, double min, double max, int? fontSize, string valueFormat, string? subValueText = null); - public string GetCustomGaugeImage(string textTop, string textBottom, double valueTop, double valueBottom, double min, double max, string valueFormat, bool horizontal, string[] chartSplits, int chartWidth, float chevronSize, bool absoluteValueText, bool hideHeaderTop, bool hideHeaderBottom); - public string GetWindImage(double windDirectionInDegrees, double windVelocity, double headingInDegrees, bool relative); - } + string GetImage(string text, bool active, string? value = null, int? fontSize = null, string? imageOnFilePath = null, byte[]? imageOnBytes = null, string? imageOffFilePath = null, byte[]? imageOffBytes = null); + string GetNumberImage(int number); + string GetNavComImage(string type, bool dependant, string value1, string value2, bool showMainOnly = false, string? imageOnFilePath = null, byte[]? imageOnBytes = null); + public string GetHorizonImage(double pitchInDegrees, double rollInDegrees); + public string GetGenericGaugeImage(string text, double value, double min, double max, int? fontSize, string valueFormat, string? subValueText = null); + public string GetCustomGaugeImage(string textTop, string textBottom, double valueTop, double valueBottom, double min, double max, string valueFormat, bool horizontal, string[] chartSplits, int chartWidth, float chevronSize, bool absoluteValueText, bool hideHeaderTop, bool hideHeaderBottom); + public string GetWindImage(double windDirectionInDegrees, double windVelocity, double headingInDegrees, bool relative); +} - public class ImageLogic : IImageLogic +public class ImageLogic : IImageLogic +{ + readonly Image defaultBackground = Image.Load("Images/button.png"); + readonly Image defaultActiveBackground = Image.Load("Images/button_active.png"); + readonly Image horizon = Image.Load("Images/horizon.png"); + readonly Image gaugeImage = Image.Load("Images/gauge.png"); + readonly Image windImage = Image.Load("Images/wind.png"); + + private const int WIDTH = 72; + private const int HALF_WIDTH = 36; + + /// + /// NOTE: either filePath or bytes should be set at the same time + /// + /// Base64 image data + public string GetImage(string text, bool active, string? value = null, + int? fontSize = null, + string? imageOnFilePath = null, byte[]? imageOnBytes = null, + string? imageOffFilePath = null, byte[]? imageOffBytes = null) { - readonly Image defaultBackground = Image.Load("Images/button.png"); - readonly Image defaultActiveBackground = Image.Load("Images/button_active.png"); - readonly Image horizon = Image.Load("Images/horizon.png"); - readonly Image gaugeImage = Image.Load("Images/gauge.png"); - readonly Image windImage = Image.Load("Images/wind.png"); - - private const int WIDTH = 72; - private const int HALF_WIDTH = 36; - - /// - /// NOTE: either filePath or bytes should be set at the same time - /// - /// Base64 image data - public string GetImage(string text, bool active, string? value = null, - int? fontSize = null, - string? imageOnFilePath = null, byte[]? imageOnBytes = null, - string? imageOffFilePath = null, byte[]? imageOffBytes = null) + var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); + var valueFont = SystemFonts.CreateFont("Arial", fontSize ?? 15, FontStyle.Regular); + + // Note: logic to choose with image to show + // 1. If user did not select custom images, the active image (with light) is used + // only when Feedback value is true AND Display value is empty. + // 2. If user select custom images (esp Active one), the custom Active image is used based on Feedback value + // ignoring Display value. + using var img = active ? + GetBackgroundImage(imageOnBytes, imageOnFilePath, () => (string.IsNullOrEmpty(value) ? defaultActiveBackground : defaultBackground).Clone(_ => { })) : + GetBackgroundImage(imageOffBytes, imageOffFilePath, () => defaultBackground.Clone(_ => { })); + + img.Mutate(ctx => { - var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); - var valueFont = SystemFonts.CreateFont("Arial", fontSize ?? 15, FontStyle.Regular); - - // Note: logic to choose with image to show - // 1. If user did not select custom images, the active image (with light) is used - // only when Feedback value is true AND Display value is empty. - // 2. If user select custom images (esp Active one), the custom Active image is used based on Feedback value - // ignoring Display value. - using var img = active ? - GetBackgroundImage(imageOnBytes, imageOnFilePath, () => (string.IsNullOrEmpty(value) ? defaultActiveBackground : defaultBackground).Clone(_ => { })) : - GetBackgroundImage(imageOffBytes, imageOffFilePath, () => defaultBackground.Clone(_ => { })); - - img.Mutate(ctx => - { - ctx.Resize(WIDTH, WIDTH); // Force image to rescale to our button size, otherwise text gets super small if it is bigger. + ctx.Resize(WIDTH, WIDTH); // Force image to rescale to our button size, otherwise text gets super small if it is bigger. - var imgSize = ctx.GetCurrentSize(); + var imgSize = ctx.GetCurrentSize(); - // Calculate scaling for header - var smallerDim = imgSize.Width < imgSize.Height ? imgSize.Width : imgSize.Height; - var scale = 1f; - if (smallerDim != WIDTH) - { - scale = (float)smallerDim / WIDTH; - font = new Font(font, font.Size * scale); - valueFont = new Font(valueFont, valueFont.Size * scale); - } + // Calculate scaling for header + var smallerDim = imgSize.Width < imgSize.Height ? imgSize.Width : imgSize.Height; + var scale = 1f; + if (smallerDim != WIDTH) + { + scale = (float)smallerDim / WIDTH; + font = new Font(font, font.Size * scale); + valueFont = new Font(valueFont, valueFont.Size * scale); + } - if (!string.IsNullOrWhiteSpace(text)) - { - var size = TextMeasurer.Measure(text, new TextOptions(font)); - ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 4)); - } + if (!string.IsNullOrWhiteSpace(text)) + { + var size = TextMeasurer.Measure(text, new TextOptions(font)); + ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 4)); + } - if (!string.IsNullOrEmpty(value)) - { - var size = TextMeasurer.Measure(value, new TextOptions(valueFont)); - ctx.DrawText(value, valueFont, active ? Color.Yellow : Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, 64 * scale - size.Height)); - } - }); + if (!string.IsNullOrEmpty(value)) + { + var size = TextMeasurer.Measure(value, new TextOptions(valueFont)); + ctx.DrawText(value, valueFont, active ? Color.Yellow : Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, 64 * scale - size.Height)); + } + }); - return ToBase64PNG(img); - } + return ToBase64PNG(img); + } + + /// Base64 image data + public string GetNumberImage(int number) + { + var font = SystemFonts.CreateFont("Arial", 20, FontStyle.Bold); - /// Base64 image data - public string GetNumberImage(int number) + var text = number.ToString(); + using var img = defaultBackground.Clone(ctx => { - var font = SystemFonts.CreateFont("Arial", 20, FontStyle.Bold); + var imgSize = ctx.GetCurrentSize(); + var size = TextMeasurer.Measure(text, new TextOptions(font)); + ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 2 - size.Height / 2)); + }); - var text = number.ToString(); - using var img = defaultBackground.Clone(ctx => - { - var imgSize = ctx.GetCurrentSize(); - var size = TextMeasurer.Measure(text, new TextOptions(font)); - ctx.DrawText(text, font, Color.White, new PointF(imgSize.Width / 2 - size.Width / 2, imgSize.Height / 2 - size.Height / 2)); - }); + return ToBase64PNG(img); + } - return ToBase64PNG(img); - } + public string GetNavComImage(string type, bool dependant, string value1, string value2, bool showMainOnly = false, string? imageFilePath = null, byte[]? imageBytes = null) + { + var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); + var valueFont = SystemFonts.CreateFont("Arial", showMainOnly ? 26 : 15, FontStyle.Regular); - public string GetNavComImage(string type, bool dependant, string value1, string value2, bool showMainOnly = false, string? imageFilePath = null, byte[]? imageBytes = null) + using var img = GetBackgroundImage(imageBytes, imageFilePath, () => defaultBackground.Clone(_ => { })); + + img.Mutate(ctx => { - var font = SystemFonts.CreateFont("Arial", 17, FontStyle.Regular); - var valueFont = SystemFonts.CreateFont("Arial", showMainOnly ? 26 : 15, FontStyle.Regular); + ctx.Resize(WIDTH, WIDTH); // Force image to rescale to our button size, otherwise text gets super small if it is bigger. - using var img = GetBackgroundImage(imageBytes, imageFilePath, () => defaultBackground.Clone(_ => { })); + var imgSize = ctx.GetCurrentSize(); - img.Mutate(ctx => + if (!string.IsNullOrWhiteSpace(type)) { - ctx.Resize(WIDTH, WIDTH); // Force image to rescale to our button size, otherwise text gets super small if it is bigger. - - var imgSize = ctx.GetCurrentSize(); + var size = TextMeasurer.Measure(type, new TextOptions(font)); + Color displayColor = dependant ? Color.White : Color.LightGray; + ctx.DrawText(type, font, displayColor, new PointF(imgSize.Width / 2 - size.Width / 2, showMainOnly ? imgSize.Height / 4 : imgSize.Height / 6)); + } - if (!string.IsNullOrWhiteSpace(type)) - { - var size = TextMeasurer.Measure(type, new TextOptions(font)); - Color displayColor = dependant ? Color.White : Color.LightGray; - ctx.DrawText(type, font, displayColor, new PointF(imgSize.Width / 2 - size.Width / 2, showMainOnly ? imgSize.Height / 4 : imgSize.Height / 6)); - } + if (!string.IsNullOrWhiteSpace(value1)) + { + var size1 = TextMeasurer.Measure(value1, new TextOptions(valueFont)); + Color displayColor = dependant ? Color.Yellow : Color.LightGray; + ctx.DrawText(value1, valueFont, displayColor, new PointF(imgSize.Width / 2 - size1.Width / 2, showMainOnly ? (imgSize.Height / 2) : (imgSize.Height / 6 + imgSize.Height / 4))); + } + if (!string.IsNullOrWhiteSpace(value2) && !showMainOnly) + { + var size2 = TextMeasurer.Measure(value2, new TextOptions(valueFont)); + Color displayColor = dependant ? Color.White : Color.LightGray; + ctx.DrawText(value2, valueFont, displayColor, new PointF(imgSize.Width / 2 - size2.Width / 2, imgSize.Height / 6 + imgSize.Height / 4 + size2.Height)); + } + }); - if (!string.IsNullOrWhiteSpace(value1)) - { - var size1 = TextMeasurer.Measure(value1, new TextOptions(valueFont)); - Color displayColor = dependant ? Color.Yellow : Color.LightGray; - ctx.DrawText(value1, valueFont, displayColor, new PointF(imgSize.Width / 2 - size1.Width / 2, showMainOnly ? (imgSize.Height / 2) : (imgSize.Height / 6 + imgSize.Height / 4))); - } - if (!string.IsNullOrWhiteSpace(value2) && !showMainOnly) - { - var size2 = TextMeasurer.Measure(value2, new TextOptions(valueFont)); - Color displayColor = dependant ? Color.White : Color.LightGray; - ctx.DrawText(value2, valueFont, displayColor, new PointF(imgSize.Width / 2 - size2.Width / 2, imgSize.Height / 6 + imgSize.Height / 4 + size2.Height)); - } - }); + return ToBase64PNG(img); + } - return ToBase64PNG(img); - } + public string GetHorizonImage(double pitchInDegrees, double rollInDegrees) + { + //var font = SystemFonts.CreateFont("Arial", 10, FontStyle.Regular); + //var valueFont = SystemFonts.CreateFont("Arial", 12, FontStyle.Regular); + var pen = new Pen(Color.Yellow, 3); - public string GetHorizonImage(double pitchInDegrees, double rollInDegrees, double headingInDegrees) + using var shiftedRolledHorizon = new Image(105, 105); + shiftedRolledHorizon.Mutate(ctx => + { + var size = horizon.Size(); + ctx.DrawImage(horizon, new Point( + (int)Math.Round((float)-size.Width / 2 + 52), + Math.Clamp((int)Math.Round((float)-size.Height / 2 + 52 - (pitchInDegrees * 2)), -size.Height + 50, 55) + ), new GraphicsOptions()); + ctx.Rotate((float)rollInDegrees); + }); + + using var img = new Image(WIDTH, WIDTH); + img.Mutate(ctx => { - //var font = SystemFonts.CreateFont("Arial", 10, FontStyle.Regular); - //var valueFont = SystemFonts.CreateFont("Arial", 12, FontStyle.Regular); - var pen = new Pen(Color.Yellow, 3); + var size = shiftedRolledHorizon.Size(); + ctx.DrawImage(shiftedRolledHorizon, new Point( + (int)Math.Round((float)-size.Width / 2 + HALF_WIDTH), + (int)Math.Round((float)-size.Height / 2 + HALF_WIDTH) + ), new GraphicsOptions()); + + // Draw bug + PointF[] leftLine = { new PointF(6, 36), new PointF(26, 36) }; + PointF[] rightLine = { new PointF(46, 36), new PointF(66, 36) }; + PointF[] bottomLine = { new PointF(36, 41), new PointF(36, 51) }; + ctx.DrawLines(pen, leftLine); + ctx.DrawLines(pen, rightLine); + ctx.DrawLines(pen, bottomLine); + }); + + return ToBase64PNG(img); + } - using var shiftedRolledHorizon = new Image(105, 105); - shiftedRolledHorizon.Mutate(ctx => - { - var size = horizon.Size(); - ctx.DrawImage(horizon, new Point( - (int)Math.Round((float)-size.Width / 2 + 52), - Math.Clamp((int)Math.Round((float)-size.Height / 2 + 52 - (pitchInDegrees * 2)), -size.Height + 50, 55) - ), new GraphicsOptions()); - ctx.Rotate((float)rollInDegrees); - }); - - using var img = new Image(WIDTH, WIDTH); - img.Mutate(ctx => - { - var size = shiftedRolledHorizon.Size(); - ctx.DrawImage(shiftedRolledHorizon, new Point( - (int)Math.Round((float)-size.Width / 2 + HALF_WIDTH), - (int)Math.Round((float)-size.Height / 2 + HALF_WIDTH) - ), new GraphicsOptions()); - - // Draw bug - PointF[] leftLine = { new PointF(6, 36), new PointF(26, 36) }; - PointF[] rightLine = { new PointF(46, 36), new PointF(66, 36) }; - PointF[] bottomLine = { new PointF(36, 41), new PointF(36, 51) }; - ctx.DrawLines(pen, leftLine); - ctx.DrawLines(pen, rightLine); - ctx.DrawLines(pen, bottomLine); - }); - - return ToBase64PNG(img); - } + public string GetWindImage(double windDirectionInDegrees, double windVelocity, double headingInDegrees, bool relative) + { + var fontDegree = SystemFonts.CreateFont("Arial", 16, FontStyle.Regular); + var fontStrength = SystemFonts.CreateFont("Arial", 16, FontStyle.Regular); - public string GetWindImage(double windDirectionInDegrees, double windVelocity, double headingInDegrees, bool relative) + int intDir = Convert.ToInt32(windDirectionInDegrees); + int intVel = Convert.ToInt32(windVelocity); + int intHdg = Convert.ToInt32(headingInDegrees); + string txtDir = intDir.ToString(); + + if (relative) { - var fontDegree = SystemFonts.CreateFont("Arial", 16, FontStyle.Regular); - var fontStrength = SystemFonts.CreateFont("Arial", 16, FontStyle.Regular); + intDir = intDir - intHdg; + } - int intDir = Convert.ToInt32(windDirectionInDegrees); - int intVel = Convert.ToInt32(windVelocity); - int intHdg = Convert.ToInt32(headingInDegrees); - string txtDir = intDir.ToString(); + using var rotatedImg = windImage.Clone(ctx => + { + // Rotate + ctx.Rotate((float)intDir); + }); - if (relative) - { - intDir = intDir - intHdg; - } + using var img = new Image(WIDTH, WIDTH); + img.Mutate(ctx => + { + var size = rotatedImg.Size(); + ctx.DrawImage(rotatedImg, new Point( + (int)Math.Round((float)-size.Width / 2 + HALF_WIDTH), + (int)Math.Round((float)-size.Height / 2 + HALF_WIDTH) + ), new GraphicsOptions()); - using var rotatedImg = windImage.Clone(ctx => - { - // Rotate - ctx.Rotate((float)intDir); - }); + FontRectangle fsize = new FontRectangle(0, 0, 0, 0); + fsize = TextMeasurer.Measure(txtDir, new TextOptions(fontDegree)); + ctx.DrawText(txtDir + "°", fontDegree, Color.Yellow, new PointF(HALF_WIDTH - fsize.Width / 2, 53)); - using var img = new Image(WIDTH, WIDTH); - img.Mutate(ctx => - { - var size = rotatedImg.Size(); - ctx.DrawImage(rotatedImg, new Point( - (int)Math.Round((float)-size.Width / 2 + HALF_WIDTH), - (int)Math.Round((float)-size.Height / 2 + HALF_WIDTH) - ), new GraphicsOptions()); + string text = intVel.ToString() + " kt"; + fsize = TextMeasurer.Measure(text, new TextOptions(fontStrength)); + ctx.DrawText(text, fontStrength, Color.Cyan, new PointF(HALF_WIDTH - fsize.Width / 2, 0)); - FontRectangle fsize = new FontRectangle(0, 0, 0, 0); - fsize = TextMeasurer.Measure(txtDir, new TextOptions(fontDegree)); - ctx.DrawText(txtDir + "°", fontDegree, Color.Yellow, new PointF(HALF_WIDTH - fsize.Width / 2, 53)); - string text = intVel.ToString() + " kt"; - fsize = TextMeasurer.Measure(text, new TextOptions(fontStrength)); - ctx.DrawText(text, fontStrength, Color.Cyan, new PointF(HALF_WIDTH - fsize.Width / 2, 0)); + var pen = new Pen(Color.Cyan, 4); + var penSmall = new Pen(Color.Cyan, 3); + if (relative) + { + PointF[] wingLine = { new PointF(1, 59), new PointF(17, 59) }; + PointF[] middleLine = { new PointF(9, 54), new PointF(9, 68) }; + PointF[] rudderLine = { new PointF(5, 67), new PointF(13, 67) }; + ctx.DrawLines(pen, middleLine); + ctx.DrawLines(pen, wingLine); + ctx.DrawLines(penSmall, rudderLine); + } + else + { + text = "N"; + fsize = TextMeasurer.Measure(text, new TextOptions(fontDegree)); + ctx.DrawText(text, fontDegree, Color.Cyan, new PointF(3, 53)); + } - var pen = new Pen(Color.Cyan, 4); - var penSmall = new Pen(Color.Cyan, 3); + }); - if (relative) - { - PointF[] wingLine = { new PointF(1, 59), new PointF(17, 59) }; - PointF[] middleLine = { new PointF(9, 54), new PointF(9, 68) }; - PointF[] rudderLine = { new PointF(5, 67), new PointF(13, 67) }; - ctx.DrawLines(pen, middleLine); - ctx.DrawLines(pen, wingLine); - ctx.DrawLines(penSmall, rudderLine); - } - else - { - text = "N"; - fsize = TextMeasurer.Measure(text, new TextOptions(fontDegree)); - ctx.DrawText(text, fontDegree, Color.Cyan, new PointF(3, 53)); - } + return ToBase64PNG(img); - }); + } - return ToBase64PNG(img); + public string GetGenericGaugeImage(string text, double value, double min, double max, int? fontSize, string valueFormat, string? subValueText = null) + { + var font = SystemFonts.CreateFont("Arial", fontSize ?? 22, FontStyle.Regular); + var titleFont = SystemFonts.CreateFont("Arial", 13, FontStyle.Regular); + var pen = new Pen(Color.DarkRed, 5); + var range = max - min; + if (range <= 0) + { + range = 1; } - public string GetGenericGaugeImage(string text, double value, double min, double max, int? fontSize, string valueFormat, string? subValueText = null) + using var img = gaugeImage.Clone(ctx => { - var font = SystemFonts.CreateFont("Arial", fontSize ?? 22, FontStyle.Regular); - var titleFont = SystemFonts.CreateFont("Arial", 13, FontStyle.Regular); - var pen = new Pen(Color.DarkRed, 5); - var range = max - min; + double angleOffset = Math.PI * -1.25; + var ratio = (value - min) / range; + if (ratio < 0) ratio = 0; + if (ratio > 1) ratio = 1; + double angle = Math.PI * ratio + angleOffset; - if (range <= 0) - { - range = 1; - } + var startPoint = new PointF(HALF_WIDTH, HALF_WIDTH); + var middlePoint = new PointF( + (float)((HALF_WIDTH - 16) * Math.Cos(angle)), + (float)((HALF_WIDTH - 16) * Math.Sin(angle)) + ); - using var img = gaugeImage.Clone(ctx => - { - double angleOffset = Math.PI * -1.25; - var ratio = (value - min) / range; - if (ratio < 0) ratio = 0; - if (ratio > 1) ratio = 1; - double angle = Math.PI * ratio + angleOffset; + var endPoint = new PointF( + (float)(HALF_WIDTH * Math.Cos(angle)), + (float)(HALF_WIDTH * Math.Sin(angle)) + ); - var startPoint = new PointF(HALF_WIDTH, HALF_WIDTH); - var middlePoint = new PointF( - (float)((HALF_WIDTH - 16) * Math.Cos(angle)), - (float)((HALF_WIDTH - 16) * Math.Sin(angle)) - ); + PointF[] needle = { startPoint + middlePoint, startPoint + endPoint }; - var endPoint = new PointF( - (float)(HALF_WIDTH * Math.Cos(angle)), - (float)(HALF_WIDTH * Math.Sin(angle)) - ); + ctx.DrawLines(pen, needle); - PointF[] needle = { startPoint + middlePoint, startPoint + endPoint }; + FontRectangle size = new FontRectangle(0, 0, 0, 0); + if (!string.IsNullOrWhiteSpace(text)) + { + size = TextMeasurer.Measure(text, new TextOptions(titleFont)); + ctx.DrawText(text, titleFont, Color.White, new PointF(HALF_WIDTH - size.Width / 2, 43)); + } - ctx.DrawLines(pen, needle); + var valueText = value.ToString(valueFormat); + var sizeValue = TextMeasurer.Measure(valueText, new TextOptions(font)); + var textColor = value > max ? Color.Red : Color.White; + ctx.DrawText(valueText, font, textColor, new PointF(18, 46 - sizeValue.Height)); - FontRectangle size = new FontRectangle(0, 0, 0, 0); - if (!string.IsNullOrWhiteSpace(text)) - { - size = TextMeasurer.Measure(text, new TextOptions(titleFont)); - ctx.DrawText(text, titleFont, Color.White, new PointF(HALF_WIDTH - size.Width / 2, 43)); - } + if (!string.IsNullOrWhiteSpace(subValueText)) ctx.DrawText(subValueText, titleFont, textColor, new PointF(20, 41 + size.Height)); + }); - var valueText = value.ToString(valueFormat); - var sizeValue = TextMeasurer.Measure(valueText, new TextOptions(font)); - var textColor = value > max ? Color.Red : Color.White; - ctx.DrawText(valueText, font, textColor, new PointF(18, 46 - sizeValue.Height)); + return ToBase64PNG(img); + } - if (!string.IsNullOrWhiteSpace(subValueText)) ctx.DrawText(subValueText, titleFont, textColor, new PointF(20, 41 + size.Height)); - }); + public string GetCustomGaugeImage(string textTop, string textBottom, double valueTop, double valueBottom, double min, double max, string valueFormat, bool horizontal, string[] splitGauge, int chartWidth, float chevronSize, bool displayAbsoluteValue, bool hideHeaderTop, bool hideHeaderBottom) + { + var font = SystemFonts.CreateFont("Arial", 25, FontStyle.Regular); + var titleFont = SystemFonts.CreateFont("Arial", 15, FontStyle.Regular); - return ToBase64PNG(img); + if (max < min) + { + // Swap max and min + var temp = max; max = min; min = temp; } - public string GetCustomGaugeImage(string textTop, string textBottom, double valueTop, double valueBottom, double min, double max, string valueFormat, bool horizontal, string[] splitGauge, int chartWidth, float chevronSize, bool displayAbsoluteValue, bool hideHeaderTop, bool hideHeaderBottom) - { - var font = SystemFonts.CreateFont("Arial", 25, FontStyle.Regular); - var titleFont = SystemFonts.CreateFont("Arial", 15, FontStyle.Regular); + var range = max - min; + range = range == 0 ? 1 : range; - if (max < min) + using var img = defaultBackground.Clone(ctx => + { + ctx.Draw(new Pen(Color.Black, 100), new RectangleF(0, 0, WIDTH, WIDTH)); + int width_margin = 10; + int img_width = WIDTH - (width_margin * 2); + + //0 = critical : Red + //1 = warning : Yellow + //2 = nominal : Green + //3 = superb : No Color + Color[] colors = { Color.Red, Color.Yellow, Color.Green }; + PointF previousWidth = new PointF(width_margin, HALF_WIDTH); + int colorSentinel = 0; + + foreach (var pct in splitGauge) { - // Swap max and min - var temp = max; max = min; min = temp; - } + string[] split = pct.Split(':'); + if (float.TryParse(split[0], out float critFloatWidth) && colors.Length > colorSentinel) + { + PointF stepWidth = previousWidth + new SizeF(critFloatWidth / 100f * img_width, 0); - var range = max - min; - range = range == 0 ? 1 : range; + Color? color = null; + if (split.Length > 1 && split[1] != string.Empty) + { + System.Drawing.Color temp = System.Drawing.Color.FromName(split[1]); + color = Color.FromRgb(temp.R, temp.G, temp.B); + } + else if (colors.Length > colorSentinel) + { + color = colors[colorSentinel]; + colorSentinel += 1; + } - using var img = defaultBackground.Clone(ctx => - { - ctx.Draw(new Pen(Color.Black, 100), new RectangleF(0, 0, WIDTH, WIDTH)); - int width_margin = 10; - int img_width = WIDTH - (width_margin * 2); - - //0 = critical : Red - //1 = warning : Yellow - //2 = nominal : Green - //3 = superb : No Color - Color[] colors = { Color.Red, Color.Yellow, Color.Green }; - PointF previousWidth = new PointF(width_margin, HALF_WIDTH); - int colorSentinel = 0; - - foreach (var pct in splitGauge) - { - string[] split = pct.Split(':'); - if (float.TryParse(split[0], out float critFloatWidth) && colors.Length > colorSentinel) + if (color != null) { - PointF stepWidth = previousWidth + new SizeF(critFloatWidth / 100f * img_width, 0); - - Color? color = null; - if (split.Length > 1 && split[1] != string.Empty) - { - System.Drawing.Color temp = System.Drawing.Color.FromName(split[1]); - color = Color.FromRgb(temp.R, temp.G, temp.B); - } - else if (colors.Length > colorSentinel) - { - color = colors[colorSentinel]; - colorSentinel += 1; - } - - if (color != null) - { - var shift = new SizeF(0, chartWidth / 2f); - ctx.FillPolygon( - color.Value, - previousWidth - shift, - previousWidth + shift, - stepWidth + shift, - stepWidth - shift - ); - } - - previousWidth = stepWidth; + var shift = new SizeF(0, chartWidth / 2f); + ctx.FillPolygon( + color.Value, + previousWidth - shift, + previousWidth + shift, + stepWidth + shift, + stepWidth - shift + ); } + + previousWidth = stepWidth; } + } - //topValue - var ratio = (valueTop - min) / range; - var valueTopText = (displayAbsoluteValue ? Math.Abs(valueTop) : valueTop).ToString(valueFormat); - DrawCustomGauge(true, textTop, valueTopText, (float)ratio, img_width, chevronSize, width_margin, chartWidth, (float)min, (float)max, ctx, hideHeaderTop); + //topValue + var ratio = (valueTop - min) / range; + var valueTopText = (displayAbsoluteValue ? Math.Abs(valueTop) : valueTop).ToString(valueFormat); + DrawCustomGauge(true, textTop, valueTopText, (float)ratio, img_width, chevronSize, width_margin, chartWidth, (float)min, (float)max, ctx, hideHeaderTop); - //bottomValue - ratio = (valueBottom - min) / range; - var valueBottomText = (displayAbsoluteValue ? Math.Abs(valueBottom) : valueBottom).ToString(valueFormat); - DrawCustomGauge(false, textBottom, valueBottomText, (float)ratio, img_width, chevronSize, width_margin, chartWidth, (float)min, (float)max, ctx, hideHeaderBottom); + //bottomValue + ratio = (valueBottom - min) / range; + var valueBottomText = (displayAbsoluteValue ? Math.Abs(valueBottom) : valueBottom).ToString(valueFormat); + DrawCustomGauge(false, textBottom, valueBottomText, (float)ratio, img_width, chevronSize, width_margin, chartWidth, (float)min, (float)max, ctx, hideHeaderBottom); - if (!horizontal) ctx.Rotate(-90); - }); + if (!horizontal) ctx.Rotate(-90); + }); - return ToBase64PNG(img); - } + return ToBase64PNG(img); + } - private Image GetBackgroundImage(byte[]? imageBytes, string? imageFilePath, Func imageDefaultFactory) + private Image GetBackgroundImage(byte[]? imageBytes, string? imageFilePath, Func imageDefaultFactory) + { + if (imageBytes != null && imageBytes.Length > 0) { - if (imageBytes != null && imageBytes.Length > 0) + try { - try - { - return Image.Load(imageBytes); - } - catch (ImageFormatException) - { - // Let it fall through to default image - // TODO: maybe show a warning background - } + return Image.Load(imageBytes); } - else if (!string.IsNullOrEmpty(imageFilePath) && File.Exists(imageFilePath)) + catch (ImageFormatException) { - try - { - return Image.Load(imageFilePath); - } - catch (ImageFormatException) - { - // Let it fall through to default image - // TODO: maybe show a warning background - } + // Let it fall through to default image + // TODO: maybe show a warning background } - - return imageDefaultFactory(); } - - private string ToBase64PNG(Image image) + else if (!string.IsNullOrEmpty(imageFilePath) && File.Exists(imageFilePath)) { - using var memoryStream = new MemoryStream(); - image.Save(memoryStream, new PngEncoder()); - var base64 = Convert.ToBase64String(memoryStream.ToArray()); - - return "data:image/png;base64, " + base64; + try + { + return Image.Load(imageFilePath); + } + catch (ImageFormatException) + { + // Let it fall through to default image + // TODO: maybe show a warning background + } } - private void DrawCustomGauge(bool top, string labelText, string value, float ratio, int img_width, float chevronSize, float width_margin, float chart_width, float min, float max, IImageProcessingContext ctx, bool hideHeader) - { - float.TryParse(value, out float floatValue); - bool missingHeaderLabel = (labelText?.Length ?? 0) == 0; - bool writeValueHeaderAndChevron = !hideHeader || (floatValue >= min && floatValue <= max); + return imageDefaultFactory(); + } - if (writeValueHeaderAndChevron && !missingHeaderLabel) - { - var pen = new Pen(Color.White, chevronSize + 1); - - var arrowStartX = (ratio * img_width) + width_margin; - var arrowStartY = (HALF_WIDTH - ((chart_width / 2) * (top ? 1 : -1))); - var arrowAddY = arrowStartY - ((chevronSize * 2) * (top ? 1 : -1)); - - var startPoint = new PointF(arrowStartX, arrowStartY); - var right = new PointF(arrowStartX + chevronSize, arrowAddY); - var left = new PointF(arrowStartX - chevronSize, arrowAddY); - - PointF[] needle = { startPoint, right, left, startPoint }; - - var valueText = value.ToString(); - var textColor = (floatValue > max || floatValue < min) ? Color.Red : Color.White; - var font = SystemFonts.CreateFont("Arial", chevronSize * 4, FontStyle.Regular); - - var size = TextMeasurer.Measure(valueText, new TextOptions(font)); - float adjustY = top ? Math.Abs(-5 - size.Height) : 5; - arrowAddY = top ? arrowAddY - adjustY : arrowAddY + adjustY; - var valuePoint = new PointF(HALF_WIDTH - size.Width / 2, arrowAddY); - ctx.DrawText(valueText, font, textColor, valuePoint); - - ctx.DrawPolygon(pen, needle); - var text = !string.IsNullOrEmpty(labelText) ? labelText[0].ToString() : string.Empty; - size = TextMeasurer.Measure(text, new TextOptions(SystemFonts.CreateFont("Arial", chevronSize * 3, FontStyle.Regular))); - startPoint.Y -= top ? size.Height : 0; - startPoint.X -= size.Width / 2; - ctx.DrawText(text, SystemFonts.CreateFont("Arial", chevronSize * 3, FontStyle.Regular), Color.Black, startPoint); - } + private string ToBase64PNG(Image image) + { + using var memoryStream = new MemoryStream(); + image.Save(memoryStream, new PngEncoder()); + var base64 = Convert.ToBase64String(memoryStream.ToArray()); + + return "data:image/png;base64, " + base64; + } + + private void DrawCustomGauge(bool top, string labelText, string value, float ratio, int img_width, float chevronSize, float width_margin, float chart_width, float min, float max, IImageProcessingContext ctx, bool hideHeader) + { + float.TryParse(value, out float floatValue); + bool missingHeaderLabel = (labelText?.Length ?? 0) == 0; + bool writeValueHeaderAndChevron = !hideHeader || (floatValue >= min && floatValue <= max); + + if (writeValueHeaderAndChevron && !missingHeaderLabel) + { + var pen = new Pen(Color.White, chevronSize + 1); + + var arrowStartX = (ratio * img_width) + width_margin; + var arrowStartY = (HALF_WIDTH - ((chart_width / 2) * (top ? 1 : -1))); + var arrowAddY = arrowStartY - ((chevronSize * 2) * (top ? 1 : -1)); + + var startPoint = new PointF(arrowStartX, arrowStartY); + var right = new PointF(arrowStartX + chevronSize, arrowAddY); + var left = new PointF(arrowStartX - chevronSize, arrowAddY); + + PointF[] needle = { startPoint, right, left, startPoint }; + + var valueText = value.ToString(); + var textColor = (floatValue > max || floatValue < min) ? Color.Red : Color.White; + var font = SystemFonts.CreateFont("Arial", chevronSize * 4, FontStyle.Regular); + + var size = TextMeasurer.Measure(valueText, new TextOptions(font)); + float adjustY = top ? Math.Abs(-5 - size.Height) : 5; + arrowAddY = top ? arrowAddY - adjustY : arrowAddY + adjustY; + var valuePoint = new PointF(HALF_WIDTH - size.Width / 2, arrowAddY); + ctx.DrawText(valueText, font, textColor, valuePoint); + + ctx.DrawPolygon(pen, needle); + var text = !string.IsNullOrEmpty(labelText) ? labelText[0].ToString() : string.Empty; + size = TextMeasurer.Measure(text, new TextOptions(SystemFonts.CreateFont("Arial", chevronSize * 3, FontStyle.Regular))); + startPoint.Y -= top ? size.Height : 0; + startPoint.X -= size.Width / 2; + ctx.DrawText(text, SystemFonts.CreateFont("Arial", chevronSize * 3, FontStyle.Regular), Color.Black, startPoint); } } } diff --git a/FlightStreamDeck.Logics/KnownVariables.cs b/FlightStreamDeck.Logics/KnownVariables.cs new file mode 100644 index 0000000..183b507 --- /dev/null +++ b/FlightStreamDeck.Logics/KnownVariables.cs @@ -0,0 +1,741 @@ +using System.Collections.Generic; + +namespace FlightStreamDeck.Core; + +public static class KnownVariables +{ + record ValueEntry(string Unit, short Decimals); + + const string DEFAULT_UNIT = "number"; + const int DEFAULT_DECIMALS = 0; + + static Dictionary availableValues = new() + { + { "ACCELERATION BODY X", new ValueEntry("meter per second squared", 2) }, + { "ACCELERATION BODY Y", new ValueEntry("meter per second squared", 2) }, + { "ACCELERATION BODY Z", new ValueEntry("meter per second squared", 2) }, + { "ACCELERATION WORLD X", new ValueEntry("meter per second squared", 2) }, + { "ACCELERATION WORLD Y", new ValueEntry("meter per second squared", 2) }, + { "ACCELERATION WORLD Z", new ValueEntry("meter per second squared", 2) }, + { "GENERAL ENG RPM:1", new ValueEntry("Rpm", 1) }, + { "GENERAL ENG RPM:2", new ValueEntry("Rpm", 1) }, + { "GENERAL ENG RPM:3", new ValueEntry("Rpm", 1) }, + { "GENERAL ENG RPM:4", new ValueEntry("Rpm", 1) }, + { "GENERAL ENG THROTTLE LEVER POSITION:1", new ValueEntry("Percent", 2) }, + { "GENERAL ENG THROTTLE LEVER POSITION:2", new ValueEntry("Percent", 2) }, + { "GENERAL ENG THROTTLE LEVER POSITION:3", new ValueEntry("Percent", 2) }, + { "GENERAL ENG THROTTLE LEVER POSITION:4", new ValueEntry("Percent", 2) }, + { "GENERAL ENG MIXTURE LEVER POSITION:1", new ValueEntry("Percent", 2) }, + { "GENERAL ENG MIXTURE LEVER POSITION:2", new ValueEntry("Percent", 2) }, + { "GENERAL ENG MIXTURE LEVER POSITION:3", new ValueEntry("Percent", 2) }, + { "GENERAL ENG MIXTURE LEVER POSITION:4", new ValueEntry("Percent", 2) }, + { "GENERAL ENG PROPELLER LEVER POSITION:1", new ValueEntry("Percent", 2) }, + { "GENERAL ENG PROPELLER LEVER POSITION:2", new ValueEntry("Percent", 2) }, + { "GENERAL ENG PROPELLER LEVER POSITION:3", new ValueEntry("Percent", 2) }, + { "GENERAL ENG PROPELLER LEVER POSITION:4", new ValueEntry("Percent", 2) }, + { "GENERAL ENG EXHAUST GAS TEMPERATURE:1", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG EXHAUST GAS TEMPERATURE:2", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG EXHAUST GAS TEMPERATURE:3", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG EXHAUST GAS TEMPERATURE:4", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG FUEL PRESSURE:1", new ValueEntry("Psi", 0) }, + { "GENERAL ENG FUEL PRESSURE:2", new ValueEntry("Psi", 0) }, + { "GENERAL ENG FUEL PRESSURE:3", new ValueEntry("Psi", 0) }, + { "GENERAL ENG FUEL PRESSURE:4", new ValueEntry("Psi", 0) }, + { "GENERAL ENG FUEL USED SINCE START", new ValueEntry("Pounds", 2) }, + { "ENG MAX RPM", new ValueEntry("Rpm", 1) }, + { "ENG FUEL FLOW GPH:1", new ValueEntry("Gallons per hour", 0) }, + { "ENG FUEL FLOW GPH:2", new ValueEntry("Gallons per hour", 0) }, + { "ENG FUEL FLOW GPH:3", new ValueEntry("Gallons per hour", 0) }, + { "ENG FUEL FLOW GPH:4", new ValueEntry("Gallons per hour", 0) }, + { "ENG FUEL FLOW PPH:1", new ValueEntry("Pounds per hour", 0) }, + { "ENG FUEL FLOW PPH:2", new ValueEntry("Pounds per hour", 0) }, + { "ENG FUEL FLOW PPH:3", new ValueEntry("Pounds per hour", 0) }, + { "ENG FUEL FLOW PPH:4", new ValueEntry("Pounds per hour", 0) }, + { "TURB ENG CORRECTED N1:1", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N1:2", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N1:3", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N1:4", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N2:1", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N2:2", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N2:3", new ValueEntry("Percent", 0) }, + { "TURB ENG CORRECTED N2:4", new ValueEntry("Percent", 0) }, + { "TURB ENG ITT:1", new ValueEntry("Celsius", 0) }, + { "TURB ENG ITT:2", new ValueEntry("Celsius", 0) }, + { "TURB ENG ITT:3", new ValueEntry("Celsius", 0) }, + { "TURB ENG ITT:4", new ValueEntry("Celsius", 0) }, + { "TURB ENG AFTERBURNER PCT ACTIVE", new ValueEntry("Percent", 0) }, + { "FUEL TANK CENTER LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK CENTER2 LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK CENTER3 LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK LEFT MAIN LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK LEFT AUX LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK LEFT TIP LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK RIGHT MAIN LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK RIGHT AUX LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK RIGHT TIP LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK EXTERNAL1 LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK EXTERNAL2 LEVEL", new ValueEntry("Percent", 0) }, + { "FUEL TANK CENTER CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK CENTER2 CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK CENTER3 CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK LEFT MAIN CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK LEFT AUX CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK LEFT TIP CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK RIGHT MAIN CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK RIGHT AUX CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK RIGHT TIP CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK EXTERNAL1 CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK EXTERNAL2 CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL LEFT CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL RIGHT CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK CENTER QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK CENTER2 QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK CENTER3 QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK LEFT MAIN QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK LEFT AUX QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK LEFT TIP QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK RIGHT MAIN QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK RIGHT AUX QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK RIGHT TIP QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK EXTERNAL1 QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TANK EXTERNAL2 QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL LEFT QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL RIGHT QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TOTAL QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL WEIGHT PER GALLON", new ValueEntry("Pounds", 2) }, + { "FUEL TOTAL CAPACITY", new ValueEntry("Gallons", 2) }, + { "FUEL SELECTED QUANTITY PERCENT", new ValueEntry("Percent", 2) }, + { "FUEL SELECTED QUANTITY", new ValueEntry("Gallons", 2) }, + { "FUEL TOTAL QUANTITY WEIGHT", new ValueEntry("Pounds", 2) }, + { "ESTIMATED FUEL FLOW", new ValueEntry("Pounds per hour", 2) }, + { "GROUND VELOCITY", new ValueEntry("Knots", 0) }, + { "TOTAL WORLD VELOCITY", new ValueEntry("meter per second", 2) }, + { "VELOCITY BODY Z", new ValueEntry("meter per second", 0) }, + { "VELOCITY BODY X", new ValueEntry("meter per second", 0) }, + { "VELOCITY BODY Y", new ValueEntry("meter per second", 0) }, + { "VELOCITY WORLD Z", new ValueEntry("meter per second", 0) }, + { "VELOCITY WORLD X", new ValueEntry("meter per second", 0) }, + { "VELOCITY WORLD Y", new ValueEntry("meter per second", 0) }, + { "ROTATION VELOCITY BODY X", new ValueEntry("meter per second", 2) }, + { "ROTATION VELOCITY BODY Y", new ValueEntry("meter per second", 2) }, + { "ROTATION VELOCITY BODY Z", new ValueEntry("meter per second", 2) }, + { "RELATIVE WIND VELOCITY BODY X", new ValueEntry("meter per second", 2) }, + { "RELATIVE WIND VELOCITY BODY Y", new ValueEntry("meter per second", 2) }, + { "RELATIVE WIND VELOCITY BODY Z", new ValueEntry("meter per second", 2) }, + { "PLANE ALT ABOVE GROUND", new ValueEntry("Feet", 2) }, + { "PLANE ALTITUDE", new ValueEntry("Feet", 2) }, + { "MAGVAR", new ValueEntry("Degrees", 0) }, + { "GROUND ALTITUDE", new ValueEntry("Meters", 2) }, + { "AIRSPEED TRUE", new ValueEntry("Knots", 0) }, + { "AIRSPEED INDICATED", new ValueEntry("Knots", 0) }, + { "AIRSPEED TRUE CALIBRATE", new ValueEntry("Degrees", 0) }, + { "AIRSPEED BARBER POLE", new ValueEntry("Knots", 0) }, + { "AIRSPEED MACH", new ValueEntry("Mach", 2) }, + { "VERTICAL SPEED", new ValueEntry("Feet per minute", 0) }, + { "MACH MAX OPERATE", new ValueEntry("Mach", 2) }, + { "BARBER POLE MACH", new ValueEntry("Mach", 2) }, + { "INDICATED ALTITUDE", new ValueEntry("Feet", 0) }, + { "KOHLSMAN SETTING MB", new ValueEntry("Millibars", 0) }, + { "KOHLSMAN SETTING HG", new ValueEntry("inHg", 2) }, + { "ATTITUDE BARS POSITION", new ValueEntry("Percent", 0) }, + { "WISKEY COMPASS INDICATION DEGREES", new ValueEntry("Degrees", 0) }, + { "RADIO HEIGHT", new ValueEntry("Feet", 0) }, + { "MAX G FORCE", new ValueEntry("Gforce", 2) }, + { "MIN G FORCE", new ValueEntry("Gforce", 2) }, + { "SUCTION PRESSURE", new ValueEntry("inHg", 2) }, + { "ADF CARD", new ValueEntry("Degrees", 0) }, + { "HSI BEARING", new ValueEntry("Degrees", 0) }, + { "HSI SPEED", new ValueEntry("Knots", 0) }, + { "HSI DISTANCE", new ValueEntry("Nautical miles", 2) }, + { "GPS POSITION LAT", new ValueEntry("Degrees", 10) }, + { "GPS POSITION LON", new ValueEntry("Degrees", 10) }, + { "GPS POSITION ALT", new ValueEntry("Meters", 2) }, + { "GPS GROUND SPEED", new ValueEntry("Meters per second", 2) }, + { "GPS WP DISTANCE", new ValueEntry("Meters", 2) }, + { "GPS WP CROSS TRK", new ValueEntry("Meters", 2) }, + { "GPS WP VERTICAL SPEED", new ValueEntry("Meters per second", 2) }, + { "GPS ETE", new ValueEntry("Seconds", 0) }, + { "GPS ETA", new ValueEntry("Seconds", 0) }, + { "GPS WP NEXT LAT", new ValueEntry("Degrees", 10) }, + { "GPS WP NEXT LON", new ValueEntry("Degrees", 10) }, + { "GPS WP NEXT ALT", new ValueEntry("Meters", 0) }, + { "GPS WP PREV LAT", new ValueEntry("Degrees", 10) }, + { "GPS WP PREV LON", new ValueEntry("Degrees", 10) }, + { "GPS WP PREV ALT", new ValueEntry("Meters", 0) }, + { "GPS WP ETE", new ValueEntry("Seconds", 0) }, + { "GPS WP ETA", new ValueEntry("Seconds", 0) }, + { "GPS APPROACH TIMEZONE DEVIATION", new ValueEntry("Seconds", 0) }, + { "GPS TARGET DISTANCE", new ValueEntry("Meters", 2) }, + { "GPS TARGET ALTITUDE", new ValueEntry("Meters", 2) }, + { "ELEVATOR TRIM POSITION", new ValueEntry("Radians", 2) }, + { "ELEVATOR TRIM PCT", new ValueEntry("Percent", 0) }, + { "SPOILERS HANDLE POSITION", new ValueEntry("Position", 2) }, + { "SPOILERS LEFT POSITION", new ValueEntry("Position", 2) }, + { "SPOILERS RIGHT POSITION", new ValueEntry("Position", 2) }, + { "FLAPS HANDLE PERCENT", new ValueEntry("Percent", 0) }, + { "TRAILING EDGE FLAPS LEFT PERCENT", new ValueEntry("Percent", 0) }, + { "TRAILING EDGE FLAPS RIGHT PERCENT", new ValueEntry("Percent", 0) }, + { "LEADING EDGE FLAPS LEFT PERCENT", new ValueEntry("Percent", 0) }, + { "LEADING EDGE FLAPS RIGHT PERCENT", new ValueEntry("Percent", 0) }, + { "AILERON LEFT DEFLECTION PCT", new ValueEntry("Percent", 0) }, + { "AILERON RIGHT DEFLECTION PCT", new ValueEntry("Percent", 0) }, + { "AILERON TRIM", new ValueEntry("Radians", 2) }, + { "AILERON TRIM PCT", new ValueEntry("Percent", 0) }, + { "RUDDER DEFLECTION PCT", new ValueEntry("Percent", 0) }, + { "RUDDER TRIM PCT", new ValueEntry("Percent", 0) }, + { "ELEVATOR DEFLECTION PCT", new ValueEntry("Percent", 0) }, + { "AUTOPILOT HEADING LOCK DIR", new ValueEntry("Degrees", 0) }, + { "AUTOPILOT HEADING LOCK DIR:1", new ValueEntry("Degrees", 0) }, + { "AUTOPILOT ALTITUDE LOCK VAR", new ValueEntry("Feet", 0) }, + { "AUTOPILOT ALTITUDE LOCK VAR:1", new ValueEntry("Feet", 0) }, + { "AUTOPILOT ALTITUDE LOCK VAR:2", new ValueEntry("Feet", 0) }, + { "AUTOPILOT ALTITUDE LOCK VAR:3", new ValueEntry("Feet", 0) }, + { "AUTOPILOT VERTICAL HOLD VAR", new ValueEntry("Feet/minute", 0) }, + { "AUTOPILOT VERTICAL HOLD VAR:1", new ValueEntry("Feet/minute", 0) }, + { "AUTOPILOT VERTICAL HOLD VAR:2", new ValueEntry("Feet/minute", 0) }, + { "AUTOPILOT VERTICAL HOLD VAR:3", new ValueEntry("Feet/minute", 0) }, + { "AUTOPILOT AIRSPEED HOLD VAR", new ValueEntry("Knots", 0) }, + { "AUTOPILOT AIRSPEED HOLD VAR:1", new ValueEntry("Knots", 0) }, + { "AUTOPILOT AIRSPEED HOLD VAR:2", new ValueEntry("Knots", 0) }, + { "GEAR HYDRAULIC PRESSURE", new ValueEntry("Pound force per square foot (psf)", 2) }, + { "GEAR CENTER POSITION", new ValueEntry("Percent", 0) }, + { "GEAR LEFT POSITION", new ValueEntry("Percent", 0) }, + { "GEAR RIGHT POSITION", new ValueEntry("Percent", 0) }, + { "GEAR TAIL POSITION", new ValueEntry("Percent", 0) }, + { "GEAR AUX POSITION", new ValueEntry("Percent", 0) }, + { "GEAR TOTAL PCT EXTENDED", new ValueEntry("Percent", 0) }, + { "WATER RUDDER HANDLE POSITION", new ValueEntry("Percent", 0) }, + { "WATER LEFT RUDDER EXTENDED", new ValueEntry("Percentage", 0) }, + { "WATER RIGHT RUDDER EXTENDED", new ValueEntry("Percentage", 0) }, + { "GEAR CENTER STEER ANGLE", new ValueEntry("Percent", 0) }, + { "GEAR LEFT STEER ANGLE", new ValueEntry("Percent", 0) }, + { "GEAR RIGHT STEER ANGLE", new ValueEntry("Percent", 0) }, + { "GEAR AUX STEER ANGLE", new ValueEntry("Percent", 0) }, + { "WATER LEFT RUDDER STEER ANGLE", new ValueEntry("Percent", 0) }, + { "WATER RIGHT RUDDER STEER ANGLE", new ValueEntry("Percent", 0) }, + { "GEAR CENTER STEER ANGLE PCT", new ValueEntry("Percent", 0) }, + { "GEAR LEFT STEER ANGLE PCT", new ValueEntry("Percent", 0) }, + { "GEAR RIGHT STEER ANGLE PCT", new ValueEntry("Percent", 0) }, + { "GEAR AUX STEER ANGLE PCT", new ValueEntry("Percent", 0) }, + { "WATER LEFT RUDDER STEER ANGLE PCT", new ValueEntry("Percent", 0) }, + { "WATER RIGHT RUDDER STEER ANGLE PCT", new ValueEntry("Percent", 0) }, + { "CENTER WHEEL RPM", new ValueEntry("Rpm", 0) }, + { "LEFT WHEEL RPM", new ValueEntry("Rpm", 0) }, + { "RIGHT WHEEL RPM", new ValueEntry("Rpm", 0) }, + { "AUX WHEEL RPM", new ValueEntry("Rpm", 0) }, + { "RETRACT LEFT FLOAT EXTENDED", new ValueEntry("Percent", 0) }, + { "RETRACT RIGHT FLOAT EXTENDED", new ValueEntry("Percent", 0) }, + { "STEER INPUT CONTROL", new ValueEntry("Percent", 0) }, + { "AMBIENT DENSITY", new ValueEntry("Slugs per cubic feet", 0) }, + { "AMBIENT TEMPERATURE", new ValueEntry("Celsius", 2) }, + { "AMBIENT PRESSURE", new ValueEntry("inHg", 2) }, + { "AMBIENT WIND VELOCITY", new ValueEntry("Knots", 0) }, + { "AMBIENT WIND DIRECTION", new ValueEntry("Degrees", 0) }, + { "AMBIENT WIND X", new ValueEntry("Meters per second", 0) }, + { "AMBIENT WIND Y", new ValueEntry("Meters per second", 0) }, + { "AMBIENT WIND Z", new ValueEntry("Meters per second", 0) }, + { "STRUCT AMBIENT WIND", new ValueEntry("Feet per second", 0) }, + { "AIRCRAFT WIND X", new ValueEntry("Knots", 0) }, + { "AIRCRAFT WIND Y", new ValueEntry("Knots", 0) }, + { "AIRCRAFT WIND Z", new ValueEntry("Knots", 0) }, + { "BAROMETER PRESSURE", new ValueEntry("Millibars", 0) }, + { "SEA LEVEL PRESSURE", new ValueEntry("Millibars", 0) }, + { "TOTAL AIR TEMPERATURE", new ValueEntry("Celsius", 2) }, + { "AMBIENT VISIBILITY", new ValueEntry("Meters", 0) }, + { "STANDARD ATM TEMPERATURE", new ValueEntry("Celsius", 0) }, + { "FOLDING WING LEFT PERCENT", new ValueEntry("Percent", 0) }, + { "FOLDING WING RIGHT PERCENT", new ValueEntry("Percent", 0) }, + { "CANOPY OPEN", new ValueEntry("Percent", 0) }, + { "TAILHOOK POSITION", new ValueEntry("Percent", 0) }, + { "ELECTRICAL TOTAL LOAD AMPS", new ValueEntry("Amperes", 2) }, + { "ELECTRICAL BATTERY LOAD", new ValueEntry("Amperes", 2) }, + { "ELECTRICAL BATTERY VOLTAGE", new ValueEntry("Volts", 2) }, + { "ELECTRICAL MAIN BUS VOLTAGE", new ValueEntry("Volts", 2) }, + { "ELECTRICAL MAIN BUS AMPS", new ValueEntry("Amperes", 2) }, + { "ELECTRICAL AVIONICS BUS VOLTAGE", new ValueEntry("Volts", 2) }, + { "ELECTRICAL AVIONICS BUS AMPS", new ValueEntry("Amperes", 2) }, + { "ELECTRICAL HOT BATTERY BUS VOLTAGE", new ValueEntry("Volts", 2) }, + { "ELECTRICAL HOT BATTERY BUS AMPS", new ValueEntry("Amperes", 2) }, + { "ELECTRICAL BATTERY BUS VOLTAGE", new ValueEntry("Volts", 2) }, + { "ELECTRICAL BATTERY BUS AMPS", new ValueEntry("Amperes", 2) }, + { "ELECTRICAL BATTERY BUS CONTACT SWITCH", new ValueEntry("Volts", 2) }, + { "HYDRAULIC SYSTEM INTEGRITY", new ValueEntry("Percent", 0) }, + { "TOTAL WEIGHT", new ValueEntry("Pounds", 0) }, + { "MAX GROSS WEIGHT", new ValueEntry("Pounds", 0) }, + { "EMPTY WEIGHT", new ValueEntry("Pounds", 0) }, + { "G FORCE", new ValueEntry("GForce", 2) }, + { "DESIGN SPEED VS0", new ValueEntry("Feet per second", 0) }, + { "DESIGN SPEED VS1", new ValueEntry("Feet per second", 0) }, + { "DESIGN SPEED VC", new ValueEntry("Feet per second", 0) }, + { "MIN DRAG VELOCITY", new ValueEntry("Feet per second", 0) }, + { "ESTIMATED CRUISE SPEED", new ValueEntry("Feet per second", 0) }, + { "CG PERCENT", new ValueEntry("Percent", 0) }, + { "CG PERCENT LATERAL", new ValueEntry("Percent", 0) }, + { "ATC SUGGESTED MIN RWY TAKEOFF", new ValueEntry("Feet", 0) }, + { "ATC SUGGESTED MIN RWY LANDING", new ValueEntry("Feet", 0) }, + { "TYPICAL DESCENT RATE", new ValueEntry("Feet per minute", 0) }, + { "VISUAL MODEL RADIUS", new ValueEntry("Meters", 2) }, + { "DYNAMIC PRESSURE", new ValueEntry("Pounds per square foot", 0) }, + { "TOTAL VELOCITY", new ValueEntry("Feet per second", 0) }, + { "AIRSPEED SELECT INDICATED OR TRUE", new ValueEntry("Knots", 0) }, + { "VARIOMETER RATE", new ValueEntry("Feet per second", 0) }, + { "PRESSURE ALTITUDE", new ValueEntry("Meters", 0) }, + { "MAGNETIC COMPASS", new ValueEntry("Degrees", 0) }, + { "BRAKE DEPENDENT HYDRAULIC PRESSURE", new ValueEntry("Pounds per square foot", 2) }, + { "WING AREA", new ValueEntry("Square feet", 2) }, + { "WING SPAN", new ValueEntry("Feet", 2) }, + { "LINEAR CL ALPHA", new ValueEntry("Per radian", 2) }, + { "CG AFT LIMIT", new ValueEntry("Percent", 0) }, + { "CG FWD LIMIT", new ValueEntry("Percent", 0) }, + { "CG MAX MACH", new ValueEntry("Machs", 2) }, + { "CG MIN MACH", new ValueEntry("Machs", 2) }, + { "EXIT POSX", new ValueEntry("Feet", 2) }, + { "EXIT POSY", new ValueEntry("Feet", 2) }, + { "EXIT POSZ", new ValueEntry("Feet", 2) }, + { "DECISION HEIGHT", new ValueEntry("Feet", 0) }, + { "DECISION ALTITUDE MSL", new ValueEntry("Feet", 0) }, + { "EMPTY WEIGHT PITCH MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "EMPTY WEIGHT ROLL MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "EMPTY WEIGHT YAW MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "EMPTY WEIGHT CROSS COUPLED MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "TOTAL WEIGHT PITCH MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "TOTAL WEIGHT ROLL MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "TOTAL WEIGHT YAW MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "TOTAL WEIGHT CROSS COUPLED MOI", new ValueEntry("Slugs per feet squared", 2) }, + { "MAX RATED ENGINE RPM", new ValueEntry("Rpm", 0) }, + { "MANUAL FUEL PUMP HANDLE", new ValueEntry("Percent", 0) }, + { "ELECTRICAL OLD CHARGING AMPS", new ValueEntry("Amps", 2) }, + { "CONCORDE VISOR POSITION PERCENT", new ValueEntry("Percent", 0) }, + { "PITOT ICE PCT", new ValueEntry("Percent", 0) }, + { "SIMULATED RADIUS", new ValueEntry("Feet", 0) }, + { "STRUCTURAL ICE PCT", new ValueEntry("Percent", 0) }, + { "ARTIFICIAL GROUND ELEVATION", new ValueEntry("Feet", 0) }, + { "PUSHBACK CONTACTX", new ValueEntry("Feet", 2) }, + { "PUSHBACK CONTACTY", new ValueEntry("Feet", 2) }, + { "PUSHBACK CONTACTZ", new ValueEntry("Feet", 2) }, + { "YAW STRING PCT EXTENDED", new ValueEntry("Percent", 0) }, + { "INDUCTOR COMPASS PERCENT DEVIATION", new ValueEntry("Percent", 0) }, + { "ANEMOMETER PCT RPM", new ValueEntry("Percent", 0) }, + { "NAV VOR LLAF64", new ValueEntry("LLA structure", 0) }, + { "NAV GS LLAF64", new ValueEntry("LLA structure", 0) }, + { "STATIC CG TO GROUND", new ValueEntry("Feet", 2) }, + { "TOW RELEASE HANDLE", new ValueEntry("Percent", 0) }, + { "APU PCT RPM", new ValueEntry("Percent", 0) }, + { "APU PCT STARTER", new ValueEntry("Percent", 0) }, + { "APU VOLTS", new ValueEntry("Volts", 2) }, + { "PRESSURIZATION CABIN ALTITUDE", new ValueEntry("Feet", 0) }, + { "PRESSURIZATION CABIN ALTITUDE GOAL", new ValueEntry("Feet", 0) }, + { "PRESSURIZATION CABIN ALTITUDE RATE", new ValueEntry("Feet per second", 0) }, + { "PRESSURIZATION PRESSURE DIFFERENTIAL", new ValueEntry("Pounds per square foot", 0) }, + { "NAV ACTIVE FREQUENCY:1", new ValueEntry("MHz", 2) }, + { "NAV STANDBY FREQUENCY:1", new ValueEntry("MHz", 2) }, + { "NAV ACTIVE FREQUENCY:2", new ValueEntry("MHz", 2) }, + { "NAV STANDBY FREQUENCY:2", new ValueEntry("MHz", 2) }, + { "COM ACTIVE FREQUENCY:1", new ValueEntry("MHz", 3) }, + { "COM STANDBY FREQUENCY:1", new ValueEntry("MHz", 3) }, + { "COM ACTIVE FREQUENCY:2", new ValueEntry("MHz", 3) }, + { "COM STANDBY FREQUENCY:2", new ValueEntry("MHz", 3) }, + { "ADF ACTIVE FREQUENCY:1", new ValueEntry("MHz", 0) }, + { "ADF STANDBY FREQUENCY:1", new ValueEntry("MHz", 0) }, + { "ADF ACTIVE FREQUENCY:2", new ValueEntry("MHz", 0) }, + { "ADF STANDBY FREQUENCY:2", new ValueEntry("MHz", 0) }, + { "PLANE PITCH DEGREES", new ValueEntry("Degrees", 2) }, + { "PLANE BANK DEGREES", new ValueEntry("Degrees", 2) }, + { "PLANE HEADING DEGREES TRUE", new ValueEntry("Degrees", 2) }, + { "PLANE HEADING DEGREES MAGNETIC", new ValueEntry("Degrees", 2) }, + { "TURB ENG MAX TORQUE PERCENT:1", new ValueEntry("Percent", 0) }, + { "TURB ENG MAX TORQUE PERCENT:2", new ValueEntry("Percent", 0) }, + { "TURB ENG MAX TORQUE PERCENT:3", new ValueEntry("Percent", 0) }, + { "TURB ENG MAX TORQUE PERCENT:4", new ValueEntry("Percent", 0) }, + { "GENERAL ENG PCT MAX RPM:1", new ValueEntry("Percent", 0) }, + { "GENERAL ENG PCT MAX RPM:2", new ValueEntry("Percent", 0) }, + { "GENERAL ENG PCT MAX RPM:3", new ValueEntry("Percent", 0) }, + { "GENERAL ENG PCT MAX RPM:4", new ValueEntry("Percent", 0) }, + { "TURB ENG PRIMARY NOZZLE PERCENT:1", new ValueEntry("Percent", 0) }, + { "TURB ENG PRIMARY NOZZLE PERCENT:2", new ValueEntry("Percent", 0) }, + { "TURB ENG PRIMARY NOZZLE PERCENT:3", new ValueEntry("Percent", 0) }, + { "TURB ENG PRIMARY NOZZLE PERCENT:4", new ValueEntry("Percent", 0) }, + { "NAV OBS:1", new ValueEntry("Degrees", 0) }, + { "NAV OBS:2", new ValueEntry("Degrees", 0) }, + { "NAV DME:1", new ValueEntry("Nautical miles", 1) }, + { "NAV DME:2", new ValueEntry("Nautical miles", 1) }, + { "NAV DMESPEED:1", new ValueEntry("Knots", 0) }, + { "NAV DMESPEED:2", new ValueEntry("Knots", 0) }, + { "RECIP ENG COWL FLAP POSITION:1", new ValueEntry("Percent", 2) }, + { "TURN COORDINATOR BALL", new ValueEntry("Position 128", 0) }, + { "RECIP ENG MANIFOLD PRESSURE:1", new ValueEntry("Psi", 0) }, + { "RECIP ENG MANIFOLD PRESSURE:2", new ValueEntry("Psi", 0) }, + { "RECIP ENG MANIFOLD PRESSURE:3", new ValueEntry("Psi", 0) }, + { "RECIP ENG MANIFOLD PRESSURE:4", new ValueEntry("Psi", 0) }, + { "TURB ENG JET THRUST:1", new ValueEntry("Pounds", 2) }, + { "TURB ENG JET THRUST:2", new ValueEntry("Pounds", 2) }, + { "TURB ENG JET THRUST:3", new ValueEntry("Pounds", 2) }, + { "TURB ENG JET THRUST:4", new ValueEntry("Pounds", 2) }, + { "PROP THRUST:1", new ValueEntry("Pounds", 2) }, + { "PROP THRUST:2", new ValueEntry("Pounds", 2) }, + { "PROP THRUST:3", new ValueEntry("Pounds", 2) }, + { "PROP THRUST:4", new ValueEntry("Pounds", 2) }, + { "PROP RPM:1", new ValueEntry("Rpm", 1) }, + { "PROP RPM:2", new ValueEntry("Rpm", 1) }, + { "PROP RPM:3", new ValueEntry("Rpm", 1) }, + { "PROP RPM:4", new ValueEntry("Rpm", 1) }, + { "ENG CYLINDER HEAD TEMPERATURE:1", new ValueEntry("Celsius", 0) }, + { "ENG CYLINDER HEAD TEMPERATURE:2", new ValueEntry("Celsius", 0) }, + { "ENG CYLINDER HEAD TEMPERATURE:3", new ValueEntry("Celsius", 0) }, + { "ENG CYLINDER HEAD TEMPERATURE:4", new ValueEntry("Celsius", 0) }, + { "RECIP ENG CYLINDER HEAD TEMPERATURE:1", new ValueEntry("Celsius", 0) }, + { "RECIP ENG CYLINDER HEAD TEMPERATURE:2", new ValueEntry("Celsius", 0) }, + { "RECIP ENG CYLINDER HEAD TEMPERATURE:3", new ValueEntry("Celsius", 0) }, + { "RECIP ENG CYLINDER HEAD TEMPERATURE:4", new ValueEntry("Celsius", 0) }, + { "ENG OIL TEMPERATURE:1", new ValueEntry("Celsius", 0) }, + { "ENG OIL TEMPERATURE:2", new ValueEntry("Celsius", 0) }, + { "ENG OIL TEMPERATURE:3", new ValueEntry("Celsius", 0) }, + { "ENG OIL TEMPERATURE:4", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG OIL TEMPERATURE:1", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG OIL TEMPERATURE:2", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG OIL TEMPERATURE:3", new ValueEntry("Celsius", 0) }, + { "GENERAL ENG OIL TEMPERATURE:4", new ValueEntry("Celsius", 0) }, + { "ENG OIL PRESSURE:1", new ValueEntry("Psi", 0) }, + { "ENG OIL PRESSURE:2", new ValueEntry("Psi", 0) }, + { "ENG OIL PRESSURE:3", new ValueEntry("Psi", 0) }, + { "ENG OIL PRESSURE:4", new ValueEntry("Psi", 0) }, + { "GENERAL ENG OIL PRESSURE:1", new ValueEntry("Psi", 0) }, + { "GENERAL ENG OIL PRESSURE:2", new ValueEntry("Psi", 0) }, + { "GENERAL ENG OIL PRESSURE:3", new ValueEntry("Psi", 0) }, + { "GENERAL ENG OIL PRESSURE:4", new ValueEntry("Psi", 0) }, + { "RECIP CARBURETOR TEMPERATURE:1", new ValueEntry("Celsius", 0) }, + { "RECIP CARBURETOR TEMPERATURE:2", new ValueEntry("Celsius", 0) }, + { "RECIP CARBURETOR TEMPERATURE:3", new ValueEntry("Celsius", 0) }, + { "RECIP CARBURETOR TEMPERATURE:4", new ValueEntry("Celsius", 0) }, + { "GYRO DRIFT ERROR", new ValueEntry("Degrees", 0) }, + { "HEADING INDICATOR", new ValueEntry("Degrees", 0) }, + { "THROTTLE LOWER LIMIT", new ValueEntry("Percent", 2) }, + + { "NUMBER OF ENGINES", null }, + { "MASTER IGNITION SWITCH", null }, + { "ENG COMBUSTION", null }, + { "GENERAL ENG COMBUSTION:1", null }, + { "GENERAL ENG COMBUSTION:2", null }, + { "GENERAL ENG COMBUSTION:3", null }, + { "GENERAL ENG COMBUSTION:4", null }, + { "GENERAL ENG MASTER ALTERNATOR:1", null }, + { "GENERAL ENG MASTER ALTERNATOR:2", null }, + { "GENERAL ENG FUEL PUMP SWITCH:1", null }, + { "GENERAL ENG FUEL PUMP SWITCH:2", null }, + { "GENERAL ENG FUEL PUMP SWITCH:3", null }, + { "GENERAL ENG FUEL PUMP SWITCH:4", null }, + { "GENERAL ENG FUEL PUMP SWITCH EX1:1", null }, + { "GENERAL ENG FUEL PUMP SWITCH EX1:2", null }, + { "GENERAL ENG FUEL PUMP SWITCH EX1:3", null }, + { "GENERAL ENG FUEL PUMP SWITCH EX1:4", null }, + { "GENERAL ENG FUEL PUMP ON:1", null }, + { "GENERAL ENG FUEL PUMP ON:2", null }, + { "GENERAL ENG FUEL PUMP ON:3", null }, + { "GENERAL ENG FUEL PUMP ON:4", null }, + { "GENERAL ENG STARTER:1", null }, + { "GENERAL ENG STARTER:2", null }, + { "GENERAL ENG STARTER:3", null }, + { "GENERAL ENG STARTER:4", null }, + { "GENERAL ENG GENERATOR SWITCH:1", null }, + { "GENERAL ENG GENERATOR SWITCH:2", null }, + { "GENERAL ENG GENERATOR SWITCH:3", null }, + { "GENERAL ENG GENERATOR SWITCH:4", null }, + { "GENERAL ENG GENERATOR ACTIVE:1", null }, + { "GENERAL ENG GENERATOR ACTIVE:2", null }, + { "GENERAL ENG GENERATOR ACTIVE:3", null }, + { "GENERAL ENG GENERATOR ACTIVE:4", null }, + { "GENERAL ENG ANTI ICE POSITION:1", null }, + { "GENERAL ENG ANTI ICE POSITION:2", null }, + { "GENERAL ENG ANTI ICE POSITION:3", null }, + { "GENERAL ENG ANTI ICE POSITION:4", null }, + { "GENERAL ENG FUEL VALVE:1", null }, + { "GENERAL ENG FUEL VALVE:2", null }, + { "GENERAL ENG FUEL VALVE:3", null }, + { "GENERAL ENG FUEL VALVE:4", null }, + { "GENERAL ENG STARTER ACTIVE", null }, + { "TURB ENG IGNITION ON", null }, + { "TURB ENG MASTER STARTER SWITCH", null }, + { "TURB ENG AFTERBURNER STAGE ACTIVE", null }, + { "FUEL TANK SELECTOR:1", null }, + { "FUEL TANK SELECTOR:2", null }, + { "FUEL TANK SELECTOR:3", null }, + { "FUEL TANK SELECTOR:4", null }, + { "FUEL TRANSFER PUMP ON:1", null }, + { "FUEL TRANSFER PUMP ON:2", null }, + { "FUEL TRANSFER PUMP ON:3", null }, + { "FUEL TRANSFER PUMP ON:4", null }, + { "NUM FUEL SELECTORS", null }, + { "UNLIMITED FUEL", null }, + { "LIGHT STROBE", null }, + { "LIGHT PANEL", null }, + { "LIGHT LANDING", null }, + { "LIGHT TAXI", null }, + { "LIGHT BEACON", null }, + { "LIGHT NAV", null }, + { "LIGHT LOGO", null }, + { "LIGHT WING", null }, + { "LIGHT RECOGNITION", null }, + { "LIGHT CABIN", null }, + { "LIGHT TAXI ON", null }, + { "LIGHT STROBE ON", null }, + { "LIGHT PANEL ON", null }, + { "LIGHT RECOGNITION ON", null }, + { "LIGHT WING ON", null }, + { "LIGHT LOGO ON", null }, + { "LIGHT CABIN ON", null }, + { "LIGHT CABIN ON:1", null }, + { "LIGHT CABIN ON:2", null }, + { "LIGHT CABIN ON:3", null }, + { "LIGHT CABIN ON:4", null }, + { "LIGHT HEAD ON", null }, + { "LIGHT BRAKE ON", null }, + { "LIGHT NAV ON", null }, + { "LIGHT BEACON ON", null }, + { "LIGHT LANDING ON", null }, + { "LIGHT PANEL POWER SETTING:1", null }, + { "LIGHT PANEL POWER SETTING:2", null }, + { "LIGHT PANEL POWER SETTING:3", null }, + { "LIGHT PANEL POWER SETTING:4", null }, + { "LIGHT CABIN POWER SETTING:1", null }, + { "LIGHT CABIN POWER SETTING:2", null }, + { "LIGHT CABIN POWER SETTING:3", null }, + { "LIGHT CABIN POWER SETTING:4", null }, + { "PROP DEICE SWITCH:1", null }, + { "PROP DEICE SWITCH:2", null }, + { "PROP DEICE SWITCH:3", null }, + { "PROP DEICE SWITCH:4", null }, + { "SIM ON GROUND", null }, + { "STALL WARNING", null }, + { "OVERSPEED WARNING", null }, + { "ATTITUDE CAGE", null }, + { "AVIONICS MASTER SWITCH", null }, + { "DME SOUND", null }, + { "TACAN DME SOUND", null }, + { "MARKER SOUND", null }, + { "INNER MARKER", null }, + { "MIDDLE MARKER", null }, + { "OUTER MARKER", null }, + { "HSI CDI NEEDLE", null }, + { "HSI GSI NEEDLE", null }, + { "HSI CDI NEEDLE VALID", null }, + { "HSI GSI NEEDLE VALID", null }, + { "HSI BEARING VALID", null }, + { "HSI HAS LOCALIZER", null }, + { "GPS IS ACTIVE FLIGHT PLAN", null }, + { "GPS IS ACTIVE WAY POINT", null }, + { "GPS IS ARRIVED", null }, + { "GPS IS DIRECTTO FLIGHTPLAN", null }, + { "GPS WP PREV VALID", null }, + { "GPS FLIGHT PLAN WP INDEX", null }, + { "GPS FLIGHT PLAN WP COUNT", null }, + { "GPS IS ACTIVE WP LOCKED", null }, + { "GPS IS APPROACH LOADED", null }, + { "GPS IS APPROACH ACTIVE", null }, + { "GPS APPROACH IS WP RUNWAY", null }, + { "GPS APPROACH APPROACH INDEX", null }, + { "GPS APPROACH TRANSITION INDEX", null }, + { "GPS APPROACH IS FINAL", null }, + { "GPS APPROACH IS MISSED", null }, + { "GPS APPROACH WP INDEX", null }, + { "GPS APPROACH WP COUNT", null }, + { "GPS DRIVES NAV1", null }, + { "COM RECIEVE ALL", null }, + { "COM RECEIVE ALL", null }, + { "COM TRANSMIT:1", null }, + { "COM TRANSMIT:2", null }, + { "COM STATUS:1", null }, + { "COM STATUS:2", null }, + { "COM AVAILABLE", null }, + { "COM TEST:1", null }, + { "COM TEST:2", null }, + { "ADF IDENT", null }, + { "ADF NAME", null }, + { "NAV IDENT", null }, + { "NAV NAME", null }, + { "TACAN IDENT", null }, + { "TACAN NAME", null }, + { "NAV GLIDE SLOPE", null }, + { "SELECTED DME", null }, + { "GPS WP NEXT ID", null }, + { "GPS WP PREV ID", null }, + { "BRAKE PARKING POSITION", null }, + { "BRAKE PARKING INDICATOR", null }, + { "SPOILERS ARMED", null }, + { "FLAPS HANDLE INDEX", null }, + { "FLAPS NUM HANDLE POSITIONS", null }, + { "FLAP DAMAGE BY SPEED", null }, + { "FLAP SPEED EXCEEDED", null }, + { "ALTERNATE STATIC SOURCE OPEN", null }, + { "FOLDING WING HANDLE POSITION", null }, + { "FUEL DUMP SWITCH", null }, + { "AUTOPILOT AVAILABLE", null }, + { "AUTOPILOT MASTER", null }, + { "AUTOPILOT DISENGAGED", null }, + { "AUTOPILOT NAV SELECTED", null }, + { "AUTOPILOT WING LEVELER", null }, + { "AUTOPILOT NAV1 LOCK", null }, + { "AUTOPILOT HEADING LOCK", null }, + { "AUTOPILOT HEADING SLOT INDEX", null }, + { "AUTOPILOT ALTITUDE LOCK", null }, + { "AUTOPILOT ALTITUDE SLOT INDEX", null }, + { "AUTOPILOT ATTITUDE HOLD", null }, + { "AUTOPILOT GLIDESLOPE HOLD", null }, + { "AUTOPILOT APPROACH HOLD", null }, + { "AUTOPILOT BACKCOURSE HOLD", null }, + { "AUTOPILOT PITCH HOLD", null }, + { "AUTOPILOT FLIGHT DIRECTOR ACTIVE", null }, + { "AUTOPILOT AIRSPEED HOLD", null }, + { "AUTOPILOT SPEED SLOT INDEX", null }, + { "AUTOPILOT FLIGHT LEVEL CHANGE", null }, + { "AUTOPILOT MACH HOLD", null }, + { "AUTOPILOT MACH HOLD VAR", null }, + { "AUTOPILOT YAW DAMPER", null }, + { "AUTOPILOT RPM HOLD VAR", null }, + { "AUTOPILOT THROTTLE ARM", null }, + { "AUTOPILOT TAKEOFF POWER ACTIVE", null }, + { "AUTOTHROTTLE ACTIVE", null }, + { "AUTOPILOT VERTICAL HOLD", null }, + { "AUTOPILOT RPM HOLD", null }, + { "FLY BY WIRE ELAC SWITCH", null }, + { "FLY BY WIRE FAC SWITCH", null }, + { "FLY BY WIRE SEC SWITCH", null }, + { "FLY BY WIRE ELAC FAILED", null }, + { "FLY BY WIRE FAC FAILED", null }, + { "FLY BY WIRE SEC FAILED", null }, + { "IS GEAR RETRACTABLE", null }, + { "IS GEAR SKIS", null }, + { "IS GEAR FLOATS", null }, + { "IS GEAR SKIDS", null }, + { "IS GEAR WHEELS", null }, + { "GEAR HANDLE POSITION", null }, + { "TAILWHEEL LOCK ON", null }, + { "AUTO BRAKE SWITCH CB", null }, + { "GEAR EMERGENCY HANDLE POSITION", null }, + { "ANTISKID BRAKES ACTIVE", null }, + { "RETRACT FLOAT SWITCH", null }, + { "GEAR DAMAGE BY SPEED", null }, + { "GEAR SPEED EXCEEDED", null }, + { "NOSEWHEEL LOCK ON", null }, + { "AMBIENT IN CLOUD", null }, + { "SMOKE ENABLE", null }, + { "PITOT HEAT", null }, + { "IS TAIL DRAGGER", null }, + { "ELECTRICAL MASTER BATTERY", null }, + { "ELECTRICAL MASTER BATTERY:1", null }, + { "ELECTRICAL MASTER BATTERY:2", null }, + { "ELECTRIC GPU ACTIVE", null }, + { "ELECTRIC GPU SWITCH", null }, + { "CIRCUIT GENERAL PANEL ON", null }, + { "CIRCUIT FLAP MOTOR ON", null }, + { "CIRCUIT GEAR MOTOR ON", null }, + { "CIRCUIT AUTOPILOT ON", null }, + { "CIRCUIT AVIONICS ON", null }, + { "CIRCUIT PITOT HEAT ON", null }, + { "CIRCUIT PROP SYNC ON", null }, + { "CIRCUIT AUTO FEATHER ON", null }, + { "CIRCUIT AUTO BRAKES ON", null }, + { "CIRCUIT STANDY VACUUM ON", null }, + { "CIRCUIT MARKER BEACON ON", null }, + { "CIRCUIT GEAR WARNING ON", null }, + { "CIRCUIT HYDRAULIC PUMP ON", null }, + { "STRUCTURAL DEICE SWITCH", null }, + { "APPLY HEAT TO SYSTEMS", null }, + { "IS USER SIM", null }, + { "LABEL SUPPORTED", null }, + { "SIM DISABLED", null }, + { "ATC HEAVY", null }, + { "AUTO COORDINATION", null }, + { "REALISM", null }, + { "TRUE AIRSPEED SELECTED", null }, + { "IS SLEW ACTIVE", null }, + { "IS SLEW ALLOWED", null }, + { "PAYLOAD STATION COUNT", null }, + { "USER INPUT ENABLED", null }, + { "CATEGORY", null }, + { "SIGMA SQRT", null }, + { "VARIOMETER SWITCH", null }, + { "TURN INDICATOR SWITCH", null }, + { "PANEL ANTI ICE SWITCH", null }, + { "PAYLOAD STATION NAME", null }, + { "WATER BALLAST VALVE", null }, + { "FULL THROTTLE THRUST TO WEIGHT RATIO", null }, + { "PROP AUTO CRUISE ACTIVE", null }, + { "DROPPABLE OBJECTS UI NAME", null }, + { "HYDRAULIC SWITCH", null }, + { "REALISM CRASH WITH OTHERS", null }, + { "REALISM CRASH DETECTION", null }, + { "MANUAL INSTRUMENT LIGHTS", null }, + { "RAD INS SWITCH", null }, + { "SURFACE INFO VALID", null }, + { "PUSHBACK WAIT", null }, + { "TOW CONNECTION", null }, + { "APU GENERATOR SWITCH", null }, + { "APU GENERATOR ACTIVE", null }, + { "APU ON FIRE DETECTED", null }, + { "PRESSURIZATION DUMP SWITCH", null }, + { "FIRE BOTTLE SWITCH", null }, + { "FIRE BOTTLE DISCHARGED", null }, + { "CABIN NO SMOKING ALERT SWITCH", null }, + { "CABIN SEATBELTS ALERT SWITCH", null }, + { "GPWS WARNING", null }, + { "GPWS SYSTEM ACTIVE", null }, + { "IS LATITUDE LONGITUDE FREEZE ON", null }, + { "IS ALTITUDE FREEZE ON", null }, + { "IS ATTITUDE FREEZE ON", null }, + { "ENG TORQUE:1", null }, + { "ENG TORQUE:2", null }, + { "ENG TORQUE:3", null }, + { "ENG TORQUE:4", null }, + { "TURB ENG FREE TURBINE TORQUE:1", null }, + { "TURB ENG FREE TURBINE TORQUE:2", null }, + { "TURB ENG FREE TURBINE TORQUE:3", null }, + { "TURB ENG FREE TURBINE TORQUE:4", null }, + { "TRANSPONDER CODE:1", null }, + { "TRANSPONDER STATE:1", null }, + { "NAV SOUND:1", null }, + { "NAV SOUND:2", null }, + { "SIMULATION RATE", null }, + { "COM SPACING MODE", null }, + { "ANGLE OF ATTACK INDICATOR", null }, + { "PLANE IN PARKING STATE", null }, + { "MASTER CAUTION ACTIVE", null }, + { "MASTER WARNING ACTIVE", null }, + { "MASTER CAUTION ACKNOWLEDGED", null }, + { "MASTER WARNING ACKNOWLEDGED", null }, + + { "ABSOLUTE TIME", null }, + { "ZULU TIME", null }, + { "LOCAL TIME", null }, + }; + + public static bool IsKnown(this string value) + => availableValues.ContainsKey(value); + + public static string GetUnit(this string value, string? unit) + { + if (!string.IsNullOrEmpty(unit)) + { + // TODO: add some validation + return unit; + } + else if (availableValues.TryGetValue(value, out var availableEntry) && availableEntry != null) + { + return availableEntry.Unit; + } + return DEFAULT_UNIT; + } + + public static int GetDecimals(this string value, int? decimals = null) + { + if (decimals.HasValue) + { + return decimals.Value; + } + else if (availableValues.TryGetValue(value, out var availableEntry) && availableEntry != null) + { + return availableEntry.Decimals; + } + + return DEFAULT_DECIMALS; + } +} diff --git a/FlightStreamDeck.Logics/SimVarManager.cs b/FlightStreamDeck.Logics/SimVarManager.cs new file mode 100644 index 0000000..082ae46 --- /dev/null +++ b/FlightStreamDeck.Logics/SimVarManager.cs @@ -0,0 +1,75 @@ +using FlightStreamDeck.Core; +using System.Collections.Generic; + +namespace FlightStreamDeck.Logics; + +public class SimVarManager +{ + private readonly ILogger logger; + private readonly IFlightConnector flightConnector; + + public SimVarManager(ILogger logger, IFlightConnector flightConnector) + { + this.logger = logger; + this.flightConnector = flightConnector; + } + + public SimVarRegistration? GetRegistration(string? name, string? unit = null) + { + if (string.IsNullOrWhiteSpace(name)) return null; + + unit = string.IsNullOrWhiteSpace(unit) ? null : unit.Trim(); + name = name.Trim(); + + if (!name.StartsWith("L:")) + { + name = name.Replace("__", ":").Replace("_", " "); + } + + if (name.IsKnown()) + { + // Variable is in the enum list + } + if (unit == null) + { + unit = name.GetUnit(unit); + } + return new SimVarRegistration(name, unit); + } + + public void RegisterSimValues(params SimVarRegistration[] registrations) + { + flightConnector.RegisterSimValues(FilterRegistrations(registrations)); + } + + public void DeRegisterSimValues(params SimVarRegistration[] registrations) + { + flightConnector.DeRegisterSimValues(FilterRegistrations(registrations)); + } + + private IEnumerable FilterRegistrations(IEnumerable registrations) + { + foreach (var registration in registrations) + { + var variable = registration.variableName; + var unit = registration.variableUnit; + if (variable.IsKnown()) + { + // Variable is in the enum list + var unitFinal = variable.GetUnit(unit); + + yield return new(variable, unitFinal); + } + else if (variable.StartsWith("L:")) + { + // LVar + yield return registration; + } + else + { + // Unknown + logger.LogInformation("Unknown variable {variable}", variable); + } + } + } +} diff --git a/FlightStreamDeck.LogicsTests/Actions/NavCom/AdfHandlerTests.cs b/FlightStreamDeck.LogicsTests/Actions/NavCom/AdfHandlerTests.cs index 8778556..fd13acc 100644 --- a/FlightStreamDeck.LogicsTests/Actions/NavCom/AdfHandlerTests.cs +++ b/FlightStreamDeck.LogicsTests/Actions/NavCom/AdfHandlerTests.cs @@ -14,16 +14,20 @@ public async Task TestSetAdf1200() new LoggerFactory().CreateLogger(), mockFlightConnector.Object ); + var simVarManager = new SimVarManager( + new LoggerFactory().CreateLogger(), + mockFlightConnector.Object + ); var registration = eventManager.RegisterEvent(KnownEvents.ADF_STBY_SET.ToString()); Assert.IsNotNull(registration); var adfHandler = new AdfHandler( - mockFlightConnector.Object, eventManager, eventManager, - Core.TOGGLE_VALUE.ADF_ACTIVE_FREQUENCY__1, - Core.TOGGLE_VALUE.ADF_STANDBY_FREQUENCY__1, + simVarManager, + "ADF ACTIVE FREQUENCY:1", + "ADF STANDBY FREQUENCY:1", null, null, KnownEvents.ADF1_RADIO_SWAP, @@ -44,16 +48,20 @@ public async Task TestSetAdf120() new LoggerFactory().CreateLogger(), mockFlightConnector.Object ); + var simVarManager = new SimVarManager( + new LoggerFactory().CreateLogger(), + mockFlightConnector.Object + ); var registration = eventManager.RegisterEvent(KnownEvents.ADF_STBY_SET.ToString()); Assert.IsNotNull(registration); var adfHandler = new AdfHandler( - mockFlightConnector.Object, eventManager, eventManager, - Core.TOGGLE_VALUE.ADF_ACTIVE_FREQUENCY__1, - Core.TOGGLE_VALUE.ADF_STANDBY_FREQUENCY__1, + simVarManager, + "ADF ACTIVE FREQUENCY:1", + "ADF STANDBY FREQUENCY:1", null, null, KnownEvents.ADF1_RADIO_SWAP, diff --git a/FlightStreamDeck.LogicsTests/ComparisonEvaluatorTests.cs b/FlightStreamDeck.LogicsTests/ComparisonEvaluatorTests.cs index a91657c..c49eb85 100644 --- a/FlightStreamDeck.LogicsTests/ComparisonEvaluatorTests.cs +++ b/FlightStreamDeck.LogicsTests/ComparisonEvaluatorTests.cs @@ -1,149 +1,157 @@ using System.Collections.Generic; using System.Linq; -namespace FlightStreamDeck.Logics.Tests +namespace FlightStreamDeck.Logics.Tests; + +[TestClass] +public class ComparisonEvaluatorTests { - [TestClass] - public class ComparisonEvaluatorTests + private void Workhorse(double currentValue, double comparisonValue, List expectedTrueComparisons) { - private void Workhorse(double currentValue, double comparisonValue, List expectedTrueComparisons) - { - List errors = new List(); + Mock mockFlightConnector = new Mock(); + var simVarManager = new SimVarManager( + new LoggerFactory().CreateLogger(), + mockFlightConnector.Object + ); - var evaluator = new ComparisonEvaluator(new Core.EnumConverter()); + var evaluator = new ComparisonEvaluator(simVarManager); - //Act - ComparisonEvaluator.AllowedComparisons.ForEach((string comparisonType) => + //Act + var errors = new List(); + ComparisonEvaluator.AllowedComparisons.ForEach((string comparisonType) => + { + (var variables, var expression) = evaluator.Parse($"GENERAL ENG OIL PRESSURE:1 {comparisonType} {comparisonValue}"); + bool status = expression.Evaluate(new Dictionary { - bool status = evaluator.CompareValues(currentValue, comparisonValue, comparisonType); - - if (expectedTrueComparisons.Contains(comparisonType) && !status) errors.Add($"{comparisonType} was not {!status}, but should have been."); - if (!expectedTrueComparisons.Contains(comparisonType) && status) errors.Add($"{comparisonType} was {status}, but should not have been."); + [new("GENERAL ENG OIL PRESSURE:1", "Psi")] = currentValue }); - //Assert - Assert.IsFalse(errors.Any(), string.Join(" | ", errors)); - } + if (expectedTrueComparisons.Contains(comparisonType) && !status) errors.Add($"{comparisonType} was not {!status}, but should have been."); + if (!expectedTrueComparisons.Contains(comparisonType) && status) errors.Add($"{comparisonType} was {status}, but should not have been."); + }); + + //Assert + Assert.IsFalse(errors.Any(), string.Join(" | ", errors)); + } - #region Numeric Comparison + #region Numeric Comparison - [TestMethod] - public void CompareValuesTest_Same_Value_Numeric() - { - //Arrange - var currentValue = 0; - var comparisonValue = 0; - List expectedTrueComparisons = new List { - ComparisonEvaluator.OperatorTruncatedEquals, - ComparisonEvaluator.OperatorEquals, - ComparisonEvaluator.OperatorGreaterOrEquals, - ComparisonEvaluator.OperatorLessOrEquals - }; - - //Act - Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - } - - [TestMethod] - public void CompareValuesTest_Same_Truncated_Value_Numeric() - { - //Arrange - var currentValue = 1.7; - var comparisonValue = 1; - List expectedTrueComparisons = new List { - ComparisonEvaluator.OperatorTruncatedEquals, - ComparisonEvaluator.OperatorNotEquals, - ComparisonEvaluator.OperatorGreaterOrEquals, - ComparisonEvaluator.OperatorGreater - }; - - //Act - Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - } - - [TestMethod] - public void CompareValuesTest_Different_Value_Greater_Numeric() - { - //Arrange - var currentValue = 1; - var comparisonValue = 0; - List expectedTrueComparisons = new List { - ComparisonEvaluator.OperatorNotEquals, - ComparisonEvaluator.OperatorGreaterOrEquals, - ComparisonEvaluator.OperatorGreater - }; - - //Act - Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - } - - [TestMethod] - public void CompareValuesTest_Different_Value_Less_Numeric() - { - //Arrange - var currentValue = -1; - var comparisonValue = 0; - List expectedTrueComparisons = new List { - ComparisonEvaluator.OperatorNotEquals, - ComparisonEvaluator.OperatorLessOrEquals, - ComparisonEvaluator.OperatorLess - }; - - //Act - Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - } - #endregion - - #region Alpha Comparison - - //[TestMethod] - //public void CompareValuesTest_Same_Value_Alpha() - //{ - // //Arrange - // string currentValue = "m"; - // string comparisonValue = "m"; - // List expectedTrueComparisons = new List { - // ComparisonEvaluator.OperatorEquals, - // ComparisonEvaluator.OperatorGreaterOrEquals, - // ComparisonEvaluator.OperatorLessOrEquals - // }; - - // //Act - // Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - //} - - //[TestMethod] - //public void CompareValuesTest_Different_Value_Greater_Alpha() - //{ - // //Arrange - // string currentValue = "n"; - // string comparisonValue = "m"; - // List expectedTrueComparisons = new List { - // ComparisonEvaluator.OperatorNotEquals, - // ComparisonEvaluator.OperatorGreaterOrEquals, - // ComparisonEvaluator.OperatorGreater - // }; - - // //Act - // Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - //} - - //[TestMethod] - //public void CompareValuesTest_Different_Value_Less_Alpha() - //{ - // //Arrange - // string currentValue = "l"; - // string comparisonValue = "m"; - // List expectedTrueComparisons = new List { - // ComparisonEvaluator.OperatorNotEquals, - // ComparisonEvaluator.OperatorLessOrEquals, - // ComparisonEvaluator.OperatorLess - // }; - - // //Act - // Workhorse(currentValue, comparisonValue, expectedTrueComparisons); - //} - - #endregion + [TestMethod] + public void CompareValuesTest_Same_Value_Numeric() + { + //Arrange + var currentValue = 0; + var comparisonValue = 0; + List expectedTrueComparisons = new List { + ComparisonEvaluator.OperatorTruncatedEquals, + ComparisonEvaluator.OperatorEquals, + ComparisonEvaluator.OperatorGreaterOrEquals, + ComparisonEvaluator.OperatorLessOrEquals + }; + + //Act + Workhorse(currentValue, comparisonValue, expectedTrueComparisons); + } + + [TestMethod] + public void CompareValuesTest_Same_Truncated_Value_Numeric() + { + //Arrange + var currentValue = 1.7; + var comparisonValue = 1; + List expectedTrueComparisons = new List { + ComparisonEvaluator.OperatorTruncatedEquals, + ComparisonEvaluator.OperatorNotEquals, + ComparisonEvaluator.OperatorGreaterOrEquals, + ComparisonEvaluator.OperatorGreater + }; + + //Act + Workhorse(currentValue, comparisonValue, expectedTrueComparisons); + } + + [TestMethod] + public void CompareValuesTest_Different_Value_Greater_Numeric() + { + //Arrange + var currentValue = 1; + var comparisonValue = 0; + List expectedTrueComparisons = new List { + ComparisonEvaluator.OperatorNotEquals, + ComparisonEvaluator.OperatorGreaterOrEquals, + ComparisonEvaluator.OperatorGreater + }; + + //Act + Workhorse(currentValue, comparisonValue, expectedTrueComparisons); + } + + [TestMethod] + public void CompareValuesTest_Different_Value_Less_Numeric() + { + //Arrange + var currentValue = -1; + var comparisonValue = 0; + List expectedTrueComparisons = new List { + ComparisonEvaluator.OperatorNotEquals, + ComparisonEvaluator.OperatorLessOrEquals, + ComparisonEvaluator.OperatorLess + }; + + //Act + Workhorse(currentValue, comparisonValue, expectedTrueComparisons); } + #endregion + + #region Alpha Comparison + + //[TestMethod] + //public void CompareValuesTest_Same_Value_Alpha() + //{ + // //Arrange + // string currentValue = "m"; + // string comparisonValue = "m"; + // List expectedTrueComparisons = new List { + // ComparisonEvaluator.OperatorEquals, + // ComparisonEvaluator.OperatorGreaterOrEquals, + // ComparisonEvaluator.OperatorLessOrEquals + // }; + + // //Act + // Workhorse(currentValue, comparisonValue, expectedTrueComparisons); + //} + + //[TestMethod] + //public void CompareValuesTest_Different_Value_Greater_Alpha() + //{ + // //Arrange + // string currentValue = "n"; + // string comparisonValue = "m"; + // List expectedTrueComparisons = new List { + // ComparisonEvaluator.OperatorNotEquals, + // ComparisonEvaluator.OperatorGreaterOrEquals, + // ComparisonEvaluator.OperatorGreater + // }; + + // //Act + // Workhorse(currentValue, comparisonValue, expectedTrueComparisons); + //} + + //[TestMethod] + //public void CompareValuesTest_Different_Value_Less_Alpha() + //{ + // //Arrange + // string currentValue = "l"; + // string comparisonValue = "m"; + // List expectedTrueComparisons = new List { + // ComparisonEvaluator.OperatorNotEquals, + // ComparisonEvaluator.OperatorLessOrEquals, + // ComparisonEvaluator.OperatorLess + // }; + + // //Act + // Workhorse(currentValue, comparisonValue, expectedTrueComparisons); + //} + + #endregion } \ No newline at end of file diff --git a/FlightStreamDeck.LogicsTests/EnumConverterTests.cs b/FlightStreamDeck.LogicsTests/EnumConverterTests.cs deleted file mode 100644 index 287cbb8..0000000 --- a/FlightStreamDeck.LogicsTests/EnumConverterTests.cs +++ /dev/null @@ -1,52 +0,0 @@ -using FlightStreamDeck.Core; - -namespace FlightStreamDeck.Logics.Tests -{ - [TestClass] - public class EnumConverterTests - { - readonly EnumConverter enumConverter = new EnumConverter(); - - #region Settings initialization - - [TestMethod] - public void InitializeToggleParameter_Parses_All_Numeric_To_UInt() - { - (var dataUInt, var variable) = enumConverter.GetUIntOrVariable("1234"); - - Assert.AreEqual(1234U, dataUInt); - Assert.IsNull(variable); - } - - [TestMethod] - public void InitializeToggleParameter_Null_for_Not_Set() - { - (var dataUInt, var variable) = enumConverter.GetUIntOrVariable(null); - - Assert.IsNull(dataUInt); - Assert.IsNull(variable); - } - - [TestMethod] - public void InitializeToggleParameter_Strings_Invalid_Variable() - { - string input = "beep 123 some text"; - (var dataUInt, var variable) = enumConverter.GetUIntOrVariable(input); - - Assert.IsNull(dataUInt); - Assert.IsNull(variable); - } - - [TestMethod] - public void InitializeToggleParameter_Strings_Valid_Variablef() - { - string input = "GENERAL ENG COMBUSTION:1"; - (var dataUInt, var variable) = enumConverter.GetUIntOrVariable(input); - - Assert.IsNull(dataUInt); - Assert.AreEqual(TOGGLE_VALUE.GENERAL_ENG_COMBUSTION__1, variable); - } - - #endregion - } -} \ No newline at end of file diff --git a/FlightStreamDeck.LogicsTests/FlightStreamDeck.LogicsTests.csproj b/FlightStreamDeck.LogicsTests/FlightStreamDeck.LogicsTests.csproj index fc03533..2f6766a 100644 --- a/FlightStreamDeck.LogicsTests/FlightStreamDeck.LogicsTests.csproj +++ b/FlightStreamDeck.LogicsTests/FlightStreamDeck.LogicsTests.csproj @@ -33,6 +33,9 @@ PreserveNewest + + PreserveNewest + diff --git a/FlightStreamDeck.LogicsTests/ImageLogicTests.cs b/FlightStreamDeck.LogicsTests/ImageLogicTests.cs index 324adf1..c23c959 100644 --- a/FlightStreamDeck.LogicsTests/ImageLogicTests.cs +++ b/FlightStreamDeck.LogicsTests/ImageLogicTests.cs @@ -1,84 +1,83 @@ using System; using System.IO; -namespace FlightStreamDeck.Logics.Tests +namespace FlightStreamDeck.Logics.Tests; + +[TestClass] +public class ImageLogicTests { - [TestClass] - public class ImageLogicTests + [TestMethod] + public void GetHorizonImageTest() { - [TestMethod] - public void GetHorizonImageTest() - { - ImageLogic images = new ImageLogic(); - - string result = images.GetHorizonImage(-10, 20, 359); + ImageLogic images = new ImageLogic(); - var path = @"Images\horizon.png"; + string result = images.GetHorizonImage(-10, 20); - if (File.Exists(path)) - { - File.Delete(path); - } + var path = @"Images\horizon.png"; - using (FileStream fs = File.Create(path)) - { - var bytes = Convert.FromBase64String(result.Substring(23)); - fs.Write(bytes, 0, bytes.Length); - } + if (File.Exists(path)) + { + File.Delete(path); } - [TestMethod] - public void GetHorizonImageBoundaryTest() + using (FileStream fs = File.Create(path)) { - ImageLogic images = new ImageLogic(); + var bytes = Convert.FromBase64String(result.Substring(23)); + fs.Write(bytes, 0, bytes.Length); + } + } - images.GetHorizonImage(-1000, 20, 359); - images.GetHorizonImage(1000, 20, 359); + [TestMethod] + public void GetHorizonImageBoundaryTest() + { + ImageLogic images = new ImageLogic(); - images.GetHorizonImage(-10, 2000, 359); - images.GetHorizonImage(10, -2000, 359); + images.GetHorizonImage(-1000, 20); + images.GetHorizonImage(1000, 20); - images.GetHorizonImage(-10, 20, 3000); - images.GetHorizonImage(10, -20, -3000); - } + images.GetHorizonImage(-10, 2000); + images.GetHorizonImage(10, -2000); - [TestMethod] - public void GetGaugeImageTest() - { - ImageLogic images = new ImageLogic(); + images.GetHorizonImage(-10, 20); + images.GetHorizonImage(10, -20); + } - string result = images.GetGenericGaugeImage("TRQ", 50, 0, 100, null, "F2"); + [TestMethod] + public void GetGaugeImageTest() + { + ImageLogic images = new ImageLogic(); - var path = @"Images\gauge.png"; + string result = images.GetGenericGaugeImage("TRQ", 50, 0, 100, null, "F2"); - if (File.Exists(path)) - { - File.Delete(path); - } + var path = @"Images\gauge.png"; - using (FileStream fs = File.Create(path)) - { - var bytes = Convert.FromBase64String(result.Substring(23)); - fs.Write(bytes, 0, bytes.Length); - } + if (File.Exists(path)) + { + File.Delete(path); } - [TestMethod] - public void GetCustomImageTest_NoCoordinateRangeError() + using (FileStream fs = File.Create(path)) + { + var bytes = Convert.FromBase64String(result.Substring(23)); + fs.Write(bytes, 0, bytes.Length); + } + } + + [TestMethod] + public void GetCustomImageTest_NoCoordinateRangeError() + { + ImageLogic images = new ImageLogic(); + bool hitError = false; + + try { - ImageLogic images = new ImageLogic(); - bool hitError = false; - - try - { - images.GetCustomGaugeImage("T", "B", 2000, -2000, 1, 1, "F2", false, new string[] { "100:green" }, 5, 3, false, false, false); - } - catch (Exception e) - { - hitError = e.Message == "Coordinate outside allowed range"; - } - - Assert.IsFalse(hitError, "we should not have hit a ClipperLib.ClipperException"); + images.GetCustomGaugeImage("T", "B", 2000, -2000, 1, 1, "F2", false, new string[] { "100:green" }, 5, 3, false, false, false); } + catch (Exception e) + { + hitError = e.Message == "Coordinate outside allowed range"; + } + + Assert.IsFalse(hitError, "we should not have hit a ClipperLib.ClipperException"); } } \ No newline at end of file diff --git a/FlightStreamDeck.LogicsTests/Images/Wind.png b/FlightStreamDeck.LogicsTests/Images/Wind.png new file mode 100644 index 0000000..c468d0a Binary files /dev/null and b/FlightStreamDeck.LogicsTests/Images/Wind.png differ diff --git a/FlightStreamDeck.SimConnectFSX/SimConnectFlightConnector.cs b/FlightStreamDeck.SimConnectFSX/SimConnectFlightConnector.cs index d18b8de..241126c 100644 --- a/FlightStreamDeck.SimConnectFSX/SimConnectFlightConnector.cs +++ b/FlightStreamDeck.SimConnectFSX/SimConnectFlightConnector.cs @@ -1,5 +1,4 @@ -using FlightStreamDeck.Core; -using FlightStreamDeck.Logics; +using FlightStreamDeck.Logics; using Microsoft.Extensions.Logging; using Microsoft.FlightSimulator.SimConnect; using System; @@ -10,727 +9,722 @@ using System.Threading; using System.Threading.Tasks; -namespace FlightStreamDeck.SimConnectFSX +namespace FlightStreamDeck.SimConnectFSX; + +public class SimConnectFlightConnector : IFlightConnector { - public class SimConnectFlightConnector : IFlightConnector - { - public event EventHandler? AircraftStatusUpdated; - public event EventHandler? GenericValuesUpdated; - public event EventHandler? InvalidEventRegistered; - public event EventHandler? Closed; + public event EventHandler? AircraftStatusUpdated; + public event EventHandler? GenericValuesUpdated; + public event EventHandler? InvalidEventRegistered; + public event EventHandler? Closed; - // Extra SimConnect functions via native pointer - IntPtr hSimConnect; - [DllImport("SimConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] - private static extern int /* HRESULT */ SimConnect_GetLastSentPacketID(IntPtr hSimConnect, out uint /* DWORD */ dwSendID); + // Extra SimConnect functions via native pointer + IntPtr hSimConnect; + [DllImport("SimConnect.dll", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] + private static extern int /* HRESULT */ SimConnect_GetLastSentPacketID(IntPtr hSimConnect, out uint /* DWORD */ dwSendID); - private const int StatusDelayMilliseconds = 100; + private const int StatusDelayMilliseconds = 100; - /// - /// This is a reference counter to make sure we do not deregister variables that are still in use. - /// - private readonly Dictionary<(TOGGLE_VALUE variables, string? unit), int> genericValues = new(); + /// + /// This is a reference counter to make sure we do not deregister variables that are still in use. + /// + private readonly Dictionary genericValues = new(); - private readonly object lockLists = new object(); + private readonly object lockLists = new object(); - // User-defined win32 event - const int WM_USER_SIMCONNECT = 0x0402; - private readonly ILogger logger; + // User-defined win32 event + const int WM_USER_SIMCONNECT = 0x0402; + private readonly ILogger logger; - public IntPtr Handle { get; private set; } + public IntPtr Handle { get; private set; } - private SimConnect? simconnect = null; - private CancellationTokenSource? cts = null; + private SimConnect? simconnect = null; + private CancellationTokenSource? cts = null; - public SimConnectFlightConnector(ILogger logger) - { - this.logger = logger; - } + public SimConnectFlightConnector(ILogger logger) + { + this.logger = logger; + } - // Simconnect client will send a win32 message when there is - // a packet to process. ReceiveMessage must be called to - // trigger the events. This model keeps simconnect processing on the main thread. - public IntPtr HandleSimConnectEvents(int message, ref bool isHandled) - { - isHandled = false; + // Simconnect client will send a win32 message when there is + // a packet to process. ReceiveMessage must be called to + // trigger the events. This model keeps simconnect processing on the main thread. + public IntPtr HandleSimConnectEvents(int message, ref bool isHandled) + { + isHandled = false; - switch (message) - { - case WM_USER_SIMCONNECT: + switch (message) + { + case WM_USER_SIMCONNECT: + { + if (simconnect != null) { - if (simconnect != null) + try { - try - { - this.simconnect.ReceiveMessage(); - } - catch (Exception ex) - { - RecoverFromError(ex); - } - - isHandled = true; + this.simconnect.ReceiveMessage(); } + catch (Exception ex) + { + RecoverFromError(ex); + } + + isHandled = true; } - break; + } + break; - default: - break; - } + default: + break; + } + + return IntPtr.Zero; + } - return IntPtr.Zero; + // Set up the SimConnect event handlers + public void Initialize(IntPtr Handle) + { + if (simconnect != null) + { + logger.LogWarning("Initialization is already done. Cancelled this request."); + return; } + simconnect = new SimConnect("Flight Tracker Stream Deck", Handle, WM_USER_SIMCONNECT, null, 0); - // Set up the SimConnect event handlers - public void Initialize(IntPtr Handle) + // Get direct access to the SimConnect handle, to use functions otherwise not supported. + var fiSimConnectValue = typeof(SimConnect).GetField("hSimConnect", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(simconnect); + if (fiSimConnectValue == null) { - if (simconnect != null) - { - logger.LogWarning("Initialization is already done. Cancelled this request."); - return; - } - simconnect = new SimConnect("Flight Tracker Stream Deck", Handle, WM_USER_SIMCONNECT, null, 0); + throw new InvalidOperationException("hSimConnect is not available!"); + } + hSimConnect = (IntPtr)fiSimConnectValue; - // Get direct access to the SimConnect handle, to use functions otherwise not supported. - var fiSimConnectValue = typeof(SimConnect).GetField("hSimConnect", BindingFlags.NonPublic | BindingFlags.Instance)?.GetValue(simconnect); - if (fiSimConnectValue == null) - { - throw new InvalidOperationException("hSimConnect is not available!"); - } - hSimConnect = (IntPtr)fiSimConnectValue; + // listen to connect and quit msgs + simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(Simconnect_OnRecvOpen); + simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(Simconnect_OnRecvQuit); - // listen to connect and quit msgs - simconnect.OnRecvOpen += new SimConnect.RecvOpenEventHandler(Simconnect_OnRecvOpen); - simconnect.OnRecvQuit += new SimConnect.RecvQuitEventHandler(Simconnect_OnRecvQuit); + // listen to exceptions + simconnect.OnRecvException += Simconnect_OnRecvException; - // listen to exceptions - simconnect.OnRecvException += Simconnect_OnRecvException; + simconnect.OnRecvSimobjectDataBytype += Simconnect_OnRecvSimobjectDataBytypeAsync; + simconnect.OnRecvSystemState += Simconnect_OnRecvSystemState; - simconnect.OnRecvSimobjectDataBytype += Simconnect_OnRecvSimobjectDataBytypeAsync; - simconnect.OnRecvSystemState += Simconnect_OnRecvSystemState; + RegisterFlightStatusDefinition(simconnect); - RegisterFlightStatusDefinition(simconnect); + simconnect.MapClientEventToSimEvent(EVENTS.AUTOPILOT_ON, "AUTOPILOT_ON"); + simconnect.MapClientEventToSimEvent(EVENTS.AUTOPILOT_OFF, "AUTOPILOT_OFF"); + simconnect.MapClientEventToSimEvent(EVENTS.AUTOPILOT_TOGGLE, "AP_MASTER"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_TOGGLE, "AP_PANEL_HEADING_HOLD"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_NAV_TOGGLE, "AP_NAV1_HOLD"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_APR_TOGGLE, "AP_APR_HOLD"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_TOGGLE, "AP_PANEL_ALTITUDE_HOLD"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_TOGGLE, "AP_VS_HOLD"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_FLC_ON, "FLIGHT_LEVEL_CHANGE_ON"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_FLC_OFF, "FLIGHT_LEVEL_CHANGE_OFF"); - simconnect.MapClientEventToSimEvent(EVENTS.AUTOPILOT_ON, "AUTOPILOT_ON"); - simconnect.MapClientEventToSimEvent(EVENTS.AUTOPILOT_OFF, "AUTOPILOT_OFF"); - simconnect.MapClientEventToSimEvent(EVENTS.AUTOPILOT_TOGGLE, "AP_MASTER"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_TOGGLE, "AP_PANEL_HEADING_HOLD"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_NAV_TOGGLE, "AP_NAV1_HOLD"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_APR_TOGGLE, "AP_APR_HOLD"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_TOGGLE, "AP_PANEL_ALTITUDE_HOLD"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_TOGGLE, "AP_VS_HOLD"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_FLC_ON, "FLIGHT_LEVEL_CHANGE_ON"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_FLC_OFF, "FLIGHT_LEVEL_CHANGE_OFF"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_SET, "HEADING_BUG_SET"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_INC, "HEADING_BUG_INC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_DEC, "HEADING_BUG_DEC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_SET, "HEADING_BUG_SET"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_INC, "HEADING_BUG_INC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_HDG_DEC, "HEADING_BUG_DEC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_SET, "AP_ALT_VAR_SET_ENGLISH"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_INC, "AP_ALT_VAR_INC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_DEC, "AP_ALT_VAR_DEC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_SET, "AP_ALT_VAR_SET_ENGLISH"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_INC, "AP_ALT_VAR_INC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_ALT_DEC, "AP_ALT_VAR_DEC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_SET, "AP_VS_VAR_SET_ENGLISH"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_INC, "AP_VS_VAR_INC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_DEC, "AP_VS_VAR_DEC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_SET, "AP_VS_VAR_SET_ENGLISH"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_INC, "AP_VS_VAR_INC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_VS_DEC, "AP_VS_VAR_DEC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_AIRSPEED_SET, "AP_SPD_VAR_SET"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_AIRSPEED_INC, "AP_SPD_VAR_INC"); + simconnect.MapClientEventToSimEvent(EVENTS.AP_AIRSPEED_DEC, "AP_SPD_VAR_DEC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_AIRSPEED_SET, "AP_SPD_VAR_SET"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_AIRSPEED_INC, "AP_SPD_VAR_INC"); - simconnect.MapClientEventToSimEvent(EVENTS.AP_AIRSPEED_DEC, "AP_SPD_VAR_DEC"); + simconnect.MapClientEventToSimEvent(EVENTS.QNH_SET, "KOHLSMAN_SET"); + simconnect.MapClientEventToSimEvent(EVENTS.QNH_INC, "KOHLSMAN_INC"); + simconnect.MapClientEventToSimEvent(EVENTS.QNH_DEC, "KOHLSMAN_DEC"); - simconnect.MapClientEventToSimEvent(EVENTS.QNH_SET, "KOHLSMAN_SET"); - simconnect.MapClientEventToSimEvent(EVENTS.QNH_INC, "KOHLSMAN_INC"); - simconnect.MapClientEventToSimEvent(EVENTS.QNH_DEC, "KOHLSMAN_DEC"); + simconnect.MapClientEventToSimEvent(EVENTS.AVIONICS_TOGGLE, "AVIONICS_MASTER_SET"); - simconnect.MapClientEventToSimEvent(EVENTS.AVIONICS_TOGGLE, "AVIONICS_MASTER_SET"); + isGenericValueRegistered = false; + RegisterGenericValues(); + } - isGenericValueRegistered = false; - RegisterGenericValues(); - } + public void Send(string message) + { + simconnect?.Text(SIMCONNECT_TEXT_TYPE.PRINT_BLACK, 3, EVENTS.MESSAGE_RECEIVED, message); + } - public void Send(string message) - { - simconnect?.Text(SIMCONNECT_TEXT_TYPE.PRINT_BLACK, 3, EVENTS.MESSAGE_RECEIVED, message); - } + public void ApOn() + { + SendCommand(EVENTS.AUTOPILOT_ON); + } - public void ApOn() - { - SendCommand(EVENTS.AUTOPILOT_ON); - } + public void ApOff() + { + SendCommand(EVENTS.AUTOPILOT_OFF); + } - public void ApOff() - { - SendCommand(EVENTS.AUTOPILOT_OFF); - } + public void ApToggle() + { + SendCommand(EVENTS.AUTOPILOT_TOGGLE); + } - public void ApToggle() - { - SendCommand(EVENTS.AUTOPILOT_TOGGLE); - } + public void ApHdgToggle() + { + SendCommand(EVENTS.AP_HDG_TOGGLE); + } - public void ApHdgToggle() - { - SendCommand(EVENTS.AP_HDG_TOGGLE); - } + public void ApNavToggle() + { + SendCommand(EVENTS.AP_NAV_TOGGLE); + } - public void ApNavToggle() - { - SendCommand(EVENTS.AP_NAV_TOGGLE); - } + public void ApAprToggle() + { + SendCommand(EVENTS.AP_APR_TOGGLE); + } - public void ApAprToggle() - { - SendCommand(EVENTS.AP_APR_TOGGLE); - } + public void ApAltToggle() + { + SendCommand(EVENTS.AP_ALT_TOGGLE); + } - public void ApAltToggle() - { - SendCommand(EVENTS.AP_ALT_TOGGLE); - } + public void ApVsToggle() + { + SendCommand(EVENTS.AP_VS_TOGGLE); + } - public void ApVsToggle() - { - SendCommand(EVENTS.AP_VS_TOGGLE); - } + public void ApFlcOn() + { + SendCommand(EVENTS.AP_FLC_ON); + } - public void ApFlcOn() - { - SendCommand(EVENTS.AP_FLC_ON); - } + public void ApFlcOff() + { + SendCommand(EVENTS.AP_FLC_OFF); + } - public void ApFlcOff() - { - SendCommand(EVENTS.AP_FLC_OFF); - } + public void ApHdgSet(uint heading) + { + SendCommand(EVENTS.AP_HDG_SET, heading); + } - public void ApHdgSet(uint heading) - { - SendCommand(EVENTS.AP_HDG_SET, heading); - } + public void ApHdgInc() + { + SendCommand(EVENTS.AP_HDG_INC); + } - public void ApHdgInc() - { - SendCommand(EVENTS.AP_HDG_INC); - } + public void ApHdgDec() + { + SendCommand(EVENTS.AP_HDG_DEC); + } - public void ApHdgDec() - { - SendCommand(EVENTS.AP_HDG_DEC); - } + public void ApAltSet(uint altitude) + { + SendCommand(EVENTS.AP_ALT_SET, altitude); + } - public void ApAltSet(uint altitude) - { - SendCommand(EVENTS.AP_ALT_SET, altitude); - } + public void ApAltInc() + { + SendCommand(EVENTS.AP_ALT_INC); + } - public void ApAltInc() - { - SendCommand(EVENTS.AP_ALT_INC); - } + public void ApAltDec() + { + SendCommand(EVENTS.AP_ALT_DEC); + } - public void ApAltDec() - { - SendCommand(EVENTS.AP_ALT_DEC); - } + public void ApVsSet(uint speed) + { + SendCommand(EVENTS.AP_VS_SET, speed); + } - public void ApVsSet(uint speed) - { - SendCommand(EVENTS.AP_VS_SET, speed); - } + public void ApAirSpeedSet(uint speed) + { + SendCommand(EVENTS.AP_AIRSPEED_SET, speed); + } - public void ApAirSpeedSet(uint speed) - { - SendCommand(EVENTS.AP_AIRSPEED_SET, speed); - } + public void ApAirSpeedInc() + { + SendCommand(EVENTS.AP_AIRSPEED_INC); + } - public void ApAirSpeedInc() - { - SendCommand(EVENTS.AP_AIRSPEED_INC); - } + public void ApAirSpeedDec() + { + SendCommand(EVENTS.AP_AIRSPEED_DEC); + } - public void ApAirSpeedDec() + public void QNHSet(uint qnh) + { + SendCommand(EVENTS.QNH_SET, qnh); + } + + public void QNHInc() + { + SendCommand(EVENTS.QNH_INC); + } + + public void QNHDec() + { + SendCommand(EVENTS.QNH_DEC); + } + + + public void AvMasterToggle(uint state) + { + SendCommand(EVENTS.AVIONICS_TOGGLE, state); + } + + private void SendCommand(EVENTS sendingEvent, uint data = 0) + { + try { - SendCommand(EVENTS.AP_AIRSPEED_DEC); + simconnect?.TransmitClientEvent(SimConnect.SIMCONNECT_OBJECT_ID_USER, sendingEvent, data, GROUPID.MAX, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); } - - public void QNHSet(uint qnh) + catch (COMException ex) when (ex.Message == "0xC00000B0") { - SendCommand(EVENTS.QNH_SET, qnh); + RecoverFromError(ex); } + } - public void QNHInc() + private void SendGenericCommand(Enum sendingEvent, uint dwData = 0) + { + try { - SendCommand(EVENTS.QNH_INC); + simconnect?.TransmitClientEvent(SimConnect.SIMCONNECT_OBJECT_ID_USER, sendingEvent, dwData, GROUPID.MAX, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); } - - public void QNHDec() + catch (COMException ex) when (ex.Message == "0xC00000B0") { - SendCommand(EVENTS.QNH_DEC); + RecoverFromError(ex); } + } - - public void AvMasterToggle(uint state) + public void CloseConnection() + { + try { - SendCommand(EVENTS.AVIONICS_TOGGLE, state); + logger.LogDebug("Trying to cancel request loop"); + cts?.Cancel(); + cts = null; } - - private void SendCommand(EVENTS sendingEvent, uint data = 0) + catch (Exception ex) { - try - { - simconnect?.TransmitClientEvent(SimConnect.SIMCONNECT_OBJECT_ID_USER, sendingEvent, data, GROUPID.MAX, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); - } - catch (COMException ex) when (ex.Message == "0xC00000B0") - { - RecoverFromError(ex); - } + logger.LogWarning(ex, $"Cannot cancel request loop! Error: {ex.Message}"); } - - private void SendGenericCommand(Enum sendingEvent, uint dwData = 0) + try { - try - { - simconnect?.TransmitClientEvent(SimConnect.SIMCONNECT_OBJECT_ID_USER, sendingEvent, dwData, GROUPID.MAX, SIMCONNECT_EVENT_FLAG.GROUPID_IS_PRIORITY); - } - catch (COMException ex) when (ex.Message == "0xC00000B0") - { - RecoverFromError(ex); - } + // Dispose serves the same purpose as SimConnect_Close() + simconnect?.Dispose(); + simconnect = null; } - - public void CloseConnection() + catch (Exception ex) { - try - { - logger.LogDebug("Trying to cancel request loop"); - cts?.Cancel(); - cts = null; - } - catch (Exception ex) - { - logger.LogWarning(ex, $"Cannot cancel request loop! Error: {ex.Message}"); - } - try - { - // Dispose serves the same purpose as SimConnect_Close() - simconnect?.Dispose(); - simconnect = null; - } - catch (Exception ex) - { - logger.LogWarning(ex, $"Cannot unsubscribe events! Error: {ex.Message}"); - } + logger.LogWarning(ex, $"Cannot unsubscribe events! Error: {ex.Message}"); } + } - private void RegisterFlightStatusDefinition(SimConnect simconnect) + private void RegisterFlightStatusDefinition(SimConnect simconnect) + { + void AddToFlightStatusDefinition(string simvar, string unit, SIMCONNECT_DATATYPE type) { - void AddToFlightStatusDefinition(string simvar, string unit, SIMCONNECT_DATATYPE type) - { - simconnect.AddToDataDefinition(DEFINITIONS.FlightStatus, simvar, unit, type, 0.0f, SimConnect.SIMCONNECT_UNUSED); - } + simconnect.AddToDataDefinition(DEFINITIONS.FlightStatus, simvar, unit, type, 0.0f, SimConnect.SIMCONNECT_UNUSED); + } - AddToFlightStatusDefinition("SIMULATION RATE", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("SIMULATION RATE", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("PLANE LATITUDE", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE LONGITUDE", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE ALTITUDE", "Feet", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE ALT ABOVE GROUND", "Feet", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE PITCH DEGREES", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE BANK DEGREES", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE HEADING DEGREES TRUE", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("PLANE HEADING DEGREES MAGNETIC", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("GROUND ALTITUDE", "Meters", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("GROUND VELOCITY", "Knots", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("AIRSPEED INDICATED", "Knots", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("VERTICAL SPEED", "Feet per minute", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE LATITUDE", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE LONGITUDE", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE ALTITUDE", "Feet", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE ALT ABOVE GROUND", "Feet", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE PITCH DEGREES", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE BANK DEGREES", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE HEADING DEGREES TRUE", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("PLANE HEADING DEGREES MAGNETIC", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("GROUND ALTITUDE", "Meters", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("GROUND VELOCITY", "Knots", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("AIRSPEED INDICATED", "Knots", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("VERTICAL SPEED", "Feet per minute", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("FUEL TOTAL QUANTITY", "Gallons", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("FUEL TOTAL QUANTITY", "Gallons", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("AMBIENT WIND VELOCITY", "Feet per second", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("AMBIENT WIND DIRECTION", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("AMBIENT WIND VELOCITY", "Feet per second", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("AMBIENT WIND DIRECTION", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("SIM ON GROUND", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("STALL WARNING", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("OVERSPEED WARNING", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("SIM ON GROUND", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("STALL WARNING", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("OVERSPEED WARNING", "number", SIMCONNECT_DATATYPE.INT32); - #region Autopilot + #region Autopilot - AddToFlightStatusDefinition("AUTOPILOT MASTER", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT MASTER", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT HEADING LOCK", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT HEADING LOCK DIR", "Degrees", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT HEADING LOCK", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT HEADING LOCK DIR", "Degrees", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT NAV1 LOCK", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT NAV1 LOCK", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT APPROACH HOLD", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT APPROACH HOLD", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT ALTITUDE LOCK", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT ALTITUDE LOCK VAR", "Feet", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT ALTITUDE LOCK", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT ALTITUDE LOCK VAR", "Feet", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT VERTICAL HOLD", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT VERTICAL HOLD VAR", "Feet per minute", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT VERTICAL HOLD", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT VERTICAL HOLD VAR", "Feet per minute", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT FLIGHT LEVEL CHANGE", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AUTOPILOT AIRSPEED HOLD VAR", "Knots", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT FLIGHT LEVEL CHANGE", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AUTOPILOT AIRSPEED HOLD VAR", "Knots", SIMCONNECT_DATATYPE.INT32); - #endregion + #endregion - AddToFlightStatusDefinition("KOHLSMAN SETTING MB", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("KOHLSMAN SETTING MB", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("TRANSPONDER CODE:1", "Hz", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("COM ACTIVE FREQUENCY:1", "kHz", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("COM ACTIVE FREQUENCY:2", "kHz", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("AVIONICS MASTER SWITCH", "number", SIMCONNECT_DATATYPE.INT32); - AddToFlightStatusDefinition("NAV OBS:1", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("NAV OBS:2", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - AddToFlightStatusDefinition("ADF CARD", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("TRANSPONDER CODE:1", "Hz", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("COM ACTIVE FREQUENCY:1", "kHz", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("COM ACTIVE FREQUENCY:2", "kHz", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("AVIONICS MASTER SWITCH", "number", SIMCONNECT_DATATYPE.INT32); + AddToFlightStatusDefinition("NAV OBS:1", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("NAV OBS:2", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); + AddToFlightStatusDefinition("ADF CARD", "Degrees", SIMCONNECT_DATATYPE.FLOAT64); - // IMPORTANT: register it with the simconnect managed wrapper marshaller - // if you skip this step, you will only receive a uint in the .dwData field. - simconnect.RegisterDataDefineStruct(DEFINITIONS.FlightStatus); - } + // IMPORTANT: register it with the simconnect managed wrapper marshaller + // if you skip this step, you will only receive a uint in the .dwData field. + simconnect.RegisterDataDefineStruct(DEFINITIONS.FlightStatus); + } - private void Simconnect_OnRecvSimobjectDataBytypeAsync(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data) + private void Simconnect_OnRecvSimobjectDataBytypeAsync(SimConnect sender, SIMCONNECT_RECV_SIMOBJECT_DATA_BYTYPE data) + { + // Must be general SimObject information + switch (data.dwRequestID) { - // Must be general SimObject information - switch (data.dwRequestID) - { - case (uint)DATA_REQUESTS.FLIGHT_STATUS: - { - var flightStatus = data.dwData[0] as FlightStatusStruct?; + case (uint)DATA_REQUESTS.FLIGHT_STATUS: + { + var flightStatus = data.dwData[0] as FlightStatusStruct?; - if (flightStatus.HasValue) - { - logger.LogTrace("Get Aircraft status"); - AircraftStatusUpdated?.Invoke(this, new AircraftStatusUpdatedEventArgs( - new AircraftStatus - { - //SimTime = flightStatus.Value.SimTime, - //SimRate = flightStatus.Value.SimRate, - Latitude = flightStatus.Value.Latitude, - Longitude = flightStatus.Value.Longitude, - Altitude = flightStatus.Value.Altitude, - AltitudeAboveGround = flightStatus.Value.AltitudeAboveGround, - Pitch = flightStatus.Value.Pitch, - Bank = flightStatus.Value.Bank, - Heading = flightStatus.Value.MagneticHeading, - TrueHeading = flightStatus.Value.TrueHeading, - GroundSpeed = flightStatus.Value.GroundSpeed, - IndicatedAirSpeed = flightStatus.Value.IndicatedAirSpeed, - VerticalSpeed = flightStatus.Value.VerticalSpeed, - FuelTotalQuantity = flightStatus.Value.FuelTotalQuantity, - WindDirection = flightStatus.Value.WindDirection, - WindVelocity = flightStatus.Value.WindVelocity, - IsOnGround = flightStatus.Value.IsOnGround == 1, - StallWarning = flightStatus.Value.StallWarning == 1, - OverspeedWarning = flightStatus.Value.OverspeedWarning == 1, - IsAutopilotOn = flightStatus.Value.IsAutopilotOn == 1, - IsApHdgOn = flightStatus.Value.IsApHdgOn == 1, - ApHeading = flightStatus.Value.ApHdg, - IsApNavOn = flightStatus.Value.IsApNavOn == 1, - IsApAprOn = flightStatus.Value.IsApAprOn == 1, - IsApAltOn = flightStatus.Value.IsApAltOn == 1, - ApAltitude = flightStatus.Value.ApAlt, - IsApVsOn = flightStatus.Value.IsApVsOn == 1, - IsApFlcOn = flightStatus.Value.IsApFlcOn == 1, - ApAirspeed = flightStatus.Value.ApAirspeed, - ApVs = flightStatus.Value.ApVs, - QNHMbar = flightStatus.Value.QNHmbar, - Transponder = flightStatus.Value.Transponder.ToString().PadLeft(4, '0'), - FreqencyCom1 = flightStatus.Value.Com1, - FreqencyCom2 = flightStatus.Value.Com2, - IsAvMasterOn = flightStatus.Value.AvMasterOn == 1, - Nav1OBS = flightStatus.Value.Nav1OBS, - Nav2OBS = flightStatus.Value.Nav2OBS, - ADFCard = flightStatus.Value.ADFCard, - })); - } - else - { - // Cast failed - logger.LogError("Cannot cast to FlightStatusStruct!"); - } + if (flightStatus.HasValue) + { + logger.LogTrace("Get Aircraft status"); + AircraftStatusUpdated?.Invoke(this, new AircraftStatusUpdatedEventArgs( + new AircraftStatus + { + //SimTime = flightStatus.Value.SimTime, + //SimRate = flightStatus.Value.SimRate, + Latitude = flightStatus.Value.Latitude, + Longitude = flightStatus.Value.Longitude, + Altitude = flightStatus.Value.Altitude, + AltitudeAboveGround = flightStatus.Value.AltitudeAboveGround, + Pitch = flightStatus.Value.Pitch, + Bank = flightStatus.Value.Bank, + Heading = flightStatus.Value.MagneticHeading, + TrueHeading = flightStatus.Value.TrueHeading, + GroundSpeed = flightStatus.Value.GroundSpeed, + IndicatedAirSpeed = flightStatus.Value.IndicatedAirSpeed, + VerticalSpeed = flightStatus.Value.VerticalSpeed, + FuelTotalQuantity = flightStatus.Value.FuelTotalQuantity, + WindDirection = flightStatus.Value.WindDirection, + WindVelocity = flightStatus.Value.WindVelocity, + IsOnGround = flightStatus.Value.IsOnGround == 1, + StallWarning = flightStatus.Value.StallWarning == 1, + OverspeedWarning = flightStatus.Value.OverspeedWarning == 1, + IsAutopilotOn = flightStatus.Value.IsAutopilotOn == 1, + IsApHdgOn = flightStatus.Value.IsApHdgOn == 1, + ApHeading = flightStatus.Value.ApHdg, + IsApNavOn = flightStatus.Value.IsApNavOn == 1, + IsApAprOn = flightStatus.Value.IsApAprOn == 1, + IsApAltOn = flightStatus.Value.IsApAltOn == 1, + ApAltitude = flightStatus.Value.ApAlt, + IsApVsOn = flightStatus.Value.IsApVsOn == 1, + IsApFlcOn = flightStatus.Value.IsApFlcOn == 1, + ApAirspeed = flightStatus.Value.ApAirspeed, + ApVs = flightStatus.Value.ApVs, + QNHMbar = flightStatus.Value.QNHmbar, + Transponder = flightStatus.Value.Transponder.ToString().PadLeft(4, '0'), + FreqencyCom1 = flightStatus.Value.Com1, + FreqencyCom2 = flightStatus.Value.Com2, + IsAvMasterOn = flightStatus.Value.AvMasterOn == 1, + Nav1OBS = flightStatus.Value.Nav1OBS, + Nav2OBS = flightStatus.Value.Nav2OBS, + ADFCard = flightStatus.Value.ADFCard, + })); } - break; + else + { + // Cast failed + logger.LogError("Cannot cast to FlightStatusStruct!"); + } + } + break; - case (uint)DATA_REQUESTS.TOGGLE_VALUE_DATA: + case (uint)DATA_REQUESTS.TOGGLE_VALUE_DATA: + { + var result = new Dictionary(); + lock (lockLists) { - var result = new Dictionary<(TOGGLE_VALUE variable, string? unit), double>(); - lock (lockLists) + if (data.dwDefineCount != genericValues.Count) { - if (data.dwDefineCount != genericValues.Count) - { - logger.LogError("Incompatible array count {actual}, expected {expected}. Skipping received data", data.dwDefineCount, genericValues.Count); - return; - } + logger.LogError("Incompatible array count {actual}, expected {expected}. Skipping received data", data.dwDefineCount, genericValues.Count); + return; + } - var dataArray = data.dwData[0] as GenericValuesStruct?; + var dataArray = data.dwData[0] as GenericValuesStruct?; - if (!dataArray.HasValue) - { - logger.LogError("Invalid data received"); - return; - } - - for (int i = 0; i < data.dwDefineCount; i++) - { - var genericValue = genericValues.Keys.ElementAt(i); - result.Add(genericValue, dataArray.Value.Get(i)); - } + if (!dataArray.HasValue) + { + logger.LogError("Invalid data received"); + return; } - GenericValuesUpdated?.Invoke(this, new ToggleValueUpdatedEventArgs(result)); + for (int i = 0; i < data.dwDefineCount; i++) + { + var genericValue = genericValues.Keys.ElementAt(i); + result.Add(genericValue, dataArray.Value.Get(i)); + } } - break; - } + + GenericValuesUpdated?.Invoke(this, new ToggleValueUpdatedEventArgs(result)); + } + break; } + } - private void Simconnect_OnRecvSystemState(SimConnect sender, SIMCONNECT_RECV_SYSTEM_STATE data) + private void Simconnect_OnRecvSystemState(SimConnect sender, SIMCONNECT_RECV_SYSTEM_STATE data) + { + switch (data.dwRequestID) { - switch (data.dwRequestID) - { - case (int)DATA_REQUESTS.FLIGHT_PLAN: - if (!string.IsNullOrEmpty(data.szString)) - { - logger.LogInformation("Receive flight plan {flightPlan}", data.szString); - } - break; - } + case (int)DATA_REQUESTS.FLIGHT_PLAN: + if (!string.IsNullOrEmpty(data.szString)) + { + logger.LogInformation("Receive flight plan {flightPlan}", data.szString); + } + break; } + } - void Simconnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data) - { - logger.LogInformation("Connected to Flight Simulator"); + void Simconnect_OnRecvOpen(SimConnect sender, SIMCONNECT_RECV_OPEN data) + { + logger.LogInformation("Connected to Flight Simulator"); - cts?.Cancel(); - cts = new CancellationTokenSource(); - Task.Run(async () => + cts?.Cancel(); + cts = new CancellationTokenSource(); + Task.Run(async () => + { + try { - try + while (true) { - while (true) + await Task.Delay(StatusDelayMilliseconds); + await smGeneric.WaitAsync(); + try { - await Task.Delay(StatusDelayMilliseconds); - await smGeneric.WaitAsync(); - try - { - cts?.Token.ThrowIfCancellationRequested(); - simconnect?.RequestDataOnSimObjectType(DATA_REQUESTS.FLIGHT_STATUS, DEFINITIONS.FlightStatus, 0, SIMCONNECT_SIMOBJECT_TYPE.USER); + cts?.Token.ThrowIfCancellationRequested(); + simconnect?.RequestDataOnSimObjectType(DATA_REQUESTS.FLIGHT_STATUS, DEFINITIONS.FlightStatus, 0, SIMCONNECT_SIMOBJECT_TYPE.USER); - if (genericValues.Count > 0 && isGenericValueRegistered) - { - simconnect?.RequestDataOnSimObjectType(DATA_REQUESTS.TOGGLE_VALUE_DATA, DEFINITIONS.GenericData, 0, SIMCONNECT_SIMOBJECT_TYPE.USER); - } - } - finally + if (genericValues.Count > 0 && isGenericValueRegistered) { - smGeneric.Release(); + simconnect?.RequestDataOnSimObjectType(DATA_REQUESTS.TOGGLE_VALUE_DATA, DEFINITIONS.GenericData, 0, SIMCONNECT_SIMOBJECT_TYPE.USER); } } + finally + { + smGeneric.Release(); + } } - catch (TaskCanceledException) { } - }); - } + } + catch (TaskCanceledException) { } + }); + } - // The case where the user closes Flight Simulator - void Simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data) - { - logger.LogInformation("Flight Simulator has exited"); - CloseConnection(); - Closed?.Invoke(this, new EventArgs()); - } + // The case where the user closes Flight Simulator + void Simconnect_OnRecvQuit(SimConnect sender, SIMCONNECT_RECV data) + { + logger.LogInformation("Flight Simulator has exited"); + CloseConnection(); + Closed?.Invoke(this, new EventArgs()); + } - void Simconnect_OnRecvException(SimConnect sender, SIMCONNECT_RECV_EXCEPTION data) - { - logger.LogError("Exception received: {error} from {sendID}", (SIMCONNECT_EXCEPTION)data.dwException, data.dwSendID); - switch ((SIMCONNECT_EXCEPTION)data.dwException) - { - case SIMCONNECT_EXCEPTION.ERROR: - // Try to reconnect on unknown error - CloseConnection(); - Closed?.Invoke(this, new EventArgs()); - break; - - case SIMCONNECT_EXCEPTION.NAME_UNRECOGNIZED: - InvalidEventRegistered?.Invoke(this, new InvalidEventRegisteredEventArgs(data.dwSendID)); - break; - - case SIMCONNECT_EXCEPTION.VERSION_MISMATCH: - // HACK: when sending an event repeatedly, - // SimConnect might sendd thihs error and stop reacting and responding. - // The workaround would be to force a reconnection. - CloseConnection(); - Closed?.Invoke(this, new EventArgs()); - break; - } + void Simconnect_OnRecvException(SimConnect sender, SIMCONNECT_RECV_EXCEPTION data) + { + logger.LogError("Exception received: {error} from {sendID}", (SIMCONNECT_EXCEPTION)data.dwException, data.dwSendID); + switch ((SIMCONNECT_EXCEPTION)data.dwException) + { + case SIMCONNECT_EXCEPTION.ERROR: + // Try to reconnect on unknown error + CloseConnection(); + Closed?.Invoke(this, new EventArgs()); + break; + + case SIMCONNECT_EXCEPTION.NAME_UNRECOGNIZED: + InvalidEventRegistered?.Invoke(this, new InvalidEventRegisteredEventArgs(data.dwSendID)); + break; + + case SIMCONNECT_EXCEPTION.VERSION_MISMATCH: + // HACK: when sending an event repeatedly, + // SimConnect might sendd thihs error and stop reacting and responding. + // The workaround would be to force a reconnection. + CloseConnection(); + Closed?.Invoke(this, new EventArgs()); + break; } + } - private void RecoverFromError(Exception exception) - { - // 0xC000014B: CTD - // 0xC00000B0: Sim has exited or any generic SimConnect error - // 0xC000014B: STATUS_PIPE_BROKEN - logger.LogError(exception, "Exception received"); - CloseConnection(); - Closed?.Invoke(this, new EventArgs()); - } + private void RecoverFromError(Exception exception) + { + // 0xC000014B: CTD + // 0xC00000B0: Sim has exited or any generic SimConnect error + // 0xC000014B: STATUS_PIPE_BROKEN + logger.LogError(exception, "Exception received"); + CloseConnection(); + Closed?.Invoke(this, new EventArgs()); + } - private uint GetLastSendID() - { - SimConnect_GetLastSentPacketID(hSimConnect, out uint dwSendID); - return dwSendID; - } + private uint GetLastSendID() + { + SimConnect_GetLastSentPacketID(hSimConnect, out uint dwSendID); + return dwSendID; + } - #region Generic Buttons + #region Generic Buttons - public uint? RegisterToggleEvent(Enum eventEnum, string eventName) - { - if (simconnect == null) return null; + public uint? RegisterToggleEvent(Enum eventEnum, string eventName) + { + if (simconnect == null) return null; - logger.LogInformation("RegisterEvent {action} {simConnectAction}", eventEnum, eventName); - simconnect.MapClientEventToSimEvent(eventEnum, eventName); + logger.LogInformation("RegisterEvent {action} {simConnectAction}", eventEnum, eventName); + simconnect.MapClientEventToSimEvent(eventEnum, eventName); - return GetLastSendID(); - } + return GetLastSendID(); + } - public void RegisterSimValues(params (TOGGLE_VALUE variables, string? unit)[] simValues) + public void RegisterSimValues(IEnumerable simValues) + { + var changed = false; + lock (lockLists) { - var changed = false; - lock (lockLists) + logger.LogInformation("Registering {values}", string.Join(", ", simValues.Select(o => o.variableName + " " + o.variableUnit))); + foreach (var simValue in simValues) { - logger.LogInformation("Registering {values}", string.Join(", ", simValues)); - foreach (var simValue in simValues) + if (genericValues.ContainsKey(simValue)) { - if (genericValues.ContainsKey(simValue)) - { - genericValues[simValue]++; - } - else - { - genericValues.Add(simValue, 1); - changed = true; - } + genericValues[simValue]++; + } + else + { + genericValues.Add(simValue, 1); + changed = true; } - } - if (changed) - { - RegisterGenericValues(); } } + if (changed) + { + RegisterGenericValues(); + } + } - public void DeRegisterSimValues(params (TOGGLE_VALUE variables, string? unit)[] simValues) + public void DeRegisterSimValues(IEnumerable simValues) + { + var changed = false; + lock (lockLists) { - var changed = false; - lock (lockLists) + logger.LogInformation("De-Registering {values}", string.Join(", ", simValues.Select(o => o.variableName + " " + o.variableUnit))); + foreach (var simValue in simValues) { - logger.LogInformation("De-Registering {values}", string.Join(", ", simValues)); - foreach (var simValue in simValues) + if (genericValues.ContainsKey(simValue)) { - if (genericValues.ContainsKey(simValue)) + var currentCount = genericValues[simValue]; + if (currentCount > 1) { - var currentCount = genericValues[simValue]; - if (currentCount > 1) - { - genericValues[simValue]--; - } - else - { - genericValues.Remove(simValue); - changed = true; - } + genericValues[simValue]--; + } + else + { + genericValues.Remove(simValue); + changed = true; } } } - if (changed) - { - RegisterGenericValues(); - } } + if (changed) + { + RegisterGenericValues(); + } + } - private CancellationTokenSource? ctsGeneric = null; - private readonly object lockGeneric = new object(); - private readonly SemaphoreSlim smGeneric = new SemaphoreSlim(1); - private bool isGenericValueRegistered = false; + private CancellationTokenSource? ctsGeneric = null; + private readonly object lockGeneric = new object(); + private readonly SemaphoreSlim smGeneric = new SemaphoreSlim(1); + private bool isGenericValueRegistered = false; - private void RegisterGenericValues() + private void RegisterGenericValues() + { + if (simconnect == null) return; + + CancellationTokenSource cts; + lock (lockGeneric) { - if (simconnect == null) return; + ctsGeneric?.Cancel(); + cts = ctsGeneric = new CancellationTokenSource(); + } - CancellationTokenSource cts; - lock (lockGeneric) + Task.Run(async () => + { + await smGeneric.WaitAsync(); + try { - ctsGeneric?.Cancel(); - cts = ctsGeneric = new CancellationTokenSource(); - } - Task.Run(async () => - { - await smGeneric.WaitAsync(); - try - { + await Task.Delay(500, cts.Token); + cts.Token.ThrowIfCancellationRequested(); - await Task.Delay(500, cts.Token); - cts.Token.ThrowIfCancellationRequested(); + if (simconnect == null) return; - if (simconnect == null) return; + if (isGenericValueRegistered) + { + logger.LogInformation("Clearing Data definition"); + simconnect.ClearDataDefinition(DEFINITIONS.GenericData); + isGenericValueRegistered = false; + } - if (isGenericValueRegistered) - { - logger.LogInformation("Clearing Data definition"); - simconnect.ClearDataDefinition(DEFINITIONS.GenericData); - isGenericValueRegistered = false; - } + if (genericValues.Count == 0) + { + logger.LogInformation("Registration is not needed."); + } + else + { + var log = "Registering generic data structure:"; - if (genericValues.Count == 0) + foreach (var registration in genericValues.Keys) { - logger.LogInformation("Registration is not needed."); + log += string.Format("\n- {0} {1}", registration.variableName, registration.variableUnit); + + simconnect.AddToDataDefinition( + DEFINITIONS.GenericData, + registration.variableName, + registration.variableUnit, + SIMCONNECT_DATATYPE.FLOAT64, + 0.0f, + SimConnect.SIMCONNECT_UNUSED + ); } - else - { - var log = "Registering generic data structure:"; - - foreach ((var simValue, var unit) in genericValues.Keys) - { - string value = simValue.ToString().Replace("__", ":").Replace("_", " "); - var simUnit = EventValueLibrary.GetUnit(simValue, unit); - log += string.Format("\n- {0} {1} {2}", simValue, value, simUnit); - - simconnect.AddToDataDefinition( - DEFINITIONS.GenericData, - value, - simUnit, - SIMCONNECT_DATATYPE.FLOAT64, - 0.0f, - SimConnect.SIMCONNECT_UNUSED - ); - } - logger.LogInformation(log); + logger.LogInformation(log); - simconnect.RegisterDataDefineStruct(DEFINITIONS.GenericData); + simconnect.RegisterDataDefineStruct(DEFINITIONS.GenericData); - isGenericValueRegistered = true; - } - } - catch (TaskCanceledException) - { - logger.LogDebug("Registration is cancelled."); - } - finally - { - smGeneric.Release(); + isGenericValueRegistered = true; } - }); - } - - public void Trigger(Enum eventEnum, uint data) - { - logger.LogInformation("Toggle {event} {data}", eventEnum, data); - SendGenericCommand(eventEnum, data); - } - - #endregion + } + catch (TaskCanceledException) + { + logger.LogDebug("Registration is cancelled."); + } + finally + { + smGeneric.Release(); + } + }); } + public void Trigger(Enum eventEnum, uint data) + { + logger.LogInformation("Toggle {event} {data}", eventEnum, data); + SendGenericCommand(eventEnum, data); + } + #endregion } diff --git a/FlightStreamDeck.SimConnectFSX/Structs.cs b/FlightStreamDeck.SimConnectFSX/Structs.cs index 29099ad..ba1ed7c 100644 --- a/FlightStreamDeck.SimConnectFSX/Structs.cs +++ b/FlightStreamDeck.SimConnectFSX/Structs.cs @@ -1,138 +1,135 @@ -using Microsoft.FlightSimulator.SimConnect; -using System; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; -namespace FlightStreamDeck.SimConnectFSX +namespace FlightStreamDeck.SimConnectFSX; + +enum GROUPID { - enum GROUPID - { - FLAG = 2000000000, - MAX = 1, - }; + FLAG = 2000000000, + MAX = 1, +}; - enum DEFINITIONS - { - AircraftData, - FlightStatus, - GenericData - } +enum DEFINITIONS +{ + AircraftData, + FlightStatus, + GenericData +} - internal enum DATA_REQUESTS - { - NONE, - SUBSCRIBE_GENERIC, - AIRCRAFT_DATA, - FLIGHT_STATUS, - ENVIRONMENT_DATA, - FLIGHT_PLAN, - TOGGLE_VALUE_DATA - } +internal enum DATA_REQUESTS +{ + NONE, + SUBSCRIBE_GENERIC, + AIRCRAFT_DATA, + FLIGHT_STATUS, + ENVIRONMENT_DATA, + FLIGHT_PLAN, + TOGGLE_VALUE_DATA +} - public enum EVENTS - { - MESSAGE_RECEIVED, - AUTOPILOT_ON, - AUTOPILOT_OFF, - AUTOPILOT_TOGGLE, - AP_HDG_TOGGLE, - AP_NAV_TOGGLE, - AP_APR_TOGGLE, - AP_ALT_TOGGLE, - AP_VS_TOGGLE, - AP_FLC_ON, - AP_FLC_OFF, - AP_HDG_SET, - AP_HDG_INC, - AP_HDG_DEC, - AP_ALT_SET, - AP_ALT_INC, - AP_ALT_DEC, - AP_VS_SET, - AP_VS_INC, - AP_VS_DEC, - AP_AIRSPEED_SET, - AP_AIRSPEED_INC, - AP_AIRSPEED_DEC, - QNH_SET, - QNH_INC, - QNH_DEC, - AVIONICS_TOGGLE, - } +public enum EVENTS +{ + MESSAGE_RECEIVED, + AUTOPILOT_ON, + AUTOPILOT_OFF, + AUTOPILOT_TOGGLE, + AP_HDG_TOGGLE, + AP_NAV_TOGGLE, + AP_APR_TOGGLE, + AP_ALT_TOGGLE, + AP_VS_TOGGLE, + AP_FLC_ON, + AP_FLC_OFF, + AP_HDG_SET, + AP_HDG_INC, + AP_HDG_DEC, + AP_ALT_SET, + AP_ALT_INC, + AP_ALT_DEC, + AP_VS_SET, + AP_VS_INC, + AP_VS_DEC, + AP_AIRSPEED_SET, + AP_AIRSPEED_INC, + AP_AIRSPEED_DEC, + QNH_SET, + QNH_INC, + QNH_DEC, + AVIONICS_TOGGLE, +} - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] - struct AircraftDataStruct - { - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string Type; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] - public string Model; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] - public string Title; - public double EstimatedCruiseSpeed; - } +[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] +struct AircraftDataStruct +{ + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string Type; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] + public string Model; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string Title; + public double EstimatedCruiseSpeed; +} - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] - struct FlightStatusStruct - { - public int SimRate; - - public double Latitude; - public double Longitude; - public double Altitude; - public double AltitudeAboveGround; - public double Pitch; - public double Bank; - public double TrueHeading; - public double MagneticHeading; - public double GroundAltitude; - public double GroundSpeed; - public double IndicatedAirSpeed; - public double VerticalSpeed; - - public double FuelTotalQuantity; - - public double WindVelocity; - public double WindDirection; - - public int IsOnGround; - public int StallWarning; - public int OverspeedWarning; - - public int IsAutopilotOn; - public int IsApHdgOn; - public int ApHdg; - public int IsApNavOn; - public int IsApAprOn; - public int IsApAltOn; - public int ApAlt; - public int IsApVsOn; - public int ApVs; - public int IsApFlcOn; - public int ApAirspeed; - - public int QNHmbar; - - public int Transponder; - public int Com1; - public int Com2; - public int AvMasterOn; - public double Nav1OBS; - public double Nav2OBS; - public double ADFCard; - public int ADFActive1; - public int ADFStandby1; - public int ADFActive2; - public int ADFStandby2; - } +[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] +struct FlightStatusStruct +{ + public int SimRate; - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] - struct GenericValuesStruct - { - unsafe public fixed double Data[64]; + public double Latitude; + public double Longitude; + public double Altitude; + public double AltitudeAboveGround; + public double Pitch; + public double Bank; + public double TrueHeading; + public double MagneticHeading; + public double GroundAltitude; + public double GroundSpeed; + public double IndicatedAirSpeed; + public double VerticalSpeed; + + public double FuelTotalQuantity; + + public double WindVelocity; + public double WindDirection; - unsafe public double Get(int index) - { - return Data[index]; - } + public int IsOnGround; + public int StallWarning; + public int OverspeedWarning; + + public int IsAutopilotOn; + public int IsApHdgOn; + public int ApHdg; + public int IsApNavOn; + public int IsApAprOn; + public int IsApAltOn; + public int ApAlt; + public int IsApVsOn; + public int ApVs; + public int IsApFlcOn; + public int ApAirspeed; + + public int QNHmbar; + + public int Transponder; + public int Com1; + public int Com2; + public int AvMasterOn; + public double Nav1OBS; + public double Nav2OBS; + public double ADFCard; + public int ADFActive1; + public int ADFStandby1; + public int ADFActive2; + public int ADFStandby2; +} + +[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] +struct GenericValuesStruct +{ + unsafe public fixed double Data[64]; + + unsafe public double Get(int index) + { + return Data[index]; } }