CLI tool for managing BACnet BBMD Broadcast Distribution Tables with audit logging and rollback
Project description
BBMD Manager
A CLI tool for managing BACnet BBMD (BACnet Broadcast Management Device) Broadcast Distribution Tables with full audit logging and rollback capability.
Features
- Network Discovery: Walk BBMD networks to discover topology
- BDT Management: Read and write Broadcast Distribution Table entries
- Link Operations: Add or delete links (unidirectional or bidirectional)
- Audit Logging: Full audit trail persisted to JSON
- Rollback: Snapshot-based rollback system to undo changes
- Safe Operations: Detailed change preview and confirmation before any mutation
- Async Architecture: Built on bacpypes3 with modern async/await patterns
Installation
# Install from PyPI
pip install ace-bbmd-manager
# Or install with uv
uv pip install ace-bbmd-manager
Development Installation
# Clone the repository
git clone https://github.com/ACE-IoT-Solutions/ace-bbmd-manager.git
cd ace-bbmd-manager
# Install with uv
uv sync
# Or install with pip in editable mode
pip install -e .
Quick Start
# Set your local IP address (the interface to use for BACnet communication)
export BBMD_LOCAL_ADDRESS=192.168.1.100
# Discover the BBMD network starting from a known BBMD
bbmd-manager walk 192.168.1.1
# View the discovered network
bbmd-manager status
# View all links
bbmd-manager links
Commands
Network Discovery
walk
Walk the BBMD network starting from one or more seed addresses. Discovers all reachable BBMDs by following BDT entries.
bbmd-manager -l 192.168.1.100 walk 192.168.1.1
bbmd-manager -l 192.168.1.100 walk 192.168.1.1 192.168.1.2 --depth 5
read
Read the BDT from a single BBMD.
bbmd-manager -l 192.168.1.100 read 192.168.1.1
Network Status
status
Show the cached network state with all BBMDs and their BDT entries.
bbmd-manager status
bbmd-manager status --format json
links
Display all links in the network, indicating which are bidirectional.
bbmd-manager links
Link Management
add-link
Add a link from one BBMD to another. Shows a detailed preview of changes before applying.
# Add unidirectional link: A -> B
bbmd-manager -l 192.168.1.100 add-link 192.168.1.1 192.168.1.2
# Add bidirectional link: A <-> B
bbmd-manager -l 192.168.1.100 add-link 192.168.1.1 192.168.1.2 --bidirectional
# Skip confirmation prompt
bbmd-manager -l 192.168.1.100 add-link 192.168.1.1 192.168.1.2 -b -y
delete-link
Delete a link between BBMDs. Shows a detailed preview of changes before applying.
# Delete unidirectional link: A -> B
bbmd-manager -l 192.168.1.100 delete-link 192.168.1.1 192.168.1.2
# Delete bidirectional link: A <-> B and B <-> A
bbmd-manager -l 192.168.1.100 delete-link 192.168.1.1 192.168.1.2 --bidirectional
delete-bbmd
Remove a BBMD from the network entirely. This removes it from all other BBMDs' BDTs and clears its own BDT.
bbmd-manager -l 192.168.1.100 delete-bbmd 192.168.1.3
Audit & Rollback
audit
View the audit log of all operations.
bbmd-manager audit
bbmd-manager audit --limit 50
bbmd-manager audit --action add_link
bbmd-manager audit --bbmd 192.168.1.1:47808
snapshots
List available snapshots for rollback.
bbmd-manager snapshots
bbmd-manager snapshots --limit 5
diff
Show differences between a snapshot and the current state.
bbmd-manager diff <snapshot-id>
rewind
Restore the network to a previous snapshot state.
# Preview what would change (dry run)
bbmd-manager rewind <snapshot-id> --dry-run
# Apply the rewind
bbmd-manager -l 192.168.1.100 rewind <snapshot-id>
Utility Commands
clear-state
Clear the cached network state (does not affect actual BBMDs).
bbmd-manager clear-state
clear-history
Clear audit log and/or snapshots.
bbmd-manager clear-history # Clear audit log only
bbmd-manager clear-history --all # Clear audit log and snapshots
Global Options
| Option | Environment Variable | Description |
|---|---|---|
-l, --local-address |
BBMD_LOCAL_ADDRESS |
Local IP address for BACnet communication |
-s, --state-file |
Path to state file (default: .bbmd_state.json) |
|
-a, --audit-file |
Path to audit log file (default: .bbmd_audit.json) |
|
--snapshot-file |
Path to snapshots file (default: .bbmd_snapshots.json) |
|
-v, --verbose |
Enable verbose output | |
-d, --debug |
Enable debug output for BACnet protocol |
Example Workflow
# 1. Discover the network
bbmd-manager -l 10.0.0.100 walk 10.0.0.1
# 2. View current topology
bbmd-manager status
bbmd-manager links
# 3. Add a new BBMD to the network (bidirectional links to existing BBMD)
bbmd-manager -l 10.0.0.100 add-link 10.0.0.1 10.0.0.99 --bidirectional
# Review the proposed changes, then confirm
# 4. Oops! Need to undo that change
bbmd-manager snapshots # Find the snapshot ID
bbmd-manager -l 10.0.0.100 rewind <snapshot-id>
# 5. Remove a BBMD from the network
bbmd-manager -l 10.0.0.100 delete-bbmd 10.0.0.50
# Review the proposed changes, then confirm
Change Preview
All mutation commands show a detailed preview before making changes:
============================================================
PROPOSED CHANGES
============================================================
BBMD: 192.168.1.1:47808
Action: Add entry -> 192.168.1.99:47808
Current BDT: 192.168.1.2, 192.168.1.3
New BDT: 192.168.1.2, 192.168.1.3, 192.168.1.99:47808
BBMD: 192.168.1.99:47808
Action: Add entry -> 192.168.1.1:47808
Current BDT: (empty)
New BDT: 192.168.1.1:47808
============================================================
Total BBMDs to modify: 2
============================================================
Proceed with these changes? [y/N]:
State Files
The tool maintains three JSON files for persistence:
| File | Description |
|---|---|
.bbmd_state.json |
Cached network topology |
.bbmd_audit.json |
Audit log of all operations |
.bbmd_snapshots.json |
Snapshots for rollback |
These files are created in the current working directory by default.
Development
# Install dev dependencies
uv sync
# Run tests
pytest tests/ -v
# Run with debug output
bbmd-manager -l 192.168.1.100 -d read 192.168.1.1
Docker
A container image is available on GitHub Container Registry, built on python:3.12-alpine with uv for fast startup.
Quick Start
# Pull the latest image
docker pull ghcr.io/ace-iot-solutions/ace-bbmd-manager:latest
# Or pull a specific version
docker pull ghcr.io/ace-iot-solutions/ace-bbmd-manager:0.3.4
Running Commands
# Run with host networking (required for BACnet UDP)
docker run --rm --network host \
-v $(pwd):/data \
ghcr.io/ace-iot-solutions/ace-bbmd-manager:latest \
-l 192.168.1.100 walk 192.168.1.1
# View status from cached state
docker run --rm -v $(pwd):/data \
ghcr.io/ace-iot-solutions/ace-bbmd-manager:latest status
# Add a bidirectional link
docker run --rm --network host \
-v $(pwd):/data \
ghcr.io/ace-iot-solutions/ace-bbmd-manager:latest \
-l 192.168.1.100 add-link 192.168.1.1 192.168.1.2 -b -y
Shell Alias
For convenience, add an alias to your shell configuration:
# Add to ~/.bashrc or ~/.zshrc
alias bbmd-manager='docker run --rm --network host -v $(pwd):/data ghcr.io/ace-iot-solutions/ace-bbmd-manager:latest'
# Then use normally
bbmd-manager -l 192.168.1.100 walk 192.168.1.1
bbmd-manager status
Networking Note
Host networking (--network host) is typically required for BACnet communication since it uses UDP port 47808 for broadcast messages. The -v $(pwd):/data mount persists state files (.bbmd_state.json, .bbmd_audit.json, .bbmd_snapshots.json) to your current directory.
Requirements
- Python 3.8+
- bacpypes3 (BACnet protocol library)
- click (CLI framework)
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ace_bbmd_manager-0.3.4.tar.gz.
File metadata
- Download URL: ace_bbmd_manager-0.3.4.tar.gz
- Upload date:
- Size: 1.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b21aeaed5e56f0db946abc4070f0c5e8ebd72d8db98c61f8505c7c8f0c8c9bf
|
|
| MD5 |
b4502789cdfcbcb242412a4978e85a5f
|
|
| BLAKE2b-256 |
ba6ea16630efae8f70202422776e0a8ae323a9bc75be9411a474f9a9b5d68770
|
Provenance
The following attestation bundles were made for ace_bbmd_manager-0.3.4.tar.gz:
Publisher:
publish.yml on ACE-IoT-Solutions/ace-bbmd-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ace_bbmd_manager-0.3.4.tar.gz -
Subject digest:
1b21aeaed5e56f0db946abc4070f0c5e8ebd72d8db98c61f8505c7c8f0c8c9bf - Sigstore transparency entry: 757575418
- Sigstore integration time:
-
Permalink:
ACE-IoT-Solutions/ace-bbmd-manager@cb59878b1da050982735e3bab5e3547c993da24b -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/ACE-IoT-Solutions
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cb59878b1da050982735e3bab5e3547c993da24b -
Trigger Event:
push
-
Statement type:
File details
Details for the file ace_bbmd_manager-0.3.4-py3-none-any.whl.
File metadata
- Download URL: ace_bbmd_manager-0.3.4-py3-none-any.whl
- Upload date:
- Size: 18.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97e20eca0d6cdacaa69716ce21e08749af71fdef5a752950f0b4ed193c43be5e
|
|
| MD5 |
10ca07d8a7877d222a1e5a755924be64
|
|
| BLAKE2b-256 |
269feffb7d31290797e25ef3ecafc7e781bc9700b2c78a3a22abe722ab06aac5
|
Provenance
The following attestation bundles were made for ace_bbmd_manager-0.3.4-py3-none-any.whl:
Publisher:
publish.yml on ACE-IoT-Solutions/ace-bbmd-manager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ace_bbmd_manager-0.3.4-py3-none-any.whl -
Subject digest:
97e20eca0d6cdacaa69716ce21e08749af71fdef5a752950f0b4ed193c43be5e - Sigstore transparency entry: 757575424
- Sigstore integration time:
-
Permalink:
ACE-IoT-Solutions/ace-bbmd-manager@cb59878b1da050982735e3bab5e3547c993da24b -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/ACE-IoT-Solutions
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@cb59878b1da050982735e3bab5e3547c993da24b -
Trigger Event:
push
-
Statement type: