做物聯網涉及到實際使用環境語音識別準確率的測驗,大量的語料如果是人來朗讀的話太費功夫,編一個自動測驗程式即可無人通宵測驗,大大提高了效率;朗讀上可以通過呼叫powershell來朗檔案中的語料,通然后過串口抓取設備設備對語料回應的資料進行分析把識別結果寫入到檔案當中;
需要安裝serial(串口支持模塊)和openxl(Exel檔案支持模塊);編譯除錯完成打包為.exe檔案,可在沒有配置python環境的電腦上運行;
使用到python多執行緒(通過Queue執行緒間通信),還有檔案讀寫操作;很有參考價值,
import serial import threading import time import os import re import fileinput from glob import glob import subprocess as sp from queue import Queue# import xlsxwriter # import xlrd from openpyxl import load_workbook from openpyxl import Workbook
print('Hellow World:',time.time()) #時間戳:秒
TheTimeIs=time.ctime() event = threading.Event() q=Queue(1) q1=Queue(1) # q2=Queue(1) #//////////////////////////////////////////////////////////////////////////////呼叫powershell的類 class PowerShell: # from scapy def __init__(self, coding, ): cmd = [self._where('PowerShell.exe'), "-NoLogo", "-NonInteractive", # Do not print headers "-Command", "-"] # Listen commands from stdin startupinfo = sp.STARTUPINFO() startupinfo.dwFlags |= sp.STARTF_USESHOWWINDOW self.popen = sp.Popen(cmd, stdout=sp.PIPE, stdin=sp.PIPE, stderr=sp.STDOUT, startupinfo=startupinfo) self.coding = coding
def __enter__(self): return self
def __exit__(self, a, b, c): self.popen.kill()
def run(self, cmd, timeout=6): #timeout=0 延時 b_cmd = cmd.encode(encoding=self.coding) try: b_outs, errs = self.popen.communicate(b_cmd, timeout=timeout) except sp.TimeoutExpired: self.popen.kill() b_outs, errs = self.popen.communicate() outs = b_outs.decode(encoding=self.coding) return outs, errs
@staticmethod def _where(filename, dirs=None, env="PATH"): """Find file in current dir, in deep_lookup cache or in system path""" if dirs is None: dirs = [] if not isinstance(dirs, list): dirs = [dirs] if glob(filename): return filename paths = [os.curdir] + os.environ[env].split(os.path.pathsep) + dirs try: return next(os.path.normpath(match) for path in paths for match in glob(os.path.join(path, filename)) if match) except (StopIteration, RuntimeError): raise IOError("File not found: %s" % filename) #//////////////////////////////////////////////////////////////////////////
#/////////////////////////////////////////////////////////////////////////文本處理 pscmd='Add-Type -AssemblyName System.speech;\ $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;\ $speak.Rate = 0;\ $speak.Speak("天貓精靈")' #powershell文本朗讀指令
cmd="天貓精靈" StandardCmd_n='' # Number_n=0 SuccessNum_n=0 FailDispaly_n=[] uart_error=0 #控制,朗讀10次天貓精靈都沒有回應,退出程式 cmd_error=0
# input() data = load_workbook('test.xlsx')#打開表格 mydata=https://www.cnblogs.com/bianwenxue/archive/2021/03/06/data["Sheet1"] #sheet1
log='' #提取日志
def SpeakTm(): global uart_error #讀天貓 with PowerShell('GBK') as ps: ps.run(pscmd) print("天貓精靈") uart_error+=1 if uart_error>10: #朗讀10次沒有回應,保存資訊,退出程式 data.save('TestResult.xlsx') os._exit(0) with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines(["天貓精靈\n"]) LogUart.close()
def changepscmd(fcmd): #讀設定朗讀陳述句 cmd=str(fcmd) pscmd0=pscmd p = re.compile("天貓精靈") pscmd1 = p.sub(cmd,pscmd0)
with PowerShell('GBK') as ps: #time.sleep(1) outs, errs = ps.run(pscmd1) #在run函式中輸入powershell指令 print('error:', os.linesep, errs) print('output:', os.linesep, outs) # with open('LogSpeech.txt', mode='a',encoding='utf-8') as LogSpeech: # LogSpeech.writelines([time.ctime(), ' say :',cmd,'\n']) # LogSpeech.close() with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines([time.ctime(), ' say :',cmd,'\n']) LogUart.close() print(cmd) #列印朗讀的語料
def checkcmd(StandardCmd_n): #比較提取的指令和標準指令 global SuccessNum_n global FailDispaly_n # q2.get() p = re.compile(", 0x") pscmd0 = p.sub('',log) pscmd1=pscmd0.upper() scmd0=str(StandardCmd_n) scmd=scmd0.upper() print('yu--->',cmd,'pscmd1--->',pscmd1,'standard--->',StandardCmd_n) with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines(['yu--->',cmd,'pscmd1--->',pscmd1,'standard--->',StandardCmd_n]) LogUart.close() if pscmd1.find(scmd)!=-1: return True else: return False
def Rouse_Tm(log): if log.find('tian mao jing ling')!=-1: return True else: return False
#//////////////////////////////////////////////////////////////////////////////////朗讀執行緒函式入口 def Speech(): global StandardCmd_n global Corpus_n global order order=1 for i in mydata['A']: if order > 1: #使得order讀取的資料和i的下標同步,好自然結束for回圈 Corpus_n=str(i.value) #取語料 StandardCmd_n=str(mydata['B%d'%order].value) #取語料對應的標準指令
Number_n=mydata['C%d'%order].value #取語料對應的朗讀次數 if Number_n==None: Number_n=0 print(Number_n) SuccessNum_n=0 #初始成功次數置0 FailDispaly_n="" #初始失敗次數置空 FailSum=0 error_check=0 while Number_n>0: #朗讀次數大于0朗讀,并遞減 SpeakTm() time.sleep(1) #使執行緒等待收到相應天貓回應指令后繼續執行 print(time.ctime()) event.wait(7) #執行緒等待觸發 print(time.ctime())
if q.empty(): print('cant listen') continue #天貓精靈沒有喚醒,重新進行喚醒 else: q.get() print('good') event.clear() #set會重置所有wait為不再等待,clear使所有wait重新生效 changepscmd(Corpus_n) #朗讀 Number_n-=1 # time.sleep(5) #必須有個時間等待接收指令 print(time.ctime()) event.wait(10) #執行緒等待觸發 print(time.ctime()) event.clear()
if q1.empty(): print('cant know') #天貓精靈喚醒成功,朗讀語料,沒有回應相關的指令 error_check+=1 with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines([time.ctime(), 'cant know\n']) LogUart.close() if cmd_error==2: if FailSum<10: FailSum+=1 FailDispaly_n+="識別T 發送F- \n" mydata['E%d'%order].value=https://www.cnblogs.com/bianwenxue/archive/2021/03/06/FailDispaly_n #直接寫入沒有識別進行下一次朗讀 else: if FailSum<10: FailSum+=1 FailDispaly_n+="識別錯誤- \n" mydata['E%d'%order].value=https://www.cnblogs.com/bianwenxue/archive/2021/03/06/FailDispaly_n #直接寫入沒有識別進行下一次朗讀 else: q1.get() print('good') with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines([time.ctime(), 'good\n']) LogUart.close() if checkcmd(StandardCmd_n): #判斷指令是否正確,正確添加成功數,不正確列印錯誤案例 error_check=0 SuccessNum_n+=1 else: error_check+=1 if FailSum<10: FailSum+=1 FailDispaly_n+=log+'\n' mydata['E%d'%order].value=https://www.cnblogs.com/bianwenxue/archive/2021/03/06/FailDispaly_n if error_check>=10: break mydata['D%d'%order].value=https://www.cnblogs.com/bianwenxue/archive/2021/03/06/SuccessNum_n #直接將所獲得得資料輸入對應單元格 try: data.save('TestResult.xlsx')#保存到一個新的excel except(): os._exit(0) order+=1
time.sleep(5) os._exit(0)
#/////////////////////////////////////////////////////////////////////////////////////串口除錯 ser = serial.Serial()
print("請輸入正確的串口號按回車健運行:") MycomX='COM'+str(input())
ser.port =MycomX # 串口 print(ser.name)
ser.baudrate = 1500000 #波特率 ser.bytesize = 8 ser.parity = serial.PARITY_NONE ser.stopbits = 1 ser.open() # 開啟串口
#///////////////////////////////////////////////////////////////////////////////////主執行緒串口接收 def UartData():
global uart_error global cmd_error global log while True: #ch = ser.read() # 收一個bytes ch=ser.readline()#讀取以“\n”結尾的行 log_can=ch.decode(encoding='utf-8') itlog=log_can.find('send')
error_1=log_can.find('fresult') #接收到指令的特征 with open('LogUart.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines([time.ctime(), ' ',log_can]) LogUart.close() # if Rouse_Tm(log_can): print("Tm已喚醒:") uart_error=0 with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines([time.ctime(), 'Tm已喚醒:\n']) LogUart.close() if q.empty(): q.put(1) #使用queue佇列來完成執行緒之間的通信,queue是執行緒安全的 event.set() # event.clear()
if itlog==0: cmdl=len(log_can) if cmdl==104: log=log_can cmd_error=1 print('cmdlen is:\n',len(log),'\n') print('log is-----> %s' % log) with open('Show.txt', mode='a',encoding='utf-8') as LogUart: LogUart.writelines([time.ctime(), 'log is----->',log,'\n']) LogUart.close()
if q.empty(): q1.put(1) #使用queue佇列來完成執行緒之間的通信,queue是執行緒安全的 event.set()
if cmd_error==0 and error_1!=-1: print('error_1log-->',log_can) cmd_error=2
#/////////////////////////////////////////////////////////////////////////////////////
#多執行緒 SpeechThread=threading.Thread(target=Speech) #SpeechThread.daemon=True #設定執行緒為守護執行緒 UartDataThread=threading.Thread(target=UartData) #UartDataThread.daemon=True
def main(): UartDataThread.start() SpeechThread.start() time.sleep(60*60*24) #主函式結束,會導致執行緒結束,阻塞main,讓執行緒繼續運行,朗讀執行緒運行完畢通過 os._exit()結束程式
if __name__ == '__main__': main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/266930.html
標籤:其他
下一篇:第一天
