def test_send_event(self):
        sm = create_autospec(SimConnect.SimConnect)

        pl1 = SimConnect.Plane(sm=sm)
        pl1.send(SimConnect.Event.GEAR_DOWN)
        pl1.gear_up

        pl2 = SimConnect.Plane(sm=sm, add_default=False)
        with self.assertRaises(AttributeError):
            pl2.gear_up
Exemple #2
0
 def calcTodDegrees():
     try:
         sm = SimConnect()
         aq = AircraftRequests(sm)
         finalAlt = float(finalAltEntry.get())
         alt = aq.get("PLANE_ALTITUDE")
         y = finalAlt - alt
         x = (y / math.tan(math.radians(-2.6))) / 6076.12
         sm.exit()
         todLabel.config(text="Descent Distance " + str(math.floor(x)))
     except Exception:
         todLabel.config(text="Could not connect to simulator!")
Exemple #3
0
 def calcTodVert():
     try:
         sm = SimConnect()
         aq = AircraftRequests(sm)
         vertSpeed = float(vertSpeedEntry.get())
         groundSpeed = aq.get("GROUND_VELOCITY")
         alt = aq.get("PLANE_ALTITUDE")
         finalAlt = float(finalAltEntry.get())
         y = alt - finalAlt
         distance = ((y / vertSpeed) / 60) * groundSpeed
         todLabel.config(text="Descent Distance: " +
                         str(math.floor(distance)))
         sm.exit()
     except Exception:
         todLabel.config(text="Could not connect to simulator!")
    def test_values(self):

        sm = create_autospec(SimConnect.SimConnect)

        def side_effect(*args, **kwargs):
            def val():
                v = 100
                x = 100
                while True:
                    yield x
                    x += v

            data = sData()
            val = val()
            data["Altitude"] = next(val)
            data["Latitude"] = next(val)
            data["Longitude"] = next(val)
            data["Kohlsman"] = next(val)
            return data

        sm.get_data.side_effect = side_effect

        pl = SimConnect.Plane(sm=sm)
        self.assertEqual(100, pl.altitude)
        self.assertEqual(200, pl.latitude)
        self.assertEqual(300, pl.longitude)
        self.assertEqual(400, pl.kohlsman)
Exemple #5
0
def simconnect_thread_func2(threadname):

    global ui_friendly_dictionary

    while True:
        try:
            sm = SimConnect()
            break
        except:
            None

    ae = AircraftEvents(sm)
    aq = AircraftRequests(sm)

    def thousandify(x):
        return f"{x:,}"

    async def ui_dictionary(ui_friendly_dictionary):
        # Additional for performance
        ui_friendly_dictionary["LATITUDE"] = round(await aq.get("PLANE_LATITUDE"), 6)
        ui_friendly_dictionary["LONGITUDE"] = round(await aq.get("PLANE_LONGITUDE"), 6)
        ui_friendly_dictionary["AUTOPILOT_HEADING_LOCK_DIR"] = round(await aq.get("AUTOPILOT_HEADING_LOCK_DIR"))
        ui_friendly_dictionary["AUTOPILOT_ALTITUDE_LOCK_VAR"] = thousandify(round(await aq.get("AUTOPILOT_ALTITUDE_LOCK_VAR")))
        ui_friendly_dictionary["AUTOPILOT_VERTICAL_HOLD_VAR"] = await aq.get("AUTOPILOT_VERTICAL_HOLD_VAR")
        ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD_VAR"] = round(await aq.get("AUTOPILOT_AIRSPEED_HOLD_VAR"))
        # NAV/ADF Compass Settings
        ui_friendly_dictionary["NAV1_OBS_DEG"] = round(await aq.get("NAV_OBS:1"), 0)
        ui_friendly_dictionary["ADF_CARD_DEG"] = round(await aq.get("ADF_CARD"), 0)
        ui_friendly_dictionary["NAV2_OBS_DEG"] = round(await aq.get("NAV_OBS:2"), 0)
    while True:
        asyncio.run(ui_dictionary(ui_friendly_dictionary))
Exemple #6
0
    def cruise(self):
        points = 20
        random.seed(0)
        cg = 0.33
        error_alt = 1
        error_ias = 1
        actual_vs = 1000

        # Read the Aircraft Data file
        df = data.data_read('CRZ')
        logger.test_header(self, "CRZ")
        start_time = time.time()
        i = 1
        # Random Aircraft situation
        weight, altitude, ias = data.a32x_state(df)
        logger.test_env(self, weight, altitude, ias, i, points)

        # Create the SimConnect link
        sm = SimConnect()
        aq = AircraftRequests(sm, _time=0)
        ae = AircraftEvents(sm)

        # Check and set initial aircraft settings:
        # AP1 ON, ATHR ON, FD ON & CLB
        ac_init(aq, ae)

        # Set Weight and CG ... this goes first to avoid excessive dumping
        W_n_B(aq, weight, cg)

        # Main test point routine - Setting stable aircraft conditions
        crz_alt_ias(sm, aq, ae, altitude, ias)

        # Altitude & Speed damping "filter". Use VS first as a measure
        # of stability
        # To avoid excesive damping, fuel and CG are set first with
        # enough headroom

        while error_alt > 1 or error_ias > 1 or abs(actual_vs) > 10:
            actual_alt = aq.get("INDICATED_ALTITUDE")
            actual_ias = aq.get("AIRSPEED_INDICATED")
            actual_vs = aq.get("VERTICAL_SPEED")
            error_alt = round(abs((actual_alt - altitude) / altitude) * 100, 3)
            error_ias = round(abs((actual_ias - ias) / ias) * 100, 3)
            elapsed_time = time.time() - start_time
            msg = "Tolerance Figures - Alt: " + str(
                error_alt) + "%  IAS: " + str(error_ias) + "%  VS: " + str(
                    round(actual_vs,
                          1)) + "fpm          Elapsed Time - " + str(
                              round(elapsed_time, 2)) + " secs."
            self.updateStatus(msg)
            QtCore.QCoreApplication.processEvents()

        #print(error_alt, " ", error_ias, " ", actual_vs)
        print(aq.get("TOTAL_WEIGHT"))
        print(aq.get("CG_PERCENT"))
Exemple #7
0
 def lbsClick():
     try:
         lbs = float(lbsEntry.get())
         sm = SimConnect()
         ae = AircraftEvents(sm)
         ar = AircraftRequests(sm)
         setFuel = ae.find("ADD_FUEL_QUANTITY")
         totalQuantity = ar.get("FUEL_TOTAL_QUANTITY")
         totalCapacitygal = ar.get("FUEL_TOTAL_CAPACITY")
         weightPerGallon = ar.get("FUEL_WEIGHT_PER_GALLON")
         totalCapacity = totalCapacitygal * weightPerGallon
         fuelToAdd = (lbs / totalCapacity) * 65535
         print(totalCapacity)
         print(totalQuantity)
         print(fuelToAdd)
         setFuel(int(fuelToAdd))
         sm.exit()
         fuelLabel.config(text="Fuel Loaded!")
     except Exception:
         fuelLabel.config(text="Could not connect to sim!")
Exemple #8
0
def connect():
    global sm
    global ae
    global aq
    if sm == None:
        try:
            sm = SimConnect()
            ae = AircraftEvents(sm)
            aq = AircraftRequests(sm, _time=10)
            return 'success'
        except:
            return 'Failed to connect to the Simulator', 500
    return 'success'
Exemple #9
0
def main():

    # Initialize program state
    DONE = False

    # Initialize pygame
    pygame.init()
    screen = pygame.display.set_mode((200, 50))  # Need this to pick up events
    clock = pygame.time.Clock()

    # Initialize joysticks
    joysticks = []
    pygame.joystick.init()
    joystick_count = pygame.joystick.get_count()
    print("Found devices:")
    for i in range(joystick_count):
        joysticks.append(pygame.joystick.Joystick(i))
        joysticks[i].init()
        print("{name} - ID: {id}".format(
            name=joysticks[i].get_name(),
            id=joysticks[i].get_id(),
        ))

    # Initialize SimConnect and adapters
    sim_connect = SimConnect()
    vor_adapter = VorAdapter(sim_connect)

    # Check for events
    while not DONE:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                DONE = True
            vor_adapter.handle_event(event)
        clock.tick(20)

    # Quit
    sim_connect.exit()
    pygame.quit()
Exemple #10
0
 def calcTodDist():
     try:
         sm = SimConnect()
         aq = AircraftRequests(sm)
         alt = aq.get("PLANE_ALTITUDE")
         groundSpeed = aq.get("GROUND_VELOCITY")
         finalAlt = float(finalAltEntry.get())
         dist = float(distanceEntry.get())
         y = alt - finalAlt
         vertSpeed = (y * groundSpeed) / (dist * 60)
         todLabel.config(text="Vertical Speed: " +
                         str(math.floor(vertSpeed)))
     except Exception:
         todLabel.config(text="Could not connect to simulator!")
Exemple #11
0
    def get_it(self, *args, **kwargs):
        try:
            sm = SimConnect()
        except ConnectionError:
            self.SetStatusText("Pretty sure flight sim is closed")
            return
        if not sm:
            self.SetStatusText("Pretty sure flight sim is closed")
            return

        aq = AircraftRequests(sm, _time=500)
        latlng = (aq.get("PLANE_LATITUDE"), aq.get("PLANE_LONGITUDE"))
        if int(latlng[0] * 10) == 0 and int(latlng[0] * 10) == 0:
            self.SetStatusText("Pretty sure you're not flying right now")
            return
        webbrowser.open(f'https://www.google.com/maps/?q={latlng}')
        self.SetStatusText(latlng)
Exemple #12
0
def init_simconnect(defaultRefreshTime: int):
    global aq
    global sm

    try:
        sm = SimConnect()
    except:
        print("Unexpected error, ", sys.exc_info()[0])
        return

    if sm:
        print("Succesful SimConnect call: ", sm)
    else:
        print("Unsuccesful Simconnect call, exiting.")
        return

    aq = AircraftRequests(sm, _time=defaultRefreshTime)
Exemple #13
0
def initAll(defaultRefreshTime: int):
    global aq
    global sm

    try:
        sm = SimConnect()
    except:
        print("Unexpected error, ", sys.exc_info()[0])
        return

    if sm:
        print("Succesful SimConnect call: ", sm)
    else:
        print("Unsuccesful Simconnect call, exiting.")
        return
    # Note the default _time is 2000 to be refreshed every 2 seconds

    aq = AircraftRequests(sm, _time=defaultRefreshTime)
