張世超


摘要:本文介紹矩陣通訊協議,詳解命令格式,提出使用基于Python的自動化軟件與X-PLUS矩陣交互通訊的方法并開發實現,達到減少操作時間,提高響應速度,降低運維成本,提高矩陣的功能性和易操作性的目的。
關鍵詞:Python;X-PLUS;Socket;廣播級矩陣
中圖分類號:TN919 文獻標識碼:A 文章編號:1007-9416(2020)03-0125-03
X-PLUS是大連捷成推出的多格式、全規模的廣播級矩陣產品.可在一個機箱完成多種格式信號的切換調度。可同時兼容大、中、小規模、并可靈活配置多種信號格式的全規模、多格式矩陣。該矩陣支持多格式混插,并具有電子切換和點對點旁通(BY-PASS)的雙切換模式[1]。矩陣功能強大,可控制最多128路信號,很多切換通道等功能要求24小時秒級操作,單靠人工無法實現,且上下位機之間可能距離遙遠。因此其與自動化系統遠程通訊交互十分必要。使用矩陣提供的大連捷成協議框架可以輕松實現。
1 通訊簡介
與矩陣通訊時,被控制的矩陣設備被看成服務端,與矩陣連接的自動化軟件被看成客戶端。通過TCP或者UDP協議,自動化軟件發送命令給矩陣,矩陣反饋命令執行結果,矩陣也可以發送報告給自動化軟件顯示自身狀態變化。
1.1 協議簡介
通訊協議框架使用大連捷成協議框架,主要分為起始、命令、數據、校驗碼和結束五部分標識符,協議第一個字節是SOH代表開始,第二個和第三個字節代表命令,中間n個字節是傳輸的數據,數據后面兩個字節是異或校驗碼,最后一個字節是EOT代表結束。
1.2 接口簡介
矩陣提供RJ45與RS232接口供外部自動化軟件控制使用。RJ45接口自適應10Mbps/100Mbps連接方式分為直連和通過集線器路由器等網絡設備連接,必須使用IPv4通過TCP或者UDP通訊,矩陣監聽外部發起的請求,端口號為8000。RS232配置波特率19200,起始位1,數據位8,奇偶校驗無。
1.3 命令詳解
命令主要分為上報命令和事務命令。上報命令是矩陣某些狀態發生改變,它主動上報外部自動化軟件。事務命令是外部自動化軟件想要改變矩陣某設置或者獲取某狀態而發送的。當自動化軟件發送命令請求給矩陣,矩陣會應答響應。
命令請求的格式如圖1所示,由于通訊過程中使用比特流,所以傳輸時數據可以看成是一串16進制數,起始標識符SOH就是0x01,結束標識符EOT就是0x04,完整的請求或者應答都是以這兩個標識符開始結束的,中間不再允許出現0x01或者0x04,為保證命令中間部分不出現起始和結束標識符,命令中間數據使用ASCII編碼轉義,當有數據是1的時候不會寫成0x01,而是通過ASCII碼轉換,變成字符1也就是16進制數0x31。
命令標識符說明要做什么,例如QS是查詢矩陣規模(16進制表示為0x51 0x53),AS是切換通道源(16進制表示為0x41 0x53),其他更多命令參見產品說明書。
對于不同的命令,其后面緊跟著的數據內容也不同,但是數據最長限制為1024字節,多余的字節會被拋棄。對于QS等命令,可能后面跟隨的數據是空的,因為只需要告訴矩陣反饋規模即可,不需要其他數據。
異或校驗碼BCC(Block Check Character),也叫信息組校驗碼,是保證數據傳輸過程中檢查完整性的重要依據,把從起始標識符之后到校驗碼之前的所有16進制數經行異或運算,最后得到的結果再通過ASCII轉換為兩個16進制數,這有些不太好理解,舉個例子:當需要向矩陣請求獲取其規模時,就需要發送QS命令,因為QS轉碼后數據是0x51 0x53,后面沒有其他數據,異或校驗碼就是 51XOR53=02,0轉換為0x30,2轉換為0x32,最后得到異或校驗碼就是0x30 0x32。
應答分兩種,一種格式跟命令請求一樣,另外一種特殊的應答只有一個字節,內容為一個感嘆號,表示立即執行。應答反饋最大超時時間為200ms,超過此時間被認為之前發送的命令沒有成功接收。
2 Python實現
在詳細了解通訊協議后就可以編寫軟件與矩陣通訊,這里選擇Python講解具體實現方法,因為Python簡單易學,讓人更加專注與矩陣通訊的方法,而非研究數據結構,降低學習門檻,幫助使用者快速上手。
2.1 Socket連接
Socket又叫套接字,它是計算機之間進行通信的一種約定或一種方式。通過它一臺計算機可以接收其他計算機的數據,也可以向其他計算機發送數據[2]。我們使用Python的Socket包實現代碼:
import socket
class TCPClient:
def __init__(self, host='192.168.1.2', port=8000, timeout=200):
self.HOST = host
self.PORT = port
self.BUFFSIZE = 1024
self.TIMEOUT = timeout
self.ADDRESS = (self.HOST, self.PORT)
self.tcpClientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.tcpClientSocket.connect(self.ADDRESS)
def send(self, msg):
……
def receive(self):
……
def main():
try:
client = TCPClient()
client.send('xxxx')
client.receive()
except Exception as e:
print(e)
這是最基礎的連接示例,首先導入Socket包,創建一個TCPClient類, host為要連接的矩陣IP地址,port為端口號,timeout是超時時間,buffsize是套接字緩存大小,socket.AF_INET表示使用IPv4, socket.SOCK_STREAM表示使用流式套接字。接著定義send函數與receive函數,分別表示發送和接收數據,最后在main中實例化TCPClient類的對象client,使用send和receive發送和接收數據。
2.2 封裝命令
send函數發送的數據是比特流,可以看成是一串以0x01開頭0x04結尾的16進制數,函數會自動在發送的msg數據前后加上起始結束標識符,同時也要計算異或校驗碼,再把校驗碼放再在結束標識符前面。所以只需要把請求的命令和數據標識符內容傳入send函數的參數msg里。
def send(self, msg):
msg = msg.encode('utf-8')
bbc = self.getBBC(msg)
bbc = bytes().fromhex(hex(ord(bbc[0]))[2:]) + bytes().fromhex(hex(ord(bbc[1]))[2:])
msg = bytes().fromhex('01') + msg + bbc + bytes().fromhex('04')
self.tcpClientSocket.send(msg)
send函數首先轉換utf-8字符,然后通過getBBC函數獲取msg這串數據的校驗碼,再把這串校驗碼從字符串轉換成比特流,跟隨開始結束標識符一起封裝。
def getBBC(self, checkData):
for index in range(len(checkData)):
if index == 0:
dataCheckSum = checkData[index]
else:
dataCheckSum = dataCheckSum ^ checkData[index]
dataCheckSum = hex(dataCheckSum)[2:]
if len(dataCheckSum) == 1:
return '0' + dataCheckSum
return dataCheckSum
getBBC函數根據傳入的checkData數據計算異或校驗碼,通過循環遍歷計算得到一個16進制數,如果是個位數就再前面加上0,因為校驗碼占用兩個字節,個位數只有一個字節,必須在前面加上0x30表示0,否則會被矩陣認為是不完整數據丟棄。
2.3 解析應答
矩陣收到命令請求會應答,receive函數就是用于監聽應答的函數。
def receive(self):
try:
while True:
msg = self.tcpClientSocket.recv(self.BUFFSIZE)
if not msg:
break
print("接收到服務器端消息:{}".format(msg))
if len(msg) == 1 and int(hex(ord(msg.decode('utf-8')))[2:]) == 21:
print('server立即應答' + msg.decode('utf-8'))
elif len(msg) < 6:
print('應答不完整或不可識別')
else:
first = msg[0]
command = (msg[1:3])
data = (msg[3:-3])
checkData = command + data
checkSum = str.lower(msg[-3:-1].decode('utf-8'))
last = msg[-1]
if self.isCheck(first, last, checkData, checkSum) is False:
print("數據不完整或者校驗失敗")
else:
……
break
except Exception as e:
print(e)
self.tcpClientSocket.close()
receive函數通過無限循環語句一直監聽接收的數據,如果收到的數據只有一個字節且內容為0x21,對應的是ASCII碼的感嘆號,說明矩陣已經立即執行之前發送的命令請求,如果既不是0x21又小于6個字節表示數據不完整,因為起始結束標識符占用2字節,命令占用2字節,校驗碼占用2字節,如果小于6字節說明數據不完整,當數據大于等于6字節獲取各個字段通過isCheck函數判斷是否正確。
def isCheck(self, first, last, checkData, checkSum):
if first != 1:
return False
if last != 4:
return False
dataCheckSum = self.getBBC(checkData)
if dataCheckSum == checkSum:
return True
else:
return False
isCheck函數判斷起始結束標識符是否正確,通過getBBC函數計算校驗碼與獲取的校驗碼對比是否一致,當對比結果一致的時候isCheck函數返回True,表示通過驗證,剩下的命令標識符字段和數據字段就是我們需要的數據。由于各個命令跟隨的數據結構及長度都不盡相同,全部詳細講解篇幅過大,下面舉簡單個例說明。
2.4 實例數據講解
如需要獲取矩陣規模,查詢說明得知獲取矩陣規模命令是QS,數據字段為空。所以可通過實例化類對象的send方法,即client.send('QS')。
使用Socket Tools工具模擬矩陣接收數據可以看到當實例化對象client.send('QS')發送QS查詢矩陣規模命令時,經過封裝發送出去的數據如圖2所示可看成是一串16進制的數,以0x01開頭0x04結尾,0x51 0x53通過ASCII轉碼為QS,0x30 0x32是0x51XOR0x53得出的結果02的轉碼結果。
當矩陣接收到QS命令會應答,通過Python軟件運行獲取軟件應答數據為b\0x01SQ00000A030B000000000000000000000000032\0x04,通過軟件解析保留命令和數據字段為SQ00000A030B外加后面一串0,通過查詢說明書可知SQ是反饋QS的命令,后面的A030B是矩陣規模數據,其余用0填滿保留字段長度,A表示音頻1層,0x03表示輸出端口有0到3四個輸出口,0x0B表示輸入端口有0到B十二個輸入口,所以矩陣規模為4x12。
如需要查詢上述矩陣音頻1層各端口狀態,獲取矩陣通道狀態命令是QD,后面跟隨數據占3各字節,前兩個字節是通道總數,為00表示查詢所有通道,第三個字節為層標示,這里只有一個音頻層,層標示為A,所以通過對象實例發送client.send('QD00A'),最終軟件獲取矩陣應答數據為b\0x01DQ04A0002NA0100LA0200LA0300L11\0x04,通過解析保留命令和數據字段為DQ04A0002NA0100LA0200LA0300L,通過查詢說明書可知DQ04為反饋有4個通道,A0002N表示A層1口輸出為1端口,輸入為3端口,狀態無鎖定。A0100L表示A層2口輸出為2端口,輸入為1端口,狀態鎖定。后面兩個口依此類推。
如需要切換1通道狀態為輸出口1,輸入口4,使用AS命令,數據依次為通道總數(只切換一個通道就為01)、層標示(音頻1層標示為A)、輸出通道(為00)、輸入通道(為03)、通道狀態(為T表示切換狀態)。當發送命令請求后軟件會收到矩陣應答數據0x21,表示切換命令已經立即執行。
3 結語
X-PLUS矩陣功能強大,它提供接口供外部自動化通訊控制,雖然通訊命令封裝解析繁瑣復雜,但是通過軟件實現自動封裝解析后各種命令變得簡單易用,原本人工手動需要數秒的操作通過自動化軟件能在1秒內完成,且7x24小時響應無差錯,節約維護成本,提高響應速度。在后期還可以用組合操作達成矩陣所不具備的功能,比如想實現通道輪巡功能可以讓軟件每隔幾秒自動切換輸入端口,想實現信號錯誤檢測可以讓軟件分析信號,發現問題自動轉換通道。由此可見,自動化系統與矩陣遠程通訊交互不僅節約資金,還能創造更多價值。
參考文獻
[1] X-PLUS多格式矩陣[J].世界廣播電視,2008,22(11):109.
[2] yongfutian.Socket技術詳解[EB/OL].https://www.jianshu.com/p/066d99da7cbd,2019-01-11/2020-02-10.
Abstract:This paper introduces the matrix communication protocol, explains the command format in detail, proposes the method of communication between x-plus matrix and automated software based on Python, and develops and realizes it, so as to reduce operation time, improve response speed, reduce operation and maintenance cost, and improve the functionality and operability of matrix.
Key words:Python;X-PLUS;Socket;broadcast matrix