bacpypes icon indicating copy to clipboard operation
bacpypes copied to clipboard

How to run two applications consecutively

Open MitchCayCRC opened this issue 3 years ago • 3 comments

I am looking for a way to do this (or am perhaps misunderstanding bacpypes functionality) but it creates communication issues.

I am trying to read values from a device that I am connecting to, but first want to discover what objects are present on this device. Because my device does not support segmentation I cannot create a request for the devices objectList. The idea is to create an application instance which discovers the objects on the device by iterating through the objectList by using indices. Once the full object_list is created there is a call to stop() and then a new application instance is created which continuously reads the objects presentValue's and run() is called again. I thought this would work but multiple objects will return a <bacpypes.apdu.AbortPDU(None, )> instance. However sometimes the second applications ReadPropertyRequest's are successful. Am I missing something?

# make a device object
    mstp_args = {
     '_address': int(args.ini.address),
     '_interface':str(args.ini.interface),
     '_max_masters': int(args.ini.max_masters),
     '_baudrate': int(args.ini.baudrate),
     '_maxinfo': int(args.ini.maxinfo),
    }
    this_device = LocalDeviceObject(ini=args.ini, **mstp_args)
    if _debug: _log.debug("    - this_device: %r", this_device)

    # make a discovery application
    discovery_application = DiscoveryApplication(this_device, args.ini.address)
    
    
    

    _log.debug("running discovery application")

    run()

    _log.debug("fini")
    
    # make a read application
    read_application = ReadPointsApplication(args.interval, 
                                             args.mac_address, 
                                             this_device, 
                                             args.ini.address)
    
    _log.debug("running read application")

    run()

    _log.debug("fini")

MitchCayCRC avatar Jun 09 '21 22:06 MitchCayCRC

The library is not designed to have more than one application like this, you are probably running into pieces of the first application that aren't disposed of or dereferenced when the second application is built.

JoelBender avatar Jun 10 '21 01:06 JoelBender

Is there no way to do something like this then? I attempted to create a single application with two different types of requests in it; one for doing the discovery of the objects on the device and then another for recurring read requests of those points and seemed to still run into the same issue. My only working solution currently is to create a scheduler that runs the two seperately:

def main():
    
    parser = argparse.ArgumentParser()
    
    parser.add_argument('--ini',
                        type=str,
                        help='.ini file to be used (default is bac_client.ini)',
                        nargs='?',
                        default='bac_client.ini')
    
    args = parser.parse_args()
    
    
    os.system(f'python DiscoveryApplication.py --ini {args.ini}')
    os.system(f'python ReadPointListApplication.py --ini {args.ini}')
    
if __name__ == '__main__':
    main()

MitchCayCRC avatar Jun 10 '21 22:06 MitchCayCRC

A bacpypes app is a BACnet device on your network. It's not only a client that make read requests on a network like you typically see on client server relationships.

You don't want a BACnet device to constantly appear and disappear on a network.

This is why you must consider your app as something that must always run and be accessible for other devices.

You could technically run other instances in parallel, by using a different port (ex 47809) or defining multiple IP adresses on your NIC, or attaching instances to other NIC... it's a path you can choose.

I prefer keeping one instance running and "defer" all traffic request to bacpypes run thread. This keep things reliable and work well.

Speed issues are most of the time created by bad usage of read_properties instead of read property multiple for example... or old devices that could not be faster anyway...

Bacpypes3 Will bring asyncio capacity to the stack but it's not ready yet.

ChristianTremblay avatar Jun 11 '21 03:06 ChristianTremblay