張喜紅 王玉香
(亳州職業(yè)技術(shù)學(xué)院, 安徽 亳州 236800)
隨著計(jì)算機(jī)技術(shù)的發(fā)展,多媒體教室的應(yīng)用逐漸普及[1]。計(jì)算機(jī)、投影機(jī)是學(xué)校多媒體教室必備的基礎(chǔ)性硬件設(shè)備,這類設(shè)備大多使用壽命有限、配件價格較高。如,普通投影機(jī)燈泡的使用壽命僅4 000 h左右,激光投影機(jī)燈泡的使用壽命僅20 000 h左右,且使用時若操作不當(dāng)極易導(dǎo)致燈泡損壞[2]。在學(xué)校多媒體教室設(shè)備日常管理中,規(guī)范使用,按需開關(guān)機(jī),有助于延長設(shè)備使用壽命。目前,大多學(xué)校采用多媒體教室外配專屬中控設(shè)備的方式來實(shí)現(xiàn)統(tǒng)一管理。亳州職業(yè)技術(shù)學(xué)院即采用此種方式在實(shí)際使用當(dāng)中發(fā)現(xiàn)存在以下問題:中控設(shè)備的配置增加了建設(shè)成本;中控設(shè)備的接入增加了系統(tǒng)施工、布線的復(fù)雜程度;后期維修、維護(hù)相對困難。為了避免這些問題,我們基于Python語言重新設(shè)計(jì)了一套多媒體教室管理系統(tǒng)。Python語言具有模塊豐富、語法簡潔、跨平臺性能較好等優(yōu)勢[3],因此基于Python的系統(tǒng)穩(wěn)定性良好,使用成本不高。
多媒體教室管理系統(tǒng)的硬件由總控計(jì)算機(jī)、路由器、各教室計(jì)算機(jī)、投影機(jī)等組成(見圖1) 。教室的多媒體設(shè)備包括教室計(jì)算機(jī)和投影機(jī),各教室計(jì)算機(jī)支持網(wǎng)卡喚醒啟動,教室計(jì)算機(jī)與投影機(jī)之間通過RS232串行總線連接,教室計(jì)算機(jī)可通過串行總線向投影機(jī)發(fā)送控制指令,最終實(shí)現(xiàn)投影機(jī)的開啟與關(guān)閉。每臺教室計(jì)算機(jī)和總控計(jì)算機(jī)通過路由器連接,形成局域網(wǎng)。
圖1 多媒體教室管理系統(tǒng)硬件組成結(jié)構(gòu)
開始管理系統(tǒng)設(shè)計(jì)之前,首先需確定以下問題:(1) 采用什么方式控制各教室計(jì)算機(jī)的自動開啟和關(guān)閉;(2) 確定課表分析功能是由教室計(jì)算機(jī)實(shí)現(xiàn),還是由總控計(jì)算機(jī)實(shí)現(xiàn);(3) 如何控制投影機(jī)按需、按時完成開啟和關(guān)閉等操作。
現(xiàn)有管理方式是通過外配中控硬件來實(shí)現(xiàn)教室計(jì)算機(jī)的自動開啟和關(guān)閉等操作。對于教室計(jì)算機(jī),是通過斷電器聯(lián)接計(jì)算機(jī)電源開機(jī)觸發(fā)線實(shí)現(xiàn)計(jì)算機(jī)的開關(guān)機(jī)控制,長期使用對硬件的損傷較大。對于投影機(jī),是通過單片機(jī)模塊的串口通信實(shí)現(xiàn)控制,且大多采用無應(yīng)答檢查控制方式,可靠性低。因此,省去中控設(shè)備,并實(shí)現(xiàn)自動控制是系統(tǒng)改造的重點(diǎn)工作。
當(dāng)前各教室計(jì)算機(jī)支持網(wǎng)卡喚醒功能,因此,在不額外增加設(shè)備的情況下,各教室計(jì)算機(jī)的開機(jī)操作可通過網(wǎng)卡遠(yuǎn)程喚醒來實(shí)現(xiàn)。如果由總控計(jì)算機(jī)完成所有課表的分析,并有針對性地實(shí)時喚醒各教室計(jì)算機(jī),將導(dǎo)致總控計(jì)算機(jī)的運(yùn)算分析工作量過大。為了保證實(shí)時性,總控計(jì)算機(jī)應(yīng)滿足較高的硬件配置要求。為了控制改造成本,課表分析任務(wù)、投影機(jī)的開關(guān)機(jī)控制都由當(dāng)前各教室計(jì)算機(jī)來完成。
基于以上考慮,確定系統(tǒng)工作流程:
(1) 總控計(jì)算機(jī)依據(jù)當(dāng)前季度的作息時間,在每節(jié)課上課前5 min內(nèi)向全校多媒體教室發(fā)送網(wǎng)絡(luò)喚醒開機(jī)指令,開啟各多媒體教室計(jì)算機(jī)。
(2) 各多媒體教室計(jì)算機(jī)開機(jī)后,運(yùn)行程序,讀取并分析本地存放的本教室課表文件。若當(dāng)前未安排課程,則執(zhí)行計(jì)算機(jī)的關(guān)機(jī)指令,立即關(guān)閉本教室計(jì)算機(jī)。
(3) 若當(dāng)前時段安排有課程,則通過串口開啟投影機(jī),并以一定的時間間隔周期性檢查是否已到下課時間。若下課時間到,就先通過串口向投影機(jī)發(fā)送關(guān)機(jī)指令,關(guān)閉投影機(jī),然后執(zhí)行計(jì)算機(jī)關(guān)機(jī)指令,立即關(guān)閉本教室計(jì)算機(jī)。
總控計(jì)算機(jī)的主要任務(wù)是依據(jù)當(dāng)前季度的作息時間,在每節(jié)課前通過網(wǎng)絡(luò)喚醒技術(shù)提前啟動多媒體教室計(jì)算機(jī)。實(shí)現(xiàn)這一功能,應(yīng)首先確定開機(jī)時間節(jié)點(diǎn)的獲取方式,然后完成網(wǎng)絡(luò)喚醒功能的程序設(shè)計(jì)。開機(jī)時間節(jié)點(diǎn)通過讀取Excel文件得到,以適應(yīng)上課時間的變化。首先,將各節(jié)次上課時間與提前開機(jī)時間設(shè)置值按圖2所示格式存放于Excel文件中,待總控端程序啟動后,通過Python語言中xlrd模塊的相應(yīng)函數(shù)將Excel 文件中的開機(jī)時間列表文件讀入;接著,程序駐留于后臺保持運(yùn)行,其間按照一定的時間間隔,通過Python語言中time模塊的time.localtime()方法,周期性提取系統(tǒng)時間,并與從Excel文件中讀入的時間安排進(jìn)行比對,若相符即可通過網(wǎng)絡(luò)喚醒技術(shù)遠(yuǎn)程啟動多媒體教室計(jì)算機(jī)。通過Python語言中xlrd模塊讀取圖2所示Excel文件,以獲取上課時間節(jié)點(diǎn)。
圖2 上課時間安排
函數(shù)代碼如下:
def Read_Class_time(class_path):#讀取本季度各節(jié)的上課時間
# class_path為表格文件的存放路徑
data=xlrd.open_workbook(class_path)
table=data.sheets()[0]#讀取表格文件的Sheet1表
# 獲取Sheet1表的第2列數(shù)據(jù),得到開機(jī)時間節(jié)點(diǎn)數(shù)據(jù)
Class_time=table.col_values(1)
# 獲取Sheet1表的第3列的第1個數(shù)據(jù),得到提前開機(jī)時間值
Difference_time =table.col(2)[0].value
# 計(jì)算開機(jī)時間,并把開機(jī)時間轉(zhuǎn)化為以“時”為單位的時間列表
value_list = []
for t in range(0,10):
h=int(24*3600*Class_time[t]/3600)#時
m=int(24*3600*Class_time[t]%3600/60)#分
#以“時”為單位整合時間列表,便于與系統(tǒng)時間比較
value=h+m/60.0-Difference_time/60.0
value_list.append(value)
return value_list #返回開機(jī)時間列表
通過Python語言time模塊獲取總控計(jì)算機(jī)系統(tǒng)時間,其函數(shù)代碼如下:
def get_current_time():#獲取當(dāng)前電腦時間
current_time=list(time.localtime())#獲取總控計(jì)算機(jī)系統(tǒng)時間
hour=current_time[3]#提取“時”
minute=current_time[4]#提取“分”
value=hour+minute/60.0#統(tǒng)一變換為以“時”為單位的數(shù)據(jù),以便后續(xù)比較
return value
網(wǎng)絡(luò)喚醒啟動,是由總機(jī)通過網(wǎng)絡(luò)對各分機(jī)傳送規(guī)定內(nèi)容的編碼包來實(shí)現(xiàn),編碼包用16進(jìn)制格式表示為:“FF FF FF FF FF FF +16次目標(biāo)機(jī)MAC地址”。同時,網(wǎng)絡(luò)喚醒具有明顯的廣播特征,通常采用UDP協(xié)議來實(shí)現(xiàn)[4-5]。通過Python提供的socket模塊,簡單配置參數(shù)后便可實(shí)現(xiàn)UDP網(wǎng)絡(luò)通信[6]。采用Python設(shè)計(jì)網(wǎng)絡(luò)喚醒功能,其函數(shù)代碼如下:
import socket#導(dǎo)入模塊
import binascii
#ip參數(shù)為主機(jī)IP地址,PORT為通信端口號,MAC_List為各目標(biāo)機(jī)MAC地址列表
def UDP_Broadcast_Tx(IP,POTR,MAC_List):
#初始化“套接字”為UDP連接
my_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
my_socket.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)
#廣播各目標(biāo)機(jī)喚醒數(shù)據(jù)包
for i in mac:
#構(gòu)造各目標(biāo)機(jī)的開機(jī)魔術(shù)數(shù)據(jù)包
data=binascii.unhexlify(′FF′ * 6 + i * 16)
#發(fā)送數(shù)據(jù)包
my_socket.sendto(data,(ip,port))
my_socket.close()#關(guān)閉網(wǎng)絡(luò)連接
教室計(jì)算機(jī)程序的功能是,依據(jù)本教室的課表按時開關(guān)投影機(jī)。具體的實(shí)現(xiàn)過程如下:
(1) 將本教室的課表按圖3所示模板來設(shè)計(jì),存放于教室計(jì)算機(jī)本地磁盤中。
辛迪·舍曼(Cindy Sherman)、杰夫·昆斯(Jeff Koons)和托恩·霍克斯(Teun Hocks)親自步入鏡頭前;霍埃爾-彼得·威特金(Joel-Peter Witkin)和喬·甘茨(Joe Gantz)則創(chuàng)造出不時使人震驚的敘述體場景。阿瑟·特雷斯(Arthur Tress)和戴維·萊維索爾(David Levinthal)長于縮微場景;卡魯姆·科爾萬(Calum Colvin)和維克托·施勒格(Victor Schrager)則擅長靜物攝影。
(2) 教室計(jì)算機(jī)被喚醒啟動后,自動啟動教室計(jì)算機(jī)端的程序,通過Python的datetime模塊,首先獲取系統(tǒng)的當(dāng)前日期與時間,并提取分解出當(dāng)前周次與時間。
(3) 通過xlrd模塊的相關(guān)函數(shù),讀取課表文件中的節(jié)次時間安排,并與當(dāng)前時間作比對,得到當(dāng)前時間對應(yīng)節(jié)次。
(4) 以周次與節(jié)次為行、列索引讀取課表信息。若當(dāng)前單元格為空,則將課程標(biāo)記變量置為‘0’,代表無課,于是執(zhí)行關(guān)閉計(jì)算機(jī)指令;若當(dāng)前單元格不為空,則將課程標(biāo)記置為‘1’,代表有課,于是執(zhí)行開啟投影機(jī)指令。
(5) 程序在后臺駐留,并以一定的時間間隔周期性地比較系統(tǒng)時間與課表文件中的下課時間。若下課時間到,則依次執(zhí)行關(guān)閉投影機(jī)和關(guān)閉計(jì)算機(jī)的指令。其中,計(jì)算機(jī)的關(guān)機(jī)操作通過os模塊的os.system(“shutdown -s -t 0”)方法實(shí)現(xiàn)。
圖3 教室課表模板
鑒于原有教室計(jì)算機(jī)與投影機(jī)已布設(shè)有串行連接線,本次設(shè)計(jì)中教室計(jì)算機(jī)對投影機(jī)的控制將通過RS232串行總線來實(shí)現(xiàn)。通常,投影機(jī)在出廠時標(biāo)配RS232串口,并提供串口控制指令碼及參數(shù)表。如日電NP-CR3125X投影機(jī)的通信波特率為38 400,串行口開、關(guān)機(jī)指令碼分別是02-00-00-00-00-02、02-01-00-00-00-03,且控制成功后會返回應(yīng)答碼,開、關(guān)機(jī)的應(yīng)答碼分別是22-00-01-20-00-43、22-01-01-20-00-44。
Python語言中實(shí)現(xiàn)串口控制的模塊是serial模塊。應(yīng)用serial模塊設(shè)計(jì)串口控制程序,主要內(nèi)容包括串口的初始化和串口的發(fā)送與接收。
(1) 串口的初始化。串口的初始化內(nèi)容主要包括端口號及波特率、位長、停止位等參數(shù)的設(shè)置。
初始化與指令發(fā)送函數(shù)代碼如下:
#串口初始化函數(shù)
def serial_init(COM,Baudrate,ByteSize,Stopbits,Timeout):
serial_COM = serial.Serial(COM)#設(shè)置端口號,如:COM=′COM1′
serial_COM.setBaudrate(Baudrate)#設(shè)置波特率,如:Baudrate=38 400
serial_COM.setByteSize(ByteSize)#設(shè)置位數(shù),如:ByteSize=8
serial_COM.setStopbits(Stopbits)#設(shè)置停止位,如:Stopbits=1
serial_COM.setTimeout(Timeout)#設(shè)置接收超時,如:Timeout=0.5 s
print serial_COM.portstr
time.sleep(1)#等1 s穩(wěn)定
returnserial_COM
#串口開、關(guān)機(jī)指令發(fā)送函數(shù)
def serial_Tx(serial_COM,Command):
for i in range(1,3):#最多發(fā)3次,未收到應(yīng)答提示控制失敗
# 通過串口發(fā)送控制命令
serial_COM.write(Command)#開機(jī)指令:Command=″x02x00x00x00x00x02″.encode(′utf-8′)
#關(guān)機(jī)指令:Command=″x02x01x00x00x00x03″.encode(′utf-8′)
if(serial_COM.read(6)!=″ ″):#接收投影機(jī)返回的6字節(jié)應(yīng)答信號
print(″投影機(jī)控制成功!″)
return 1
print(″投影機(jī)控制成功!″)
showinfo(title=′提示′,message=′程序控制可能出錯,請您用遙控器操控投影機(jī)′)
return 0
在Pycharm 2016.3.3開發(fā)環(huán)境下,采用python 2.7版本設(shè)計(jì)、調(diào)試總控計(jì)算機(jī)與教室計(jì)算機(jī)程序;然后,再借助py2exe將所設(shè)計(jì)程序編譯打包成exe可執(zhí)行文件[7],安裝對應(yīng)的總控計(jì)算機(jī)與106臺教室計(jì)算機(jī)。總控計(jì)算機(jī)與教室計(jì)算機(jī)的CPU型號為Intel(R) Core(TM) i3-4160 3.6GHz,內(nèi)存大小為4 GiB,操作系統(tǒng)為Win7-64位。通過Windows系統(tǒng)自帶任務(wù)計(jì)劃程序安排功能,將總控計(jì)算機(jī)與教室計(jì)算機(jī)的exe程序設(shè)為開機(jī)自啟動模式。最后,進(jìn)入教室計(jì)算機(jī)的BIOS系統(tǒng),開啟允許網(wǎng)絡(luò)喚醒功能。在為期1周的運(yùn)行測試過程中,總控計(jì)算機(jī)能夠?qū)崟r喚醒106臺教室計(jì)算機(jī)。其中,有105臺計(jì)算機(jī)能夠按照課表實(shí)時開啟和關(guān)閉投影機(jī);有1臺計(jì)算機(jī),因其系統(tǒng)時間設(shè)置有誤,未能按課表安排的上課時間正常開機(jī)。
我們以亳州職業(yè)技術(shù)學(xué)院現(xiàn)有多媒體教室布設(shè)結(jié)構(gòu)為基礎(chǔ),針對外配中控管理方式維護(hù)不便的問題,設(shè)計(jì)了基于Python的多媒體教室管理系統(tǒng)。在該系統(tǒng)中應(yīng)用了Python的datetime 、xlrd 、socket等模塊,使總控計(jì)算機(jī)可以依照Excel文件中預(yù)設(shè)的時間節(jié)點(diǎn)喚醒各教室計(jì)算機(jī);同時,應(yīng)用了Python的serial等模塊,使教室計(jì)算機(jī)可以通過串口按照Excel課表安排完成按時開關(guān)機(jī)的工作。在實(shí)際測試中,系統(tǒng)運(yùn)行良好,在一定程度上減少了教室管理員的工作量。所設(shè)計(jì)的軟件是以本地計(jì)算機(jī)系統(tǒng)時間為操控設(shè)備的基準(zhǔn)時間,因此在實(shí)際應(yīng)用中需注意主板電池、系統(tǒng)時間設(shè)置的匹配性。