Skip to content

Asyncio Testing - #60

Draft
odwdinc wants to merge 9 commits into
masterfrom
asyncio-test
Draft

Asyncio Testing#60
odwdinc wants to merge 9 commits into
masterfrom
asyncio-test

Conversation

@odwdinc

Copy link
Copy Markdown
Owner

Not shure if this is the right direction or not thoughts?

Not shure if this is the right derection or not thoughts?
_attemps is depercataed
@odwdincodwdinc mentioned this pull request Oct 24, 2020
@danricho

Copy link
Copy Markdown

I like the idea of asyncio in principal, but I haven't tested it as I'm away from home (and hence the Sim).
Does it mean that the "time" and "attemp" parameters will no longer be necessary?

@odwdinc
odwdinc marked this pull request as draft October 25, 2020 16:01
@odwdinc

Copy link
Copy Markdown
OwnerAuthor

@danricho just thinking about removing attempts,
not 100% on this so left in the pluming for now.
values are set on thread

self.timerThread=threading.Thread(target=self._run)
self.timerThread.daemon=True
self.timerThread.start()

_run

def_run(self):
whileself.quit==0:
self.dll.CallDispatch(self.hSimConnect, self.my_dispatch_proc_rd, None)
time.sleep(.002)

Data is revived by

asyncdefget_return_data(self, _Request):
while_Request.outDataisNone:
awaitasyncio.sleep(0.01)
asyncdefget_data(self, _Request):
self.request_data(_Request)
awaitself.get_return_data(_Request)

normally attempts are check in the while loop (Line 244) to escape if data is not received in a given time. I don't know if this is still needed or wanted with the new async bits.

With time, it is how long to return cashed data vs new data form the sim.

@property
asyncdefvalue(self):
ifself._deff_test():
# self.sm.run()
if (self.LastData+self.time) <millis():
awaitself.sm.get_data(self)
self.LastData=millis()
returnself.outData
else:
raiseException(self.definitions[0][0])

@viboux

Copy link
Copy Markdown

Just tested this last version of the asyncio branch for a good 45 min reading altitude/long/lat/baro with another instance giving command and so far very stable and received no None value.

@daheise

daheise commented Nov 6, 2020

Copy link
Copy Markdown
Contributor

I haven't tested this PR, but I was just considering writing an async wrapper around my calls to Python-SimConnect so I hit fewer cases of needing to handle a None, so I think aync support is a good direction.

@danricho

Copy link
Copy Markdown

I tested this change this morning and have found it flawless.

It enabled me to log flight parameters at a much higher frequency than the old method which essentially hangs until a value is received.

Only limitation I found is the returning of 'None's when I used get() on signals with an index (eg: 'x:1') or the wind direction/speed. But I used request in setup then .value() in the main loop to get around this. I didn't figure out why this happened.

@odwdinc

Copy link
Copy Markdown
OwnerAuthor

so with such a big change how should we make handle the move?
I have been holding off to see if I can think of some way..

@odwdinc

Copy link
Copy Markdown
OwnerAuthor

new sample, added an a to the async vertions of functions to keep backwords code woking.

asyncdefavalue(self):

Sample:

fromSimConnectimport*importloggingfromSimConnect.Enumimport*fromtimeimportsleepimportasynciologging.basicConfig(level=logging.DEBUG)
LOGGER=logging.getLogger(__name__)
LOGGER.info("START")
# creat simconnection and pass used user classessm=SimConnect()
aq=AircraftRequests(sm, _time=10, _attemps=10)
Throttle=aq.find('GENERAL_ENG_THROTTLE_LEVER_POSITION:1')
# none async Function still worksprint("Throttle:", Throttle.value)
print("Alt=%f Lat=%f Lon=%f Kohlsman=%.2f"% (
aq.PositionandSpeedData.get('PLANE_ALTITUDE'),
aq.PositionandSpeedData.get('PLANE_LATITUDE'),
aq.PositionandSpeedData.get('PLANE_LONGITUDE'),
aq.FlightInstrumentationData.get('KOHLSMAN_SETTING_HG')
))
# New async FunctionasyncdefPrintData():
# THROTTLE Requestprint("Throttle:", awaitThrottle.avalue)
print("Lat=%f Lon=%f Alt=%f Kohlsman=%.2f"%tuple(
awaitasyncio.gather(
aq.PositionandSpeedData.aget('PLANE_LATITUDE'),
aq.PositionandSpeedData.aget('PLANE_LONGITUDE'),
aq.PositionandSpeedData.aget('PLANE_ALTITUDE'),
aq.FlightInstrumentationData.aget('KOHLSMAN_SETTING_HG')
)
))
asyncio.run(PrintData())
sm.exit()
quit()

@daheise

daheise commented Nov 15, 2020

Copy link
Copy Markdown
Contributor

My opinion: Follow semantic versioning. If this is a breaking change to old code, increment the major version number. It's on us as library users if we failed to pin the version correctly.

Unless there's a good reason to maintain both versions of the functions, don't.

@danricho

Copy link
Copy Markdown

I do agree that library users should be managing library versions and that we shouldn't keep both versions side by side due to maintenance burden; however I have a few thoughts that might help or at least ease the transition:

  • could we call the non-async versions from within the async version so only the core functions nee to be maintained, or
  • could we add a deprecated feedback message in the non-async version, with an end-of-support point defined?

I only suggest this as there seems to be quite a number of users now.
Just my 2 cents!

@mracko

Copy link
Copy Markdown

I'd like to report the following bug I've noticed:

The asyncio version doesn't work when getting two SimVars with the same key but different index consecutively. Example:

ui_friendly_dictionary["NAV1_OBS_DEG"] = round(await aq.get("NAV_OBS:1"),0)
ui_friendly_dictionary["NAV2_OBS_DEG"] = round(await aq.get("NAV_OBS:2"),0)

NAV2_OBS_DEG will be getting the NAV_OBS:1 value.

The code works, however, when I introduce a different key inbetween. Like this:

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)

This issue has been introduced with asyncio version and hasn't been a problem before. I'm not sure if it's a problem on my part or it's a bug in general. Unfortunately, my Python skills aren't up to the skills to propose a bug fix.

Thanks!

@danricho

danricho commented Nov 16, 2020

Copy link
Copy Markdown

Hi @mracko, I'd suggest checking the thread in issue #67. I had a similar issue, albeit no with the Asyncio version.

It may or may not be useful, but I thought I'd share and I hope it's useful.

Cheers.

@mracko

Copy link
Copy Markdown

Thanks @danricho. This seems to explain the behavior and I understand the performance reasons. Hopefully, I'll be able to come up with a solution on how to efficiently get the NAV OBSs myself. Again, I'm not a Python pro. :)

@danricho

Copy link
Copy Markdown

If you post your code, I or someone else could help you adjust it to get this working.
;)

@Koseng

Copy link
Copy Markdown
Contributor

Hi guys,

let's go async ;-)
See #98 for introducing asyncio, including a sync wrapper to stay compatible.

Please test.
In a next step code can be ported to async, and async examples can be added.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@odwdinc@danricho@viboux@daheise@mracko@Koseng