def simconnect_thread_func(threadname):
    
    global ui_friendly_dictionary
    global event_name
    global value_to_use
    global sm
    global ae
    
    while True:
        try:
            sm = SimConnect()
            print("\n********* MSFS 2020 Mobile Companion App *********\n")
            print(f"Local web server for MSFS 2020 Mobile Companion App initialized.\n")
            print(f"Launch {socket.gethostbyname(socket.gethostname())}:4000 in your browser to access MSFS 2020 Mobile Companion App.\n")
            print(f"Make sure your your mobile device is connected to the same local network (WIFI) as this PC.\n")
            print(f"Notice: If your computer has more than one active ethernet/WIFI adapter, please check ipconfig in command prompt.\n")
            print("**************************************************\n\n")
            break
        except:
            print("Could not find MSFS running. Please launch MSFS first and then restart the MSFS 2020 Mobile Companion App.")
            sleep(5)
            
    ae = AircraftEvents(sm)
    aq = AircraftRequests(sm)

    # Initialize previous altitude for code stability
    previous_alt = -400

    # Initialize vars for landing info
    ui_friendly_dictionary["LANDING_VS1"] = "N/A"
    ui_friendly_dictionary["LANDING_T1"] = 0
    ui_friendly_dictionary["LANDING_VS2"] = "N/A"
    ui_friendly_dictionary["LANDING_T2"] = 0
    ui_friendly_dictionary["LANDING_VS3"] = "N/A"
    ui_friendly_dictionary["LANDING_T3"] = 0

    
    def thousandify(x):
        return f"{x:,}"

    async def ui_dictionary(ui_friendly_dictionary, previous_alt, landing_t1, landing_vs1, landing_t2, landing_vs2, landing_t3, landing_vs3):
        # Position
        try:
            ui_friendly_dictionary["LATITUDE"] = round(await aq.get("PLANE_LATITUDE"),6)
            ui_friendly_dictionary["LONGITUDE"] = round(await aq.get("PLANE_LONGITUDE"),6)
            ui_friendly_dictionary["MAGNETIC_COMPASS"] = round(round(await aq.get("PLANE_HEADING_DEGREES_TRUE"),2) * 180/3.1416, 2)
            #ui_friendly_dictionary["MAGVAR"] = round(await aq.get("MAGVAR"))
        except:
            None

        # Radios
        ui_friendly_dictionary["NAV1_STANDBY"] = round(await aq.get("NAV_STANDBY_FREQUENCY:1"),2)
        ui_friendly_dictionary["NAV1_ACTIVE"] = round(await aq.get("NAV_ACTIVE_FREQUENCY:1"),2)

        ui_friendly_dictionary["NAV2_STANDBY"] = round(await aq.get("NAV_STANDBY_FREQUENCY:2"),2)
        ui_friendly_dictionary["NAV2_ACTIVE"] = round(await aq.get("NAV_ACTIVE_FREQUENCY:2"),2)

        # ADF Active
        adf_use_bcd = int(await aq.get("ADF_ACTIVE_FREQUENCY:1"))
        adf_use_digits = ""

        for i in reversed(range(4)):
            adf_use_digit = math.floor(adf_use_bcd / (65536*(16**i)))
            adf_use_digits = adf_use_digits + str(adf_use_digit)
            adf_use_bcd = adf_use_bcd - (65536*(16**i)) * adf_use_digit

        try:
            ui_friendly_dictionary["ADF_USE_1000"] = adf_use_digits[0]
            ui_friendly_dictionary["ADF_USE_100"] = adf_use_digits[1]
            ui_friendly_dictionary["ADF_USE_10"] = adf_use_digits[2]
            ui_friendly_dictionary["ADF_USE_1"] = adf_use_digits[3]
            ui_friendly_dictionary["ADF_USE"] = int(adf_use_digits)
        except:
            None

        # ADF Standby
        adf_stby = int(await aq.get("ADF_STANDBY_FREQUENCY:1"))/1000
        try:
            if adf_stby >= 1000:
                ui_friendly_dictionary["ADF_STBY_1000"] = str(adf_stby)[0]
                ui_friendly_dictionary["ADF_STBY_100"] = str(adf_stby)[1]
                ui_friendly_dictionary["ADF_STBY_10"] = str(adf_stby)[2]
                ui_friendly_dictionary["ADF_STBY_1"] = str(adf_stby)[3]
            else:
                ui_friendly_dictionary["ADF_STBY_1000"] = "0"
                ui_friendly_dictionary["ADF_STBY_100"] = str(adf_stby)[0]
                ui_friendly_dictionary["ADF_STBY_10"] = str(adf_stby)[1]
                ui_friendly_dictionary["ADF_STBY_1"] = str(adf_stby)[2]
        except:
            None

        # NAV/ADF Compass Settings
        ui_friendly_dictionary["NAV1_OBS_DEG"] = round(await aq.get("NAV_OBS:1"),0)
        ui_friendly_dictionary["ADF_CARD_DEG"] = round(await aq.get("ADF_CARD"),0)
        ui_friendly_dictionary["NAV2_OBS_DEG"] = round(await aq.get("NAV_OBS:2"),0)

        # Comms
        ui_friendly_dictionary["COM1_STANDBY"] = round(await aq.get("COM_STANDBY_FREQUENCY:1"),3)
        ui_friendly_dictionary["COM1_ACTIVE"] = round(await aq.get("COM_ACTIVE_FREQUENCY:1"),3)
        ui_friendly_dictionary["COM1_TRANSMIT"] = await aq.get("COM_TRANSMIT:1")
        ui_friendly_dictionary["COM2_STANDBY"] = round(await aq.get("COM_STANDBY_FREQUENCY:2"),3)
        ui_friendly_dictionary["COM2_ACTIVE"] = round(await aq.get("COM_ACTIVE_FREQUENCY:2"),3)
        ui_friendly_dictionary["COM2_TRANSMIT"] = await aq.get("COM_TRANSMIT:2")
        
        # XPNDR
        xpndr_bcd = await aq.get("TRANSPONDER_CODE:1")
        xpndr_digits = ""
        
        # XPNDR Conversion from BCD to Decimal
        try:
            for i in reversed(range(4)):
                xpndr_digit = math.floor(xpndr_bcd / (16**i))
                xpndr_digits = xpndr_digits + str(xpndr_digit)
                xpndr_bcd = xpndr_bcd - (16**i) * xpndr_digit
        except:
            None

        try:
            ui_friendly_dictionary["XPNDR_1000"] = xpndr_digits[0]
            ui_friendly_dictionary["XPNDR_100"] = xpndr_digits[1]
            ui_friendly_dictionary["XPNDR_10"] = xpndr_digits[2]
            ui_friendly_dictionary["XPNDR_1"] = xpndr_digits[3]
            ui_friendly_dictionary["XPNDR"] = int(xpndr_digits)
        except:
            None

        # Autopilot
        ui_friendly_dictionary["AUTOPILOT_MASTER"] = await aq.get("AUTOPILOT_MASTER")
        ui_friendly_dictionary["AUTOPILOT_NAV1_LOCK"] = await aq.get("AUTOPILOT_NAV1_LOCK")
        ui_friendly_dictionary["AUTOPILOT_HEADING_LOCK"] = await aq.get("AUTOPILOT_HEADING_LOCK")
        ui_friendly_dictionary["AUTOPILOT_HEADING_LOCK_DIR"] = round(await aq.get("AUTOPILOT_HEADING_LOCK_DIR"))
        ui_friendly_dictionary["AUTOPILOT_ALTITUDE_LOCK"] = await aq.get("AUTOPILOT_ALTITUDE_LOCK")
        ui_friendly_dictionary["AUTOPILOT_ALTITUDE_LOCK_VAR"] = thousandify(round(await aq.get("AUTOPILOT_ALTITUDE_LOCK_VAR")))
        ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] = await aq.get("AUTOPILOT_GLIDESLOPE_HOLD")
        ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] = await aq.get("AUTOPILOT_APPROACH_HOLD")
        ui_friendly_dictionary["AUTOPILOT_BACKCOURSE_HOLD"] = await aq.get("AUTOPILOT_BACKCOURSE_HOLD")
        ui_friendly_dictionary["AUTOPILOT_VERTICAL_HOLD"] = await aq.get("AUTOPILOT_VERTICAL_HOLD")
        ui_friendly_dictionary["AUTOPILOT_VERTICAL_HOLD_VAR"] = await aq.get("AUTOPILOT_VERTICAL_HOLD_VAR")
        ui_friendly_dictionary["AUTOPILOT_FLIGHT_LEVEL_CHANGE"] = await aq.get("AUTOPILOT_FLIGHT_LEVEL_CHANGE")
        ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD_VAR"] = round(await aq.get("AUTOPILOT_AIRSPEED_HOLD_VAR"))
        ui_friendly_dictionary["AUTOPILOT_AUTOTHROTTLE"] = await aq.get("AUTOTHROTTLE_ACTIVE")
        ui_friendly_dictionary["AIRSPEED_INDICATED"] = round(await aq.get("AIRSPEED_INDICATED"))
        # Placeholders - Not Actively Used for stress testing
        #ui_friendly_dictionary["AUTOPILOT_NAV_SELECTED"] = await aq.get("AUTOPILOT_NAV_SELECTED")
        #ui_friendly_dictionary["AUTOPILOT_WING_LEVELER"] = await aq.get("AUTOPILOT_WING_LEVELER")
        #ui_friendly_dictionary["AUTOPILOT_PITCH_HOLD"] = await aq.get("AUTOPILOT_PITCH_HOLD")
        #ui_friendly_dictionary["AUTOPILOT_PITCH_HOLD_REF"] = await aq.get("AUTOPILOT_PITCH_HOLD_REF")
        ui_friendly_dictionary["AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE"] = await aq.get("AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE")
        # Lights
        ui_friendly_dictionary["LIGHT_LANDING"] = await aq.get("LIGHT_LANDING")
        ui_friendly_dictionary["LIGHT_TAXI"] = await aq.get("LIGHT_TAXI")
        ui_friendly_dictionary["LIGHT_STROBE"] = await aq.get("LIGHT_STROBE")
        ui_friendly_dictionary["LIGHT_NAV"] = await aq.get("LIGHT_NAV")
        ui_friendly_dictionary["LIGHT_BEACON"] = await aq.get("LIGHT_BEACON")
        ui_friendly_dictionary["LIGHT_CABIN"] = await aq.get("LIGHT_CABIN")
        ui_friendly_dictionary["LIGHT_LOGO"] = await aq.get("LIGHT_CABIN")
        ui_friendly_dictionary["LIGHT_PANEL"] = await aq.get("LIGHT_PANEL")
        ui_friendly_dictionary["LIGHT_WING"] = await aq.get("LIGHT_WING")
        ui_friendly_dictionary["LIGHT_RECOGNITION"] = await aq.get("LIGHT_RECOGNITION")
        # Pitot Heat and Deice
        ui_friendly_dictionary["PITOT_HEAT"] = await aq.get("PITOT_HEAT")
        #ui_friendly_dictionary["PROP_DEICE_SWITCH"] = await aq.get("PROP_DEICE_SWITCH:1")
        ui_friendly_dictionary["ENG_ANTI_ICE"] = await aq.get("ENG_ANTI_ICE:1")
        #ui_friendly_dictionary["GEN_ENG_ANTI_ICE"] = await aq.get("GENERAL_ENG_ANTI_ICE_POSITION:1")
        ui_friendly_dictionary["STRUCTURAL_DEICE_SWITCH"] = await aq.get("STRUCTURAL_DEICE_SWITCH")
        #ui_friendly_dictionary["PANEL_ANTI_ICE_SWITCH"] = await aq.get("PANEL_ANTI_ICE_SWITCH")
        # Sim Rate
        ui_friendly_dictionary["SIMULATION_RATE"] = await aq.get("SIMULATION_RATE")
        # GPS Next Waypoint
        ui_friendly_dictionary["NEXT_WP_LAT"] = await aq.get("GPS_WP_NEXT_LAT")
        ui_friendly_dictionary["NEXT_WP_LON"] = await aq.get("GPS_WP_NEXT_LON")
        
        # Current altitude
        current_alt = await aq.get("INDICATED_ALTITUDE")
        if current_alt > -300:
            ui_friendly_dictionary["INDICATED_ALTITUDE"] = round(current_alt)
            previous_alt = current_alt
        else:
            try:
                ui_friendly_dictionary["INDICATED_ALTITUDE"] = previous_alt
            except:
                pass
        
        # LOC and APPR Mode
        try:
            if (ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] == 1 and ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] == 1):
                ui_friendly_dictionary["AUTOPILOT_APPR_MODE"] = 1
            else:
                ui_friendly_dictionary["AUTOPILOT_APPR_MODE"] = 0
            if (ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] == 1 and ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] == 0):
                ui_friendly_dictionary["AUTOPILOT_LOC_MODE"] = 1
            else:
                ui_friendly_dictionary["AUTOPILOT_LOC_MODE"] = 0     
        except:
            None
        
        # Other
        
        current_landing = round(await aq.get("PLANE_TOUCHDOWN_NORMAL_VELOCITY") * 60)
        current_time = datetime.datetime.now().strftime('%H:%M:%S')
        
        if landing_vs1 != current_landing:
            # Move 2nd to 3rd
            landing_t3 = landing_t2
            landing_vs3 = landing_vs2
            # Move 1st to 2nd
            landing_t2 = landing_t1
            landing_vs2 = landing_vs1
            # Assign new 1st
            landing_t1 = current_time
            landing_vs1 = current_landing
            # Dictionary Output
            ui_friendly_dictionary["LANDING_VS1"] = landing_vs1
            ui_friendly_dictionary["LANDING_T1"] = landing_t1
            ui_friendly_dictionary["LANDING_VS2"] = landing_vs2
            ui_friendly_dictionary["LANDING_T2"] = landing_t2
            ui_friendly_dictionary["LANDING_VS3"] = landing_vs3
            ui_friendly_dictionary["LANDING_T3"] = landing_t3
        
    while True:
        asyncio.run(ui_dictionary(ui_friendly_dictionary, previous_alt, ui_friendly_dictionary["LANDING_T1"], ui_friendly_dictionary["LANDING_VS1"], ui_friendly_dictionary["LANDING_T2"], ui_friendly_dictionary["LANDING_VS2"], ui_friendly_dictionary["LANDING_T3"], ui_friendly_dictionary["LANDING_VS3"]))
