Platform Driver

The Platform Driver Agent manages all device communication. This agent automatically collects data from configured devices and publishes it to the message bus, generally on a specified interval. It also features a number of RPC endpoints for getting and setting points on devices.

The Platform Driver creates a driver instance for each device configuration in the platform driver’s configuration store. While running, the driver periodically polls data from the device and publishes it to the message bus. The driver additionally handles ad-hoc read and write requests issued by RPC through the Actuator or Platform Driver agents. When device configurations are removed from the store, the corresponding driver instance is also removed by the Platform Driver.

Actual communication with devices is handled by the driver’s “Interface” class. An Interface is a Python class which serves to handle communication with the device. Interfaces wrap protocol-specific functionality in standard methods to be used by the driver. Information on developing new driver interfaces can be found on the driver development page.

Note

Earlier versions of VOLTTRON referred to all data collection from a device as “scraping”. The current documentation has been update to use the more precise language. The word “pull” or “query” are used for the activity of discretely requesting data from a remote, while the word “polling” is used where the data is requested in a periodic loop. The words “poll” and “scape”, as used here, may be considered interchangeable.

Configuration and Installation

Installation

The platform driver agent may be installed using vctl:

vctl install volttron-platform-driver --vip-identity platform.driver --tag driver

Additionally, to communicate with any devices, it will be necessary to install one or more interface libraries. These may be installed from pypi using pip:

pip install volttron-lib-fake-driver

Officially maintained driver interfaces (with corresponding package names) include:

Configuration

The Platform Driver requires use of the configuration store and expects three types of configuration file:

  • Platform Driver Agent Configuration (one for the agent): global settings for all drivers.

  • Device Configuration (one per device): settings for the driver to manage an individual device.

  • Registry (up to one per device): contains the settings for each individual data point for a device or class of device. Some drivers may require one per registry per individual device, but often one registry may be shared by multiple devices of the same type.

Platform Driver Agent Configuration

The Platform Driver Agent configuration consists of general settings for all devices. The default values should be sufficient for most users. If changes are made to any of the global settings, this configuration should be saved to the configuration store with the name “config”:

vctl config store platform.driver config path/to/edited/config/file

The following example sets the driver_scrape_interval to 0.05 seconds or 20 devices per second:

{
    "driver_scrape_interval": 0.05,
    "publish_breadth_first_all": false,
    "publish_depth_first": false,
    "publish_breadth_first": false,
    "publish_depth_first_all": true,
    "group_offset_interval": 0.0
}
  • driver_scrape_interval - Sets the interval between devices polls. Defaults to 0.02 or 50 devices per second. This is useful for when the platform polls too many devices at once resulting in failed polls. To spread polling of n devices evenly throughout a polling cycle, this may be set to:

    length_of_cycle_in_seconds / n
    

    If multiple groups are used, n would be the size of the largest group.

  • group_offset_interval - Sets the delay between when each group of devices begins to be polled. There is no effect if all devices are in the same group. Group 0 will begin at t=0. The first device of each subsequent group will be polled starting at

    t = group_number * group_offset_interval.
    

To improve the scalability of the platform unneeded device state publishes for all devices can be turned on and off. Configured at the agent level, these settings will apply to all devices, but may also be overridden on a device-by-device manner in the Device Configuration.

Note

  • Depth first publishes have topics with the point name at the end (i.e., “campus/building/device/point”).

  • Breadth first publishes have topics with the point name at the beginnning (i.e., “point/device/building/campus”).

  • Historian agents subscribe only to the publish_depth_first_all version, so this must be true to archive data.

  • publish_depth_first_all (default True) - Enable “depth first” publish of all points to a single topic.

  • publish_breadth_first_all - (default False) Enable “breadth first” publish of all points to a single topic.

  • publish_depth_first - (default False) Enable separate “depth first” device state publishes for each point.

  • publish_breadth_first - (default False) Enable separate “breadth first” device state publishes for each point.

See device scalability settings for more details on the effect of these settings.

An example platform driver configuration file, with default settings can be found in the volttron-platform-driver repository.

Device Configuration

Each device must have a corresponding device configuration in the platform driver configuration store. The topic used to reference the device is derived from the name of this device configuration. For instance, to follow the common topic convention of {campus}/{building}/{unit}, the device configuration file should be given the name devices/{campus}/{building}/{unit} in the configuration store:

vctl config store platform.driver devices/PNNL/Building1/AHU2 path/to/config/file.json

Each device configuration has the following form:

{
    "driver_config": {"device_address": "10.1.1.5",
                      "device_id": 500},
    "driver_type": "bacnet",
    "registry_config":"config://registry_configs/vav.csv",
    "interval": 60,
    "heart_beat_point": "heartbeat",
    "group": 0
}

The following settings are required for all device configurations:

  • driver_config - Interface specific settings. See documentation for each interface type.

  • driver_type - Driver interface to use for this device: “bacnet”, “modbus”, “fake”, etc.

  • registry_config - Reference to another file in the configuration store containing information regarding points on the device. See the Registry-Configuration-File section below.

