Hugovdberg / PIconnect

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

Open PI Connection without context manager #656

Open dpcamargo opened 2 years ago

dpcamargo commented 2 years ago

Feature request

I am trying to open a connection to the PI Server without using "with open" like the examples provided.

Works fine

with PI.PIServer('SERVER_IP', 'USERNAME', 'PASSWORD') as server:
    points = server.search(['SINUSOID'])
    print(points)

>>> [PIPoint(SINUSOID, 12 Hour Sine Wave; Current Value: 98.22202 )]

Code below does not work:

server = PI.PIServer('SERVER_IP', 'USERNAME', 'PASSWORD')
points = server.search(['SINUSOID'])
print(points)

Error:

Traceback (most recent call last):
  File "d:\Dario\repos\Painel Py Refactor\z.py", line 6, in <module>
    points = server.search(['SINUSOID'])
  File "C:\Program Files (x86)\Python3.8\lib\site-packages\PIconnect\PI.py", line 181, in search
    return [y for x in query for y in self.search(x, source)]
  File "C:\Program Files (x86)\Python3.8\lib\site-packages\PIconnect\PI.py", line 181, in <listcomp>
    return [y for x in query for y in self.search(x, source)]
  File "C:\Program Files (x86)\Python3.8\lib\site-packages\PIconnect\PI.py", line 185, in search
    return [
  File "C:\Program Files (x86)\Python3.8\lib\site-packages\PIconnect\PI.py", line 185, in <listcomp>
    return [
OSIsoft.AF.PI.PIAuthenticationException: Cannot connect to the PI Data Archive. Windows authentication trial failed because the authentication method was not tried. Trust authentication trial failed because insufficient privilege to access the PI Data Archive. 
   at OSIsoft.AF.PI.PIException.ConvertAndThrowException(PIServer piServer, Exception ex, String message)

   at OSIsoft.AF.PI.PIServer.RemoteConnect(AFConnectionPreference preference, NetworkCredential credential, PIAuthenticationMode authenticationMode)

   at OSIsoft.AF.PI.PIServer.InternalConnect(Int32 numRetries, IWin32Window owner, AFConnectionPreference preference, NetworkCredential credential, PIAuthenticationMode authenticationMode, Boolean checkConnectingAsSameUser)

   at OSIsoft.AF.PI.PIServer.AutoConnect(Boolean allowDirectConnect, Boolean force)

   at OSIsoft.AF.PI.PIPoint.<FindPIPoints>d__26.MoveNext()

   at Python.Runtime.Iterator.tp_iternext(IntPtr ob)

I've tried using "authenticate=AuthenticationMode.PI_USER_AUTHENTICATION" but got the same error.

Is there a way that this can be done?

Hugovdberg commented 1 year ago

Could you please explain why you don't want to use the contextmanager (==with block)? This is exactly the kind of use case for which contextmanagers were added to the Python language as they take care of the setup and teardown of connections to ensure no dangling connections remain. If you do have a valid use case then I can see what I can do to provide another option, but this is definitely the prefered method to make a connection.

dpcamargo commented 1 year ago

I dont know if I can do this in another way, but I'm constantly reading tags, and the opening and closing of the connection puts a small overhead that I have to get rid of. I wanted to create a singleton with the reference, but did not manage to get it to work using the context with. I used the with before calling the reading functions and leaving it open during the program execution, but I would like to put all the PI code inside my class.

Im new at Python and OOP, so maybe i'm doing something wrong.

Hugovdberg commented 1 year ago

Maybe you are right that it would be nice to provide the possibility to connect/disconnect manually. For now, you could do the following:

import PIconnect as PI

server = PI.PIServer('SERVER_IP', 'USERNAME', 'PASSWORD')
server.connection.Connect(*server._credentials) # <- This only works if you actually provide credentials on the line above
points = server.search()
server.connection.Disconnect()