TSourceImpl.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. # -*- coding:utf-8 -*-
  2. from ssat_sdk.utils.LoggingUtil import printLog
  3. from ssat_sdk.pic_tool import ImageCMP
  4. from ssat_sdk.sat_environment import getSATTmpDIR
  5. from ssat_sdk.sat_environment import getMenuTree3SelectedProjectCfgPath
  6. import os, sys, time
  7. import cv2 as cv
  8. import json
  9. class TSourceImpl():
  10. def __init__(self, ocr, ccard, tvOperator, tfocus, tconfig, uitRunner, \
  11. ocrDict=[{"lan": "ChinesePRC+English", "type": 4}, {"lan": "ChinesePRC+English", "type": 253}, \
  12. {"lan": "ChinesePRC+English", "type": 10001}]):
  13. self.ocr = ocr
  14. self.ccard = ccard
  15. self.tvOperator = tvOperator
  16. self.tFocus = tfocus
  17. self.tConfig = tconfig
  18. self.uitRunner = uitRunner
  19. self.imgCMP = ImageCMP()
  20. if not self.get_ocr_list():
  21. self.ocrDict = ocrDict
  22. # 某数据是否读取过;
  23. self.got_dict = {}
  24. self.sourceKeyErrCount = 0
  25. def get_ocr_list(self):
  26. if self.tConfig.has_option('First', 'source.ocr'):
  27. self.ocrDict = self.tConfig.get_dict(self.tConfig.get_value('First', 'source.ocr'))
  28. return True
  29. else:
  30. return False
  31. # 截图并返回当前截图路径
  32. def getCurrentUIPath(self):
  33. current_uiPic = os.path.join(getSATTmpDIR(), "menutree_runpath.png")
  34. self.ccard.takePicture(current_uiPic)
  35. return current_uiPic
  36. def getFocusTextBox2(self, level, root, focus_box):
  37. icon_path = os.path.join(getMenuTree3SelectedProjectCfgPath(), "icon\\",
  38. str(root) + "." + str(level) + ".dir.png")
  39. if icon_path in self.got_dict:
  40. x, y = focus_box[0] - self.got_dict[icon_path]['ref_box'][0], focus_box[1] - \
  41. self.got_dict[icon_path]['ref_box'][1]
  42. return [x, y, x + self.got_dict[icon_path]['width'], y + self.got_dict[icon_path]['height']]
  43. else:
  44. if os.path.exists(icon_path) is True:
  45. # 读取例图,宽高;
  46. img = cv.imread(icon_path)
  47. # 在例图中查找轮廓;
  48. result, box = self.tFocus.findRectByIcon(icon_path, level, root)
  49. if result is True:
  50. self.got_dict[icon_path] = {"ref_box": box, "width": img.shape[1], "height": img.shape[0]}
  51. x, y = focus_box[0] - box[0], focus_box[1] - box[1]
  52. return [x, y, x + img.shape[1], y + img.shape[0]]
  53. # endif
  54. # endif
  55. # 如果没有字段原样返回;
  56. return focus_box
  57. '''
  58. 检测信源界面是否存在,分成两部分:1 检测焦点框;2 检测文字(可选 checkOCR控制)。
  59. '''
  60. def checkSourceView(self, level, first_parent, parent, option, value_for_ocr, isForValue=False, checkOCR=False):
  61. print "checkSourceView:", level, first_parent, parent, option
  62. current_uiPic = self.getCurrentUIPath()
  63. if isForValue:
  64. isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, "value", first_parent, option=parent)
  65. else:
  66. isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, first_parent, option=option)
  67. if not isFind or contourRect == []:
  68. return False
  69. else:
  70. if checkOCR is False:
  71. return True
  72. else:
  73. isFind, ocrStr = self.getFocusText(current_uiPic, level, first_parent, parent, option, value_for_ocr)
  74. return isFind
  75. def getFocusText(self, current_uiPic, level, first_parent, parent, option, list_str, isSource=False,
  76. isForValue=False):
  77. if isForValue:
  78. isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, "value", first_parent, option=parent)
  79. else:
  80. isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, first_parent, option=option)
  81. if not isFind or contourRect == []:
  82. return False, ""
  83. found, ocr_str = False, ''
  84. # tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text11.png")
  85. # self.imgCMP.saveCropPic(current_uiPic, tmpPic,
  86. # (contourRect[0], contourRect[1], contourRect[2], contourRect[3]))
  87. # 是否有文字方向字段存在在ini里,如果有则转换文本框坐标;
  88. tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png")
  89. contourRect = self.getFocusTextBox2(level, first_parent, contourRect)
  90. self.imgCMP.saveCropPic(current_uiPic, tmpPic,
  91. (contourRect[0], contourRect[1], contourRect[2], contourRect[3]))
  92. # print "self.ocrDict:", self.ocrDict
  93. # 获取ocr_list;
  94. ocr_list = self.uitRunner.uitData.UITree.get_ocr_list(level, parent, option, True if parent == option else False)
  95. print "%s,%s,%s =>ocr_list=%s" % (level, parent, option, str(ocr_list))
  96. # 遍历ocr类型;
  97. for item in self.ocrDict:
  98. # 识别ocr;
  99. thresholdDict = self.tConfig.getThresholdDict(first_parent)
  100. ocr_str = self.ocr.getStrWithImgProcess(tmpPic, {}, item["lan"], item["type"], reconTimes=1)
  101. # print "\n\ngetCurrentFocusTextEx ==========================:OCR-Type=%s, OCR-Text=%s\n\n" % (
  102. # str(item), str(ocr_str))
  103. printLog(u"OCR识别的类型字典:%s" % str(item))
  104. printLog(u"OCR识别出的ocr_str为:%s" % str(ocr_str))
  105. # print(u"getCurrentFocusTextEx.ocr_str land = %s, type =%d, ocr_str=%s:"%(item["lan"], item["type"], ocr_str.encode('GB18030')))
  106. ocr_str = unicode(ocr_str).lower()
  107. if isSource is False:
  108. parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(option)
  109. print "getCurrentFocusTextEx.parent_ocr_dict:", parent_ocr_dict
  110. list_parent_ocr_value = list(parent_ocr_dict.keys())
  111. print "getCurrentFocusTextEx.list_parent_ocr_value:", list_parent_ocr_value
  112. current_parent_ocr_value = ""
  113. for parent_ocr_value in list_parent_ocr_value:
  114. parent_ocr_value = str(parent_ocr_value).lower()
  115. if parent_ocr_value in ocr_str or parent_ocr_value == ocr_str:
  116. current_parent_ocr_value = parent_ocr_value
  117. break
  118. try:
  119. curentOption = parent_ocr_dict[current_parent_ocr_value]
  120. except Exception, e:
  121. curentOption = ""
  122. printLog(u"OCR识别出的current_parent_ocr_value为:%s" % str(current_parent_ocr_value))
  123. printLog(u"OCR识别出的curentOCROption为:%s" % str(curentOption))
  124. printLog(u"传入的目标option为:%s" % str(option))
  125. # 通过OCR来反向识别判断当前识别的option是否为传入的option
  126. if str(curentOption).lower() != "" and str(curentOption).lower() != str(option).lower():
  127. # print "非焦点框=%s" % (ocr_str)
  128. printLog(u"非焦点框=%s" % str(ocr_str))
  129. return False, ocr_str
  130. # 再遍历目标焦点ocr;
  131. for std_str in list_str:
  132. std_str = str(std_str).lower()
  133. # print 'std_str:', std_str, type(std_str)
  134. # print 'ocr_str:', ocr_str, type(ocr_str)
  135. if std_str in ocr_str or std_str == ocr_str:
  136. found = True
  137. break
  138. # endfor
  139. if found is True:
  140. break
  141. else:
  142. if isSource is True:
  143. # 如果是信源 而且识别出是非目标信源则跳出该语言
  144. for ocr_std_str_list in ocr_list:
  145. # print "ocr_std_str_list:",ocr_std_str_list
  146. for ocr_std_str in ocr_std_str_list:
  147. # print "ocr_std_str:",ocr_std_str
  148. ocr_std_str = str(ocr_std_str).lower()
  149. # print 'ocr_std_str:', ocr_std_str, type(ocr_std_str)
  150. # print 'ocr_str:', ocr_str, type(ocr_str)
  151. if ocr_std_str in ocr_str or ocr_std_str == ocr_str:
  152. printLog(u"非焦点信源=%s" % str(ocr_str))
  153. return False, ocr_str
  154. # endfor
  155. return found, ocr_str
  156. # 遍历获取ocr结果;
  157. def getCurrentFocusTextEx(self, level, first_parent, parent, option, list_str, isSource=False,
  158. isForValue=False):
  159. print level, first_parent, parent, option
  160. current_uiPic = self.getCurrentUIPath()
  161. if isForValue:
  162. isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, "value", first_parent, option=parent)
  163. else:
  164. isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, first_parent, option=option)
  165. # print "getCurrentFocusText isFind:", isFind, contourRect
  166. printLog(u"获取当前聚焦效果isFind:%s 聚焦区域contourRect:%s" % (str(isFind), str(contourRect)))
  167. if not isFind or contourRect == []:
  168. return -1, ""
  169. else:
  170. found, ocr_str = False, ''
  171. # tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text11.png")
  172. # self.imgCMP.saveCropPic(current_uiPic, tmpPic,
  173. # (contourRect[0], contourRect[1], contourRect[2], contourRect[3]))
  174. # 是否有文字方向字段存在在ini里,如果有则转换文本框坐标;
  175. tmpPic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png")
  176. contourRect = self.getFocusTextBox2(level, first_parent, contourRect)
  177. self.imgCMP.saveCropPic(current_uiPic, tmpPic,
  178. (contourRect[0], contourRect[1], contourRect[2], contourRect[3]))
  179. if isSource:
  180. self.tvOperator.sendKey("ok")
  181. # print "self.ocrDict:", self.ocrDict
  182. # 获取ocr_list;
  183. ocr_list = self.uitRunner.uitData.UITree.get_ocr_list(level, parent, option, True if parent == option else False)
  184. print "%s,%s,%s =>ocr_list=%s" % (level, parent, option, str(ocr_list))
  185. # 遍历ocr类型;
  186. for item in self.ocrDict:
  187. # 识别ocr;
  188. thresholdDict = self.tConfig.getThresholdDict(first_parent)
  189. ocr_str = self.ocr.getStrWithImgProcess(tmpPic, thresholdDict, item["lan"], item["type"], reconTimes=1)
  190. # print "\n\ngetCurrentFocusTextEx ==========================:OCR-Type=%s, OCR-Text=%s\n\n" % (
  191. # str(item), str(ocr_str))
  192. printLog(u"OCR识别的类型字典:%s" % str(item))
  193. printLog(u"OCR识别出的ocr_str为:%s" % str(ocr_str))
  194. # print(u"getCurrentFocusTextEx.ocr_str land = %s, type =%d, ocr_str=%s:"%(item["lan"], item["type"], ocr_str.encode('GB18030')))
  195. ocr_str = unicode(ocr_str).lower()
  196. if isSource is False:
  197. parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(option)
  198. print "getCurrentFocusTextEx.parent_ocr_dict:", parent_ocr_dict
  199. list_parent_ocr_value = list(parent_ocr_dict.keys())
  200. print "getCurrentFocusTextEx.list_parent_ocr_value:", list_parent_ocr_value
  201. current_parent_ocr_value = ""
  202. for parent_ocr_value in list_parent_ocr_value:
  203. parent_ocr_value = str(parent_ocr_value).lower()
  204. if parent_ocr_value in ocr_str or parent_ocr_value == ocr_str:
  205. current_parent_ocr_value = parent_ocr_value
  206. break
  207. try:
  208. curentOption = parent_ocr_dict[current_parent_ocr_value]
  209. except Exception, e:
  210. curentOption = ""
  211. printLog(u"OCR识别出的current_parent_ocr_value为:%s" % str(current_parent_ocr_value))
  212. printLog(u"OCR识别出的curentOCROption为:%s" % str(curentOption))
  213. printLog(u"传入的目标option为:%s" % str(option))
  214. # 通过OCR来反向识别判断当前识别的option是否为传入的option
  215. if str(curentOption).lower() != "" and str(curentOption).lower() != str(option).lower():
  216. # print "非焦点框=%s" % (ocr_str)
  217. printLog(u"非焦点框=%s" % str(ocr_str))
  218. return 0, ocr_str
  219. # 再遍历目标焦点ocr;
  220. for std_str in list_str:
  221. std_str = str(std_str).lower()
  222. # print 'std_str:', std_str, type(std_str)
  223. # print 'ocr_str:', ocr_str, type(ocr_str)
  224. if std_str in ocr_str or std_str == ocr_str:
  225. found = True
  226. break
  227. # endfor
  228. if found is True:
  229. break
  230. else:
  231. if isSource is True:
  232. # 如果是信源 而且识别出是非目标信源则跳出该语言
  233. for ocr_std_str_list in ocr_list:
  234. # print "ocr_std_str_list:",ocr_std_str_list
  235. for ocr_std_str in ocr_std_str_list:
  236. # print "ocr_std_str:",ocr_std_str
  237. ocr_std_str = str(ocr_std_str).lower()
  238. # print 'ocr_std_str:', ocr_std_str, type(ocr_std_str)
  239. # print 'ocr_str:', ocr_str, type(ocr_str)
  240. if ocr_std_str in ocr_str or ocr_std_str == ocr_str:
  241. printLog(u"非焦点信源=%s" % str(ocr_str))
  242. return 0, ocr_str
  243. # endfor
  244. return int(found), ocr_str
  245. def checkSource(self, value_for_ocr, option,enter_key, count=0):
  246. printLog(u"checkSource。开始检测当前信源")
  247. sourceWaitTime = self.tConfig.getParentWaitTime("source")
  248. self.tvOperator.sendKey('source', duration=sourceWaitTime)
  249. isFind, text = self.getCurrentFocusTextEx('First', 'source', 'source', option, value_for_ocr)
  250. # 未找到焦点
  251. if isFind == -1:
  252. isFind, text = self.getCurrentFocusTextEx('First', 'source', 'source', option, value_for_ocr)
  253. if isFind == -1 and count < 3:
  254. self.sourceKeyErrCount += 1
  255. count += 1
  256. return self.checkSource(value_for_ocr, option, enter_key, count)
  257. elif isFind == 1:
  258. self.tvOperator.sendKey(enter_key)
  259. return True
  260. else:
  261. return False
  262. # 信源不匹配
  263. elif isFind == 0:
  264. #画面卡顿处理
  265. isFind, text = self.getCurrentFocusTextEx('First', 'source', 'source', option, value_for_ocr)
  266. if isFind == 1:
  267. self.tvOperator.sendKey(enter_key)
  268. return True
  269. else:
  270. return False
  271. else:
  272. self.tvOperator.sendKey(enter_key)
  273. return True
  274. def toNextSource(self, moveKey, enterKey, option, value_for_ocr, count=0):
  275. printLog(u"进入下一个信源.moveKey, enterKey:" + moveKey + enterKey)
  276. sourceWaitTime = self.tConfig.getParentWaitTime("source")
  277. self.tvOperator.sendKey('source', duration=sourceWaitTime)
  278. ret = self.checkSourceView('First', 'source', 'source', option, value_for_ocr)
  279. # 未弹出source界面
  280. if ret is False:
  281. printLog(u"未进入信源界面")
  282. ret = self.checkSourceView('First', 'source', 'source', option, value_for_ocr)
  283. if ret is False and count < 3:
  284. count += 1
  285. self.tvOperator.sendKeys('exit', "return") # 在某些界面弹不出信源界面
  286. return self.toNextSource(moveKey, enterKey, option, value_for_ocr, count)
  287. elif count >= 3:
  288. return False, ""
  289. printLog(u"已进入信源界面")
  290. self.tvOperator.sendKey(moveKey)
  291. current_uiPic = self.getCurrentUIPath()
  292. self.tvOperator.sendKey(enterKey)
  293. isFind, text = self.getFocusText(current_uiPic, 'First', 'source', 'source', option, value_for_ocr,
  294. isSource=True)
  295. return isFind, text
  296. def exitUSB(self):
  297. self.tvOperator.sendKey("exit", duration=2)
  298. self.tvOperator.sendKey("return", duration=2)
  299. def exitSourceView(self, level, first_parent, parent, option, value_for_ocr, isForValue=False):
  300. print u"退出信源界面"
  301. count = 0
  302. while count < 3:
  303. count += 1
  304. ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True)
  305. if ret is False:
  306. break
  307. self.tvOperator.sendKey("ok", duration=2)
  308. ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True)
  309. if ret is False:
  310. break
  311. self.tvOperator.sendKey("exit", duration=2)
  312. ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True)
  313. if ret is False:
  314. break
  315. self.tvOperator.sendKey("return", duration=2)
  316. ret = self.checkSourceView(level, first_parent, parent, option, value_for_ocr, isForValue, checkOCR=True)
  317. if ret is False:
  318. break
  319. def setSourceValue(self, option, value, sourceWaitTime=1.0, Max_Try=10):
  320. printLog(u"开始执行setSourceValue。option:%s value:%s" % (str(option), str(value)))
  321. # self.get_ocr_list('First', 'source')
  322. # 获取menu path;
  323. value_params, path_params = self.uitRunner.uitPathManage.get_menu_paths(option, value)
  324. # print "value_params:", value_params
  325. printLog(u"获取设置信源value:%s的值字典value_params:%s" % (str(value), str(value_params)))
  326. value_for_ocr = value_params['value_for_ocr']
  327. old_text = "init_old_text"
  328. enter_key = value_params["enter_key"]
  329. move_keyArr = value_params["move_key"]
  330. if enter_key.__len__() < 1 or move_keyArr.__len__() < 2:
  331. printLog(u"Error:Enter Key or Move Key错误:%s" % (str(enter_key), str(move_keyArr)))
  332. return False
  333. # 正向寻找的次数计数和最大次数
  334. count = 0
  335. # 读取menutree中的信源数量
  336. source_list = self.uitRunner.uitData.UITree.getSubOptionList(option)
  337. printLog(u"setSourceValue.%s source_list:%s" % (option, source_list))
  338. if source_list.__len__() != 0:
  339. Max_Try = source_list.__len__()
  340. isOldSouceCount = 0
  341. # 反向寻找的次数计数和最大次数
  342. Reversecount = 0
  343. Reverse_Max_Try = Max_Try
  344. sourceWaitTime = self.tConfig.getParentWaitTime("source")
  345. print "sourceWaitTime:", sourceWaitTime, type(sourceWaitTime)
  346. # 第一次直接判断是不是目标信源
  347. ret = self.checkSource(value_for_ocr, option, enter_key)
  348. printLog(u"第一次判断是否目标信源:" + str(ret))
  349. if ret is True:
  350. # 退出信源
  351. self.exitSourceView('First', 'source', 'source', option, value_for_ocr)
  352. return True
  353. if self.sourceKeyErrCount >= 3:
  354. printLog(u"第一次信源判断,Source界面弹出异常次数>3")
  355. return False
  356. # 用于信源切换不适用场景,快速结束脚本
  357. if self.enableSourceChange() is False:
  358. printLog(u"设定:不允许切换信源。")
  359. return False
  360. while True:
  361. # 循环遍历控制
  362. if count < Max_Try and Reversecount < Reverse_Max_Try and isOldSouceCount < 1:
  363. count += 1
  364. moveKey = move_keyArr[0]
  365. elif count >= Max_Try and Reversecount < Reverse_Max_Try and isOldSouceCount < 1:
  366. Reversecount += 1
  367. moveKey = move_keyArr[1]
  368. else:
  369. break
  370. # 切入下一个信源
  371. result, text = self.toNextSource(moveKey, enter_key, option, value_for_ocr)
  372. if result is True:
  373. return True
  374. elif result is False and ("usb" in text.lower() or "media" in text.lower()):
  375. isOldSouceCount = 0
  376. self.exitUSB()
  377. count = Max_Try
  378. elif result is False and (old_text in text):
  379. isOldSouceCount += 1
  380. # 信源与之前信源一样,超过3次调转方向,如果已经调转方向,则返回失败结果
  381. if isOldSouceCount > 3 and count >= Max_Try:
  382. Reversecount += Reverse_Max_Try
  383. isOldSouceCount = 0
  384. elif isOldSouceCount > 3 and count < Max_Try:
  385. count = Max_Try
  386. isOldSouceCount = 0
  387. # 退出信源
  388. self.exitSourceView('First', 'source', 'source', option, value_for_ocr)
  389. return False
  390. def enableSourceChange(self):
  391. jsonStr = self.tConfig.get_value("First", "source")
  392. sourceDict = json.loads(jsonStr)
  393. if sourceDict.has_key("enable"):
  394. enable = sourceDict["enable"]
  395. return enable == 1
  396. else:
  397. return True