Python-SimConnect icon indicating copy to clipboard operation
Python-SimConnect copied to clipboard

Asyncio Testing

Open odwdinc opened this issue 4 years ago • 14 comments

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

odwdinc avatar Oct 24 '20 20:10 odwdinc

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?

danricho avatar Oct 25 '20 05:10 danricho

@danricho just thinking about removing attempts, not 100% on this so left in the pluming for now. values are set on thread https://github.com/odwdinc/Python-SimConnect/blob/152fa14bd71ed6a5b71b139f5b10c84ca9bc5db5/SimConnect/SimConnect.py#L163-L165

_run https://github.com/odwdinc/Python-SimConnect/blob/152fa14bd71ed6a5b71b139f5b10c84ca9bc5db5/SimConnect/SimConnect.py#L172-L175

Data is revived by https://github.com/odwdinc/Python-SimConnect/blob/152fa14bd71ed6a5b71b139f5b10c84ca9bc5db5/SimConnect/SimConnect.py#L243-L249

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. https://github.com/odwdinc/Python-SimConnect/blob/152fa14bd71ed6a5b71b139f5b10c84ca9bc5db5/SimConnect/RequestList.py#L15-L24

odwdinc avatar Oct 25 '20 16:10 odwdinc

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.

viboux avatar Oct 26 '20 04:10 viboux

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.

daheise avatar Nov 06 '20 00:11 daheise

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.

danricho avatar Nov 11 '20 01:11 danricho

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 avatar Nov 15 '20 17:11 odwdinc

new sample, added an a to the async vertions of functions to keep backwords code woking. https://github.com/odwdinc/Python-SimConnect/blob/c6da1c8d475e25d07f112f95993c462393e6d4e8/SimConnect/RequestList.py#L19 Sample:

from SimConnect import *
import logging
from SimConnect.Enum import *
from time import sleep
import asyncio

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

# creat simconnection and pass used user classes
sm = SimConnect()
aq = AircraftRequests(sm, _time=10, _attemps=10)
Throttle = aq.find('GENERAL_ENG_THROTTLE_LEVER_POSITION:1')


# none async Function still works
print("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 Function
async def PrintData():
	# THROTTLE Request
	print("Throttle:", await Throttle.avalue)
	print("Lat=%f Lon=%f Alt=%f Kohlsman=%.2f" % tuple(
		await asyncio.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()

odwdinc avatar Nov 15 '20 18:11 odwdinc

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.

daheise avatar Nov 15 '20 18:11 daheise

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!

danricho avatar Nov 15 '20 22:11 danricho

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!

mracko avatar Nov 16 '20 08:11 mracko

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.

danricho avatar Nov 16 '20 08:11 danricho

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. :)

mracko avatar Nov 16 '20 14:11 mracko

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

danricho avatar Nov 16 '20 14:11 danricho

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.

Koseng avatar Jun 03 '21 11:06 Koseng