Exemple #15
0
from SimConnect import *
import logging
from SimConnect.Enum import *
from time import sleep

logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.info("START")
# time holder for inline commands
ct_g = millis()

# creat simconnection and pass used user classes
sm = SimConnect()
aq = AircraftRequests(sm)
ae = AircraftEvents(sm)

mc = aq.find("MAGNETIC_COMPASS")
mv = aq.find("MAGVAR")
print(mc.get() + mv.get())

sm.exit()
quit()

# Set pos arund space nedle in WA.
sm.set_pos(
    _Altitude=1000.0,
    _Latitude=47.614699,
    _Longitude=-122.358473,
    _Airspeed=130,
    _Heading=70.0,
    # _Pitch=0.0,
debug = "OFF"


engine = tts.init()
def sayit(text):
    engine.say(text)
    engine.runAndWait()

simconnect_path = os.getcwd() + "/SimConnect.dll"

if debug == "OFF":
  # Create SimConnect link
  while True:
    try:
        sm = SimConnect(library_path=simconnect_path)
        break
    except:
        print("Could not find MSFS running. Please launch MSFS.")
        sleep(5)

    # Note the default _time is 2000 to be refreshed every 2 seconds
  aq = AircraftRequests(sm, _time=1000)
    # Use _time=ms where ms is the time in milliseconds to cache the data.
    # Setting ms to 0 will disable data caching and always pull new data from the sim.
    # There is still a timeout of 4 tries with a 10ms delay between checks.
    # If no data is received in 40ms the value will be set to None
    # Each request can be fine tuned by setting the time param.

    # To find and set timeout of cached data to 200ms:
    #altitude = aq.find("PLANE_ALTITUDE")
Exemple #17
0
    def cruise(self):
        rnd = 1
        points = 200
        random.seed(0)
        cg = 0.27
        error_alt = 1
        error_tas = 1
        actual_vs = 1000
        n = 1

        # Read the Aircraft Data file
        df = data.data_read('CRZ')
        logger.test_header(self, "CRZ")
        if os.path.exists("test.txt"):
            os.remove("test.txt")

        start_time = time.time()

        if (rnd == 0):
            points = len(df.index) - 1

        # Create the SimConnect link
        sm = SimConnect()
        aq = AircraftRequests(sm, _time=0)
        ae = AircraftEvents(sm)
        logger.test_simconnect(self, 1)

        hsi = Event(b'HEADING_SLOT_INDEX_SET', sm)
        hsi(1)

        # Check and set initial aircraft settings:
        # AP1 ON, ATHR ON, FD ON & CLB
        ac_init(aq, ae)
        logger.test_init(self, 1)

        for i in range(n, points + 1):
            if (rnd == 1):
                # Random Aircraft situation
                if (n == i):
                    start = n
                else:
                    start = 0

                weight, altitude, tas, mach, n1 = data.a32x_state_rnd(
                    df, start)
            else:
                weight, altitude, tas, mach, n1 = data.a32x_state_nrm(df, i)

            # Set Weight and CG ... this goes first to avoid excessive dumping
            W_n_B(aq, weight, cg)
            if (i == 1):
                logger.test_init(self, 0)
                logger.test_loop(self, 1)
            logger.test_obj(self, weight, cg, altitude, tas, mach, n1, i,
                            points)

            # Main test point routine - Setting stable aircraft conditions
            crz_alt_tas(sm, aq, ae, altitude, tas)

            # Altitude & Speed damping "filter". Use VS first as a measure
            # of stability
            # To avoid excesive damping, fuel and CG are set first with
            # enough headroom
            # A stability counter is implemented to account for VS damping
            counter = 0
            prev_n1 = 0
            ap_cycler = time.time()
            while counter < 50:
                if not (round(time.time() - ap_cycler) % 10):
                    actual_fcu_speed = float(
                        aq.get("AUTOPILOT_AIRSPEED_HOLD_VAR"))
                    event_to_trigger = ae.find("AP_MASTER")
                    if (abs(actual_fcu_speed - tas) > 2):
                        crz_alt_tas(sm, aq, ae, altitude, tas)
                        print("FCU Trigger")

                    if (counter == 0):
                        print("AP Trigger")
                        event_to_trigger()
                        time.sleep(1)
                        event_to_trigger()

                actual_alt = float(aq.get("INDICATED_ALTITUDE"))
                actual_tas = float(aq.get("AIRSPEED_TRUE"))
                actual_vs = float(aq.get("VERTICAL_SPEED"))
                error_alt = round(
                    abs((actual_alt - altitude) / altitude) * 100, 3)
                error_tas = round(abs((actual_tas - tas) / tas) * 100, 3)

                if (error_alt < 0.5 and error_tas < 0.5
                        and abs(actual_vs) < 10):
                    actual_n1 = aq.get("TURB_ENG_N1:1")
                    print("Diff N1=" + str(actual_n1 - prev_n1))
                    if (abs(float(actual_n1) - prev_n1) < 0.1):
                        counter += 1
                        print("counter=" + str(counter))
                        time.sleep(0.1)
                    else:
                        counter = 0
                    prev_n1 = float(actual_n1)

                elapsed_time = time.time() - start_time
                msg = "Tolerance Figures - Alt: " + str(
                    error_alt) + "%  TAS: " + str(error_tas) + "%  VS: " + str(
                        round(actual_vs,
                              1)) + "fpm          Elapsed Time - " + str(
                                  round(elapsed_time, 2)) + " secs."

                self.updateStatus(msg)
                QtCore.QCoreApplication.processEvents()

            actual_weight = aq.get("TOTAL_WEIGHT")
            actual_alt = aq.get("INDICATED_ALTITUDE")
            actual_tas = aq.get("AIRSPEED_TRUE")
            actual_mach = aq.get("AIRSPEED_MACH")
            actual_vs = aq.get("VERTICAL_SPEED")
            actual_cg = aq.get("CG_PERCENT")
            actual_fn = float(aq.get("TURB_ENG_JET_THRUST:1")) * 2
            actual_n1 = aq.get("TURB_ENG_N1:1")
            actual_n2 = aq.get("TURB_ENG_N2:1")
            actual_n1_cor = aq.get("TURB_ENG_CORRECTED_N1:1")
            actual_n2_cor = aq.get("TURB_ENG_CORRECTED_N2:1")
            actual_egt_R = float(
                aq.get("GENERAL_ENG_EXHAUST_GAS_TEMPERATURE:1"))
            actual_egt = (actual_egt_R - 491.67) * 5 / 9
            actual_ff = float(
                aq.get("TURB_ENG_FUEL_FLOW_PPH:1")) * 2 * 0.453592
            logger.test_actual(self, actual_weight, actual_cg, actual_alt,
                               actual_tas, actual_mach, actual_vs, actual_fn,
                               actual_n1, actual_n2, actual_n1_cor,
                               actual_n2_cor, actual_egt, actual_ff, i, points)

            time.sleep(0.5)
            os.system('copy test.txt test.bck >NUL')
            self.dumpToFile()
            time.sleep(0.5)

            if not (i % 10):
                eta = ((time.time() - start_time) / i) * (points - i)
                if (eta > 3600):
                    eta = round(eta / 3600, 2)
                    subject = "FBW Tester: ETA is " + str(eta) + " hours"
                elif (eta < 3600 and eta > 60):
                    eta = round(eta / 60)
                    subject = "FBW Tester: ETA is " + str(eta) + " minutes"
                else:
                    eta = eta
                    subject = "FBW Tester: ETA is " + str(eta) + " seconds"

                gmail.gmail(subject)

        #sm.quit()
        logger.test_loop(self, 0)
        logger.test_simconnect(self, 0)
        self.dumpToFile()
Exemple #18
0
import sys

def signal_handler(sig, frame):
	print('Received SIGINT! Exiting now...')
	sm.exit()
	sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)

# logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.info("START")
# time holder for inline commands
ct_g = millis()

# creat simconnection and pass used user classes
sm = SimConnect()
aq = AircraftRequests(sm)
ae = AircraftEvents(sm)

# Add a simple REPL, exposing the SimConnect Interface.

