Hugovdberg / PIconnect

A python connector to the OSISoft PI and PI-AF databases
MIT License
91 stars 41 forks source link

Asyncio compatibility #570

Closed ldariva closed 6 months ago

ldariva commented 3 years ago

Feature request

asyncronous reading

Abstract

I am wondering if it would be possible to make the PIConnect to be asyncio compatible. The idea here is to collect data from various tags without waiting for one tag read to finish to start the next one. Something similar to what is done with pyodbc and aioodcb libraries

Motivation and summary

I come up with this need because I am trying to develop an asyncronous application that reads data from PI. The problem is that the real asyncronous behaviours is not achieved because the PIConnect don't use the Asyncio library

Suggested solution

There is this link from PISquare website that explain how to use asyncronous reading with PI.

https://pisquare.osisoft.com/s/Blog-Detail/a8r1I000000GvS4QAK/async-with-pi-af-sdk-introduction

Hugovdberg commented 3 years ago

I can see the benefits of using asynchronous access to the PI data. However, I have never done any async programming before, so I'm not sure what exactly is required to implement this. I know there are asynchronous data access functions in the SDK, so if it is sufficient to add an async def recorded_values_async(...) then it should be pretty easy to implement.

Hugovdberg commented 3 years ago

I added this to the 0.10 milestone as async support in Python 2 is very minimal. Version 0.9 will still support Python 2.7.

stefanhawk commented 9 months ago

Is Async now possible?

Hugovdberg commented 6 months ago

Unfortunately, it seems that async will not be possible due to limitations in the pythonnet package that is used to load the PI AF SDK: https://github.com/pythonnet/pythonnet/issues/604. Async is more of a syntactic sugar, both in Python as well as in .NET, and is therefore quite hard to get to work in unison. For now I'm inclined to close this issue until the way smarter guys in the pythonnet community fix this problem on their end.

Hugovdberg commented 5 months ago

Today I ran into an issue where I really wanted asynchronous behaviour as I was calling it from a tkinter GUI, and the workaround I implemented is using asyncio.to_thread, which simply opens a separate thread and async sleeps until the thread finishes. If you do this in tkinter, make sure you only wrap PIPoint.recorded_values (or whatever data retrieval method) in the asyncio.to_thread, since any calls from another thread to tkinter objects will trigger a RuntimeError: main thread is not in main loop.

Also, for obscure reasons the tkinter.filedialogs don't work if you've imported PIconnect before the first time you've opened a dialog. (https://github.com/pywinauto/pywinauto/issues/517)