Search code examples
pythonvolttron

volttron create agent with discoverable BACnet points


I was curious with VOLTTRON agent development if an agent could be used to expose discoverable BACnet points to a building automation system.

For example, BAC0 that also uses bacpypes under the hood like VOLTTRON I can create a really simple BACnet app (shown below) and discover my BAC0 app (and points) via BACnet to the building automation system.

I have an odd use case not to control or acquire data (I think typical VOLTTRON use case) but only to "expose" a few read only AV BACnet points (integers that represent the count of people in particular HVAC zones from some other system counting people) to the building automation system.

Sorry another vague question but would there be any examples to look at if anyone has done this with an agent development? I'm curious if some BAC0 code could just run in an agent if the BACnet proxy has not been installed via typical VOLTTON development. Any tips/help greatly appreciated.

import BAC0,time,random

from BAC0.core.devices.local.models import (
    analog_output,
    analog_value,
    binary_value
    )

from BAC0.tasks.RecurringTask import RecurringTask 
from bacpypes.primitivedata import Real


  

# create writeable point to kill plugs
_new_objects = binary_value(
        name="plugs_enabled",
        description="BACnet Writeable Plug Load Relay Status",
        presentValue=True,is_commandable=True
    )

     
# create app
#bacnet = BAC0.lite(ip='10.0.2.20/24',deviceId='2021') #if static IP is needed
bacnet = BAC0.lite()
  
_new_objects.add_objects_to_application(bacnet)

bacnet._log.info("APP Created Success!")



def main():

    while True:
        plugs = bacnet.this_application.get_object_name('plugs_enabled')
        bacnet._log.info('plugs_enabled is currently {}'.format(plugs.presentValue))
        time.sleep(10)


if __name__ == "__main__":
    main()

Solution

  • I think for discovery purposes, it would be easiest to use subprocess to run the VOLTTRON BACnet utility scripts, but this isn't going to feel very clean, and the output may not be the form you desire. I'd recommend instead to cannibalize the bacnet_scan.py and grab_bacnet_config.py scripts.

    The general process would be to create a BACnet server application using BACpypes, use the WhoIs/IAm service requests to find devices on the network, and then use readProperties requests to get point data.

    I will note that this will likely be challenging - BACnet is a bit of a callback maze.

    Here are some jumping off points:

    https://github.com/VOLTTRON/volttron/blob/main/scripts/bacnet/bacnet_scan.py#L210 https://github.com/VOLTTRON/volttron/blob/main/scripts/bacnet/bacnet_scan.py#L78

    https://github.com/VOLTTRON/volttron/blob/main/scripts/bacnet/grab_bacnet_config.py#L375 https://github.com/VOLTTRON/volttron/blob/main/scripts/bacnet/grab_bacnet_config.py#L410 https://github.com/VOLTTRON/volttron/blob/main/scripts/bacnet/grab_bacnet_config.py#L69