These settings are optional:

  • interval - Period (in seconds) on which to poll the device and publish the results. Defaults to 60 seconds.

  • heart_beat_point - A Point on the device to toggle as a heartbeat. A point with this Volttron Point Name must exist in the registry. If this setting is missing, the driver will not send a heart beat signal to the device. Heart beats are triggered by the Actuator Agent which must be running to use this feature.

  • group - Group to which this device belongs. (Defaults to 0) — See Device Grouping.

Device Grouping

Devices may be assigned to groups to separate them logically when they are polled. This is done by configuration of two settings:

  1. Each device configuration may have a group setting, which should be an integer greater than or equal to 0.

  2. group_offset_interval, in the platform driver agent configuration is the number of seconds to delay the start of each group after the start of the previous. When using this setting, assign devices only consecutive group values starting from 0.

An independent polling schedule is created for each group, where the first device in each group is polled group_offset_interval * group seconds after the first device of group 0. Each device within the group will then be polled driver_scrape_interval seconds apart.

Groups are most commonly useful in two cases:

  • To ensure that certain devices are polled in close proximity to each other, you can put them in their own group. They are then guaranteed to be polled driver_scrape_interval seconds apart.

  • You may poll devices on different networks in parallel for performance. For instance BACnet devices behind a single MSTP router need to be polled slowly and serially, but devices behind different routers may be polled in parallel. Grouping devices by router will achieve this automatically.

Registry Configuration File

Registry configuration files setup each individual point on a device. As the registry is a list of records, this file will typically be provided as CSV, but may also be JSON (a list of objects). The exact set of fields in each record is driver specific. See the section for a particular driver for the registry configuration format.

The following is a simple example of a Modbus registry configuration file:

Catalyst 371

Reference Point Name

Volttron Point Name

Units

Units Details

Modbus Register

Writable

Point Address

Default Value

Notes

CO2Sensor

ReturnAirCO2

PPM

0.00-2000.00

>f

FALSE

1001

CO2 Reading 0.00-2000.0 ppm

CO2Stpt

ReturnAirCO2Stpt

PPM

1000.00 (default)

>f

TRUE

1011

1000

Setpoint to enable demand control ventilation

HeatCall2

HeatCall2

On / Off

on/off

BOOL

FALSE

1114

Status indicator of heating stage 2 need

Adding Device Configurations to the Configuration Store

Configurations are added to the Configuration Store using the command line:

vctl config store platform.driver <name> <file name> <file type>
  • name - The label given to the configuration in the store.

  • file name - A file containing the contents of the configuration.

  • file type - --raw, --json, or --csv. Indicates the type of the file. Defaults to --json.

The main configuration must have the name config

Device configuration but not registry configurations must have a name prefixed with devices/. Scripts that automate the process will prefix registry configurations with registry_configs/, but that is not a requirement for registry files.

The name of the device’s configuration in the store is used to create the topic used to reference the device. For instance, a configuration named devices/PNNL/ISB1/vav1 will publish polling results to devices/PNNL/ISB1/vav1.

The name of a registry configuration must match the name used to refer to it in the driver configuration. The reference is not case sensitive.

If the Platform Driver Agent is running, any changes to the configuration store will immediately affect the running devices according to the changes.

Example

Consider the following three configuration files: A platform driver configuration called platform-driver.agent, a Modbus device configuration file called modbus_driver.config and corresponding Modbus registry configuration file called modbus_registry.csv

To store the platform driver configuration run the command:

vctl config store platform.driver config platform-driver.agent

To store the registry configuration run the command (note the --csv option):

vctl config store platform.driver registry_configs/modbus_registry.csv modbus_registry.csv --csv

Note

The registry_configs/modbus_registry.csv argument in the above command must match the reference to the registry_config found in modbus_driver.config.

To store the driver configuration run the command:

volttron-ctl config store platform.driver devices/my_campus/my_building/my_device modbus_config.config

Usage

After installing the Platform Driver and loading driver configs into the config store, the installed drivers begin polling and JSON-RPC endpoints become usable.

Polling

Once running, the Platform Driver will spawn drivers using the driver_type parameter of the driver configuration and periodically poll devices for all point data specified in the registry configuration at the interval specified by the interval parameter of the driver configuration. This is done using the scrape_all method, which can also be called outside the polling scheduler by a user using RPC.

Consider a device configured with the name devices/pnnl/isb1/vav1 and a registry containing two points: “Temperature” and “AirFlow”. A “depth first all” publish to the topic devices/pnnl/isb1/vav1/all may contain the following message:

[
    {
        "Temperature": 75.2,
        "AirFlow": 302
    },
    {
        "Temperature": {
            "units": "F"
        },
        "AirFlow": {
            "units": "CFM"
        }
    }
]

The first dictionary in the publish contains the current values reported by the device when polled. The second dictionary contains meta-data, which generally has been obtained by the driver interface from the registry file. The exact contents of the meta-data dictionary will be interface specific. Note that if this data is being archived by an historian, two topics will be stored in the database. These contain the topic (without “devices/” or “/all”, and the point name:

  • “pnnl/isb1/vav1/Temperature”

  • “pnnl/isb1/vav1/AirFlow”

Note

For additional, non-default publish formats, see Device Scalability Settings.

Getting Values

While a device driver for a device will periodically poll and publish the state of a device you may want an up to the moment value for a point on a device. This can be accomplished using the get_point & get_multiple_points RPC methods. The scrape_all method, employed in polling, can also be used to retreive all points on a single device.

Get Point

The get_point method returns the value of one device, and takes two parameters:

topic:

The topic of the device, without the point name.

point_name:

The point name.

Get Multiple Points

The get_multiple_points method return values corresponding to multiple points on a single device. It takes two parameters:

path:

The device topic (without point name).

point_names:

An iterable of device point names.

Scrape All

The scrape_all method returns values for all points on the specified device. This is the same method called internally by the driver’s polling mechanism. The scrape_all method takes one parameter:

path:

The device topic (not including point names).

Setting Values

The value of points may be set using one of two methods. The set_point method sets an indvidual point, while the set_points_multiple, sets a batch of points with a single RPC call.

Warning

When points are set by sending requests directly to the Platform Driver Agent, it bypasses the scheduling capability of the Actuator agent.

Set Point

The set_point method sets the value of a single device. If the global override is condition is set, it will raise an OverrideError exception. Set point takes three parameters:

path:

The device topic (without point name).

point_name:

The name of the point to be set.

value:

The new value for the point.

Set Multiple Points

The set_multiple_points sets the values of multiple points on the same device. If the global override is condition is set, it will raise an OverrideError exception. set_multiple_points takes two parameters:

path:

The device topic (not including point names).

point_names_value:

A list of tuples consisting of (point_name, value) pairs for each point.

Reverting Values and Devices to a Default State

The value of previously set devices may be reverted to default or prior values. The exact mechanism used to accomplish this is driver specific. Points may be reverted individually or across entire devices.

Revert Point

The ``revert_point``reverts the value of a specific point on a device to a default state. If the global override condition is set, it will raise an OverrideError exception. This method requires two parameters:

path:

The device topic (not including the point name).

point_name:

The name of the point.

Revert Device

The revert_device reverts all points on a single device to default state/values. If global override is condition is set, it will raise an OverrideError exception. This method takes one parameter:

path:

The device topic (not including point names).

Overrides

By default, every user is allowed write access to the devices by the platform driver. The override feature allows a user (for example, building administrator) to lock devices from being written for a specified duration of time or indefinitely. Optionally, the devices may also be reset when they are overridden.

Any changes made to override patterns are stored in the config store. On startup, the list of override patterns and their corresponding end times are retrieved from the config store. If the end time is indefinite or greater than current time for any pattern, then override is set on the matching devices for remaining duration of time.

Whenever a device is newly configured, a check is made to see if it is part of the overridden patterns. If yes, it is added to list of overridden devices. Conversely, when a device is being removed, a check is made to see if it is part of the overridden devices. If yes, it is removed from the list of overridden devices.

Override Patterns

The topics to be overridden are determined by a “pattern” string. This pattern can be specify single devices, groups of devices, or even all configured devices. The pattern matching is based on bash style filename matching semantics. For example:

  • If the pattern is campus/building1/* the override condition is applied for all the devices under campus/building1/.

  • If the pattern is campus/building1/ahu1 the override condition is applied for only the campus/building1/ahu1 device. The pattern matching is based on bash style filename matching semantics.

Set Override On

The Platform Driver’s set_override_on RPC method can be used to set the override condition for all drivers with topic matching the provided pattern. It accepts four parameters:

pattern:

Override pattern to be applied.

duration:

Time duration for the override in seconds. If duration <= 0.0, it implies an indefinite duration. (default 0.0)

failsafe_revert:

Flag to indicate if all the devices falling under the override condition has to be set to its default state/value immediately. If False, the value of overridden points is untouched. (default True)

staggered_revert:

If this flag is set, reverting of devices will be staggered. (default False)

Example set_override_on RPC call:

self.vip.rpc.call(PLATFORM_DRIVER, "set_override_on", <override pattern>, <override duration>)

Set Override Off

The override condition can also be toggled off based on a provided pattern using the Platform Driver’s set_override_off RPC call. This method accepts one parameter:

pattern:

Override pattern to be applied.

Get Override Devices

A list of all overridden devices can be obtained with the Platform Driver’s get_override_devices RPC call.

This method call does not take any parameters.

Get Override Patterns

A list of all patterns which have been requested for override can be obtained with the Platform Driver’s get_override_patterns RPC call.

This method does not take any parameters

Clear Overrides

All overrides set by RPC calls described above can be toggled off at using a single clear_overrides RPC call.

This method call does not take any parameters