volttron create agent with discoverable BACnet points

209 Views Asked by At

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()
2

There are 2 best solutions below

0
On BEST ANSWER

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

0
On

I get the feeling that the question might still be slight vague/open-ended (- possibly open to interpretation), but if you're talking about exposing some custom (/additional?) objects via BACnet, then to be compliant with a BACnet 'client' - such as the BMS, you'd have to include those objects within the Device's/device-object's 'Object-List' property, so that the BACnet clients would recognise it's availability.

(One day someone could try to be clever - for security reasons and support the Read-Property service for objects without having them available/advertised within the Object-List but 1) it would only work if they were also developing the client too - with knowledge of this, and 2) it would not be compliant with the standard.)