Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asyncio Testing #60

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions SimConnect/RequestList.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,41 @@
from SimConnect import *
from .Enum import *
from .Constants import *
import asyncio


class Request(object):

def get(self):
return self.value

async def aget(self):
return await self.avalue

def set(self, _value):
self.value = _value

@property
async def avalue(self):
if self._deff_test():
# self.sm.run()
if (self.LastData + self.time) < millis():
await self.sm.get_data(self)
self.LastData = millis()
return self.outData
else:
raise Exception(self.definitions[0][0])

@property
def value(self):
if self._deff_test():
# self.sm.run()
if (self.LastData + self.time) < millis():
if self.sm.get_data(self):
self.LastData = millis()
else:
return None
asyncio.run(self.sm.get_data(self))
self.LastData = millis()
return self.outData
else:
return None
raise Exception(self.definitions[0][0])

@value.setter
def value(self, val):
Expand Down Expand Up @@ -69,9 +82,9 @@ def redefine(self):
)
self.defined = False
# self.sm.run()
if self._deff_test():
# self.sm.run()
self.sm.get_data(self)
# if self._deff_test():
# # self.sm.run()
# self.sm.get_data(self)

def _deff_test(self):
if ':index' in str(self.definitions[0][0]):
Expand Down Expand Up @@ -137,6 +150,11 @@ def get(self, _name):
return None
return getattr(self, _name).value

async def aget(self, _name):
if getattr(self, _name) is None:
return None
return await getattr(self, _name).avalue

def set(self, _name, _value=0):
temp = getattr(self, _name)
if temp is None:
Expand Down Expand Up @@ -170,6 +188,8 @@ def find(self, key):
if key in clas.list:
rqest = getattr(clas, key)
if index is not None:
if 'index' in index:
index = 0
rqest.setIndex(index)
return rqest
return None
Expand All @@ -180,6 +200,12 @@ def get(self, key):
return None
return request.value

async def aget(self, key):
request = self.find(key)
if request is None:
return None
return await request.avalue

def set(self, key, _value):
request = self.find(key)
if request is None:
Expand Down
18 changes: 7 additions & 11 deletions SimConnect/SimConnect.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .Attributes import *
import os
import threading
import asyncio

_library_path = os.path.splitext(os.path.abspath(__file__))[0] + '.dll'

Expand Down Expand Up @@ -239,18 +240,13 @@ def set_data(self, _Request):
else:
return False

def get_data(self, _Request):
self.request_data(_Request)
# self.run()
attemps = 0
while _Request.outData is None and attemps < _Request.attemps:
# self.run()
time.sleep(.01)
attemps += 1
if _Request.outData is None:
return False
async def get_return_data(self, _Request):
while _Request.outData is None:
await asyncio.sleep(0.01)

return True
async def get_data(self, _Request):
self.request_data(_Request)
await self.get_return_data(_Request)

def send_event(self, evnt, data=DWORD(0)):
err = self.dll.TransmitClientEvent(
Expand Down
128 changes: 65 additions & 63 deletions glass_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from SimConnect import *
from time import sleep
import random

import asyncio

app = Flask(__name__)

Expand All @@ -11,7 +11,7 @@
# Create simconnection
sm = SimConnect()
ae = AircraftEvents(sm)
aq = AircraftRequests(sm, _time=10)
aq = AircraftRequests(sm)

# Create request holders

Expand Down Expand Up @@ -50,10 +50,10 @@
#]

request_location = [
'ALTITUDE',
'LATITUDE',
'LONGITUDE',
'KOHLSMAN',
'PLANE_ALTITUDE',
'PLANE_LATITUDE',
'PLANE_LONGITUDE',
'KOHLSMAN_SETTING_HG',
]

request_airspeed = [
Expand Down Expand Up @@ -295,82 +295,83 @@ def get_dataset(data_type):

return request_to_action


@app.route('/ui')
def output_ui_variables():

# Initialise dictionaru
ui_friendly_dictionary = {}
ui_friendly_dictionary["STATUS"] = "success"

async def ui_dictionary(ui_friendly_dictionary):
# Fuel
fuel_percentage = (aq.get("FUEL_TOTAL_QUANTITY") / aq.get("FUEL_TOTAL_CAPACITY")) * 100
ui_friendly_dictionary["FUEL_PERCENTAGE"] = round(fuel_percentage)
ui_friendly_dictionary["AIRSPEED_INDICATE"] = round(aq.get("AIRSPEED_INDICATED"))
ui_friendly_dictionary["ALTITUDE"] = thousandify(round(aq.get("PLANE_ALTITUDE")))

ui_friendly_dictionary["FUEL_PERCENTAGE"] = round((await aq.get("FUEL_TOTAL_QUANTITY") / await aq.get("FUEL_TOTAL_CAPACITY")) * 100)
ui_friendly_dictionary["AIRSPEED_INDICATE"] = round(await aq.get("AIRSPEED_INDICATED"))
ui_friendly_dictionary["ALTITUDE"] = thousandify(round(await aq.get("PLANE_ALTITUDE")))
# Control surfaces
if aq.get("GEAR_HANDLE_POSITION") == 1:
if await aq.get("GEAR_HANDLE_POSITION") == 1:
ui_friendly_dictionary["GEAR_HANDLE_POSITION"] = "DOWN"
else:
ui_friendly_dictionary["GEAR_HANDLE_POSITION"] = "UP"
ui_friendly_dictionary["FLAPS_HANDLE_PERCENT"] = round(aq.get("FLAPS_HANDLE_PERCENT") * 100)
ui_friendly_dictionary["FLAPS_HANDLE_PERCENT"] = round(await aq.get("FLAPS_HANDLE_PERCENT") * 100)

ui_friendly_dictionary["ELEVATOR_TRIM_PCT"] = round(aq.get("ELEVATOR_TRIM_PCT") * 100)
ui_friendly_dictionary["RUDDER_TRIM_PCT"] = round(aq.get("RUDDER_TRIM_PCT") * 100)
ui_friendly_dictionary["ELEVATOR_TRIM_PCT"] = round(await aq.get("ELEVATOR_TRIM_PCT") * 100)
ui_friendly_dictionary["RUDDER_TRIM_PCT"] = round(await aq.get("RUDDER_TRIM_PCT") * 100)

# Navigation
ui_friendly_dictionary["LATITUDE"] = aq.get("PLANE_LATITUDE")
ui_friendly_dictionary["LONGITUDE"] = aq.get("PLANE_LONGITUDE")
ui_friendly_dictionary["MAGNETIC_COMPASS"] = round(aq.get("MAGNETIC_COMPASS"))
ui_friendly_dictionary["MAGVAR"] = round(aq.get("MAGVAR"))
ui_friendly_dictionary["VERTICAL_SPEED"] = round(aq.get("VERTICAL_SPEED"))
ui_friendly_dictionary["LATITUDE"] = await aq.get("PLANE_LATITUDE")
ui_friendly_dictionary["LONGITUDE"] = await aq.get("PLANE_LONGITUDE")
ui_friendly_dictionary["MAGNETIC_COMPASS"] = round(await aq.get("MAGNETIC_COMPASS"))
ui_friendly_dictionary["MAGVAR"] = round(await aq.get("MAGVAR"))
ui_friendly_dictionary["VERTICAL_SPEED"] = round(await aq.get("VERTICAL_SPEED"))

# Autopilot
ui_friendly_dictionary["AUTOPILOT_MASTER"] = aq.get("AUTOPILOT_MASTER")
ui_friendly_dictionary["AUTOPILOT_NAV_SELECTED"] = aq.get("AUTOPILOT_NAV_SELECTED")
ui_friendly_dictionary["AUTOPILOT_WING_LEVELER"] = aq.get("AUTOPILOT_WING_LEVELER")
ui_friendly_dictionary["AUTOPILOT_HEADING_LOCK"] = aq.get("AUTOPILOT_HEADING_LOCK")
ui_friendly_dictionary["AUTOPILOT_HEADING_LOCK_DIR"] = round(aq.get("AUTOPILOT_HEADING_LOCK_DIR"))
ui_friendly_dictionary["AUTOPILOT_ALTITUDE_LOCK"] = aq.get("AUTOPILOT_ALTITUDE_LOCK")
ui_friendly_dictionary["AUTOPILOT_ALTITUDE_LOCK_VAR"] = thousandify(round(aq.get("AUTOPILOT_ALTITUDE_LOCK_VAR")))
ui_friendly_dictionary["AUTOPILOT_ATTITUDE_HOLD"] = aq.get("AUTOPILOT_ATTITUDE_HOLD")
ui_friendly_dictionary["AUTOPILOT_GLIDESLOPE_HOLD"] = aq.get("AUTOPILOT_GLIDESLOPE_HOLD")
ui_friendly_dictionary["AUTOPILOT_APPROACH_HOLD"] = aq.get("AUTOPILOT_APPROACH_HOLD")
ui_friendly_dictionary["AUTOPILOT_BACKCOURSE_HOLD"] = aq.get("AUTOPILOT_BACKCOURSE_HOLD")
ui_friendly_dictionary["AUTOPILOT_VERTICAL_HOLD"] = aq.get("AUTOPILOT_VERTICAL_HOLD")
ui_friendly_dictionary["AUTOPILOT_VERTICAL_HOLD_VAR"] = aq.get("AUTOPILOT_VERTICAL_HOLD_VAR")
ui_friendly_dictionary["AUTOPILOT_PITCH_HOLD"] = aq.get("AUTOPILOT_PITCH_HOLD")
ui_friendly_dictionary["AUTOPILOT_PITCH_HOLD_REF"] = aq.get("AUTOPILOT_PITCH_HOLD_REF")
ui_friendly_dictionary["AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE"] = aq.get("AUTOPILOT_FLIGHT_DIRECTOR_ACTIVE")
ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD"] = aq.get("AUTOPILOT_AIRSPEED_HOLD")
ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD_VAR"] = round(aq.get("AUTOPILOT_AIRSPEED_HOLD_VAR"))
ui_friendly_dictionary["AUTOPILOT_MASTER"] = await aq.get("AUTOPILOT_MASTER")
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_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_ATTITUDE_HOLD"] = await aq.get("AUTOPILOT_ATTITUDE_HOLD")
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_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")
ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD"] = await aq.get("AUTOPILOT_AIRSPEED_HOLD")
ui_friendly_dictionary["AUTOPILOT_AIRSPEED_HOLD_VAR"] = round(await aq.get("AUTOPILOT_AIRSPEED_HOLD_VAR"))

# Cabin
ui_friendly_dictionary["CABIN_SEATBELTS_ALERT_SWITCH"] = aq.get("CABIN_SEATBELTS_ALERT_SWITCH")
ui_friendly_dictionary["CABIN_NO_SMOKING_ALERT_SWITCH"] = aq.get("CABIN_NO_SMOKING_ALERT_SWITCH")
ui_friendly_dictionary["CABIN_SEATBELTS_ALERT_SWITCH"] = await aq.get("CABIN_SEATBELTS_ALERT_SWITCH")
ui_friendly_dictionary["CABIN_NO_SMOKING_ALERT_SWITCH"] = await aq.get("CABIN_NO_SMOKING_ALERT_SWITCH")

@app.route('/ui')
def output_ui_variables():
# Initialise dictionaru
ui_friendly_dictionary = {}
ui_friendly_dictionary["STATUS"] = "success"
asyncio.run(ui_dictionary(ui_friendly_dictionary))
return jsonify(ui_friendly_dictionary)


async def _dictionary(data_dictionary):
dataset_map = {} # I have renamed map to dataset_map as map is used elsewhere
for datapoint_name in data_dictionary:
print(datapoint_name)
dataset_map[datapoint_name] = await aq.get(datapoint_name)
return jsonify(dataset_map)

@app.route('/dataset/<dataset_name>/', methods=["GET"])
def output_json_dataset(dataset_name):
dataset_map = {} #I have renamed map to dataset_map as map is used elsewhere
data_dictionary = get_dataset(dataset_name)
for datapoint_name in data_dictionary:
dataset_map[datapoint_name] = aq.get(datapoint_name)
return jsonify(dataset_map)
return asyncio.run(_dictionary(data_dictionary))


def get_datapoint(datapoint_name, index=None):
async def get_datapoint(datapoint_name, index=None):
# This function actually does the work of getting the datapoint

if index is not None and ':index' in datapoint_name:
dp = aq.find(datapoint_name)
if dp is not None:
dp.setIndex(int(index))

return aq.get(datapoint_name)
return await aq.get(datapoint_name)


@app.route('/datapoint/<datapoint_name>/get', methods=["GET"])
Expand All @@ -380,7 +381,7 @@ def get_datapoint_endpoint(datapoint_name):
ds = request.get_json() if request.is_json else request.form
index = ds.get('index')

output = get_datapoint(datapoint_name, index)
output = asyncio.run(get_datapoint(datapoint_name, index))

if isinstance(output, bytes):
output = output.decode('ascii')
Expand Down Expand Up @@ -413,17 +414,14 @@ def set_datapoint(datapoint_name, index=None, value_to_use=None):
@app.route('/datapoint/<datapoint_name>/set', methods=["POST"])
def set_datapoint_endpoint(datapoint_name):
# This is the http endpoint wrapper for setting a datapoint

ds = request.get_json() if request.is_json else request.form
index = ds.get('index')
value_to_use = ds.get('value_to_use')

status = set_datapoint (datapoint_name, index, value_to_use)

status = set_datapoint(datapoint_name, index, value_to_use)
return jsonify(status)


def trigger_event(event_name, value_to_use = None):
def trigger_event(event_name, value_to_use=None):
# This function actually does the work of triggering the event

EVENT_TO_TRIGGER = ae.find(event_name)
Expand Down Expand Up @@ -452,17 +450,21 @@ def trigger_event_endpoint(event_name):
return jsonify(status)


async def get_engen_ct():
return await aq.get("NUMBER_OF_ENGINES")

@app.route('/custom_emergency/<emergency_type>', methods=["GET", "POST"])
def custom_emergency(emergency_type):

text_to_return = "No valid emergency type passed"

if emergency_type == "random_engine_fire":
# Calculate number of engines
number_of_engines = aq.get("NUMBER_OF_ENGINES")
number_of_engines = asyncio.run(get_engen_ct())

if number_of_engines < 0: return "error, no engines found - is sim running?"
engine_to_set_on_fire = random.randint(1,number_of_engines)
if number_of_engines < 0:
return "error, no engines found - is sim running?"
engine_to_set_on_fire = random.randint(1, number_of_engines)

set_datapoint("ENG_ON_FIRE:index", engine_to_set_on_fire, 1)

Expand Down
Loading