Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError in BAC0 during ReadMultiple Process #488

Open
salsfasser opened this issue Oct 7, 2024 · 7 comments
Open

TypeError in BAC0 during ReadMultiple Process #488

salsfasser opened this issue Oct 7, 2024 · 7 comments

Comments

@salsfasser
Copy link

salsfasser commented Oct 7, 2024

Description:
When attempting to run an asynchronous BACnet script with BAC0 and the asyncio event loop, I encountered a TypeError during the process of reading multiple properties from a device. The issue arises specifically at the point where the read_multiple function is called, and the error points to a TypeError with an apdu object in the bacpypes3 package.

Code to Reproduce:

import asyncio
import BAC0
from BAC0.scripts.script_runner import run

bacnet = None
BAC0.log_level('info')

async def main():
    # Configuration
    ip = "192.168.50.220"
    bbmdIP = '192.168.50.50:47808'

    # Initialize BACnet
    async with BAC0.start(ip=ip, bbmdAddress=bbmdIP, bbmdTTL=900) as bacnet:
        dev = await BAC0.device("192.168.50.30", 2101250, bacnet, segmentation_supported=False)

if __name__ == "__main__":
    asyncio.run(main())

Observed Error:

2024-10-07 13:12:09,159 - INFO    | BACnet/IP App | mode foreign
...
2024-10-07 13:12:19,144 - INFO    | BACnet stopped
2024-10-07 13:12:19,144 - INFO    | BAC0|3056357 disconnected. Exiting context manager.
Traceback (most recent call last):
...
  File "C:\...\read_mixin.py", line 468, in read_multiple
    val = await self.properties.network.readMultiple(
  File "C:\...\Read.py", line 254, in readMultiple
    address, parameter_list = await self.build_rpm_request(
  File "C:\...\Read.py", line 442, in build_rpm_request
    await _app.response(
  File "C:\...\bacpypes3\app.py", line 936, in response
    raise TypeError("apdu")
TypeError: apdu

Environment:
BAC0 Version: 2024.09.10 (Lite)
bacpypes3 Version: 0.0.98
Python Version: 3.11
OS: Windows

Additional Information:
The issue seems related to the APDU handling in bacpypes3. Any guidance on resolving this or confirming if this is a bug would be appreciated.

@ChristianTremblay
Copy link
Owner

first you need to "not use" a BBMD as your IP is in the same subnet than the BBMD itself.

import asyncio
import BAC0
from BAC0.scripts.script_runner import run

bacnet = None
BAC0.log_level('info')

async def main():
    # Configuration
    ip = "192.168.50.220"
    #bbmdIP = '192.168.50.50:47808'

    # Initialize BACnet
    async with BAC0.start(ip=ip) as bacnet:
        dev = await BAC0.device("192.168.50.30", 2101250, bacnet, segmentation_supported=False)

if __name__ == "__main__":
    asyncio.run(main())

retry your script.

IP device that do not support segmentation are pretty rare....or old.

You can greatly improve the performance of the script if you can build a custom object list with the stuff you need and pass it when creating the device.

ex. : https://github.com/ChristianTremblay/BAC0/blob/main/BAC0/tools/jci_tec_points_list.py

Also see: https://bac0.readthedocs.io/en/stable/controller.html#segmentation

@ChristianTremblay
Copy link
Owner

if you want to use BAC0 run helper...

if __name__ == "__main__":
    run(main, bacnet)

it deals with a lot of things, loops, signals....

see : https://github.com/ChristianTremblay/BAC0/blob/main/BAC0/scripts/script_runner.py

@salsfasser
Copy link
Author

Thank you for your quick response, Christian!

I followed your suggestion to remove the BBMD configuration since the device is on the same subnet, but unfortunately, the issue persists. I’m still encountering the same TypeError: apdu error when running the script.

Here’s the updated code based on your advice:

import asyncio
import BAC0
from BAC0.scripts.script_runner import run

bacnet = None
BAC0.log_level('info')

async def main():
    # Configuration
    ip = "192.168.50.220"
    # Initialize BACnet
    async with BAC0.start(ip=ip) as bacnet:
        dev = await BAC0.device("192.168.50.30", 2101250, bacnet)

if __name__ == "__main__":
    run(main, bacnet)

I also tried using the run(main, bacnet) helper function as you suggested, but I’m still seeing the same error. In addition, I attempted setting segmentation_supported=True to check if that would make a difference, but unfortunately, the issue remains unchanged.

Here’s the error message:

Traceback (most recent call last):
...
  File "C:\...\read_mixin.py", line 468, in read_multiple
    val = await self.properties.network.readMultiple(
  File "C:\...\Read.py", line 254, in readMultiple
    address, parameter_list = await self.build_rpm_request(
  File "C:\...\Read.py", line 442, in build_rpm_request
    await _app.response(
  File "C:\...\bacpypes3\app.py", line 936, in response
    raise TypeError("apdu")
TypeError: apdu

It seems like the issue occurs during the read_multiple process. Do you have any further suggestions on what might be causing this? Is there something specific in the read_multiple method or apdu handling that I should investigate further?

Thanks again for your help, and I appreciate any further insights you can provide!

@ChristianTremblay
Copy link
Owner

When your device is created... you exit the async with loop the bacnet closes.

Try doing something else. Or add a while true loop with await asyncio.sleep(0.1) in it...

I prefer running those "test" using the repl...

Try

Python -m asyncio

Then write your script, it'll keep running.

@salsfasser
Copy link
Author

Thank you for the suggestion!

I implemented your idea by adding the while True loop with await asyncio.sleep(0.1) at the end of the main function to keep the connection open. This way, the async with block isn’t exited as long as the script is running. Unfortunately, I’m still seeing the same TypeError: apdu during the read_multiple process.

It seems like the issue may not be directly related to the connection closing, but rather something deeper in the read_multiple process or in the handling of the APDU in the script itself.

Do you have any other suggestions on how to troubleshoot this specific part of the read_multiple method? Or perhaps a workaround that might help bypass this issue?

Thank you again for the continued support!

@ChristianTremblay
Copy link
Owner

I suspect there is one BACnet object not well defined in the device.

You could read the objectList, then try to identify the object giving troubles... once done, you can define a custom object list to connect to the device.

[ref] https://bac0.readthedocs.io/en/stable/controller.html#object-list

Copy link

This issue had no activity for a long period of time. If this issue is still required, please update the status or else, it will be closed. Please note that an issue can be reopened if required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants