VOLTTRON is a free, open-source distributed sensing and control platform developed by Pacific Northwest National Laboratory (PNNL) with funding from the U.S. Department of Energy. It provides a Python-based agent framework on top of a publish-subscribe message bus, enabling building automation, energy management, and grid-interactive controls on hardware as small as a Raspberry Pi. Install it in a Python virtual environment with pip install volttron, configure the Platform Driver agent for BACnet or Modbus devices, and deploy custom agents that subscribe to device data topics and execute control logic.
What Is VOLTTRON
VOLTTRON is an open-source IoT platform originally created in 2012 at PNNL under DOE's Building Technologies Office. The project's initial goal was to deliver a low-cost, software-only building automation system for small and medium commercial buildings that could not justify the expense of a traditional BAS. Over time it grew into a general-purpose distributed control platform with applications spanning HVAC optimization, demand response, fault detection and diagnostics (FDD), EV charging management, and utility-scale solar monitoring.
The platform is written entirely in Python and runs on Linux. Its lightweight resource footprint means it can operate on inexpensive single-board computers such as a Raspberry Pi, on a dedicated server, or on a virtual machine in the cloud. VOLTTRON is now maintained under the Eclipse Foundation as Eclipse VOLTTRON, with the source code hosted across multiple repositories in the eclipse-volttron GitHub organization. The legacy monolithic repository at github.com/VOLTTRON/volttron has accumulated over 400 stars and remains a reference for earlier versions.
For building automation professionals, VOLTTRON fills a specific niche: it acts as an independent middleware layer that sits alongside or on top of an existing BAS. You can use it as a data bridge to pull BACnet or Modbus points into a central historian, run custom analytics agents against that data, and push supervisory control commands back to field controllers. Because it is protocol-agnostic at the agent level, the same analytics agent works whether the underlying device speaks BACnet/IP, Modbus TCP, or DNP3.
Architecture: Agents, Platform, and Message Bus
VOLTTRON's architecture has three core layers: the platform core, the message bus, and the agents.
Platform Core
The platform core manages the lifecycle of agents (starting, stopping, monitoring), handles authentication and authorization, and provides shared services like the configuration store and the historian framework. It runs as a persistent process on the host machine and exposes a command-line tool, volttron-ctl (aliased as vctl), for administration. The platform stores its state and configuration under the VOLTTRON_HOME directory, which defaults to ~/.volttron.
Message Bus
All inter-agent communication flows through a publish-subscribe message bus. VOLTTRON supports two message bus implementations: ZeroMQ (the default, brokerless) and RabbitMQ (broker-based, added in version 6). Agents publish data to hierarchical topics such as devices/campus/building/ahu1/all, and any agent subscribed to that topic receives the data automatically. ZeroMQ is simpler to set up and sufficient for single-platform deployments. RabbitMQ adds features like message persistence, fine-grained routing, and native multi-platform federation, making it better suited for deployments that span multiple buildings or sites. If no message bus is specified in the platform configuration, VOLTTRON defaults to ZeroMQ.
Agents
Agents are Python programs that run within the VOLTTRON environment. Each agent inherits from a base class that provides hooks for subscribing to topics, publishing data, scheduling periodic tasks, and interacting with the configuration store. VOLTTRON ships with several built-in agents:
- Platform Driver Agent — manages communication with field devices over BACnet, Modbus, and other protocols, publishing point data on a configurable scrape interval
- BACnet Proxy Agent — provides a virtual BACnet device that handles the low-level BACnet stack on behalf of the Platform Driver
- Historian Agents — archive time-series data to SQLite, MySQL, PostgreSQL, MongoDB, or InfluxDB
- Weather Agent — fetches external weather data for use by analytics and control agents
- Intelligent Load Control (ILC) — a DOE-developed application agent that performs demand limiting and load shedding while respecting occupant comfort constraints
Installing VOLTTRON
VOLTTRON requires a Linux operating system and Python 3.10 or later. It has been tested on Ubuntu 22.04, Debian Buster and newer, and Raspberry Pi OS 10 (Buster) and newer. The following steps cover a standard installation on Ubuntu.
Step 1: Install System Dependencies
sudo apt update
sudo apt install -y build-essential python3-dev python3-venv openssl libssl-dev libevent-dev gitStep 2: Create a Virtual Environment
Always install VOLTTRON inside a Python virtual environment to avoid conflicts with system packages.
python3 -m venv ~/volttron-venv
source ~/volttron-venv/bin/activateStep 3: Set VOLTTRON_HOME
export VOLTTRON_HOME=~/.volttronStep 4: Install VOLTTRON via pip
For the modular Eclipse VOLTTRON (version 10+), install the core package and the ZeroMQ message bus:
pip install volttron-core volttron-lib-zmq volttron-lib-authFor the monolithic VOLTTRON (version 9.x and earlier), the single pip install volttron command pulls in the full platform. After installation, start the platform with:
volttron -vv &
vctl statusThe -vv flag enables verbose logging. The vctl status command confirms the platform is running and lists installed agents.
BACnet Agent Setup
VOLTTRON communicates with BACnet devices through two cooperating agents: the BACnet Proxy Agent and the Platform Driver Agent. The proxy manages a virtual BACnet device on the network, while the Platform Driver uses it to scrape points from physical devices.
Configure the BACnet Proxy Agent
Create a JSON configuration file for the proxy. Key parameters include:
{
"device_address": "192.168.1.50",
"max_apdu_length": 1024,
"object_id": 599,
"object_name": "Volttron BACnet driver",
"vendor_id": 15,
"segmentation_supported": "segmentedBoth"
}The device_address must be the IP address of the network interface connected to your BACnet network. The object_id must be unique across the BACnet network to avoid device ID conflicts. Valid max_apdu_length values are 50, 128, 206, 480, 1024, and 1476. If you have BACnet devices on separate physical networks, deploy one BACnet Proxy Agent per network, each with a distinct VIP identity.
Generate a Registry Configuration
VOLTTRON includes a utility script, grab_bacnet_config.py, that discovers a BACnet device and generates a CSV registry file listing every object on the device. Run it against a target device, review the output, and remove any objects you do not need before using the CSV in production.
Store Configurations and Install
vctl config store platform.driver devices/campus/building/ahu1 ahu1-driver.config
vctl config store platform.driver campus/building/ahu1.csv ahu1-registry.csv --csvThe first command stores the driver configuration (which references the registry CSV and specifies "driver_type": "bacnet"). The second stores the registry CSV. Once both are loaded, the Platform Driver begins scraping the device at the configured interval and publishing data to the message bus.
Modbus Agent Setup
Modbus device communication also runs through the Platform Driver Agent. VOLTTRON ships with two Modbus driver implementations: the original Modbus driver and the Modbus-TK driver. Modbus-TK is generally recommended because it supports both Modbus TCP and Modbus RTU (serial) through a unified configuration format.
Device Configuration
A typical Modbus device configuration file looks like this:
{
"driver_config": {
"device_address": "192.168.1.100",
"port": 502,
"slave_id": 1
},
"driver_type": "modbus",
"registry_config": "config://campus/building/meter1.csv",
"interval": 60
}Registry Configuration
The registry CSV maps Modbus registers to named points. Each row defines a Volttron Point Name (the topic name agents use to reference the value), the register address, the register type (holding or input), the data type (uint16, float, etc.), the unit of measurement, and whether the point is writable. Careful attention to byte order and data type is critical: a 32-bit floating-point value occupies two consecutive 16-bit registers, and misaligning the register address by one position returns garbage data.
Store and Activate
vctl config store platform.driver devices/campus/building/meter1 meter1-driver.config
vctl config store platform.driver campus/building/meter1.csv meter1-registry.csv --csvAfter storing both files, the Platform Driver picks up the new device configuration automatically and begins polling registers at the specified interval.
Building a Custom Agent
Custom agents are where VOLTTRON delivers its real value for building energy management. A custom agent can subscribe to device data, run analytics (such as fault detection rules or energy optimization algorithms), and publish control commands back through the Platform Driver.
Agent Skeleton
Every VOLTTRON agent inherits from the Agent base class and uses decorators to subscribe to topics and schedule periodic tasks. A minimal agent that logs AHU discharge air temperature looks like this:
from volttron.platform.vip.agent import Agent, Core
from volttron.platform.messaging import topics
class MonitorAgent(Agent):
def __init__(self, config_path, **kwargs):
super().__init__(**kwargs)
self.config = utils.load_config(config_path)
@Core.receiver("onstart")
def on_start(self, sender, **kwargs):
self.vip.pubsub.subscribe(
peer="pubsub",
prefix="devices/campus/building/ahu1",
callback=self.on_device_data
)
def on_device_data(self, peer, sender, bus, topic, headers, message):
data = message[0]
dat = data.get("DischargeAirTemperature")
if dat and dat > 65.0:
self._log.warning(f"High DAT: {dat} F")
Packaging and Installing
For modular VOLTTRON (version 10+), agents are packaged as standard Python packages with a pyproject.toml. You install them with pip install and register them with vctl install. For the monolithic platform (version 9.x and earlier), agents are packaged as wheel files and installed using the install-agent.py script or vctl install with a path to the agent directory.
Testing
VOLTTRON provides a test harness that spins up an isolated platform instance for unit and integration testing. The documentation strongly recommends writing automated tests before deploying agents to production. The test framework supports simulating device data on the message bus so you can validate agent logic without connecting to physical hardware.
Common Mistakes
- Running outside a virtual environment. Installing VOLTTRON at the system Python level creates dependency conflicts with other packages and can break system tools that rely on specific library versions. Always create a dedicated virtual environment before running
pip install. If your platform starts throwing import errors after an OS update, a missing or corrupted virtual environment is the most likely cause. - BACnet Proxy object ID colliding with a real device. The BACnet Proxy Agent creates a virtual BACnet device on the network. If its
object_idduplicates a physical device's instance number, both devices respond to WHO-IS requests for that ID and BACnet routing breaks down. Always check the site's device instance schedule and assign the proxy an ID in an unused range (e.g., 599 or above 90000). - Wrong device_address in the BACnet Proxy configuration. The
device_addressmust be the IP address of the local network interface connected to the BACnet network, not the IP address of a target device. Setting this to a remote device address causes the proxy to fail silently, and no BACnet traffic is sent or received. - Modbus register misalignment. Many Modbus devices store 32-bit floats across two consecutive 16-bit registers. If the registry CSV points to the wrong starting register, or specifies the wrong data type (uint16 instead of float), the Platform Driver reads corrupt data. Always cross-reference register addresses against the device manufacturer's register map documentation and verify byte order (big-endian versus little-endian).
- Not setting VOLTTRON_HOME before starting the platform. If
VOLTTRON_HOMEis not set, VOLTTRON defaults to~/.volttron. Running multiple platform instances on the same machine without uniqueVOLTTRON_HOMEpaths causes port conflicts and corrupted state files. Export the variable in your shell profile or systemd service file for each instance.
Platform Compatibility
| Platform | Support Level | Notes |
|---|---|---|
| Ubuntu 22.04 LTS | Full (tested) | Primary development and testing target for VOLTTRON 9.x and 10.x |
| Ubuntu 20.04 LTS | Full | Supported; may require manually installing Python 3.10 from a PPA |
| Debian 10 (Buster)+ | Full | Minimum Debian version for reliable dependency resolution |
| Raspberry Pi OS 10+ | Full | Runs on Raspberry Pi 3 and 4; ARM-compatible; minimum recommended version is Buster |
| RHEL / CentOS 8+ | Community | Not officially tested but reported working with manual dependency installation |
| macOS / Windows | Not supported | VOLTTRON requires Linux; use a VM or WSL2 on non-Linux hosts |
Python version: VOLTTRON 9.x and the modular Eclipse VOLTTRON require Python 3.10 or later (Python < 4.0). Earlier VOLTTRON versions (7.x, 8.x) support Python 3.6 through 3.8 but are no longer receiving feature updates.
Message bus dependency: ZeroMQ-based installations require libzmq (installed automatically via pip). RabbitMQ-based installations require a running RabbitMQ server (version 3.7+) and the Erlang runtime, which add approximately 200 MB of additional dependencies.
Source Attribution
This article draws from the following sources:
- VOLTTRON GitHub Repository (VOLTTRON/volttron) — source code, issue tracker, and legacy documentation for the monolithic platform
- Eclipse VOLTTRON GitHub Organization — modular platform repositories including volttron-core, volttron-lib-zmq, and driver agents
- VOLTTRON ReadTheDocs Documentation — official installation guides, agent development tutorials, and driver configuration references
- AutomatedBuildings.com: An Updated Overview of the Open Source VOLTTRON Platform — architecture overview and use-case analysis from ACE IoT Solutions
- Nexus Labs: Open-Source in Building Automation — industry perspective on VOLTTRON's role in smart building technology
- U.S. Department of Energy: VOLTTRON — program overview, funding history, and research publications
- volttron.org — official project website with developer resources and community links
Was this article helpful?
Related Articles
Need to do this remotely? SiteConduit provides Layer 2 access that preserves BACnet broadcasts — no BBMD needed for remote sessions. Join the waitlist.
SiteConduit Technical Team
Idea Networks Inc.
SiteConduit builds managed remote access for building automation. Our knowledge base is maintained by BAS professionals with hands-on experience deploying and troubleshooting BACnet, Niagara, Modbus, and Facility Explorer systems.