
專案設計目的:在這個專案中,我擴展了基於 Python 的虛擬遠端終端單元模擬器系統(該系統透過Modbus-TCP、Siemens-S7Comm、IEC 60870-5-104 和IEC 62541 OPC-UA-TCP 連接到 Lvl3-OT SCADA 系統),增加了對 ISO 16484-5 BACnet(樓宇自動化和控制網路)協定的支援。在本文中,我還將展示 RTU 函式庫框架的詳細用法,以模擬一個自動化的 HVAC 控制系統。
在這個專案中開發的增強型虛擬 RTU 模擬器,專注於模擬 BACnet 裝置和控制器的核心行為,包括資料擷取、數值交換、處理和根據 ISO 16484-5 規範進行的自動控制,這有助於在網路範圍內構建 OT 元件。這個專案提供了三個關鍵功能:
-
BACnet 通訊模組 – 一個 Python BACnet 通訊層(伺服器和客戶端),支援感測器、控制器、RTU、BACnet 閘道和 SCADA/HMI 系統之間的互動,從而實現類比和離散 BACnet 資料交換。
-
RTU 模擬器框架 – 一個虛擬建築系統遠端控制器框架,用於模擬 HVAC、照明和安全系統等物理元件,支援基於預定義邏輯規則的監控和自動控制。
-
資料處理和控制模組 – 一個外掛 Python 模組,用於 BACnet 資料儲存、處理和控制訊號產生,與 RTU 模擬器框架整合以執行控制策略。
# Author: Yuancheng Liu
# Created: 2026/01/08
# Version: v_0.0.1
# Copyright: Copyright (c) 2026 Liu Yuancheng
# License: MIT License
1. 簡介
BACnet(樓宇自動化和控制網路)是在 ANSI/ASHRAE 135 和 ISO 16484-5 中定義的開放通訊協定。它廣泛用於樓宇自動化,以整合 HVAC、照明、能源管理、安全和門禁控制等系統。透過提供通用的通訊語言,BACnet 使不同製造商的裝置能夠無縫協同工作。
Python ISO 16484-5 BACnet 模擬器旨在 OT 網路雙生/範圍環境中構建虛擬樓宇自動化元件,例如 HVAC、照明、安全和環境監控系統。它既是學習平台,也是基於 BACnet 的樓宇自動化應用程式的測試平台,使用戶無需實際的樓宇自動化硬體即可探索協定行為。
RTU 模擬器並非試圖 1:1 模擬真實 BACnet 裝置的每個功能。相反,它側重於 BACnet 遠端控制器的基本操作行為,包括:
-
BACnet 變數/物件儲存模型
-
資料交換和互動模式
-
週期性控制邏輯執行和決策
1.1 系統架構簡介
該模擬器允許使用者構建反映真實 OT 系統中常見的三層結構的網路雙生架構。在這個虛擬環境中,使用者可以在 BACnet 匯流排上,對支援 BACnet 的現場控制器、RTU、I/O 伺服器和樓宇管理 SCADA/HMI 客戶端進行原型設計。如下面的系統結構圖所示:

該平台支援跨 OT 層的互動,從:
-
第 0 層 – 物理世界裝置和感測器,例如 HVAC 溫度感測器、安全門鎖、照明移動感測器。
-
第 1 層 – OT 現場控制器和 RTU,例如 HVAC 自動控制器、照明控制器。
-
第 2 層 – 管理室/處理 LAN 環境,例如建築物監視站。
此專案中的通訊功能是使用 Python 函式庫 BACpypes 實現的,該函式庫提供符合 ISO 16484-5 BACnet 標準的軟體堆疊。模擬器中的 BACnet 節點通訊拓撲支援主機-連接器和發布-訂閱互動模型,具體取決於配置:
-
較低層級的 OT 元件(RTU、現場控制器)透過嵌入式 BACnet 伺服器/發布者模組公開製程資料。
-
較高層級的元件(HMI、SCADA、歷史記錄器、資料庫伺服器)使用 BACnet 客戶端/訂閱者模組來瀏覽、讀取、寫入和訂閱公開的資料。
透過對這些核心方面進行建模,該模擬器為以下領域的教育、原型設計和實驗提供了一個有效的環境:
-
樓宇和工業自動化領域的學術研究
-
學習 OT 通訊協定和 BACnet 裝置行為的學生
-
設計或驗證支援 BACnet 的系統的開發人員
-
分析協定流量和系統互動的 OT 網路安全專業人員
2. BACnet 背景知識
BACnet 是一種開放通訊協定,標準化為 ANSI/ASHRAE 135 和 ISO 16484-5。它專為樓宇自動化和控制系統而設計,可實現來自不同製造商的裝置之間的互通性,包括:HVAC 控制器、照明和能源管理系統、門禁控制和安全系統、環境監控裝置以及樓宇管理平台和 SCADA 系統。這些 BACnet 裝置將其功能和資料公開為標準化的 BACnet 物件(例如類比輸入或二進位輸出),從而為跨異質系統的監控和控制提供通用語義。
BACnet 支援多個傳輸層,包括:
-
BACnet/IP(透過 IP 網路的 UDP)
-
BACnet MS/TP(RS-485 串列匯流排)
-
BACnet 乙太網路
-
BACnet over LonTalk
-
BACnet over ARCNET
在這個專案中,模擬器側重於 BACnet/IP,它是現代樓宇自動化網路中最廣泛部署的選項。BACnet 訊息封裝在 UDP/IP 封包中,並透過乙太網路傳送。預設情況下,該協定使用 UDP 連接埠 47808 (0xBAC0)。
2.1 BACnet/IP 協定封包結構
BACnet/IP 使用 UDP 協定進行資料傳輸,典型的 BACnet/IP 訊框可以概念性地分為以下幾個部分,如下所示:

-
UDP/IP 標頭:標準網路層和傳輸層定址。
-
BACnet 虛擬連結控制 (BVLC):識別 BACnet/IP 訊息並處理廣播和轉發。
-
網路協定資料單元 (NPDU):執行 BACnet 網路層路由,包含
版本、控制旗標、目的地/來源網路資訊、躍點計數和網路訊息類型。 -
應用程式協定資料單元 (APDU):編碼應用程式層服務,包括
PDU 類型、調用 ID、服務選擇和服務參數。
2.4 BACnet 資料結構和物件模型
BACnet 以具有屬性的標準化物件組織資料。每個 BACnet 物件代表裝置內的功能元素。ISO 16484-5 中定義的典型物件類型包括:類比輸入、類比輸出、類比值、二進位輸入、二進位輸出、二進位值、多狀態輸入/輸出/值、裝置、排程、日曆、趨勢日誌和事件註冊。
每個物件在裝置內都有唯一的 物件識別碼 (Object ID) 和 物件名稱。每個 BACnet 物件都包含一組 屬性。範例包括(一些是強制性的,一些是可選的):
-
Present_Value:物件的目前物理或邏輯值
-
Description:人類可讀的文字
-
Status_Flags:警報中、故障、已覆寫、停止服務
-
Units:工程單位(°C、%、Pa 等)
-
Event_State 和警報限制:用於警報處理
BACnet 物件的範例:
{
"objectName": "Temperature",
"objectIdentifier": ("analogValue", 1),
"presentValue": 22.5,
"description": "Room Temperature",
"units": "degreesCelsius"
},
屬性透過 ReadProperty 或 WriteProperty 服務存取,ReadProperty 和 WriteProperty 請求如下所示:

3. 虛擬 RTU 的設計
本節介紹基於 Python 的虛擬樓宇控制器 (RTU) 的設計,以中央樓宇 HVAC 自動化系統作為代表性範例。目的是展示軟體定義的 HVAC 控制器 RTU 如何監控模擬的物理裝置、處理 I/O 訊號、執行控制邏輯,以及透過 ISO 16484-5 BACnet 協定與第 0 層現場裝置和第 2 層 SCADA/HMI 應用程式無縫整合。
如下面的系統工作流程圖所示,虛擬 RTU 架構分為三個主要 OT 層:

-
第 0 層 – OT 物理現場 I/O 裝置:模擬的 HVAC 元件和感測器,代表物理環境。
-
第 1 層 – OT 控制器裝置:虛擬 HVAC RTU,負責通訊、資料處理和控制邏輯。
-
第 2 層 – OT 控制台/HMI:基於 BACnet 的牆壁恆溫器、樓宇管理儀表板和監控應用程式。
架構的中心 – 第 1 層 OT 控制器裝置 – 代表虛擬 HVAC 中心控制器 (RTU)。此 RTU 模擬由四個緊密耦合的功能模組組成:通訊模組、BACnet 資料結構模組和RTU 自動控制邏輯模組。
3.1 通訊模組
通訊模組充當虛擬 RTU 與周圍 OT 生態系統之間的外部介面。它支援與第 0 層現場裝置和第 2 層監控系統的雙向資料交換,如架構圖的橙色部分所示。
3.2.1 基於 UDP 的模擬電氣訊號 I/O
使用基於 UDP 的資料交換來模擬 HVAC 系統中常用的電氣和現場匯流排連接(例如 RS-232、RS-485、CAN 匯流排或離散電氣訊號)。
-
RTU 輸入(UDP 輸入):模擬的 HVAC 感測器 – 包括室溫、室內濕度和系統運作狀態 – 定期產生測量資料,並透過 UDP 封包將其傳輸到 RTU。
-
RTU 輸出(UDP 輸出):RTU 將控制命令傳送到模擬的致動器,例如
壓縮機、風扇、加熱器、冷卻泵和電源單元。
3.2.2 BACnet (BAC01) 通訊堆疊
在模擬的電氣 I/O 之上,RTU 嵌入了 BACnet/IP 通訊堆疊,該堆疊使用 Python BACpypes 函式庫來瀏覽 RTU BACnet 物件、讀取感測器和狀態值、寫入控制設定點。主要特性包括:
-
RTU 內部的嵌入式 BACnet 伺服器將內部 I/O 變數公開到 BACnet 匯流排。
-
第 2 層元件,例如牆壁安裝的 HVAC 恆溫器控制器、樓宇管理儀表板和具有 BACnet 客戶端的資料歷史記錄器。
-
外部建築裝置(例如,人員偵測或移動雷達感測器)也可以透過 BACnet 發布或交換資料。
3.2 BACnet 資料結構模組
BACnet 資料結構模組(由圖中的深綠色部分表示)定義了如何將 RTU 內部變數對應到標準化的 BACnet 物件和屬性。
3.3.1 唯讀 BACnet 物件(輸入建模)
感測器讀數和物理輸入狀態公開為唯讀 BACnet 物件:
-
BACnet 輸入物件 [R]:表示離散或電氣訊號狀態(例如,開啟/關閉、故障狀態)。 -
BACnet 類比物件 [R]:表示連續感測器值,例如溫度、濕度和電壓...
HMI 或恆溫器控制器將傳送 BACnet ReadProperty 請求,以從 HVAC RTU 擷取資料。
3.3.2 可寫入 BACnet 物件(控制建模)
控制命令和運作狀態使用可寫入 BACnet 物件建模:
-
BACnet 類比物件 [W]:用於控制設定點、閾值和運作參數。 -
BACnet 輸出物件 [W]:用於表示傳送到 HVAC 元件的致動器狀態和控制訊號。
可寫入物件的屬性 Present_Value 可以透過 BACnet 資料集 WriteProperty 函數變更。
3.3 RTU 自動控制邏輯模組
RTU 自動控制邏輯模組是一個基於 Python 的執行引擎,用於實現虛擬 HVAC 系統的閉迴路控制行為。控制週期如下運作:
-
從以下位置擷取輸入資料:
BACnet 輸入物件 [R]、BACnet 類比物件 [R]和BACnet 類比物件 [W]。 -
執行預定義的控制邏輯規則。
-
透過將結果寫入
BACnet 輸出物件 [W]來更新致動器狀態。
以下是冷卻房間的控制情境範例:

HVAC RTU 模組從恆溫器讀取室溫、HVAC 模式(冷卻/加熱)和目標設定點。如果系統處於冷卻模式且室溫超過設定點,則壓縮機和冷卻泵將啟動。冷卻過程將持續到達到目標溫度。當室溫達到目標溫度時,如果人員偵測雷達報告房間內沒有人,則壓縮機將轉換為閒置模式,並且電源單元將切換到節能狀態。
4. 使用案例和使用範例
本節提供了一個實用的演練,用於使用專案中包含的 Python 模組構建和執行簡化的基於 BACnet 的虛擬 RTU 模擬器。該範例展示了 BACnet 裝置、RTU 和控制器如何在模擬的樓宇自動化環境中互動,並以中央 HVAC 系統作為代表性使用案例。
4.1 專案模組概述
以下 Python 模組構成了 BACnet RTU 模擬器的基準實作:
| 程式檔案 | 執行環境 | 描述 |
|---|---|---|
src/BACnetComm.py |
Python 3.7.8 + | 實作 ISO 16484-5 BACnet 客戶端和伺服器 API 的核心函式庫。它提供 BACnet 物件管理以及 RTU 和 SCADA/HMI 系統之間的資料/命令交換。 |
src/BACnetCommTest.py |
Python 3.7.8 + | BACnetComm.py 的測試案例程式。它在子執行緒中啟動 BACnet 伺服器,並初始化客戶端以驗證資料讀/寫操作和自動控制邏輯執行。 |
testcase /bacnetRtuClientTest.py |
Python 3.7.8 + | 模擬 SCADA 或監控控制器連接到 RTU 的 BACnet 客戶端程式範例。 |
testcase /bacnetRtuServerTest.py |
Python 3.7.8 + | 模擬 BACnet RTU 裝置的 BACnet 伺服器程式範例。 |
testcase/HvacMachineSimulator.py |
Python 3.7.8 + | 代表物理元件模擬器與支援 BACnet 的 RTU 結合的中央 HVAC 機器模擬器。 |
testcase/HvacControllerSimulator.py |
Python 3.7.8 + | 具有圖形 UI 的牆壁安裝 HVAC 恆溫器控制器模擬器。 |
若要建構一個簡單的 RTU 和控制器系統,您可以參考儲存庫中提供的範例測試案例:https://github.com/LiuYuancheng/PLC_and_RTU_Simulator/tree/main/BACnet_PLC_Simulator/testCase
4.2 使用範例:HVAC 系統模擬
在這個 HVAC 使用案例範例中,一個中央 HVAC RTU 在自動控制模式下運作,而一個或多個恆溫器遠端控制器透過 BACnet 連接到它,以監控感測器資料並發出控制命令。
4.2.1 HVAC 機器模擬器 (虛擬 RTU)
對於 HVAC 機器模擬器模組:https://github.com/LiuYuancheng/PLC_and_RTU_Simulator/blob/main/BACnet_PLC_Simulator/testCase/hvacMachineSimulator.py,代表一個 Level 1 OT 控制器,結合了部分 level0 物理元件,這些元件公開 BACnet 物件並執行內部 HVAC 控制邏輯。
感測器資料(例如房間濕度和溫度)被建模為唯讀 BACnet 類比值物件。這些物件在 initInternalParams() 函數中定義,如下例所示:
{
"objectName": "Sensor_Humidity",
"objectIdentifier": ("analogValue", PARM_ID4),
"presentValue": 45.0,
"description": "Room Humidity",
"units": "percent"
}...
控制參數和致動器狀態被建模為可寫入的 BACnet 物件,在 initControlParams() 函數中定義,如下例所示:
{
"objectName": "Control_Fan_Speed",
"objectIdentifier": ("analogValue", PARM_ID12),
"presentValue": 1, # range 0 - 10
"description": "Fan Speed",
"units": "level"
}...
BACnet 伺服器在一個子執行緒中運行,持續處理來自多個恆溫器控制器的請求。同時,主要的 HVAC 控制執行緒執行一個週期性的控制迴路,負責管理:壓縮機、加熱器、冷卻泵和風扇。以下是一個簡化的壓縮機控制邏輯範例:
elif power == 1:
print("Start cooling process.")
print("[*] Make sure heater is off")
self.server.setObjValue("Heater_Power", 0)
if sensorTemp > ctrlTemp:
print("[*] Sensor_Temperature > Control_Temperature, set compressor [power on]")
self.server.setObjValue("Compressor_Power", 2)
newSensorTemp = sensorTemp - 0.1 # update the room temp sensor value when cooling pump activated.
self.server.setObjValue("Sensor_Temperature", newSensorTemp)
else:
print("[*] Sensor_Temperature <= Control_Temperature, set compressor [idle]")
self.server.setObjValue("Compressor_Power", 1)
4.2.2 壁掛式 HVAC 恆溫器控制器
對於 HVAC 恆溫器遠端控制器模擬器模組:https://github.com/LiuYuancheng/PLC_and_RTU_Simulator/blob/main/BACnet_PLC_Simulator/testCase/hvacControllerSimulator.py。此模組代表一個 Level 2 OT 控制介面,提供一個圖形化 UI 用於監控和控制,如下所示:

每個恆溫器控制器啟動一個 BACnet 客戶端子執行緒,該執行緒定期連接到 HVAC RTU 以獲取感測器資料並發出控制命令。要連接到模擬的 HVAC 機器,請設定 HVAC IP 位址,並且恆溫器遠端控制器向 HVAC 註冊,如下所示:
DEV_ID = 123456
DEV_NAME = "HVAC_Thermostat_Controller_01"
HVAC_IP = '127.0.0.1'
啟動後,恆溫器嘗試註冊並與目標 HVAC RTU 通訊。建立連線後:
-
感測器值顯示在左側資訊面板中
-
使用者可以使用旋轉控制旋鈕調整溫度設定點
-
可以透過 UI 按鈕選擇 HVAC 運作模式和風扇速度
當使用者確認設定時,BACnet 客戶端會將相應的 WriteProperty 請求發送到 HVAC RTU,從而觸發立即控制邏輯執行。
5.結論與參考文獻
總之,這個專案成功地透過整合 ISO 16484-5 BACnet 協定來擴展基於 Python 的虛擬 RTU 模擬器,從而建立了一個多功能的平台,用於模擬建築 HVAC 自動化系統。透過實作 BACnet 通訊堆疊、模組化 RTU 框架和自動化控制邏輯,該模擬器為原型設計、測試和教育目的提供了一個功能性的網路雙生體。它展示了軟體定義控制器如何模擬真實 OT 環境的資料交換和控制行為,從而在安全、虛擬化的網路範圍內提供了一個學習 BACnet、開發建築自動化策略和進行網路安全研究的實用工具。
5.1 專案參考文獻
-
https://www.emqx.com/en/blog/bacnet-protocol-basic-concepts-structure-obejct-model-explained
-
https://www.majestic-ac.com/how-a-residential-hvac-system-works-a-homeowners-guide/
感謝您花時間查看文章詳細資訊,如果您有任何問題和建議或發現任何程式錯誤,請隨時給我留言。非常感謝您能提供一些意見並分享任何改進建議,以便我們能夠使我們的工作做得更好〜
last edit by LiuYuancheng ([email protected]) by 16/01/2026 if you have any problem, please send me a message.
No comment for this article.