I Built a BACnet Chiller Plant Simulator


A chiller plant overlaid with a network topology

While working on a security audit for a building management system, chillers, pumps, and cooling towers all running on BACnet, I ran into a practical problem: testing anything needs a device to talk to, and a live plant isn’t something you can safely poke at. Vendor simulators are tied to their own ecosystems, and the open examples only model a single room. I needed a full plant, so I built one and released it as open source.

BACnet in 30 Seconds

BACnet (Building Automation and Control Network) is the language most commercial buildings speak: HVAC, chillers, lighting, access control. It was first published as ANSI/ASHRAE Standard 135 in 1995 and became an ISO standard (ISO 16484-5) in 2004. Every device exposes objects, and each object has properties. A sensor is an Analog Input with a presentValue. A setpoint is an Analog Value you can write to. Devices announce themselves with a Who-Is broadcast, and you read or change values with ReadProperty and WriteProperty.

That’s the whole model. Objects, properties, and a few services to read, write, and discover.

Why It Isn’t Secure

Classic BACnet, the version in the overwhelming majority of buildings, has no real security:

  • No authentication. Devices don’t check who is asking. Reach the network and you can enumerate everything on it.
  • No encryption. Traffic is plaintext. Anyone on the wire reads every setpoint and sensor value.
  • Trusted writes. WriteProperty needs no credentials. If a point is writable, whoever reaches it can change it.
  • Broadcast discovery. One Who-Is maps the whole network. Recon is a single packet.

These are not just theoretical: CISA ICS advisories on building-automation products regularly cite cleartext transmission and unauthenticated BACnet traffic as the underlying weakness, pointing to BACnet Secure Connect as the fix (example advisory). BACnet/SC, added in the 2020 edition of the standard, wraps communication in TLS and certificates, but it’s barely deployed. Buildings last decades and nobody rips out a working control system, so the reality stays flat and open. Soft target for an attacker, under-examined domain for defenders.

The Simulator

Mine stands up a BACnet/IP device with the full point map of a chiller plant: supply and return water temps, flow rate, plant power and efficiency, individual chillers with load and COP, pumps, cooling towers, and the aggregate metrics a dashboard pulls. A physics loop drives the values so they move like a real plant across a day instead of sitting frozen. It answers Who-Is, serves ReadProperty, and accepts WriteProperty.

It’s built on BAC0 (on top of bacpypes), so the plant is plain data: points with names, units, and starting values, and a loop nudges them over time.

One command brings a plant online:

python chiller_simulator.py -a 192.168.10.11/24 -p 47808 -id 101

Point a scanner at it and it looks like a building.

Multiple Plants on One VM

Testing against one device only goes so far. For a small campus of plants, give a single VM multiple network cards and bind one simulator to each. Different NIC, different subnet, different device ID, so from the network they look like separate buildings.

Multiple simulated plants on one VM, each bound to its own network card

  1. Add adapters to the VM. Two or three, coming up as eth0, eth1, eth2 on a Linux guest.
  2. Assign an address per NIC, e.g. 192.168.10.11/24, 192.168.20.11/24, 192.168.30.11/24.
  3. Launch one simulator per NIC with a unique device ID:
python chiller_simulator.py -a 192.168.10.11/24 -id 101 &
python chiller_simulator.py -a 192.168.20.11/24 -id 102 &
python chiller_simulator.py -a 192.168.30.11/24 -id 103 &

A discovery scan now sees three distinct plants, each with a full point set, each on its own network. A building automation lab on a laptop, for nothing.

Get It

git clone https://github.com/prashsiv-eng/bacnet-chiller-simulator.git
cd bacnet-chiller-simulator
pip install -r requirements.txt
python chiller_simulator.py -a 127.0.0.1/24

If you work in OT or ICS security, or you’re just curious how the building around you runs, it’s a low-stakes way to get hands on the protocol. Break it, script against it, extend the plant model.

Learn More