header = "SimConnect Test REPL"
footer = "Closing now!"

# Some Example definitions:
A = aq.find("ATC_ID")
T = ae.find("TOGGLE_PUSHBACK")
H = ae.find("KEY_TUG_HEADING")
S = ae.find("KEY_TUG_SPEED")
def H2I(hdg):
	return int((2**32-1)*hdg/360)
Exemple #19
0
def cruise(w, points):
    df = fbw.data_read('CRZ')
    logger.test_header(w, "CRZ")
    start_time = time.time()
    i = 1
    weight, altitude, ias = fbw.a32x_state(df)
    logger.test_env(w, weight, altitude, ias, i, points)

    ## Create SimConnect link
    sm = SimConnect()
    aq = AircraftRequests(sm, _time=0)
    ae = AircraftEvents(sm)

    ############################################
    ## Check Environment and Aircraft Status:
    ## - AP1 ON, ATHR ON, FD ON
    ############################################
    AP = aq.get("AUTOPILOT_MASTER")
    ATHR = aq.get("AUTOTHROTTLE_ACTIVE")
    FD = aq.get("AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE")

    event_to_trigger = ae.find("TOGGLE_FLIGHT_DIRECTOR")
    event_to_trigger()
    event_to_trigger()

    if (AP == 0):
        event_to_trigger = ae.find("AP_MASTER")
        event_to_trigger()
    if (ATHR == 0):
        event_to_trigger = ae.find("AUTO_THROTTLE_ARM")
        event_to_trigger()
    if (FD == 0):
        event_to_trigger = ae.find("TOGGLE_FLIGHT_DIRECTOR")
        event_to_trigger()

    ## Set Throttle to CLIMB
    aq.set("GENERAL_ENG_THROTTLE_LEVER_POSITION:1", 82)
    aq.set("GENERAL_ENG_THROTTLE_LEVER_POSITION:2", 82)

    ## Set Key Aircraft Parameters
    asi = Event(b'ALTITUDE_SLOT_INDEX_SET', sm)
    ssi = Event(b'SPEED_SLOT_INDEX_SET', sm)

    ## Altitude
    target_altitude = int(altitude)
    event_to_trigger = ae.find("AP_ALT_VAR_SET_ENGLISH")
    event_to_trigger(target_altitude)
    asi(1)
    aq.set("INDICATED_ALTITUDE", altitude)

    ## Speed
    target_speed = int(ias)
    event_to_trigger = ae.find("AP_SPD_VAR_SET")
    event_to_trigger(target_speed)
    ssi(1)
    aq.set("AIRSPEED_INDICATED", ias)

    ####################################
    ## Check Altitude/ Speed Stability
    ####################################
    error_alt = 1
    error_ias = 1
    actual_vs = 1000
    while error_alt > 1 or error_ias > 1 or abs(actual_vs) > 20:
        actual_alt = aq.get("INDICATED_ALTITUDE")
        actual_ias = aq.get("AIRSPEED_INDICATED")
        actual_vs = aq.get("VERTICAL_SPEED")
        error_alt = abs((actual_alt - altitude) / altitude) * 100
        error_ias = abs((actual_ias - ias) / ias) * 100
        msg = "Alt: " + str(error_alt) + "  IAS: " + str(
            error_ias) + "  VS: " + str(actual_vs)
        w.updateStatus(msg)
        #time.sleep(1)

    print(error_alt, " ", error_ias, " ", actual_vs)

    ## Tweak Aircraft Weight
    actual_weight = aq.get("TOTAL_WEIGHT")

    print(actual_weight)
    elapsed_time = time.time() - start_time
    #w.statusBar().showMessage("Elapsed= " + str(elapsed_time))

    #sm.quit()
    exit()

    return
Exemple #20
0
import time
from SimConnect import *

sm = SimConnect()
aq = AircraftRequests(sm, _time=0)
ae = AircraftEvents(sm)

# target_speed = 260 #240 - 260
# event_to_trigger = ae.find("AP_SPD_VAR_SET")
# event_to_trigger(target_speed)

# time.sleep(0.5)
# ssi = Event(b'SPEED_SLOT_INDEX_SET', sm)
# ssi(1)
# time.sleep(0.5)

# sm.quit()
# exit()

hsi = Event(b'HEADING_SLOT_INDEX_SET', sm)
hsi(1)

# Check and set initial aircraft settings:
# AP1 ON, ATHR ON, FD ON & CLB
AP = aq.get("AUTOPILOT_MASTER")
ATHR = aq.get("AUTOTHROTTLE_ACTIVE")
FD = aq.get("AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE")

event_to_trigger = ae.find("TOGGLE_FLIGHT_DIRECTOR")
event_to_trigger()
event_to_trigger()
def simconnect_thread_func(threadname):

    global simconnect_dict

    # Init SimConnect
    sm = SimConnect()
    aq = AircraftRequests(sm, _time=0)

    # Init variables
    airborne = False
    v_speed_list = []
    g_force_list = []
    plane_alt_above_ground_list = []
    sim_on_ground_list = [1, 1, 1, 1, 1, 1, 1, 1]
    run_app = 1
    simconnect_dict["G_FORCE"] = 0
    simconnect_dict["VERTICAL_SPEED"] = 0
    simconnect_dict["SIM_ON_GROUND"] = 0
    simconnect_dict["G_FORCE_LANDING"] = "N/A"
    simconnect_dict["VERTICAL_SPEED_LANDING"] = "N/A"
    simconnect_dict["G_FORCE_LANDING_LIST"] = "N/A"
    simconnect_dict["VERTICAL_SPEED_LANDING_LIST"] = "N/A"
    simconnect_dict["SIM_ON_GROUND_LIST"] = "N/A"
    simconnect_dict["AIRBORNE"] = 0
    simconnect_dict["G_FORCE_LIST"] = g_force_list
    simconnect_dict["V_SPEED_LIST"] = v_speed_list
    simconnect_dict[
        "PLANE_ALT_ABOVE_GROUND_LIST"] = plane_alt_above_ground_list
    simconnect_dict["LANDING_RATING"] = "N/A"
    simconnect_dict["LANDING_COUNTER"] = 0

    # Create empty labels for charts
    labels_list = []
    for i in range(150):
        labels_list.append("")
    simconnect_dict["LABELS"] = labels_list

    # Run Simconnect Calculations
    while run_app == 1:

        if airborne == True and sum(sim_on_ground_list) == 30:
            simconnect_dict["G_FORCE_LANDING"] = max(g_force_list)
            max_gforce_index = g_force_list.index(max(g_force_list))
            simconnect_dict["VERTICAL_SPEED_LANDING"] = v_speed_list[
                max_gforce_index]
            simconnect_dict["G_FORCE_LANDING_LIST"] = g_force_list[::-1] * 1
            v_speed_list_neg = [elem * (-1) for elem in v_speed_list]
            simconnect_dict[
                "VERTICAL_SPEED_LANDING_LIST"] = v_speed_list_neg[::-1] * 1
            simconnect_dict[
                "PLANE_ALT_ABOVE_GROUND_LIST"] = plane_alt_above_ground_list[::
                                                                             -1] * 1
            simconnect_dict[
                "LANDING_COUNTER"] = simconnect_dict["LANDING_COUNTER"] + 1

            # Landing Rating Based on G-Forces
            if simconnect_dict["G_FORCE_LANDING"] < 1.25:
                simconnect_dict["LANDING_RATING"] = "Smooth landing"
            elif simconnect_dict["G_FORCE_LANDING"] < 1.5:
                simconnect_dict["LANDING_RATING"] = "Acceptable landing"
            elif simconnect_dict["G_FORCE_LANDING"] < 1.75:
                simconnect_dict["LANDING_RATING"] = "Poor landing"
            elif simconnect_dict["G_FORCE_LANDING"] < 2:
                simconnect_dict["LANDING_RATING"] = "Hard landing"
            elif simconnect_dict["G_FORCE_LANDING"] <= 2.5:
                simconnect_dict["LANDING_RATING"] = "Very hard landing"
            else:
                simconnect_dict[
                    "LANDING_RATING"] = "Structural damage to plane"
            airborne = False

        if sum(sim_on_ground_list) == 0 and airborne == False:
            airborne = True

        # Get Current Data
        simconnect_dict["G_FORCE"] = round(aq.get("G_FORCE"), 2)
        simconnect_dict["VERTICAL_SPEED"] = round(aq.get("VERTICAL_SPEED"))
        simconnect_dict["SIM_ON_GROUND"] = aq.get("SIM_ON_GROUND")
        simconnect_dict["AIRBORNE"] = airborne
        simconnect_dict["G_FORCE_LIST"] = g_force_list

        # Make lists
        v_speed_list.insert(0, simconnect_dict["VERTICAL_SPEED"])
        if len(v_speed_list) > 151:
            v_speed_list.pop()
        g_force_list.insert(0, simconnect_dict["G_FORCE"])
        if len(g_force_list) > 151:
            g_force_list.pop()
        sim_on_ground_list.insert(0, simconnect_dict["SIM_ON_GROUND"])
        if len(sim_on_ground_list) > 31:
            sim_on_ground_list.pop()
        plane_alt_above_ground_list.insert(
            0, (round(aq.get("PLANE_ALT_ABOVE_GROUND"), 1)))
        if len(plane_alt_above_ground_list) > 151:
            plane_alt_above_ground_list.pop()
Exemple #22
0
def simconnect_thread_func(threadname):

    global ui_friendly_dictionary
    global event_name
    global value_to_use
    global sm
    global ae

    while True:
        try:
            sm = SimConnect()
            print("\n********* MSFS 2020 Mobile Companion App *********\n")
            print(f"Local web server for MSFS 2020 Mobile Companion App initialized.\n")
            print(
                f"Launch {socket.gethostbyname(socket.gethostname())}:4000 in your browser to access MSFS 2020 Mobile Companion App.\n")
            print(
                f"Make sure your your mobile device is connected to the same local network (WIFI) as this PC.\n")
            print(f"Notice: If your computer has more than one active ethernet/WIFI adapter, please check ipconfig in command prompt.\n")
            print("**************************************************\n\n")
            break
        except:
            print("Could not find MSFS running. Please launch MSFS first and then restart the MSFS 2020 Mobile Companion App.")
            sleep(5)

    ae = AircraftEvents(sm)
    aq = AircraftRequests(sm)

    # Initialize previous altitude for code stability
    previous_alt = -400

    # Initialize vars for landing info
    ui_friendly_dictionary["LANDING_VS1"] = "N/A"
    ui_friendly_dictionary["LANDING_T1"] = 0
    ui_friendly_dictionary["LANDING_G1"] = "N/A"
    ui_friendly_dictionary["LANDING_VS2"] = "N/A"
    ui_friendly_dictionary["LANDING_T2"] = 0
    ui_friendly_dictionary["LANDING_G2"] = "N/A"
    ui_friendly_dictionary["LANDING_VS3"] = "N/A"
    ui_friendly_dictionary["LANDING_T3"] = 0
    ui_friendly_dictionary["LANDING_G3"] = "N/A"

    def thousandify(x):
        return f"{x:,}"

    async def ui_dictionary(ui_friendly_dictionary, previous_alt, landing_t1, landing_vs1, landing_t2, landing_vs2, landing_t3, landing_vs3, landing_g1, landing_g2, landing_g3):
        # Position
        try:
            ui_friendly_dictionary["LATITUDE"] = round(await aq.get("PLANE_LATITUDE"), 6)
            ui_friendly_dictionary["LONGITUDE"] = round(await aq.get("PLANE_LONGITUDE"), 6)
            ui_friendly_dictionary["MAGNETIC_COMPASS"] = round(round(await aq.get("PLANE_HEADING_DEGREES_TRUE"), 2) * 180/3.1416, 2)
            # ui_friendly_dictionary["MAGVAR"] = round(await aq.get("MAGVAR"))
        except:
            None

        # Radios
        ui_friendly_dictionary["NAV1_STANDBY"] = round(await aq.get("NAV_STANDBY_FREQUENCY:1"), 2)
        ui_friendly_dictionary["NAV1_ACTIVE"] = round(await aq.get("NAV_ACTIVE_FREQUENCY:1"), 2)

        ui_friendly_dictionary["NAV2_STANDBY"] = round(await aq.get("NAV_STANDBY_FREQUENCY:2"), 2)
        ui_friendly_dictionary["NAV2_ACTIVE"] = round(await aq.get("NAV_ACTIVE_FREQUENCY:2"), 2)

        # ADF Active
        adf_use_bcd = int(await aq.get("ADF_ACTIVE_FREQUENCY:1"))
        adf_use_digits = ""

        for i in reversed(range(4)):
            adf_use_digit = math.floor(adf_use_bcd / (65536*(16**i)))
            adf_use_digits = adf_use_digits + str(adf_use_digit)
            adf_use_bcd = adf_use_bcd - (65536*(16**i)) * adf_use_digit

        try:
            ui_friendly_dictionary["ADF_USE_1000"] = adf_use_digits[0]
            ui_friendly_dictionary["ADF_USE_100"] = adf_use_digits[1]
            ui_friendly_dictionary["ADF_USE_10"] = adf_use_digits[2]
            ui_friendly_dictionary["ADF_USE_1"] = adf_use_digits[3]
            ui_friendly_dictionary["ADF_USE"] = int(adf_use_digits)
        except:
            None

        # ADF Standby
        adf_stby = int(await aq.get("ADF_STANDBY_FREQUENCY:1"))/1000
        try:
            if adf_stby >= 1000:
                ui_friendly_dictionary["ADF_STBY_1000"] = str(adf_stby)[0]
                ui_friendly_dictionary["ADF_STBY_100"] = str(adf_stby)[1]
                ui_friendly_dictionary["ADF_STBY_10"] = str(adf_stby)[2]
                ui_friendly_dictionary["ADF_STBY_1"] = str(adf_stby)[3]
            else:
                ui_friendly_dictionary["ADF_STBY_1000"] = "0"
                ui_friendly_dictionary["ADF_STBY_100"] = str(adf_stby)[0]
                ui_friendly_dictionary["ADF_STBY_10"] = str(adf_stby)[1]
                ui_friendly_dictionary["ADF_STBY_1"] = str(adf_stby)[2]
        except:
            None

        # NAV/ADF Compass Settings
        # ui_friendly_dictionary["NAV1_OBS_DEG"] = round(await aq.get("NAV_OBS:1"),0)
        # ui_friendly_dictionary["ADF_CARD_DEG"] = round(await aq.get("ADF_CARD"),0)
        # ui_friendly_dictionary["NAV2_OBS_DEG"] = round(await aq.get("NAV_OBS:2"),0)

        # Comms
        ui_friendly_dictionary["COM1_STANDBY"] = round(await aq.get("COM_STANDBY_FREQUENCY:1"), 3)
        ui_friendly_dictionary["COM1_ACTIVE"] = round(await aq.get("COM_ACTIVE_FREQUENCY:1"), 3)
        ui_friendly_dictionary["COM1_TRANSMIT"] = await aq.get("COM_TRANSMIT:1")
        ui_friendly_dictionary["COM2_STANDBY"] = round(await aq.get("COM_STANDBY_FREQUENCY:2"), 3)
        ui_friendly_dictionary["COM2_ACTIVE"] = round(await aq.get("COM_ACTIVE_FREQUENCY:2"), 3)
        ui_friendly_dictionary["COM2_TRANSMIT"] = await aq.get("COM_TRANSMIT:2")

        # XPNDR
        xpndr_bcd = await aq.get("TRANSPONDER_CODE:1")
        xpndr_digits = ""

        # XPNDR Conversion from BCD to Decimal
        try:
            for i in reversed(range(4)):
                xpndr_digit = math.floor(xpndr_bcd / (16**i))
                xpndr_digits = xpndr_digits + str(xpndr_digit)
                xpndr_bcd = xpndr_bcd - (16**i) * xpndr_digit
        except:
            None

        try:
            ui_friendly_dictionary["XPNDR_1000"] = xpndr_digits[0]
            ui_friendly_dictionary["XPNDR_100"] = xpndr_digits[1]
            ui_friendly_dictionary["XPNDR_10"] = xpndr_digits[2]
            ui_friendly_dictionary["XPNDR_1"] = xpndr_digits[3]
            ui_friendly_dictionary["XPNDR"] = int(xpndr_digits)
        except:
            None

        # Autopilot
        ui_friendly_dictionary["AUTOPILOT_MASTER"] = await aq.get("AUTOPILOT_MASTER")
        ui_friendly_dictionary["AUTOPILOT_NAV1_LOCK"] = await aq.get("AUTOPILOT_NAV1_LOCK")
        ui_friendly_dictionary["AUTOPILOT_HEADING_LOCK"] = await aq.get("AUTOPILOT_HEADING_LOCK")
        ui_friendly_dictionary["AUTOPILOT_ALTITUDE_LOCK"] = await aq.get("AUTOPILOT_ALTITUDE_LOCK")
        ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] = await aq.get("AUTOPILOT_GLIDESLOPE_HOLD")
        ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] = await aq.get("AUTOPILOT_APPROACH_HOLD")
        ui_friendly_dictionary["AUTOPILOT_BACKCOURSE_HOLD"] = await aq.get("AUTOPILOT_BACKCOURSE_HOLD")
        ui_friendly_dictionary["AUTOPILOT_VERTICAL_HOLD"] = await aq.get("AUTOPILOT_VERTICAL_HOLD")
        ui_friendly_dictionary["AUTOPILOT_FLIGHT_LEVEL_CHANGE"] = await aq.get("AUTOPILOT_FLIGHT_LEVEL_CHANGE")
        ui_friendly_dictionary["AUTOPILOT_AUTOTHROTTLE"] = await aq.get("AUTOTHROTTLE_ACTIVE")
        ui_friendly_dictionary["AUTOPILOT_YAW_DAMPER"] = await aq.get("AUTOPILOT_YAW_DAMPER")
        ui_friendly_dictionary["AIRSPEED_INDICATED"] = round(await aq.get("AIRSPEED_INDICATED"))
        ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD"] = await aq.get("AUTOPILOT_AIRSPEED_HOLD")
        # ui_friendly_dictionary["AUTOPILOT_MACH_HOLD_VAR"] = round(await aq.get("AUTOPILOT_MACH_HOLD_VAR"),2)
        ui_friendly_dictionary["PLANE_HEADING_DEGREES"] = round(round(await aq.get("PLANE_HEADING_DEGREES_MAGNETIC"), 2) * 180/3.1416, 0)
        # Placeholders - Not Actively Used for stress testing
        # ui_friendly_dictionary["DA62_DEICE_PUMP"] = await aq.get("MobiFlight.DA62_DEICE_PUMP")
        # ui_friendly_dictionary["DA62_ICE_LIGHT_MAX_STATE_ENABLED"] = await aq.get("MobiFlight.DA62_ICE_LIGHT_MAX_STATE_ENABLED")
        # ui_friendly_dictionary["JFARROW_AP_HDG"] = await aq.get("MobiFlight.JFARROW_AP_HDG")
        # ui_friendly_dictionary["AUTOPILOT_WING_LEVELER"] = await aq.get("AUTOPILOT_WING_LEVELER")
        # ui_friendly_dictionary["AUTOPILOT_PITCH_HOLD"] = await aq.get("AUTOPILOT_PITCH_HOLD")
        # ui_friendly_dictionary["AUTOPILOT_PITCH_HOLD_REF"] = await aq.get("AUTOPILOT_PITCH_HOLD_REF")
        ui_friendly_dictionary["AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE"] = await aq.get("AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE")
        # Lights
        #ui_friendly_dictionary["LIGHT_LANDING"] = await aq.get("LIGHT_LANDING")
        #ui_friendly_dictionary["LIGHT_TAXI"] = await aq.get("LIGHT_TAXI")
        #ui_friendly_dictionary["LIGHT_STROBE"] = await aq.get("LIGHT_STROBE")
        #ui_friendly_dictionary["LIGHT_NAV"] = await aq.get("LIGHT_NAV")
        #ui_friendly_dictionary["LIGHT_BEACON"] = await aq.get("LIGHT_BEACON")
        #ui_friendly_dictionary["LIGHT_CABIN"] = await aq.get("LIGHT_CABIN")
        #ui_friendly_dictionary["LIGHT_LOGO"] = await aq.get("LIGHT_LOGO")
        #ui_friendly_dictionary["LIGHT_PANEL"] = await aq.get("LIGHT_PANEL")
        #ui_friendly_dictionary["LIGHT_WING"] = await aq.get("LIGHT_WING")
        #ui_friendly_dictionary["LIGHT_RECOGNITION"] = await aq.get("LIGHT_RECOGNITION")
        # Pitot Heat and Deice
        #ui_friendly_dictionary["PITOT_HEAT"] = await aq.get("PITOT_HEAT")
        # ui_friendly_dictionary["PROP_DEICE_SWITCH"] = await aq.get("PROP_DEICE_SWITCH:1")
        #ui_friendly_dictionary["ENG_ANTI_ICE"] = await aq.get("ENG_ANTI_ICE:1")
        # ui_friendly_dictionary["GEN_ENG_ANTI_ICE"] = await aq.get("GENERAL_ENG_ANTI_ICE_POSITION:1")
        #ui_friendly_dictionary["STRUCTURAL_DEICE_SWITCH"] = await aq.get("STRUCTURAL_DEICE_SWITCH")
        # ui_friendly_dictionary["PANEL_ANTI_ICE_SWITCH"] = await aq.get("PANEL_ANTI_ICE_SWITCH")
        # Sim Rate
        ui_friendly_dictionary["SIMULATION_RATE"] = await aq.get("SIMULATION_RATE")
        # GPS Next Waypoint
        ui_friendly_dictionary["NEXT_WP_LAT"] = await aq.get("GPS_WP_NEXT_LAT")
        ui_friendly_dictionary["NEXT_WP_LON"] = await aq.get("GPS_WP_NEXT_LON")
        # Other
        ui_friendly_dictionary["GEAR_POSITION"] = await aq.get("GEAR_POSITION:1")
        ui_friendly_dictionary["FLAPS_HANDLE_PERCENT"] = round(await aq.get("FLAPS_HANDLE_PERCENT")*100)
        ui_friendly_dictionary["SPOILERS_ARMED"] = await aq.get("SPOILERS_HANDLE_POSITION")

        # Current altitude
        current_alt = await aq.get("INDICATED_ALTITUDE")
        if current_alt > -300:
            ui_friendly_dictionary["INDICATED_ALTITUDE"] = round(current_alt)
            previous_alt = current_alt
        else:
            try:
                ui_friendly_dictionary["INDICATED_ALTITUDE"] = previous_alt
            except:
                pass

        # LOC and APPR Mode
        try:
            if (ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] == 1 and ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] == 1):
                ui_friendly_dictionary["AUTOPILOT_APPR_MODE"] = 1
            else:
                ui_friendly_dictionary["AUTOPILOT_APPR_MODE"] = 0
            if (ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] == 1 and ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] == 0):
                ui_friendly_dictionary["AUTOPILOT_LOC_MODE"] = 1
            else:
                ui_friendly_dictionary["AUTOPILOT_LOC_MODE"] = 0
        except:
            None

        # Other

        current_landing = round(await aq.get("PLANE_TOUCHDOWN_NORMAL_VELOCITY") * 60)
        current_time = datetime.datetime.now().strftime('%H:%M:%S')
        # Calculate Custom G-Force based on vertical speed
        # Model uses Harvsine acceleration model for peak acceleration https://www.nhtsa.gov/sites/nhtsa.dot.gov/files/18esv-000501.pdf
        # For time a custom function is used that ranges from 0.25 for GA to 0.35 for airliners. This simulates the rigidness of suspention.
        try:
            plane_weight = await aq.get("TOTAL_WEIGHT")
        except:
            plane_weight = 0
        plane_weight_adj = max(round(plane_weight * 0.45), 200)
        custom_g_force_impact_duration = 0.355 + (-0.103/(1 + (plane_weight_adj/15463)**1.28))

        if landing_vs1 != current_landing:
            # Move 2nd to 3rd
            landing_t3 = landing_t2
            landing_vs3 = landing_vs2
            landing_g3 = landing_g2
            # Move 1st to 2nd
            landing_t2 = landing_t1
            landing_vs2 = landing_vs1
            landing_g2 = landing_g1
            # Assign new 1st
            landing_t1 = current_time
            landing_vs1 = current_landing
            landing_g1 = round(1 + (((2 * (current_landing / (60 * 3.281))) / custom_g_force_impact_duration) / 9.80665), 2)
            # Dictionary Output
            ui_friendly_dictionary["LANDING_VS1"] = landing_vs1
            ui_friendly_dictionary["LANDING_T1"] = landing_t1
            ui_friendly_dictionary["LANDING_G1"] = landing_g1
            ui_friendly_dictionary["LANDING_VS2"] = landing_vs2
            ui_friendly_dictionary["LANDING_T2"] = landing_t2
            ui_friendly_dictionary["LANDING_G2"] = landing_g2
            ui_friendly_dictionary["LANDING_VS3"] = landing_vs3
            ui_friendly_dictionary["LANDING_T3"] = landing_t3
            ui_friendly_dictionary["LANDING_G3"] = landing_g3

    while True:
        asyncio.run(ui_dictionary(ui_friendly_dictionary, previous_alt, ui_friendly_dictionary["LANDING_T1"], ui_friendly_dictionary["LANDING_VS1"], ui_friendly_dictionary["LANDING_T2"], ui_friendly_dictionary["LANDING_VS2"], ui_friendly_dictionary["LANDING_T3"], ui_friendly_dictionary["LANDING_VS3"], ui_friendly_dictionary["LANDING_G1"], ui_friendly_dictionary["LANDING_G2"], ui_friendly_dictionary["LANDING_G3"]))
        client.publish(topic, value)
        LOGGER.debug(topic + " = " + str(value))


client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message

client.connect("192.168.89.52", 1883, 60)
client.publish("/FS/CONNECTION", "CONNECTED")
"""Logging settings"""
logging.basicConfig(level=logging.DEBUG)
LOGGER = logging.getLogger(__name__)
LOGGER.info("START")
"""Simconnect Settings"""
sm = SimConnect()
aq = AircraftRequests(sm)
ae = AircraftEvents(sm)
"""Datasets"""
request_lights = [
    'LIGHT_STROBE', 'LIGHT_PANEL', 'LIGHT_LANDING', 'LIGHT_TAXI',
    'LIGHT_BEACON', 'LIGHT_NAV', 'LIGHT_WING'
]

toggle_plane = [
    'SMOKE_TOGGLE',
    'GEAR_TOGGLE',
    'PITOT_HEAT_TOGGLE',
    'PARKING_BRAKES',
]
Exemple #24
0
def main_app(offline: bool):
    sm = None
    aq = None
    ae = None
    if not offline:
        sm = SimConnect()
        aq = AircraftRequests(sm, _time=200)
        ae = AircraftEvents(sm)

    outport = mido.open_output('X-TOUCH MINI 1')

    control_change_dict = {}
    note_dict = {}

    def event(name: str):
        print(f"{name}")

    def create_partial(name: str):
        return partial(event, name)

    def handle_message(msg: mido.Message):
        # print(msg)
        if msg.type == 'control_change':
            if msg.control in control_change_dict:
                control_change_dict[msg.control].on_cc_data(msg.value)
        elif msg.type == 'note_on':
            if msg.note in note_dict:
                note_dict[msg.note].on_note_data(True)
        elif msg.type == 'note_off':
            if msg.note in note_dict:
                note_dict[msg.note].on_note_data(False)

    inport = mido.open_input('X-TOUCH MINI 0', callback=handle_message)

    encoders = []
    buttons = []
    faders = []

    for e in range(1, 17):
        encoder = RotaryEncoder(e, outport)
        encoders.append(encoder)

    for b in range(1, 33):
        btn = PushButton(b, outport)
        buttons.append(btn)

    for f in range(1, 3):
        fader = Fader(f)
        faders.append(fader)

    c = ConfigFile(encoders, buttons, faders, ae)
    c.configure()
    triggers = c.triggers

    for encoder in encoders:
        control_change_dict[encoder.rotary_control_channel] = encoder
        note_dict[encoder.button_note] = encoder

    for btn in buttons:
        note_dict[btn.button_note] = btn

    for f in faders:
        control_change_dict[f.control_channel] = f

    triggers[0].on_simvar_data(1.0)
    objs = buttons + encoders + triggers
    while True:
        for obj in objs:
            if obj.bound_simvar and aq:
                sv = aq.get(obj.bound_simvar)
                obj.on_simvar_data(sv)
        time.sleep(0.1)
Exemple #25
0

def get_pyfirmata(settings):
    return pyfirmata.util.Iterator(pyfirmata.Arduino(settings["comm_port"]))


if __name__ == "__main__":

    logging.basicConfig(level=logging.DEBUG)
    LOGGER = logging.getLogger(__name__)
    LOGGER.info("Program Start")

    LOGGER.info("Simulation Setup")
    settings = get_settings()
    arduinoBoard = get_pyfirmata(settings)
    simulation = SimConnect()
    aircraftEvents = AircraftEvents(simulation)
    aircraftRequests = AircraftRequests(simulation)

    inputs = []

    LOGGER.info("Simulation Setup")
    for pin in settings["pins"]:
        inputs.append(
            Pins(
                arduinoBoard.get_pin(pin["input_type"] + ":" +
                                     pin["pin_number"] + ":" + "i"),
                pin["can_repeat"], pin["timeout"], pin["max_value"],
                pin["threshold"], pin["compare"],
                pin["min_value"], pin["starting_value"],
                aircraftEvents.find(pin["function"]), pin["inputType"]))
Exemple #26
0
    def on_created(self, event):
        print("\nFile created: '{}'.".format(event.src_path))

        # Check if sim is running (https://stackoverflow.com/a/7788702)
        if not 'FlightSimulator.exe' in (p.name()
                                         for p in psutil.process_iter()):
            print(
                'Warning: The simulator is not running. Not going to add GPS data to this file.'
            )
            return

        # Connect to sim
        print('Getting data from sim..')
        sm = SimConnect()
        aq = AircraftRequests(sm)

        # Get data from sim
        data = {
            'GPSLatitude': round(aq.get("GPS_POSITION_LAT"), 5),  # degrees
            'GPSLongitude': round(aq.get("GPS_POSITION_LON"), 5),  # degrees
            'GPSAltitude': round(aq.get('GPS_POSITION_ALT'), 2),  # meter
            'GPSSpeed': aq.get('GPS_GROUND_SPEED')  # m/s
        }

        # Disconnect from sim
        sm.exit()

        # Check if player is not in flight
        if round(data['GPSLatitude'], 2) < 0.1 and round(
                data['GPSLongitude'], 2) < 0.1 and data['GPSSpeed'] < 0.1:
            print(
                'Warning: It looks like the player is in a menu. Not going to add GPS data to this file.'
            )
            return

        # Set additional tags (https://exiftool.org/TagNames/GPS.html)
        data['GPSLatitudeRef'] = 'North'
        if data['GPSLatitude'] < 0:
            data['GPSLatitudeRef'] = 'South'

        data['GPSLongitudeRef'] = 'East'
        if data['GPSLongitude'] < 0:
            data['GPSLongitudeRef'] = 'West'

        data['GPSAltitudeRef'] = 'Above Sea Level'

        data['GPSSpeed'] = round(data['GPSSpeed'] * 3.6,
                                 2)  # Convert m/s to km/h
        data['GPSSpeedRef'] = 'km/h'  # Set unit to km/h

        # Compile exiftool command
        cmdline = [exiftool]

        for key, value in data.items():
            if value == -999999:
                print('Warning: invalid value for {}: {}.'.format(key, value))
                continue
            cmdline.append('-{}={}'.format(key, value))

        if OVERWRITE:
            cmdline.append('-overwrite_original')

        if DEBUG:
            cmdline.append('-verbose')

        cmdline.append(event.src_path)

        if DEBUG:
            import json
            print('data:', json.dumps(data, indent=4))
            print(cmdline)

        # Add GPS data to screenshot
        print('Adding EXIF data to image..')
        process = subprocess.Popen(cmdline,
                                   stdin=subprocess.PIPE,
                                   stdout=subprocess.PIPE)
        process.communicate(input=b'\n')  # Pass exiftool's '-- press ENTER --'

        print('Finished. Watching for changes..')

        self.process(event)
