# -*- coding:utf-8 -*- from ssat_sdk.utils.LoggingUtil import printLog from ssat_sdk.pic_tool import ImageCMP from ssat_sdk.sat_environment import getSATTmpDIR from ssat_sdk.sat_environment import getMenuTree3SelectedProjectCfgPath import os, sys, time import cv2 as cv import json class TSourceImpl(): def __init__(self, ocr, ccard, tvOperator, tfocus, tconfig, uitRunner, \ ocrDict=[{"lan": "ChinesePRC+English", "type": 4}, {"lan": "ChinesePRC+English", "type": 253}, \ {"lan": "ChinesePRC+English", "type": 10001}]): self.ocr = ocr self.ccard = ccard self.tvOperator = tvOperator self.tFocus = tfocus self.tConfig = tconfig self.uitRunner = uitRunner self.imgCMP = ImageCMP() if not self.get_ocr_list(): self.ocrDict = ocrDict # 某数据是否读取过; self.got_dict = {} self.sourceKeyErrCount = 0 def get_ocr_list(self): if self.tConfig.has_option('First', 'source.ocr'): self.ocrDict = self.tConfig.get_dict(self.tConfig.get_value('First', 'source.ocr')) return True else: return False # 截图并返回当前截图路径 def getCurrentUIPath(self): current_uiPic = os.path.join(getSATTmpDIR(), "menutree_runpath.png") self.ccard.takePicture(current_uiPic) return current_uiPic def getFocusTextBox2(self, level, root, focus_box): icon_path = os.path.join(getMenuTree3SelectedProjectCfgPath(), "icon\\", str(root) + "." + str(level) + ".dir.png") if icon_path in self.got_dict: x, y = focus_box[0] - self.got_dict[icon_path]['ref_box'][0], focus_box[1] - \ self.got_dict[icon_path]['ref_box'][1] return [x, y, x + self.got_dict[icon_path]['width'], y + self.got_dict[icon_path]['height']] else: if os.path.exists(icon_path) is True: # 读取例图,宽高; img = cv.imread(icon_path) # 在例图中查找轮廓; result, box = self.tFocus.findRectByIcon(icon_path, level, root) if result is True: self.got_dict[icon_path] = {"ref_box": box, "width": img.shape[1], "height": img.shape[0]} x, y = focus_box[0] - box[0], focus_box[1] - box[1] return [x, y, x + img.shape[1], y + img.shape[0]] # endif # endif # 如果没有字段原样返回; return focus_box ''' 检测信源界面是否存在,分成两部分:1 检测焦点框;2 检测文字(可选 checkOCR控制)。 ''' def checkSourceView(self, level, first_parent, parent, option, value_for_ocr, isForValue=False, checkOCR=False): print "checkSourceView:", level, first_parent, parent, option current_uiPic = self.getCurrentUIPath() if isForValue: isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, "value", first_parent, option=parent) else: isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, first_parent, option=option) if not isFind or contourRect == []: return False else: if checkOCR is False: return True else: isFind, ocrStr = self.getFocusText(current_uiPic, level, first_parent, parent, option, value_for_ocr) return isFind def getFocusText(self, current_uiPic, level, first_parent, parent, option, list_str, isSource=False, isForValue=False): if isForValue: isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, "value", first_parent, option=parent) else: isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, first_parent, option=option) if not isFind or contourRect == []: return False, "" found, ocr_str = False, '' # tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text11.png") # self.imgCMP.saveCropPic(current_uiPic, tmpPic, # (contourRect[0], contourRect[1], contourRect[2], contourRect[3])) # 是否有文字方向字段存在在ini里,如果有则转换文本框坐标; tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png") contourRect = self.getFocusTextBox2(level, first_parent, contourRect) self.imgCMP.saveCropPic(current_uiPic, tmpPic, (contourRect[0], contourRect[1], contourRect[2], contourRect[3])) # print "self.ocrDict:", self.ocrDict # 获取ocr_list; ocr_list = self.uitRunner.uitData.UITree.get_ocr_list(level, parent, option, True if parent == option else False) print "%s,%s,%s =>ocr_list=%s" % (level, parent, option, str(ocr_list)) # 遍历ocr类型; for item in self.ocrDict: # 识别ocr; thresholdDict = self.tConfig.getThresholdDict(first_parent) ocr_str = self.ocr.getStrWithImgProcess(tmpPic, {}, item["lan"], item["type"], reconTimes=1) # print "\n\ngetCurrentFocusTextEx ==========================:OCR-Type=%s, OCR-Text=%s\n\n" % ( # str(item), str(ocr_str)) printLog(u"OCR识别的类型字典:%s" % str(item)) printLog(u"OCR识别出的ocr_str为:%s" % str(ocr_str)) # print(u"getCurrentFocusTextEx.ocr_str land = %s, type =%d, ocr_str=%s:"%(item["lan"], item["type"], ocr_str.encode('GB18030'))) ocr_str = unicode(ocr_str).lower() if isSource is False: parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(option) print "getCurrentFocusTextEx.parent_ocr_dict:", parent_ocr_dict list_parent_ocr_value = list(parent_ocr_dict.keys()) print "getCurrentFocusTextEx.list_parent_ocr_value:", list_parent_ocr_value current_parent_ocr_value = "" for parent_ocr_value in list_parent_ocr_value: parent_ocr_value = str(parent_ocr_value).lower() if parent_ocr_value in ocr_str or parent_ocr_value == ocr_str: current_parent_ocr_value = parent_ocr_value break try: curentOption = parent_ocr_dict[current_parent_ocr_value] except Exception, e: curentOption = "" printLog(u"OCR识别出的current_parent_ocr_value为:%s" % str(current_parent_ocr_value)) printLog(u"OCR识别出的curentOCROption为:%s" % str(curentOption)) printLog(u"传入的目标option为:%s" % str(option)) # 通过OCR来反向识别判断当前识别的option是否为传入的option if str(curentOption).lower() != "" and str(curentOption).lower() != str(option).lower(): # print "非焦点框=%s" % (ocr_str) printLog(u"非焦点框=%s" % str(ocr_str)) return False, ocr_str # 再遍历目标焦点ocr; for std_str in list_str: std_str = str(std_str).lower() # print 'std_str:', std_str, type(std_str) # print 'ocr_str:', ocr_str, type(ocr_str) if std_str in ocr_str or std_str == ocr_str: found = True break # endfor if found is True: break else: if isSource is True: # 如果是信源 而且识别出是非目标信源则跳出该语言 for ocr_std_str_list in ocr_list: # print "ocr_std_str_list:",ocr_std_str_list for ocr_std_str in ocr_std_str_list: # print "ocr_std_str:",ocr_std_str ocr_std_str = str(ocr_std_str).lower() # print 'ocr_std_str:', ocr_std_str, type(ocr_std_str) # print 'ocr_str:', ocr_str, type(ocr_str) if ocr_std_str in ocr_str or ocr_std_str == ocr_str: printLog(u"非焦点信源=%s" % str(ocr_str)) return False, ocr_str # endfor return found, ocr_str # 遍历获取ocr结果; def getCurrentFocusTextEx(self, level, first_parent, parent, option, list_str, isSource=False, isForValue=False): print level, first_parent, parent, option current_uiPic = self.getCurrentUIPath() if isForValue: isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, "value", first_parent, option=parent) else: isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, first_parent, option=option) # print "getCurrentFocusText isFind:", isFind, contourRect printLog(u"获取当前聚焦效果isFind:%s 聚焦区域contourRect:%s" % (str(isFind), str(contourRect))) if not isFind or contourRect == []: return -1, "" else: found, ocr_str = False, '' # tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text11.png") # self.imgCMP.saveCropPic(current_uiPic, tmpPic, # (contourRect[0], contourRect[1], contourRect[2], contourRect[3])) # 是否有文字方向字段存在在ini里,如果有则转换文本框坐标; tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png") contourRect = self.getFocusTextBox2(level, first_parent, contourRect) self.imgCMP.saveCropPic(current_uiPic, tmpPic, (contourRect[0], contourRect[1], contourRect[2], contourRect[3])) if isSource: self.tvOperator.sendKey("ok") # print "self.ocrDict:", self.ocrDict # 获取ocr_list; ocr_list = self.uitRunner.uitData.UITree.get_ocr_list(level, parent, option, True if parent == option else False) print "%s,%s,%s =>ocr_list=%s" % (level, parent, option, str(ocr_list)) # 遍历ocr类型; for item in self.ocrDict: # 识别ocr; thresholdDict = self.tConfig.getThresholdDict(first_parent) ocr_str = self.ocr.getStrWithImgProcess(tmpPic, thresholdDict, item["lan"], item["type"], reconTimes=1) # print "\n\ngetCurrentFocusTextEx ==========================:OCR-Type=%s, OCR-Text=%s\n\n" % ( # str(item), str(ocr_str)) printLog(u"OCR识别的类型字典:%s" % str(item)) printLog(u"OCR识别出的ocr_str为:%s" % str(ocr_str)) # print(u"getCurrentFocusTextEx.ocr_str land = %s, type =%d, ocr_str=%s:"%(item["lan"], item["type"], ocr_str.encode('GB18030'))) ocr_str = unicode(ocr_str).lower() if isSource is False: parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(option) print "getCurrentFocusTextEx.parent_ocr_dict:", parent_ocr_dict list_parent_ocr_value = list(parent_ocr_dict.keys()) print "getCurrentFocusTextEx.list_parent_ocr_value:", list_parent_ocr_value current_parent_ocr_value = "" for parent_ocr_value in list_parent_ocr_value: parent_ocr_value = str(parent_ocr_value).lower() if parent_ocr_value in ocr_str or parent_ocr_value == ocr_str: current_parent_ocr_value = parent_ocr_value break try: curentOption = parent_ocr_dict[current_parent_ocr_value] except Exception, e: curentOption = "" printLog(u"OCR识别出的current_parent_ocr_value为:%s" % str(current_parent_ocr_value)) printLog(u"OCR识别出的curentOCROption为:%s" % str(curentOption)) printLog(u"传入的目标option为:%s" % str(option)) # 通过OCR来反向识别判断当前识别的option是否为传入的option if str(curentOption).lower() != "" and str(curentOption).lower() != str(option).lower(): # print "非焦点框=%s" % (ocr_str) printLog(u"非焦点框=%s" % str(ocr_str)) return 0, ocr_str # 再遍历目标焦点ocr; for std_str in list_str: std_str = str(std_str).lower() # print 'std_str:', std_str, type(std_str) # print 'ocr_str:', ocr_str, type(ocr_str) if std_str in ocr_str or std_str == ocr_str: found = True break # endfor if found is True: break else: if isSource is True: # 如果是信源 而且识别出是非目标信源则跳出该语言 for ocr_std_str_list in ocr_list: # print "ocr_std_str_list:",ocr_std_str_list for ocr_std_str in ocr_std_str_list: # print "ocr_std_str:",ocr_std_str ocr_std_str = str(ocr_std_str).lower() # print 'ocr_std_str:', ocr_std_str, type(ocr_std_str) # print 'ocr_str:', ocr_str, type(ocr_str) if ocr_std_str in ocr_str or ocr_std_str == ocr_str: printLog(u"非焦点信源=%s" % str(ocr_str)) return 0, ocr_str # endfor return int(found), ocr_str def checkSource(self, value_for_ocr, option,enter_key, count=0): printLog(u"checkSource。开始检测当前信源") sourceWaitTime = self.tConfig.getParentWaitTime("source") self.tvOperator.sendKey('source', duration=sourceWaitTime) isFind, text = self.getCurrentFocusTextEx('First', 'source', 'source', option, value_for_ocr) # 未找到焦点 if isFind == -1: isFind, text = self.getCurrentFocusTextEx('First', 'source', 'source', option, value_for_ocr) if isFind == -1 and count < 3: self.sourceKeyErrCount += 1 count += 1 return self.checkSource(value_for_ocr, option, enter_key, count) elif isFind == 1: self.tvOperator.sendKey(enter_key) return True else: return False # 信源不匹配 elif isFind == 0: #画面卡顿处理 isFind, text = self.getCurrentFocusTextEx('First', 'source', 'source', option, value_for_ocr) if isFind == 1: self.tvOperator.sendKey(enter_key) return True else: return False else: self.tvOperator.sendKey(enter_key) return True def toNextSource(self, moveKey, enterKey, option, value_for_ocr, count=0): printLog(u"进入下一个信源.moveKey, enterKey:" + moveKey + enterKey) sourceWaitTime = self.tConfig.getParentWaitTime("source") self.tvOperator.sendKey('source', duration=sourceWaitTime) ret = self.checkSourceView('First', 'source', 'source', option, value_for_ocr) # 未弹出source界面 if ret is False: printLog(u"未进入信源界面") ret = self.checkSourceView('First', 'source', 'source', option, value_for_ocr) if ret is False and count < 3: count += 1 self.tvOperator.sendKeys('exit', "return") # 在某些界面弹不出信源界面 return self.toNextSource(moveKey, enterKey, option, value_for_ocr, count) elif count >= 3: return False, "" printLog(u"已进入信源界面") self.tvOperator.sendKey(moveKey) current_uiPic = self.getCurrentUIPath() self.tvOperator.sendKey(enterKey) isFind, text = self.getFocusText(current_uiPic, 'First', 'source', 'source', option, value_for_ocr, isSource=True) return isFind, text def exitUSB(self): self.tvOperator.sendKey("exit", duration=2) self.tvOperator.sendKey("return", duration=2) def exitSourceView(self, level, first_parent, parent, option, value_for_ocr, isForValue=False): print u"退出信源界面" count = 0 while count < 3: count += 1 ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True) if ret is False: break self.tvOperator.sendKey("ok", duration=2) ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True) if ret is False: break self.tvOperator.sendKey("exit", duration=2) ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True) if ret is False: break self.tvOperator.sendKey("return", duration=2) ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True) if ret is False: break def setSourceValue(self, option, value, sourceWaitTime=1.0, Max_Try=10): printLog(u"开始执行setSourceValue。option:%s value:%s" % (str(option), str(value))) # self.get_ocr_list('First', 'source') # 获取menu path; value_params, path_params = self.uitRunner.uitPathManage.get_menu_paths(option, value) # print "value_params:", value_params printLog(u"获取设置信源value:%s的值字典value_params:%s" % (str(value), str(value_params))) value_for_ocr = value_params['value_for_ocr'] old_text = "init_old_text" enter_key = value_params["enter_key"] move_keyArr = value_params["move_key"] if enter_key.__len__() < 1 or move_keyArr.__len__() < 2: printLog(u"Error:Enter Key or Move Key错误:%s" % (str(enter_key), str(move_keyArr))) return False # 正向寻找的次数计数和最大次数 count = 0 # 读取menutree中的信源数量 source_list = self.uitRunner.uitData.UITree.getSubOptionList(option) printLog(u"setSourceValue.%s source_list:%s" % (option, source_list)) if source_list.__len__() != 0: Max_Try = source_list.__len__() isOldSouceCount = 0 # 反向寻找的次数计数和最大次数 Reversecount = 0 Reverse_Max_Try = Max_Try sourceWaitTime = self.tConfig.getParentWaitTime("source") print "sourceWaitTime:", sourceWaitTime, type(sourceWaitTime) # 第一次直接判断是不是目标信源 ret = self.checkSource(value_for_ocr, option, enter_key) printLog(u"第一次判断是否目标信源:" + str(ret)) if ret is True: # 退出信源 self.exitSourceView('First', 'source', 'source', option, value_for_ocr) return True if self.sourceKeyErrCount >= 3: printLog(u"第一次信源判断,Source界面弹出异常次数>3") return False # 用于信源切换不适用场景,快速结束脚本 if self.enableSourceChange() is False: printLog(u"设定:不允许切换信源。") return False while True: # 循环遍历控制 if count < Max_Try and Reversecount < Reverse_Max_Try and isOldSouceCount < 1: count += 1 moveKey = move_keyArr[0] elif count >= Max_Try and Reversecount < Reverse_Max_Try and isOldSouceCount < 1: Reversecount += 1 moveKey = move_keyArr[1] else: break # 切入下一个信源 result, text = self.toNextSource(moveKey, enter_key, option, value_for_ocr) if result is True: return True elif result is False and ("usb" in text.lower() or "media" in text.lower()): isOldSouceCount = 0 self.exitUSB() count = Max_Try elif result is False and (old_text in text): isOldSouceCount += 1 # 信源与之前信源一样,超过3次调转方向,如果已经调转方向,则返回失败结果 if isOldSouceCount > 3 and count >= Max_Try: Reversecount += Reverse_Max_Try isOldSouceCount = 0 elif isOldSouceCount > 3 and count < Max_Try: count = Max_Try isOldSouceCount = 0 # 退出信源 self.exitSourceView('First', 'source', 'source', option, value_for_ocr) return False def enableSourceChange(self): jsonStr = self.tConfig.get_value("First", "source") sourceDict = json.loads(jsonStr) if sourceDict.has_key("enable"): enable = sourceDict["enable"] return enable == 1 else: return True