Search code examples
volttron

get_multiple_points volttron RPC call


Any chance I could get a tip for proper way to build an agent that could do read multiple points from multiple devices on a BACnet system? I am viewing the actuator agent code trying learn how to make the proper rpc call.

So going through the agent development procedure with the agent creation wizard.

In the init I have this just hard coded at the moment:

def __init__(self, **kwargs):
    super(Setteroccvav, self).__init__(**kwargs)
    _log.debug("vip_identity: " + self.core.identity)

    self.default_config = {}


    self.agent_id = "dr_event_setpoint_adj_agent"

    self.topic = "slipstream_internal/slipstream_hq/"
    self.jci_zonetemp_string = "/ZN-T"

So the BACnet system in the building has JCI VAV boxes all with the same zone temperature sensor point self.jci_zonetemp_string and self.topic is how I pulled them into volttron/config store through BACnet discovery processes.

In my actuate point function (copied from CSV driver example) am I at all close for how to make the rpc call named reads using the get_multiple_points? Hoping to scrape the zone temperature sensor readings on BACnet device ID's 6,7,8,9,10 which are all the same VAV box controller with the same points/BAS program running.

def actuate_point(self):
    """
    Request that the Actuator set a point on the CSV device
    """

    # Create a start and end timestep to serve as the times we reserve to communicate with the CSV Device
    _now = get_aware_utc_now()
    str_now = format_timestamp(_now)
    _end = _now + td(seconds=10)
    str_end = format_timestamp(_end)

    # Wrap the timestamps and device topic (used by the Actuator to identify the device) into an actuator request
    schedule_request = [[self.ahu_topic, str_now, str_end]]
    
    # Use a remote procedure call to ask the actuator to schedule us some time on the device
    result = self.vip.rpc.call(
        'platform.actuator', 'request_new_schedule', self.agent_id, 'my_test', 'HIGH', schedule_request).get(
        timeout=4)
    _log.info(f'*** [INFO] *** - SCHEDULED TIME ON ACTUATOR From "actuate_point" method sucess')

 
    reads = publish_agent.vip.rpc.call(
                   'platform.actuator',
                   'get_multiple_points',
                   self.agent_id,
                   [(('self.topic'+'6', self.jci_zonetemp_string)),
                   (('self.topic'+'7', self.jci_zonetemp_string)),
                   (('self.topic'+'8', self.jci_zonetemp_string)),
                   (('self.topic'+'9', self.jci_zonetemp_string)),
                   (('self.topic'+'10', self.jci_zonetemp_string))]).get(timeout=10)

Any tips before I break something on the live system greatly appreciated :)


Solution

  • The basic form of an RPC call to the actuator is as follows:

    # use the agent's VIP connection to make an RPC call to the actuator agent 
    result = self.vip.rpc.call('platform.actuator', <RPC exported function>, <args>).get(timeout=<seconds>)
    

    Because we're working with devices, we need to know which devices we're interested in, and what their topics are. We also need to know which points on the devices that we're interested in.

    device_map = {
      'device1': '201201',
      'device2': '201202',
      'device3': '201203',
      'device4': '201204', 
    }
    
    building_topic = 'campus/building'
    
    all_device_points = ['point1', 'point2', 'point3']
    

    Getting points with the actuator requires a list of point topics, or device/point topic pairs.

    # we only need one of the following:
    point topics = []
    for device in device_map.values():
        for point in all_device_points:
            point_topics.append('/'.join([building_topic, device, point]))
    
    device_point_pairs = []
    for device in device_map.values():
        for point in all_device_points:
            device_point_pairs.append(('/'.join([building_topic, device]),point,))
    

    Now we send our RPC request to the actuator:

    # can use instead device_point_pairs
    point_results = self.vip.rpc.call('platform.actuator', 'get_multiple_points', point_topics).get(timeout=3)