# -*- 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