Skip to content

jamesccupps/P2Scanner

Repository files navigation

P2 Scanner

Scanner and point-read library for field controllers over the P2 protocol. Runs as a CLI, a Tk GUI, or an importable Python library.

Single Python module, zero external dependencies, read-only by design.


Features

Discovery

  • Cold-site onboarding via BACnet recon + tiered dictionary probe
  • Passive multicast listener (no probes sent)
  • Passive TCP 5034 listener for live COV / virtual-point / routing events
  • Port-scan discovery on TCP 5033
  • Automatic firmware-dialect detection (legacy vs modern panels)

Point operations

  • Read by point name or slot number
  • Full-panel walk — every point on a controller, including panel-internal variables
  • FLN device enumeration
  • PPCL program source dump
  • 797 TEC application definitions bundled — state labels, units, and types
  • Comm-status detection — distinguishes live readings from stale cached data on offline devices
  • Structured error decoding (not silent Nones)

I/O

  • Table, CSV, and JSON output
  • Sniff or decode packet captures for automatic BLN-name learning
  • Per-host dialect cache avoids re-probing on reconnect

Files

File Description
p2_scanner.py CLI / library. Python 3.6+.
p2_gui.py, p2_gui_widgets.py, p2_gui_workers.py Tk GUI front-end
tecpoints.json Point definitions for 797 TEC applications
site.json Site-configuration template
PROTOCOL.md Wire-level protocol reference

Requirements

  • Python 3.6 or later
  • Network access to PXC controllers on TCP/5033
  • tshark on PATH (optional — only needed for live-sniff discovery)
  • L2 access to the BAS subnet (only needed for cold discovery)

No pip packages required for the scanner itself.


Quick start

Cold onboarding (no prior knowledge)

python p2_scanner.py --cold-discover --range 192.168.1.0/24 --save site.json

Known BLN name

python p2_scanner.py --discover --range 192.168.1.0/24 --network MYBLN --save site.json

Read a point

python p2_scanner.py --config site.json -n NODE1 -d DEVICE1 -p "ROOM TEMP"

Launch the GUI

python p2_gui.py

Command reference

Common commands shown below. Full flag list: python p2_scanner.py --help.

Discovery

# Default cold discovery (BACnet recon + dictionary probe)
python p2_scanner.py --cold-discover --range 192.168.1.0/24 --save site.json

# Conservative (2-second delay between probes — safe during production hours)
python p2_scanner.py --cold-discover --range 192.168.1.0/24 --cold-delay 2

# Passive multicast listen (no probes sent)
python p2_scanner.py --listen 60 --save site.json

# Learn BLN name from a packet capture
python p2_scanner.py --pcap capture.pcapng --save site.json

Reading

# All points on a device
python p2_scanner.py --config site.json -n NODE1 -d DEVICE1

# Specific point by name
python p2_scanner.py --config site.json -n NODE1 -d DEVICE1 -p "ROOM TEMP"

# Specific point by slot number (Desigo-style)
python p2_scanner.py --config site.json -n NODE1 -d DEVICE1 -p 4

# Full-panel walk — includes panel-internal / PPCL variables
python p2_scanner.py --config site.json -n NODE1 --walk-points

# Dump PPCL program source
python p2_scanner.py --config site.json -n NODE1 --dump-programs

# Panel firmware info
python p2_scanner.py --config site.json -n NODE1 --info

Output formats

python p2_scanner.py --config site.json -n NODE1 -d DEVICE1 -f csv > out.csv
python p2_scanner.py --config site.json -n NODE1 -d DEVICE1 -f json > out.json

IP range formats

10.0.0.50 · 10.0.0.0/24 · 10.0.0.80-200 · 10.0.0 (shorthand for .1-254) · comma-separated ranges.


Output

Each point read produces a result dictionary:

Field Description
point_name Point name
point_slot Subpoint slot number (1–99)
value Numeric value
value_text Label for digital points ("NIGHT", "COOL", etc.)
units Engineering units
point_type analog_ro / analog_rw / digital_ro / digital_rw
comm_status online or comm_fault
point_info Full metadata (state labels, units, scaling)

Table output shows Desigo-style (slot) NAME for each point. Digital points render as LABEL (raw). Comm-faulted points get a #COM suffix.

Exit codes

Code Meaning
0 Success
1 Scan ran but returned nothing (device offline, no readable points)
2 Input rejected before any network I/O

Config file

{
  "p2_network": "MYBLN",
  "p2_site": "SITE",
  "scanner_name": "P2SCAN|5034",
  "known_nodes": {
    "NODE1": "192.168.1.10",
    "NODE2": "192.168.1.11"
  }
}
  • p2_network — BLN network name. Required. PXCs reject messages with the wrong name.
  • scanner_name — Scanner identity. Some sites require a specific format; if handshakes fail, try <SITE>DCC-SVR|5034.
  • known_nodes — Node name → IP map.

Auto-updated by --save. Extra keys are preserved.


Programmatic use

import p2_scanner as p2

p2.P2_NETWORK = "MYBLN"
p2.SCANNER_NAME = "P2SCAN|5034"

conn = p2.P2Connection("192.168.1.50")
if conn.connect("NODE1"):
    result = conn.read_point("DEVICE1", "ROOM TEMP", "NODE1")
    print(result['value'], result.get('units'))
    conn.close()

Core API:

Function Purpose
P2Connection(host) Open TCP session
conn.connect(node_name) Handshake
conn.read_point(device, point, node) Read a single point
conn.enumerate_fln(node) List FLN devices
conn.read_firmware(node) Panel model / firmware
scan_device(host, device, ...) High-level device scan with rendering
get_point_info(app, point_name) Metadata lookup
render_point_value(value, info) Value → display string

The library is synchronous. For a GUI, run reads on a worker thread (see p2_gui_workers.py for reference).


Troubleshooting

Issue Fix
"P2 network name required" Provide --network or --config
"Handshake failed" Verify BLN / scanner / node names
Handshake takes 2+ seconds First connect to a modern-firmware panel; the dialect auto-probe is doing its thing. Cached on subsequent connects.
Listener hears nothing Site has multicast disabled — use --sniff or --cold-discover
"Max peer sessions reached" Try when other supervisor connections are idle
All device points show #COM FLN bus disconnected
Digital point shows raw float instead of label Read APPLICATION first — use -n NODE -d DEVICE so the scanner can auto-detect the app

Safety

  • Read-only. The scanner never writes points, changes setpoints, or modifies controller state. Write-capable opcodes are documented in PROTOCOL.md but intentionally not exposed.
  • PXCs have a limited number of peer sessions (typically 8–16). Don't run parallel scanners against the same panel.
  • Cold discovery sends dictionary probes. Observed as non-disruptive, but use --cold-delay 2 during production hours as a precaution.

See also

  • PROTOCOL.md — wire-level protocol reference. Every opcode, every format variant, every edge case. Read this if you're debugging unusual responses, implementing your own client, or just curious how a BAS protocol works on the wire.

About

P2 Protocol HVAC Scanner for Building Automation - CLI and GUI

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages