Closed bbartling closed 3 years ago
Well, that was fast :-).
@bbartling How did you managed to solve this issue?
to be honest I cannot remember : )
The best advice I could probably give on the matter is Plopping the code into chat GPT:
The error message you've received is coming from the BACpypes library in your Python script grab_config.py. This error occurs because the library expects a IOCB (Input/Output Control Block) for confirmed requests.
In your make_request method, you are directly calling self.request(request). However, BACpypes expects this to be wrapped with IOCB for confirmed requests.
You can modify your make_request function to use an IOCB as follows:
from bacpypes.app import IOCB
def make_request(self, request, expected_device_id=None):
self.expected_device_id = expected_device_id
self._request = request
iocb = IOCB(request) # Create an IOCB for the request
self.request_io(iocb) # Send the request using request_io instead of request
iocb.wait() # Wait for the response
if iocb.ioError: # If there was an error, handle it
print(f"Error occurred: {iocb.ioError}")
else:
self.apdu = iocb.ioResponse # If not, proceed as usual
return self.apdu
In this modification, I've used the IOCB class from bacpypes.app to create an IOCB for the request. This IOCB is then passed to the request_io method, which can handle IOCBs. The wait method of the IOCB is used to pause execution until a response is received. If there's an error, it's printed out. If not, the response is stored in self.apdu as usual.
This change should resolve the error message you're seeing. However, you'll need to handle the IOCB appropriately in your other functions, especially those which call make_request.
Thanks @bbartling clouds are clear now, You saved much of my time.
That's an excellent answer, but there are dragons. The iocb.wait()
will block the thread so it has to be called from a different thread than the one calling core.run()
which is usually the main thread, so if there is data that is shared between threads it needs to be appropriately fenced in (resource locks or semaphores). You can also use the callback API, but the callback will execute in the main thread context, not necessarily the one that created the IOCB.
I usually do not use threads because most of my applications are headless (client and server daemons).
The advantage of BACpypes3 using asyncio is that "await" is very similar to iocb.wait()
without blocking the thread and it is vastly simpler to maintain state, e.g., being able to say value = await app.read_property(...)
and do something with the decoded result.
Hi Joel,
I am updating some code that works on fine bacpypes version 0.16.7
But when I run the code on bacpypes version 0.18.3 I run into some issues:
This maybe asking a lot but any chance I could get a high level on what needs to be changed? The traceback probably spells out everything, but I am still trying soak it all in.
In the
make_request
method, this is throwing the error:self.request(request)
Snip it of the code below, any tips greatly appreciated.