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
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!")
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)
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))
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"))
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!")
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'
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()
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!")
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)
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)
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"]))
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")
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()
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)
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
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()
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', ]
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)
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"]))
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()
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