def simconnect_thread_func(threadname):

    global simconnect_dict

    # Init SimConnect
    sm = SimConnect()
    aq = AircraftRequests(sm, _time=0)

    # Init variables
    airborne = False
    g_force = 0
    v_speed = 0
    plane_alt_above_ground = 0
    sim_on_ground = 0
    g_force_prev = 0
    v_speed_prev = 0
    plane_alt_above_ground_prev = 0
    lat_prev = 0
    lng_prev = 0
    bearing_prev = 0
    sim_on_ground_prev = 0
    v_speed_list_all = []
    g_force_list_all = []
    v_speed_list = []
    g_force_list = []
    plane_alt_above_ground_list = []
    v_speed_list_ground = []
    g_force_list_ground = []
    plane_alt_above_ground_list_ground = []
    sim_on_ground_list = [1, 1, 1, 1, 1, 1, 1, 1]
    run_app = 1
    simconnect_dict["G_FORCE"] = 0
    simconnect_dict["MAX_G_FORCE"] = 0
    simconnect_dict["VERTICAL_SPEED"] = 0.0
    simconnect_dict["HORIZONTAL_SPEED"] = 0.0
    simconnect_dict["LATITUDE"] = 0.0
    simconnect_dict["LONGITUDE"] = 0.0
    simconnect_dict["PLANE_ALTITUDE"] = 0.0
    simconnect_dict["PLANE_BEARING"] = 0.0
    simconnect_dict["PLANE_PITCH_DEGREES"] = 0.0
    simconnect_dict["PLANE_BANK_DEGREES"] = 0.0
    simconnect_dict["SIM_ON_GROUND"] = 0
    simconnect_dict["G_FORCE_LANDING"] = "N/A"
    simconnect_dict["VERTICAL_SPEED_LANDING"] = "N/A"
    simconnect_dict["SIM_ON_GROUND_LIST"] = "N/A"
    simconnect_dict["AIRBORNE"] = 0
    simconnect_dict["ENGINE_TYPE"] = -1
    simconnect_dict["G_FORCE_LIST"] = g_force_list
    simconnect_dict["V_SPEED_LIST"] = v_speed_list
    simconnect_dict["G_FORCE_LANDING_LIST"] = "N/A"
    simconnect_dict["G_FORCE_LANDING_LIST_GROUND"] = "N/A"
    simconnect_dict["VERTICAL_SPEED_LANDING_LIST"] = "N/A"
    simconnect_dict["VERTICAL_SPEED_LANDING_LIST_GROUND"] = "N/A"
    simconnect_dict[
        "PLANE_ALT_ABOVE_GROUND_LIST"] = plane_alt_above_ground_list
    simconnect_dict[
        "PLANE_ALT_ABOVE_GROUND_LIST_GROUND"] = plane_alt_above_ground_list_ground
    simconnect_dict["LANDING_RATING"] = "N/A"
    simconnect_dict["LANDING_COUNTER"] = 0

    # Create empty labels for charts
    labels_list = []
    for i in range(150):
        labels_list.append("")
    simconnect_dict["LABELS"] = labels_list

    # Run Simconnect Calculations
    while run_app == 1:

        # Get Current Data
        # Fix for -999999 values
        max_g = round(aq.get("MAX_G_FORCE"), 2)
        engine = aq.get("ENGINE_TYPE")
        v_speed = round(aq.get("VERTICAL_SPEED"), 2)
        z_speed = round(aq.get("VELOCITY_WORLD_Z"), 3)
        x_speed = round(aq.get("VELOCITY_WORLD_X"), 3)

        alt = aq.get("PLANE_ALTITUDE")
        gndAlt = aq.get("PLANE_ALT_ABOVE_GROUND")
        grnd_elv = round(alt - gndAlt, 0)
        dist = aq.get("GPS_WP_DISTANCE") * 0.539957

        grnd_speed = math.sqrt((z_speed * z_speed) +
                               (x_speed * x_speed)) * 0.592484
        grnd_speed = round(grnd_speed, 2)
        true_speed = round(aq.get("AIRSPEED_TRUE"), 2)
        indi_speed = round(aq.get("AIRSPEED_INDICATED"), 2)
        mach_speed = round(aq.get("AIRSPEED_MACH"), 3)

        lat = aq.get("PLANE_LATITUDE")
        if lat < -99999:
            lat = lat_prev
        else:
            lat_prev = lat

        lng = aq.get("PLANE_LONGITUDE")
        if lng < -99999:
            lng = lng_prev
        else:
            lng_prev = lng

        bearing = aq.get("PLANE_HEADING_DEGREES_TRUE")
        if bearing < -99999:
            bearing = bearing_prev
        else:
            bearing_prev = bearing

        if v_speed < -99999:
            v_speed = v_speed_prev
        else:
            g_force_custom = (round(aq.get("ACCELERATION_WORLD_Y")) / 32.2) + 1
            v_speed_prev = v_speed

        g_force = round(aq.get("G_FORCE"), 2)
        if g_force < -99999:
            g_force = g_force_prev
        else:
            g_force_prev = g_force

        plane_alt_above_ground = round(aq.get("PLANE_ALT_ABOVE_GROUND"), 1)
        if plane_alt_above_ground < -99999:
            plane_alt_above_ground = plane_alt_above_ground_prev
        else:
            plane_alt_above_ground_prev = plane_alt_above_ground

        sim_on_ground = aq.get("SIM_ON_GROUND")
        if sim_on_ground < -99999:
            sim_on_ground = sim_on_ground_prev
        else:
            sim_on_ground_prev = sim_on_ground

        # Make lists
        sim_on_ground_list.insert(0, sim_on_ground)
        if len(sim_on_ground_list) > 31:
            sim_on_ground_list.pop()
        v_speed_list_all.insert(0, v_speed)
        if len(v_speed_list_all) > 151:
            v_speed_list_all.pop()
        g_force_list_all.insert(0, g_force)
        if len(g_force_list_all) > 151:
            g_force_list_all.pop()

        # Make lists for graph - separation between airborne and landing
        if sim_on_ground == 1:
            v_speed_list.insert(0, "null")
            if len(v_speed_list) > 151:
                v_speed_list.pop()
            g_force_list.insert(0, "null")
            if len(g_force_list) > 151:
                g_force_list.pop()
            plane_alt_above_ground_list.insert(0, "null")
            if len(plane_alt_above_ground_list) > 151:
                plane_alt_above_ground_list.pop()
            v_speed_list_ground.insert(0, v_speed)
            if len(v_speed_list_ground) > 151:
                v_speed_list_ground.pop()
            g_force_list_ground.insert(0, g_force)
            if len(g_force_list_ground) > 151:
                g_force_list_ground.pop()
            plane_alt_above_ground_list_ground.insert(0,
                                                      plane_alt_above_ground)
            if len(plane_alt_above_ground_list_ground) > 151:
                plane_alt_above_ground_list_ground.pop()
        else:
            v_speed_list.insert(0, v_speed)
            if len(v_speed_list) > 151:
                v_speed_list.pop()
            g_force_list.insert(0, g_force)
            if len(g_force_list) > 151:
                g_force_list.pop()
            plane_alt_above_ground_list.insert(0, plane_alt_above_ground)
            if len(plane_alt_above_ground_list) > 151:
                plane_alt_above_ground_list.pop()
            v_speed_list_ground.insert(0, "null")
            if len(v_speed_list_ground) > 151:
                v_speed_list_ground.pop()
            g_force_list_ground.insert(0, "null")
            if len(g_force_list_ground) > 151:
                g_force_list_ground.pop()
            plane_alt_above_ground_list_ground.insert(0, "null")
            if len(plane_alt_above_ground_list_ground) > 151:
                plane_alt_above_ground_list_ground.pop()

        # Populate vars to JSON dictionary
        simconnect_dict["ENGINE_TYPE"] = engine
        simconnect_dict["G_FORCE"] = g_force
        simconnect_dict["MAX_G_FORCE"] = max_g
        simconnect_dict["VERTICAL_SPEED"] = v_speed
        simconnect_dict["HORIZONTAL_SPEED"] = true_speed
        simconnect_dict["INDICATED_SPEED"] = indi_speed
        simconnect_dict["MACH_SPEED"] = mach_speed
        simconnect_dict["GRND_SPEED"] = grnd_speed
        simconnect_dict["LATITUDE"] = round(lat, 7)
        simconnect_dict["LONGITUDE"] = round(lng, 7)
        simconnect_dict["BEARING"] = math.degrees(bearing)
        simconnect_dict["ALTITUDE"] = round(alt, 1)
        simconnect_dict["GND_ALTITUDE"] = round(plane_alt_above_ground, 1)
        simconnect_dict["GRND_ELEV"] = grnd_elv
        simconnect_dict["SIM_ON_GROUND"] = sim_on_ground
        simconnect_dict["AIRBORNE"] = airborne
        simconnect_dict["TARGET_DIST"] = round(dist / 1000, 2)

        # Make landing/airborne decision
        if airborne == True and sum(sim_on_ground_list) == 30:
            # Fix - need to get the last value before on ground readings
            v_speed_list_touchdown = v_speed_list_ground
            g_force_list_touchdown = g_force_list_ground
            change_last = False
            for idx, element in enumerate(v_speed_list_touchdown):
                if idx >= 1:
                    if element == 0 and v_speed_list_touchdown[idx - 1] == 1:
                        if change_last == False:
                            v_speed_list_touchdown[idx] = v_speed_list[idx]
                            g_force_list_touchdown[idx] = g_force_list[idx]
                            change_last = True
                        else:
                            change_last = False
                    else:
                        change_last = False

            v_speed_list_touchdown = [
                0 if x == "null" else x for x in v_speed_list_touchdown
            ]
            g_force_list_touchdown = [
                0 if x == "null" else x for x in g_force_list_touchdown
            ]

            simconnect_dict["G_FORCE_LANDING"] = max(g_force_list_touchdown)
            simconnect_dict["VERTICAL_SPEED_LANDING"] = min(
                v_speed_list_touchdown)
            # Create Lists for Graphs
            simconnect_dict["G_FORCE_LANDING_LIST"] = g_force_list[::-1] * 1
            simconnect_dict[
                "G_FORCE_LANDING_LIST_GROUND"] = g_force_list_ground[::-1] * 1
            v_speed_list_neg = [
                elem * (-1) if elem != "null" else "null"
                for elem in v_speed_list
            ]
            v_speed_list_ground_neg = [
                elem * (-1) if elem != "null" else "null"
                for elem in v_speed_list_ground
            ]
            simconnect_dict[
                "VERTICAL_SPEED_LANDING_LIST"] = v_speed_list_neg[::-1] * 1
            simconnect_dict[
                "VERTICAL_SPEED_LANDING_LIST_GROUND"] = v_speed_list_ground_neg[::
                                                                                -1] * 1
            simconnect_dict[
                "PLANE_ALT_ABOVE_GROUND_LIST"] = plane_alt_above_ground_list[::
                                                                             -1] * 1
            simconnect_dict[
                "PLANE_ALT_ABOVE_GROUND_LIST_GROUND"] = plane_alt_above_ground_list_ground[::
                                                                                           -1] * 1
            simconnect_dict[
                "LANDING_COUNTER"] = simconnect_dict["LANDING_COUNTER"] + 1

            # Landing Rating Based on G-Forces
            if simconnect_dict["VERTICAL_SPEED_LANDING"] > -60:
                simconnect_dict["LANDING_RATING"] = "Very soft landing"
            elif simconnect_dict["VERTICAL_SPEED_LANDING"] > -120:
                simconnect_dict["LANDING_RATING"] = "Soft landing"
            elif simconnect_dict["VERTICAL_SPEED_LANDING"] > -200:
                simconnect_dict["LANDING_RATING"] = "Average landing"
            elif simconnect_dict["VERTICAL_SPEED_LANDING"] > -300:
                simconnect_dict["LANDING_RATING"] = "Firm landing"
            elif simconnect_dict["VERTICAL_SPEED_LANDING"] > -400:
                simconnect_dict["LANDING_RATING"] = "Hard landing"
            elif simconnect_dict["VERTICAL_SPEED_LANDING"] > -600:
                simconnect_dict["LANDING_RATING"] = "Very hard landing"
            else:
                simconnect_dict[
                    "LANDING_RATING"] = "Structural damage to plane"
            airborne = False

        if sum(sim_on_ground_list) == 0 and airborne == False:
            airborne = True
    def cruise(self):
        rnd = self.radioButton.isChecked()
        points = int(self.linePoints.text())
        random.seed(int(self.lineSeed.text()))
        cg = float(self.lineCG.text()) / 100
        error_alt = 1000
        error_tas = 1000
        actual_vs = 1000
        limit_alt = float(self.lineAltErr.text())
        limit_tas = float(self.lineTASErr.text())
        limit_vs = float(self.lineVSErr.text())
        inFile = "data/" + self.lineInFile.text()
        clb = float(self.lineCLB.text())
        n = 1

        # Read the Aircraft Data file
        df = data.data_read('CRZ', inFile)
        logger.test_header(self, "CRZ")
        if os.path.exists(self.lineOutFile.text()):
            os.remove(self.lineOutFile.text())

        start_time = time.time()

        if (rnd == False):
            points = len(df.index) - 1

        # Create the SimConnect link
        sm = SimConnect()
        aq = AircraftRequests(sm, _time=0)
        ae = AircraftEvents(sm)
        logger.test_simconnect(self, 1)

        hsi = Event(b'HEADING_SLOT_INDEX_SET', sm)
        hsi(1)

        # Check and set initial aircraft settings:
        # AP1 ON, ATHR ON, FD ON & CLB
        ac_init(aq, ae, clb)
        logger.test_init(self, 1)

        for i in range(n, points + 1):
            if (rnd == True):
                # Random Aircraft situation
                if (n == i):
                    start = n
                else:
                    start = 0

                weight, altitude, tas, mach, n1 = data.a32x_state_rnd(
                    df, start)
            else:
                weight, altitude, tas, mach, n1 = data.a32x_state_nrm(df, i)

            # Set Weight and CG ... this goes first to avoid excessive dumping
            W_n_B(aq, weight, cg)
            if (i == 1):
                logger.test_init(self, 0)
                logger.test_loop(self, 1)
            logger.test_obj(self, weight, cg, altitude, tas, mach, n1, i,
                            points)

            # Main test point routine - Setting stable aircraft conditions
            crz_alt_tas(sm, aq, ae, altitude, tas)

            # Altitude & Speed damping "filter". Use VS first as a measure
            # of stability
            # To avoid excesive damping, fuel and CG are set first with
            # enough headroom
            # A stability counter is implemented to account for VS damping

            counter = 0  # 0 - initial, 1 - within the loop, 10 - outside the loop
            previous = []
            minimums = []
            maximums = []
            averages = []
            step = 0  # 0 - none, 1 - one found, 2 - two found
            increment = -1  # -1 - Initial, 0 - decreasing, 1 - increasing
            ap_cycler = time.time()

            while counter < 10:
                if not (round(time.time() - ap_cycler) % 10):
                    actual_fcu_speed = float(
                        aq.get("AUTOPILOT_AIRSPEED_HOLD_VAR"))
                    event_to_trigger = ae.find("AP_MASTER")
                    if (abs(actual_fcu_speed - tas) > 2):
                        crz_alt_tas(sm, aq, ae, altitude, tas)
                        # #print("FCU Trigger")

                    # if (counter == 0):
                    # #print("AP Trigger")
                    # event_to_trigger()
                    # time.sleep(1)
                    # event_to_trigger()

                actual_alt = float(aq.get("INDICATED_ALTITUDE"))
                actual_tas = float(aq.get("AIRSPEED_TRUE"))
                actual_vs = float(aq.get("VERTICAL_SPEED"))
                error_alt = round(
                    abs((actual_alt - altitude) / altitude) * 100, 3)
                error_tas = round(abs((actual_tas - tas) / tas) * 100, 3)

                # Stability has been reached
                if (error_alt < limit_alt and error_tas < limit_tas
                        and abs(actual_vs) < limit_vs):
                    actual_n1 = float(aq.get("TURB_ENG_N1:1"))
                    actual_n2 = float(aq.get("TURB_ENG_N2:1"))
                    actual_n1_cor = float(aq.get("TURB_ENG_CORRECTED_N1:1"))
                    actual_n2_cor = float(aq.get("TURB_ENG_CORRECTED_N2:1"))
                    actual_fn = float(aq.get("TURB_ENG_JET_THRUST:1")) * 2
                    actual_egt_R = float(
                        aq.get("GENERAL_ENG_EXHAUST_GAS_TEMPERATURE:1"))
                    actual_ff = float(aq.get("TURB_ENG_FUEL_FLOW_PPH:1"))

                    # First pass
                    if (counter == 0):
                        previous = [
                            actual_n1, actual_n2, actual_n1_cor, actual_n2_cor,
                            actual_fn, actual_egt_R, actual_ff
                        ]
                        counter = 1
                        #print("start")

                    # Looking for a Maximum
                    #print(actual_n1)
                    if (actual_n1 > previous[0]):
                        if (increment != 0):  # If not swtiching
                            maximums = [
                                actual_n1, actual_n2, actual_n1_cor,
                                actual_n2_cor, actual_fn, actual_egt_R,
                                actual_ff
                            ]
                            previous = [
                                actual_n1, actual_n2, actual_n1_cor,
                                actual_n2_cor, actual_fn, actual_egt_R,
                                actual_ff
                            ]
                        else:
                            minimums = previous
                            #print("minimum")
                            step += 1
                            if (step == 2):
                                counter += 10
                            else:
                                previous = [
                                    actual_n1, actual_n2, actual_n1_cor,
                                    actual_n2_cor, actual_fn, actual_egt_R,
                                    actual_ff
                                ]
                        increment = 1
                    else:
                        if (increment != 1):  # If not swtiching
                            minimums = [
                                actual_n1, actual_n2, actual_n1_cor,
                                actual_n2_cor, actual_fn, actual_egt_R,
                                actual_ff
                            ]
                            previous = [
                                actual_n1, actual_n2, actual_n1_cor,
                                actual_n2_cor, actual_fn, actual_egt_R,
                                actual_ff
                            ]
                        else:
                            maximums = previous
                            #print("maximum")
                            step += 1
                            if (step == 2):
                                counter += 10
                            else:
                                previous = [
                                    actual_n1, actual_n2, actual_n1_cor,
                                    actual_n2_cor, actual_fn, actual_egt_R,
                                    actual_ff
                                ]
                        increment = 0
                    time.sleep(0.5)
                else:
                    counter = 0  # 0 - initial, 1 - within the loop, 10 - outside the loop
                    previous = []
                    minimums = []
                    maximums = []
                    averages = []
                    step = 0  # 0 - none, 1 - one found, 2 - two found
                    increment = -1  # -1 - Initial, 0 - decreasing, 1 - increasing

                elapsed_time = time.time() - start_time
                msg = "Tolerance Figures - Alt: " + str(
                    error_alt) + "%  TAS: " + str(error_tas) + "%  VS: " + str(
                        round(actual_vs,
                              1)) + "fpm          Elapsed Time - " + str(
                                  round(elapsed_time, 2)) + " secs."

                self.updateStatus(msg)
                QtCore.QCoreApplication.processEvents()

            a = minimums[0] + ((maximums[0] - minimums[0]) / 2)
            print("Max= " + str(maximums[0]) + " Min= " + str(minimums[0]) +
                  " Avg= " + str(a))

            actual_weight = aq.get("TOTAL_WEIGHT")
            actual_alt = aq.get("INDICATED_ALTITUDE")
            actual_tas = aq.get("AIRSPEED_TRUE")
            actual_mach = aq.get("AIRSPEED_MACH")
            actual_vs = aq.get("VERTICAL_SPEED")
            actual_cg = aq.get("CG_PERCENT")
            actual_n1 = minimums[0] + ((maximums[0] - minimums[0]) / 2)
            actual_n2 = minimums[1] + ((maximums[1] - minimums[1]) / 2)
            actual_n1_cor = minimums[2] + ((maximums[2] - minimums[2]) / 2)
            actual_n2_cor = minimums[3] + ((maximums[3] - minimums[3]) / 2)
            actual_fn = minimums[4] + ((maximums[4] - minimums[4]) / 2)
            actual_egt_R = minimums[5] + ((maximums[5] - minimums[5]) / 2)
            actual_ff = (minimums[6] +
                         ((maximums[6] - minimums[6]) / 2)) * 2 * 0.453592
            actual_egt = (actual_egt_R - 491.67) * 5 / 9
            logger.test_actual(self, actual_weight, actual_cg, actual_alt,
                               actual_tas, actual_mach, actual_vs, actual_fn,
                               actual_n1, actual_n2, actual_n1_cor,
                               actual_n2_cor, actual_egt, actual_ff, i, points)

            time.sleep(0.5)
            os.system('copy ' + self.lineOutFile.text() + ' test.bck >NUL')
            self.dumpToFile()
            time.sleep(0.5)

            if not (i % 10):
                eta = ((time.time() - start_time) / i) * (points - i)
                if (eta > 3600):
                    eta = round(eta / 3600, 2)
                    subject = "FBW Tester: ETA is " + str(eta) + " hours"
                elif (eta < 3600 and eta > 60):
                    eta = round(eta / 60)
                    subject = "FBW Tester: ETA is " + str(eta) + " minutes"
                else:
                    eta = eta
                    subject = "FBW Tester: ETA is " + str(eta) + " seconds"
                outFile = self.lineOutFile.text()
                gmail.gmail(subject, outFile)

        #sm.quit()
        logger.test_loop(self, 0)
        logger.test_simconnect(self, 0)
        self.dumpToFile()
Exemple #29
0
 def init_simconnect(self):
     self.sc = SimConnect()
     self.aircraftReqs = AircraftRequests(self.sc, _time=0)
     self.aircraftEvents = AircraftEvents(self.sc)
    def test_no_default_attributes_in_init(self):
        sm = create_autospec(SimConnect.SimConnect)

        pl = SimConnect.Plane(sm=sm, add_default=False)
        with self.assertRaises(AttributeError):
            pl.altitude