# -*- coding:utf-8 -*-
from ssat_sdk.utils.LoggingUtil import printLog

from ssat_sdk.utils.string_util import getDigitFromString

from ssat_sdk.device_manage.capturecard_manager import CCardManager

from ssat_sdk.MenuTree3.TExcelParser import CExcelParser
from ssat_sdk.MenuTree3.UIT_runner import UITRunner
from ssat_sdk import getMenuTree3SelectedProjectCfgPath, OCRConvert, getSATTmpDIR, ImageCMP, \
    getMenuTree3SelectedPExcelPath, getMenuTree3SelectedTvExcelPath
from ssat_sdk.MenuTree3.TFocus import TFocus
from ssat_sdk.MenuTree3.TConfig import TConfig
from ssat_sdk.MenuTree3.TSourceImpl import TSourceImpl
from ssat_sdk.tv_operator import *
import json
import time
import cv2 as cv
from ssat_sdk.utils.string_util import strcmp
from ssat_sdk.picture.DoubleImage import DoubleImage
from ssat_sdk.source_input import SourceGenInput

g_level = ['First', 'Second', 'Third', 'Fourth', 'Fifth', 'Sixth', 'Seventh', 'Eighth', 'Ninth', 'Tenth', 'Eleventh',
           'Twelfth']


class CTMenu():
    # def __init__(self, ocrDict={"lan": "CHN_ENG", "type": 10000}):
    def __init__(self, ocrDict=[{"lan": "ChinesePRC+English", "type": 4}, {"lan": "ChinesePRC+English", "type": 253},
                                {"lan": "ChinesePRC+English", "type": 10001}]):
        self.uitRunner = UITRunner()
        self.uitPathManage = self.uitRunner.uitPathManage

        # 创建视频采集对象
        self.ccard = CCardManager()
        # 创建OCR对象
        self.ocr = OCRConvert()
        # 图片切割对象
        self.imgCMP = ImageCMP()
        # 读取excel并解析出内容;
        # 红老鼠遥控对象;
        self.redRat3 = TvOperator()
        # 配置文件;
        self.tconfig = self.uitRunner.uitData.tConfig
        self.icon_shape = [1920, 1080]
        if self.tconfig.has_option('Screen', 'shape'):
            self.icon_shape = self.tconfig.get_value_dict('Screen', 'shape')

        # 截图,获取分辨率;
        self.Screen = [1920, 1080]
        pic = self.getCurrentUIPath()
        if os.path.exists(pic) is True:
            img = cv.imread(pic)
            if img is not None:
                self.Screen = [img.shape[1], img.shape[0]]

        # 创建获取聚焦区域对象
        self.tFocus = TFocus(getMenuTree3SelectedProjectCfgPath(), self.uitRunner, self.Screen, self.icon_shape)
        self.ocrDict = ocrDict
        # 某数据是否读取过;
        self.got_dict = {}
        # 22293
        self.sourceInput = SourceGenInput()
        self.tSource = TSourceImpl(self.ocr, self.ccard, self.redRat3, self.tFocus, self.tconfig, self.uitRunner)

    def currentTime(self):
        return time.strftime('_%Y-%m-%d_%H_%M_%S', time.localtime(time.time()))

    '''
    对应OptionConfig中的getThresholdDict和__getICONConfig
    '''
    def get_ocr_list(self, level, option):
        # OCR识别参数字典   默认值为:百度中英文免费类型
        ini_path = os.path.join(getMenuTree3SelectedProjectCfgPath(), "menutree.ini")
        if os.path.exists(ini_path) is True:
            tconfig = self.uitRunner.uitData.tConfig
            # if tconfig.has_option(level, parent + u'.ocr'):
            #     self.ocrDict = tconfig.get_dict(tconfig.get_value(level, parent + u'.ocr'))
            #     return
            result, path = self.uitRunner.uitData.UITree.get_option(option)
            print u"get_ocr_list, path:",path
            if result:
                # 从当前层逐层往上遍历,寻找ocr参数列表
                for i in range(g_level.index(level), -1, -1):
                    cur_parent = path['parent']
                    first_parent = path['first_parent']
                    i_level = g_level[i]
                    if tconfig.has_option(i_level, option + u'.ocr'):
                        self.ocrDict = tconfig.get_dict(tconfig.get_value(i_level, option + u'.ocr'))
                        printLog("TMenu.get_ocr_list:", "Get ocr list by: %s.ocr"%option)
                        break
                    elif tconfig.has_option(i_level, cur_parent + u'.ocr'):
                        self.ocrDict = tconfig.get_dict(tconfig.get_value(i_level, cur_parent + u'.ocr'))
                        printLog("TMenu.get_ocr_list:", "Get ocr list by: %s.ocr"%cur_parent)
                        break
                    elif tconfig.has_option(i_level, first_parent + u'.ocr'):
                        self.ocrDict = tconfig.get_dict(tconfig.get_value(i_level, first_parent + u'.ocr'))
                        printLog("TMenu.get_ocr_list:", "Get ocr list by: %s.ocr"%first_parent)
                        break
        else:
            # 如果没有,使用默认;
            self.ocrDict = [{"lan": "ChinesePRC+English", "type": 4}, {"lan": "ChinesePRC+English", "type": 253},
                            {"lan": "ChinesePRC+English", "type": 10001}]
            printLog("TMenu.get_ocr_list:", "Get ocr list fail!!!Using default list!!!")

        printLog("TMenu.get_ocr_list:", "Present ocr list:%s"%self.ocrDict)

    # 截图并返回当前截图路径
    def getCurrentUIPath(self):
        current_uiPic = os.path.join(getSATTmpDIR(), "menutree_runpath.png")
        self.ccard.takePicture(current_uiPic)
        return current_uiPic

    def getFocusTextBox3(self, cur_option, focus_box, is_value_sheet=False):
        resutl, opcfg = self.tFocus.getOptionConfig(cur_option, is_value_sheet)
        dcfg = opcfg['dcfg']
        icon_path = opcfg['icon_path']
        icon_dir_path = opcfg['dir_path']
        if resutl is False or os.path.exists(icon_dir_path) is False:
            print u'getFocusTextBox:current use dir_path=%s is null' % (
                icon_dir_path)
            return focus_box

        if icon_dir_path in self.got_dict:
            x, y = focus_box[0] - self.got_dict[icon_dir_path]['ref_box'][0], focus_box[1] - \
                   self.got_dict[icon_dir_path]['ref_box'][1]
            return [x, y, x + self.got_dict[icon_dir_path]['width'], y + self.got_dict[icon_dir_path]['height']]
        else:
            if os.path.exists(icon_dir_path) is True:
                # 读取例图,宽高;
                img = cv.imread(icon_dir_path)
                # 在例图中查找轮廓;
                result, box = self.tFocus.findRectByIcon2(icon_dir_path, cur_option, is_value_sheet)
                if result is True:
                    self.got_dict[icon_dir_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

    def getFocusTextBox4(self, icon_dir_path, cur_option, focus_box, is_value_sheet=False):
        if os.path.exists(icon_dir_path) is False:
            print u'getFocusTextBox:current use dir_path=%s is null' % (
                icon_dir_path)
            return focus_box

        if icon_dir_path in self.got_dict:
            x, y = focus_box[0] - self.got_dict[icon_dir_path]['ref_box'][0], focus_box[1] - \
                   self.got_dict[icon_dir_path]['ref_box'][1]
            return [x, y, x + self.got_dict[icon_dir_path]['width'], y + self.got_dict[icon_dir_path]['height']]
        else:
            if os.path.exists(icon_dir_path) is True:
                # 读取例图,宽高;
                img = cv.imread(icon_dir_path)
                # 在例图中查找轮廓;
                result, box = self.tFocus.findRectByIcon2(icon_dir_path, cur_option, is_value_sheet)
                if result is True:
                    self.got_dict[icon_dir_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

    # 获取焦点框文本;
    def getFocusText(self, level, first_parent, paths, src_pic, focus_box, is_for_value=False):
        # 是否有文字方向字段存在在ini里,如果有则转换文本框坐标;
        text_pic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png")
        contourRect = self.getFocusTextBox3(paths['option'], focus_box, is_for_value)
        self.imgCMP.saveCropPic(src_pic, text_pic, (contourRect[0], contourRect[1], contourRect[2], contourRect[3]))
        # 获取ocr_list;
        cur_parent, cur_option = paths['parent'], paths['option']
        ocr_list = self.uitRunner.uitData.UITree.get_ocr_list(level, cur_parent, cur_option,
                                               True if cur_parent == cur_option else False)
        print u"%s,%s,%s =>ocr_list=%s" % (level, cur_parent, cur_option, str(ocr_list))
        # 遍历ocr类型;
        found = False
        ocr_str = ''
        # 获取ocr列表;
        self.get_ocr_list(level, cur_option)
        for item in self.ocrDict:
            # 识别ocr;
            thresholdDict = self.tconfig.getThresholdDict(first_parent)
            ocr_str = self.ocr.getStrWithImgProcess(text_pic, thresholdDict, item["lan"], item["type"], reconTimes=1)
            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 is_for_value:
                parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(cur_parent, value_sheet=True)
            else:
                parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(cur_option)

            print u"getCurrentFocusTextEx.parent_ocr_dict:", parent_ocr_dict
            list_parent_ocr_value = list(parent_ocr_dict.keys())
            print u"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(cur_option).lower():
                # print "非焦点框=%s" % (ocr_str)
                printLog(u"非焦点框=%s" % str(ocr_str))
                return 0, ocr_str

            # 再遍历目标焦点ocr;
            for std_str in paths["option_for_ocr"]:
                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
        # endfor

        return found, ocr_str

    # 获取焦点框轮廓;
    def getFocusBox_temp(self, level, first_parent, option=''):
        # 焦点框截图;
        bx_pic = ''
        # 当前截图;
        cur_img = self.getCurrentUIPath()
        # 查找焦点框轮廓;
        bx_found, bx_focus = self.tFocus.findRectByIcon(cur_img, level, first_parent, option)
        printLog("getCurrentFocusBox(%d,%s):" % (int(bx_found), str(bx_focus)))
        if bx_found is True:
            # 保存焦点框截图;
            bx_pic = os.path.join(getSATTmpDIR(), "menutree_focus_area" + str(time.time()) + ".png")
            self.imgCMP.saveCropPic(cur_img, bx_pic, (bx_focus[0], bx_focus[1], bx_focus[2], bx_focus[3]))
        # 返回结果;
        return bx_found, bx_focus, bx_pic

    # 获取焦点框滚动文本;
    def getMarqueeText(self, level, first_parent, option=''):
        # 获取焦点框信息;
        bx_found, bx_focus, bx_pic = self.getFocusBox_temp(level, first_parent, option)
        if bx_found is False:
            printLog("getMarqueeText=>焦点框识别失败")
            return False, ''

        # 按要求,跑马灯只需要百度高精度;
        orc_type = {"lan": "ChinesePRC+English", "type": 253}
        # ocr识别;
        thresholdDict = self.tconfig.getThresholdDict(first_parent)
        # ocr_result = self.ocr.getStr(bx_pic, orc_type["lan"], orc_type["type"])
        ocr_result = self.ocr.getStrWithImgProcess(bx_pic, thresholdDict, orc_type["lan"], orc_type["type"],
                                                   reconTimes=1)
        if ocr_result == "ERR<Exp>" or ocr_result.__len__() == 0:
            printLog("getMarqueeText=>ocr识别失败=%s" % (ocr_result))
            return False, ocr_result
        # 返回结果;
        return True, ocr_result

    def getOCRStrListByOptionList(self, optionList):
        OCRStrList = []
        for option in optionList:
            hasOption, optionDict = self.uitRunner.uitData.UITree.get_option(option)
            if hasOption:
                optionStrList = optionDict["option_ocr"]
                OCRStrList.extend(optionStrList)
        return OCRStrList

    def getOCRStrDictByOptionList(self, optionList):
        OCRStrDict = {}
        for option in optionList:
            hasOption, optionDict = self.uitRunner.uitData.UITree.get_option(option)
            if hasOption:
                optionStrList = optionDict["option_ocr"]
                OCRStrDict[option] = optionStrList
        return OCRStrDict

    def getFocusBoxMarqueeText(self, marquee_dict, level, first_parent, paths):
        # 截图2次,判断是否是跑马菜单;
        # 第一次;
        bx_found, bx_focus, bx_pic1 = self.getFocusBox_temp(level, first_parent, paths['option'])
        if bx_found is False:
            printLog("getFocusBoxMarqueeText:焦点框识别失败1")
            return -1, ''

        # 等待1秒后截图;
        time.sleep(marquee_dict['sleep_time'])
        # 发送鲜活键;
        self.redRat3.sendKey(marquee_dict['alive_key'], 1, 0.1)

        # 第二次;
        bx_found, bx_focus, bx_pic2 = self.getFocusBox_temp(level, first_parent, paths['option'])
        if bx_found is False:
            printLog("getFocusBoxMarqueeText:焦点框识别失败2")
            return -1, ''

        # 二图ocr文本是否相似,如果相似认为不是滚动文本;#如果网络问题;
        thresholdDict = self.tconfig.getThresholdDict(first_parent)
        # ocr_result_text1 = self.ocr.getStr(bx_pic1, "ChinesePRC+English", 253)
        ocr_result_text1 = self.ocr.getStrWithImgProcess(bx_pic1, thresholdDict, "CHN_ENG", 10000,
                                                         reconTimes=1)
        # 发送鲜活键;
        self.redRat3.sendKey(marquee_dict['alive_key'], 1, 0.1)
        # ocr_result_text2 = self.ocr.getStr(bx_pic2, "ChinesePRC+English", 253)
        ocr_result_text2 = self.ocr.getStrWithImgProcess(bx_pic2, thresholdDict, "CHN_ENG", 10000,
                                                         reconTimes=1)
        # 发送鲜活键;
        self.redRat3.sendKey(marquee_dict['alive_key'], 1, 0.1)

        # 对比结果:相等非滚动文本,否则视为滚动文本;
        if ocr_result_text1 != "" and ocr_result_text1 == ocr_result_text2:
            return self.getCurrentFocusTextEx(level, first_parent, paths['parent'], paths['option'],
                                              paths['option_for_ocr'])
        else:
            destOption = paths['option']
            menuList = marquee_dict["menu"]
            # 如果只有一项跑马灯,且目标option亦在跑马灯列表中,则直接返回成功结果
            if menuList.__len__() == 1 and (destOption in menuList):
                return 1, destOption
            list_img = []
            result = False
            ocr_result_text = ''
            ocr_text_list = []

            # 截图5次;
            for i in range(0, 5):
                bx_found, bx_focus, bx_pic = self.getFocusBox_temp(level, first_parent, paths['option'])
                if bx_found is True:
                    list_img.append(bx_pic)
                # 间隔多久截图;
                time.sleep(marquee_dict['sleep_time'])
                # 发送鲜活键;
                self.redRat3.sendKey(marquee_dict['alive_key'], 1, 0.1)
            # endfor

            # 遍历文本list_img;
            # 按要求,跑马灯只用百度识别;
            orc_type = {"lan": "ChinesePRC+English", "type": 10000}
            for bx_pic in list_img:
                # ocr识别;
                # ocr_result_text = self.ocr.getStr(bx_pic, orc_type["lan"], orc_type["type"])
                ocr_result_text = self.ocr.getStrWithImgProcess(bx_pic, thresholdDict, orc_type["lan"],
                                                                orc_type["type"],
                                                                reconTimes=1)

                # 识别一次,发送一次鲜活键;
                self.redRat3.sendKey(marquee_dict['alive_key'], 1, 0.1)
                if ocr_result_text == "ERR<Exp>" and ocr_result_text.__len__() == 0:
                    return 0, ocr_result_text
                ocr_text_list.append(ocr_result_text)
            #end for

            # 处理识别到的ocr列表:有部分聚焦状态会将option及其值一起包括其中,所以要把相同的部分(option或者值)去掉
            ocr_text_list = self.removeDuplicateString(ocr_text_list)
            # 获取到跑马灯option的ocr字典
            ocrStrDict = self.getOCRStrDictByOptionList(menuList)
            print u"获取到的跑马灯Option对应的ocr字典ocrStrDict:", ocrStrDict
            print u"识别到的跑马灯ocr文字列表ocr_text_list:",ocr_text_list
            for marquee_option in ocrStrDict:
                option_ocr_list = ocrStrDict[marquee_option]
                for option_ocr in option_ocr_list:
                    # 一共5张截图,只要有3张满足条件,就算找到了该option(规避同时存在两条相似的跑马灯选项问题,以及跑马灯头尾同时显示的问题)
                    count = 0
                    for ocr_text in ocr_text_list:
                        if ocr_text.lower() in option_ocr:
                            count += 1
                    if count >= 3 and destOption == marquee_option:
                        return 1, destOption
                    elif count >= 3:
                        printLog(u"当前聚焦的跑马灯Option实际为:%s"%marquee_option)
                        return 0, marquee_option
            else:
                printLog(u"未能识别到当前聚焦的跑马灯Option!!!")
                return 0, "unknown marquee text"



    def strSplit(self, str):
        ret = []
        str_int = ''
        str_ch = ''
        ch_last = ' '
        for ch in str:
            if 47 < ord(ch) < 58:
                str_int += ch
                if str_ch.__len__():
                    ret.append(str_ch)
                    str_ch = ''
            else:
                if 47 < ord(ch_last) < 58 and ch == '.':
                    str_int += ch
                    if str_ch.__len__():
                        ret.append(str_ch)
                        str_ch = ''
                else:
                    str_ch += ch
                    if str_int.__len__():
                        ret.append(str_int)
                        str_int = ''
            ch_last = ch
        if str_ch.__len__():
            ret.append(str_ch)
        if str_int.__len__():
            ret.append(str_int)
        return ret

    def getCurrentFocusOcr_Int(self, icon_level, first_parent, option="", isForValue=False):
        print u"getCurrentFocusOcr_Int Start>>>", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        # 聚集框识别;
        cur_img = self.getCurrentUIPath()
        print u"isForValue:", isForValue
        if isForValue:
            bxfound, cur_box = self.tFocus.findRectByIcon2(cur_img, option, True)
        else:
            bxfound, cur_box = self.tFocus.findRectByIcon2(cur_img, option)
        # print "getCurrentFocusBox(%d,%s):" % (int(bxfound), str(cur_box))
        printLog("getCurrentFocusBox(%d,%s):" % (int(bxfound), str(cur_box)))
        if not bxfound or cur_box == []:
            return False, "", 0

        cur_box = self.getFocusTextBox3(option, cur_box, True)
        printLog("getCurrentFocusBox(%d,%s):" % (int(bxfound), str(cur_box)))
        # 截图文本框;
        txt_pic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png")
        self.imgCMP.saveCropPic(cur_img, txt_pic, (cur_box[0], cur_box[1], cur_box[2], cur_box[3]))
        # ocr识别;
        ocr_result = ''
        # 获取ocr列表;
        hasOption, path = self.uitRunner.uitData.UITree.get_option(option)
        if hasOption:
            self.get_ocr_list(path['level'], option)
        for orc_item in self.ocrDict:
            thresholdDict = self.tconfig.getThresholdDict(first_parent)
            # ocr_result = self.ocr.getStr(txt_pic, orc_item["lan"], orc_item["type"])
            ocr_result = self.ocr.getStrWithImgProcess(txt_pic, thresholdDict, orc_item["lan"], orc_item["type"],
                                                       reconTimes=1)
            # print("getCurrentFocusOcr_Int=ocr识别结果=%s" % (ocr_result))
            printLog("getCurrentFocusOcr_Int=ocr识别结果=%s" % (ocr_result))
            if ocr_result == "ERR<Exp>" or ocr_result.__len__() == 0:
                continue
            # 字符串去掉末尾">"符号;
            ocr_result = ocr_result.strip('>')
            # 按数字分解多组文本;
            # list_orc = getDigitFromString(ocr_result)
            list_ocr = self.strSplit(ocr_result)
            # 只判断最后一位是否是数字;
            if list_ocr.__len__() < 1:
                errorPngName = "menutree_error_" + self.currentTime() + "ocr.png"
                error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                self.ccard.takePicture(error_uiPic)
                # print u"当前识别的ocr 不包含int类型值,截图为:%s" % (str(ocr_result))
                printLog(u"当前识别的ocr 不包含int类型值,截图为:%s" % (str(ocr_result)))
                continue

            try:
                # 获取最右边的文本,如果是数字则退出;
                text_int_str = list_ocr[list_ocr.__len__() - 1]
                # print 'text_int_str:', text_int_str
                printLog('text_int_str:%s' % str(text_int_str))
                text_num = float(text_int_str)
                # 返回结果;
                return True, ocr_result, text_num
            except Exception:
                continue

        # endfor
        print u"getCurrentFocusOcr_Int End<<<", time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
        return False, "", 0

    # 遍历获取ocr结果;
    def getCurrentFocusTextEx(self, level, first_parent, cur_parent, option, list_str, isSource=False,
                              isForValue=False):
        print level, first_parent, cur_parent, option
        current_uiPic = self.getCurrentUIPath()
        if isForValue:
            # cur_parent 对应value表里的option;
            # option_info = self.xlsparser.get_option(cur_parent)
            isFind, contourRect = self.tFocus.findRectByIcon2(current_uiPic, cur_parent, isForValue)
        else:
            isFind, contourRect = self.tFocus.findRectByIcon2(current_uiPic, option)
        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")

            if isForValue:
                contourRect = self.getFocusTextBox3(cur_parent, contourRect, True)
            else:
                contourRect = self.getFocusTextBox3(option, contourRect)

            self.imgCMP.saveCropPic(current_uiPic, tmpPic,
                                    (contourRect[0], contourRect[1], contourRect[2], contourRect[3]))
            if isSource:
                self.redRat3.sendKey("ok")

            # print "self.ocrDict:", self.ocrDict
            # 获取ocr_list;
            ocr_list = self.uitRunner.uitData.UITree.get_ocr_list(level, cur_parent, option, True if cur_parent == option else False)
            print u"%s,%s,%s =>ocr_list=%s" % (level, cur_parent, option, str(ocr_list))

            # 获取ocr列表;
            self.get_ocr_list(level, option)
            # 遍历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:
                    if isForValue:
                        parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(cur_parent, value_sheet=True)
                    else:
                        parent_ocr_dict = self.uitRunner.uitData.UITree.get_parent_ocr_dict(option)
                    print u"getCurrentFocusTextEx.parent_ocr_dict:", parent_ocr_dict
                    list_parent_ocr_value = list(parent_ocr_dict.keys())
                    print u"getCurrentFocusTextEx.list_parent_ocr_value:", list_parent_ocr_value

                    # 比较所有的ocr
                    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 strcmp(parent_ocr_value, ocr_str):
                            # 优先比较目标option,如果符合要求则直接返回找到结果
                            for std_str in list_str:
                                std_str = str(std_str).lower()
                                if strcmp(std_str, parent_ocr_value):
                                    printLog(u"传入的目标Value_ocr_list为:%s" % list_str)
                                    printLog(u"与目标option的ocr_value:%s相同"%std_str)
                                    return 1, option
                            else:
                                # 否则则识别出该ocr_value所对应的option
                                try:
                                    currentOption = parent_ocr_dict[parent_ocr_value]
                                except Exception,e:
                                    currentOption = ""
                                    printLog(u"识别出的currentOption为:%s" % currentOption)
                                if currentOption != "":
                                    return 0, currentOption
                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
            else:
                # 全部ocr_value都不符合要求,则视为menutree中不存在此option相关的数据
                printLog(u"未能识别出当前Option!!!请检查Mnenutree相关参数配置!!!")
                return 0, ocr_str


    # 移动到目标网格焦点上;
    def move2TargetGridNode(self, level, first_parent, paths, returnKeyEventCount, Max_Try=15):
        result = False
        cur_option = paths['option']
        last_box, cur_box = [], []

        # 遍历正序;
        is_positive = True
        key_idx = False
        key_dir = ['right', 'left']
        # 第一个,最后一个;
        is_first, is_last = False, False
        # 上一行,下一行;
        is_up, is_down = False, False

        # 获取等待时间
        waitTime = self.getOptionWaitTime(paths['option'])
        time.sleep(waitTime)

        while True:
            cur_pic = self.getCurrentUIPath()
            found_box, cur_box = self.tFocus.findRectByIcon2(cur_pic, cur_option)
            if found_box is True:
                if last_box == cur_box:
                    if is_positive is True:  # 正序;
                        if is_last is True:
                            is_positive = False
                            key_idx = not key_idx
                            last_box = []
                            # 移动上一格;
                            self.redRat3.sendKey(key_dir[int(key_idx)])
                            continue

                        if is_down is False:
                            is_down = True
                            # 移动下一行;
                            self.redRat3.sendKey('down')
                            key_idx = not key_idx
                        else:
                            is_last = True
                            key_idx = not key_idx
                    else:  # 逆序;
                        if is_first is True:
                            break

                        if is_up is False:
                            is_up = True
                            # 移动上一行;
                            self.redRat3.sendKey('up')
                            key_idx = not key_idx
                        else:
                            is_first = True
                            key_idx = not key_idx
                    # endif
                else:
                    found_target, cur_text = self.getFocusText(level, first_parent, paths, cur_pic, cur_box)
                    if found_target is True:
                        result = True
                        break
                    # 保留为上一焦点框;
                    last_box = cur_box
                    # 移动下一焦点;
                    self.redRat3.sendKey(key_dir[int(key_idx)])

                    # 第一个,最后一个;
                    is_first, is_last = False, False
                    # 上一行,下一行;
                    is_up, is_down = False, False
                # endif
            else:
                printLog(u"网格焦点框识别失败")
                break
            # endif

        # 返回结果;
        return result

    def move2TargetGridNode_matchTemp(self, level, first_parent, paths, returnKeyEventCount, Max_Try = 15):
        # 目标结点;
        tgt_option = paths['option']
        temp_dir = os.path.join(getMenuTree3SelectedProjectCfgPath(), "match_temp", paths['parent'])        
        # 选中时的模板
        img_focus_temp = os.path.join(temp_dir, tgt_option + '_focus.jpg')
        # 未选中模板图
        img_unfocus_temp = os.path.join(temp_dir, tgt_option + '_unfocus.jpg')

        # 获取等待时间
        waitTime = self.getOptionWaitTime(paths['option'])
        time.sleep(waitTime)
        
        # 尝试次数;
        page_try_time = 15
        focus_try_time = 100
        # 目标聚集结果;
        tgt_focus_result = False
        while tgt_focus_result is False:
            # 电视截图(原图);
            img_tv = self.getCurrentUIPath()
            # 查找聚集框是否在目标上;
            match_result = self.tFocus.feature_detect.matchSingleImage(img_tv, None, img_focus_temp)
            if match_result is not None:
                tgt_focus_result = True
                break
            #end-if

            # 查找非聚集目标;
            match_result = self.tFocus.feature_detect.matchSingleImage(img_tv, None, img_unfocus_temp)
            if match_result is None:
                # 尝试次数使用完;
                if page_try_time == 0:
                    break
                # 没找到,可能在别的页面,向右移动;
                self.redRat3.sendKey('right')
                page_try_time = page_try_time - 1
                continue
            # end-if

            print u'匹配度=', match_result['tmpVal']
            # 找到非聚集目标后,再查找当前聚集框坐标;
            bfound_box, focus_box = self.tFocus.findRectByIcon2(img_tv, tgt_option, is_value_sheet=False)  # 不支持叶结点;
            if bfound_box is False:
                printLog("move2TargetGridNode_matchTemp:未找到聚集框")
                break
            #end-if

            box1, box2 = focus_box, match_result['coordinate']
            # 计算非聚集模板与聚集框的位置;
            dir = self.tFocus.feature_detect.getOrientationEx(box1, box2)
            if dir == -1:
                break

            # 中心点坐标;center point
            # cpt1 = [box1[2]-box1[0],box1[3]-box1[1]]
            # cpt2 = [box2[2]-box2[0],box2[3]-box2[1]]
            if dir == 0:# 左上方;
                self.redRat3.sendKey('right')
            elif dir == 1:# 正上方;
                self.redRat3.sendKey('down')
            elif dir == 2:# 右上方;
                self.redRat3.sendKey('left')
            elif dir == 3:# 正左方;
                self.redRat3.sendKey('right')
            elif dir == 4:# 正右方;
                self.redRat3.sendKey('left')
            elif dir == 5:# 左下方;
                self.redRat3.sendKey('right')
            elif dir == 6:# 正下方;
                self.redRat3.sendKey('up')
            elif dir == 7:# 右下方;
                self.redRat3.sendKey('left')
                    
            # 移动次数用完;
            focus_try_time = focus_try_time -1
            if focus_try_time == 0:
                break
        #end-while;

        return tgt_focus_result

    # 移动到目标节点上;
    def move2TargetNode(self, level, first_parent, paths, returnKeyEventCount, findDirection="down", Max_Try=15):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到option_for_ocr所在的区域,则按照传入方向的反方向 反向寻找 Max_Try 次
        # 正向寻找的次数计数和最大次数
        count = 0
        parent = paths['parent']
        option_list = self.uitRunner.uitData.UITree.getSubOptionList(parent)
        if option_list.__len__() != 0:
            Max_Try = option_list.__len__()
            print u"move2TargetNode.%s option_list:"%parent, option_list
        # 反向寻找的次数计数和最大次数
        Reversecount = 0
        Reverse_Max_Try = Max_Try
        print u"move2TargetNode:Max_Try:%s, Reverse_Max_Try:%s"%(Max_Try, Reverse_Max_Try)

        if findDirection == "grid":
            temp_dir = os.path.join(getMenuTree3SelectedProjectCfgPath(), "match_temp", paths['parent'])
            if os.path.exists(temp_dir):
                return self.move2TargetGridNode_matchTemp(level, first_parent, paths, returnKeyEventCount, Max_Try)
            else:
                return self.move2TargetGridNode(level, first_parent, paths, returnKeyEventCount, Max_Try)

        # 记录上一个焦点识别的文字内容   用于判断是否到达列表的边界 如果到达边界则反向寻找
        old_text = "init_old_text"
        # 反向寻找的遥控器按键值
        findReverseDirection = "up"

        if findDirection == "up":
            findReverseDirection = "down"
        if findDirection == "down":
            findReverseDirection = "up"
        if findDirection == "left":
            findReverseDirection = "right"
        if findDirection == "right":
            findReverseDirection = "left"

        print u"findDirection:", findDirection, type(findDirection)
        print u"findReverseDirection:", findReverseDirection, type(findReverseDirection)

        # # 去除大小写的识别字符
        # option_for_ocr_low = str(option_for_ocr).lower()

        isMarquee = False
        marquee_dict = {}
        # 是否有跑马灯文本;
        if paths["others"].__len__():
            data_other = json.loads(paths["others"])
            if "marquee" in data_other:
                marquee_dict = data_other['marquee']
                isMarquee = True

        # 获取等待时间
        waitTime = self.getOptionWaitTime(paths['option'])
        printLog(u"move2TargetNode:获取到进入option_%s,等待时间为%s"%(paths['option'],waitTime))
        time.sleep(waitTime)

        while (True):
            print "count:", count
            if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                break
            if isMarquee is True:
                isFind, text = self.getFocusBoxMarqueeText(marquee_dict, level, first_parent, paths)
            else:
                isFind, text = self.getCurrentFocusTextEx(level, first_parent, paths["parent"], paths["option"],
                                                          paths["option_for_ocr"])
            if isFind == -1:
                errorPngName = "menutree_error_" + str(paths["option"]) + self.currentTime() + ".png"
                error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                self.ccard.takePicture(error_uiPic)
                printLog(u"聚焦到目标option:%s失败!当前界面无法找到焦点区域!!!出错界面截图%s" % (str(paths["option"]), str(error_uiPic)))
                self.redRat3.sendKey("return", returnKeyEventCount, 0.5)
                return False
            # elif (self.ocr.cmpOcrStr(text, option_for_ocr)):
            # 由比较目标文本和识别文本 是否相等  改为 识别文本是否包含目标文本
            else:
                if isFind == 1:
                    printLog(u"聚焦到目标option:%s成功!" % str(paths["option"]))
                    return True
                # 判断两次识别的text是否相等来判断是否到达边界
                print u"move2TargetNode.text",text
                print u"move2TargetNode.old_text",old_text
                if self.ocr.cmpOcrStr(text, old_text):
                    # 如果已经到达边界则不再正方向寻找焦点
                    count = Max_Try
                    old_text = "init_old_text"
                else:
                    old_text = text

                if count < Max_Try:
                    count = count + 1
                    self.redRat3.sendKey(findDirection)
                else:
                    Reversecount = Reversecount + 1
                    self.redRat3.sendKey(findReverseDirection)
        errorPngName = "menutree_error_" + str(paths["option"]) + self.currentTime() + ".png"
        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
        self.ccard.takePicture(error_uiPic)
        printLog(u"聚焦到目标option:%s失败!正向遍历%s次,和反向遍历%s次都没有聚焦到option:%s中,截图路径:%s" % (str(paths["option"]),
                                                                                 str(Max_Try), str(Reverse_Max_Try),
                                                                                 str(paths["option"]),
                                                                                 str(error_uiPic)))
        return False

    # 设置叶子节点值;
    def setLeafNodeValue(self, level, first_parent, option, value_excel, value_for_ocr, value, move_key, enter_key,
                         Max_Try=15):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到option_for_ocr所在的区域,则按照传入方向的反方向 反向寻找 2*Max_Try 次

        # 正向寻找的次数计数和最大次数
        count = 0
        Max_Try = Max_Try
        # 反向寻找的次数计数和最大次数
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        # 记录上一个焦点识别的文字内容   用于判断是否到达列表的边界 如果到达边界则反向寻找
        old_text = "init_old_text"

        # 正向寻找的遥控器按键值
        findDirection = move_key[1]  # 向右或者向下
        # 反向寻找的遥控器按键值
        findReverseDirection = move_key[0]  # 向左或者向上




        # 获取等待时间
        waitTime = self.getLeafWaitTime(option)
        printLog(u"setLeafNodeValue:获取到进入叶节点%s,等待时间为%s"%(option, waitTime))
        time.sleep(waitTime)

        duration = 0.2

        isMarquee = False
        marquee_dict = {}
        leaf_data = self.uitRunner.uitData.UITree.get_value(option)
        if leaf_data["others"].__len__():
            data_other = json.loads(leaf_data["others"])
            # 是否有跑马灯文本;
            if "marquee" in data_other:
                marquee_dict = data_other['marquee']
                isMarquee = True
            # 是否有按键时间设置
            if "duration" in data_other:
                duration = float(data_other['duration'])
        printLog(u"读取到的设值间隔为%s"%duration)

        value_for_ocr_low = str(value_for_ocr[0]).lower()
        # 判断设置值的类型 是rang类型还是str类型
        if "range(" in value_for_ocr_low:
            isRangeType = True
            str_num = value_for_ocr_low.replace("range", "")
            list_num = eval(str_num)
            min_num = list_num[0]
            max_num = list_num[1]
            try:
                value_num = int(value)
            except Exception:
                printLog(u"传入的值value:%s和option:%s对应的类型不匹配 !" % (str(value), str(option)))
                return False
        else:
            isRangeType = False
        if isRangeType:
            # 设置数值范围类型的处理
            pass
            while (True):
                # 执行超过3次操作仍然失败则返回False
                if count > 3:
                    break

                isFind, text, text_num = self.getCurrentFocusOcr_Int(level, first_parent, option=option,
                                                                     isForValue=True)
                if not isFind:
                    errorPngName = "menutree_error_" + str(option) + str(value_excel) + self.currentTime() + ".png"
                    error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                    self.ccard.takePicture(error_uiPic)
                    printLog(u"设置叶子节点值时,当前界面无法找到焦点区域!!!getCurrentFocusOcr_Int出错界面截图%s" % str(error_uiPic))
                    return False
                else:

                    if text_num < min_num or text_num > max_num:
                        errorPngName = "menutree_error_" + str(option) + '_' + str(
                            value_excel) + self.currentTime() + ".png"
                        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                        self.ccard.takePicture(error_uiPic)
                        printLog(u"设置叶子节点值时,当前option:%s 识别出来的值text:%s 不在value_for_ocr:%s范围内,截图为:%s" % (
                            str(option), str(text), str(value_for_ocr), str(error_uiPic)))
                        return False
                    # if abs(text_num) == abs(value_num):
                    if text_num == value_num:
                        printLog(u"聚焦到目标option:%s,设置value:%s选项成功!" % (str(option), str(value_excel)))
                        # 聚焦成功发送enter_key
                        if enter_key != 'default':
                            self.redRat3.sendKey(enter_key)
                        return True
                    else:
                        if findDirection == 'input':
                            # 发送按键;
                            for key in list(str(value_num)):
                                self.redRat3.sendKey(key, 1, duration)
                            if max_num > 100:
                                return True
                        else:
                            count = count + 1
                            # 如果目标值大于现有值,则按正方向按键(向下或者向右)增加当前界面的值
                            if value_num > text_num:
                                self.redRat3.sendKey(findDirection, value_num - text_num, duration)
                            # 如果目标值小于现有值,则按反方向按键(向上或者向左)减少当前界面的值
                            if value_num < text_num:
                                self.redRat3.sendKey(findReverseDirection, text_num - value_num, duration)
            errorPngName = "menutree_error_" + str(option) + '_' + str(value_excel) + self.currentTime() + ".png"
            error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
            self.ccard.takePicture(error_uiPic)
            printLog(u"设置叶子节点值时,当前option:%s 设置3次仍未设置到目标值value:%s,截图为:%s " % (str(option), str(value), str(error_uiPic)))
            return False
        else:
            # 设置选项类型的处理
            while (True):
                print "count:", count
                if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                    break
                if isMarquee is True:
                    # 跑马灯函数需要cur_parent的参数,把cur_parent参数加入到leaf_data中再传进去
                    result, paths = self.uitRunner.uitData.UITree.get_option(option)
                    leaf_data['parent'] = paths['parent']
                    leaf_data['option_for_ocr'] = leaf_data['value_for_ocr']
                    isFind, text = self.getFocusBoxMarqueeText(marquee_dict, level, first_parent, leaf_data)
                else:
                    isFind, text = self.getCurrentFocusTextEx(level, first_parent, option, value_excel, value_for_ocr,
                                                          isForValue=True)
                if isFind == -1:
                    errorPngName = "menutree_error_" + str(option) + '_' + str(
                        value_excel) + self.currentTime() + ".png"
                    error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                    self.ccard.takePicture(error_uiPic)
                    printLog(u"设置叶子节点值时,当前界面无法找到焦点区域!!!getCurrentFocusTextEx 出错界面截图%s" % str(error_uiPic))
                    return False
                # elif (self.ocr.cmpOcrStr(text, value_for_ocr)):
                # 由比较目标文本和识别文本 是否相等  改为 识别文本是否包含目标文本
                else:
                    if isFind == 1:
                        printLog(u"聚焦到目标option:%s,设置value:%s选项成功!" % (str(option), str(value_excel)))
                        # 聚焦成功发送enter_key
                        if enter_key != 'default':
                            self.redRat3.sendKey(enter_key)
                        return True
                        # 判断两次识别
                    # 判断两次识别的text是否相等来判断是否到达边界
                    if self.ocr.cmpOcrStr(text, old_text):
                        # 如果已经到达边界则不再正方向寻找焦点
                        count = Max_Try
                        old_text = "init_old_text"
                    else:
                        old_text = text

                    if count < Max_Try:
                        count = count + 1
                        self.redRat3.sendKey(findDirection)
                    else:
                        Reversecount = Reversecount + 1
                        self.redRat3.sendKey(findReverseDirection)
            errorPngName = "menutree_error_" + str(option) + '_' + str(value_excel) + self.currentTime() + ".png"
            error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
            self.ccard.takePicture(error_uiPic)
            printLog(u"设置叶子节点值时,正向遍历%s次,和反向遍历%s次都没有聚焦到option:%s的value:%s选项中,截图为%s" % (
                str(Max_Try), str(Reverse_Max_Try), str(option), str(value_excel), str(error_uiPic)))
            return False

        return True

    # 处理others字段;
    def dealOthers(self, level, path):
        others = json.loads(path['others'])
        if "password" in others:
            password = self.tconfig.get_value("Password", others["password"])
            # 发送密码前,停2秒(因为像6586机芯响应很慢,密码框还没弹出就完成了密码输入的操作);
            time.sleep(2)
            # 发送按键;
            for key in list(password):
                self.redRat3.sendKey(key, 1, 0.2)
            time.sleep(1)
            # 发送ok键;
            if others["enter_key"] != "default":
                self.redRat3.sendKey(others["enter_key"])
                # 判断是否成功输入密码;
            current_uiPic = self.getCurrentUIPath()
            # 此处findRectByIcon参数3传递的不是first_parent,而是当前option的parent;
            isFind, contourRect = self.tFocus.findRectByIcon(current_uiPic, level, path['parent'])
            return not isFind
        return False

    # 由于测试开始之前都切到黑屏背景,去掉聚焦效果OCR验证,3次焦点验证,验证到有聚焦效果就返回
    def isFirstOptionShow(self, level, first_parent, first_option):
        for i in range(3):
            current_uiPic = self.getCurrentUIPath()
            isFind, contourRect = self.tFocus.findRectByIcon2(current_uiPic, first_option)
            if isFind:
                return True
        return False

    # 对外接口:设置操作值;
    def setOptionValue(self, option, value, Max_Try=15, reTryTime=0, leafNodeValueWaitTime=0.0, returnKeyEventTimes=-1):
        # 切黑场;
        self.sourceInput.setPattern(11)
        printLog(u"开始执行setOptionValue。option:%s  value:%s" % (str(option), str(value)))
        # 寻路结果;
        result = False
        # 获取menu path;
        value_params, path_params = self.uitPathManage.get_menu_paths(option, value)
        printLog(u"获取到达option:%s的路径字典path_params:%s" % (str(option), str(path_params)))
        printLog(u"获取设置value:%s的值字典value_params:%s" % (str(value), str(value_params)))

        checkRunOptionPathResult = self.uitPathManage.checkRunOptionPath(path_params)
        if str(checkRunOptionPathResult) == "NoExit":
            printLog(u"表格中不存在到达Option:   %s   的路径,在表格中排查到达该Option路径" % str(option))
            return False
        if str(checkRunOptionPathResult) == "Fail":
            printLog(u"表格中到达Option:   %s   的路径出现数据断层找不到First层级,在表格中排查到达该Option路径" % str(option))
            return False

        # returnKeyEventCount = path_params.__len__() + 1
        returnKeyEventCount = 0
        print u"returnKeyEventCount:", returnKeyEventCount
        # 逆序路径key;
        revpp = reversed(path_params)
        # 根节点是否已进入;
        entry = False
        first_parent = u''
        first_option = u''
        # 遍历路径(已排序,从first开始);
        # print "revpp:", revpp
        for level in revpp:
            # print "level:", level, path_params[level]
            printLog(u"执行路径level:%s  对应路径字典:%s" % (str(level), str(path_params[level])))
            # 是否进入根结点;
            if entry == False:
                # 标记已进入根;
                entry = True
                first_parent = path_params[level]["parent"]
                first_option = path_params[level]["option"]
                checkFirstOptionTimes = 0
                while True:
                    if checkFirstOptionTimes > 2:
                        errorPngName = "menutree_error_" + str(option) + '_' + str(value) + self.currentTime() + ".png"
                        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                        self.ccard.takePicture(error_uiPic)
                        printLog(u"执行setOptionValue ERROR!option:%s  value:%s ;尝试3次快捷按键仍然没有唤出聚焦焦点界面!!!  出错截图:%s" % (
                            str(option), str(value), str(error_uiPic)))
                        return False
                    printLog(u"第%s次尝试呼出一级界面" % str(checkFirstOptionTimes))
                    # 判断是否存在others字段,others字段中存在first_key,则优先使用first_key进入
                    try:
                        others = json.loads(path_params[level]["others"])
                    except Exception,e:
                        others = {}
                    printLog("section others:%s"%others)
                    if "first_key" in others.keys():
                        first_key = others["first_key"]
                    else:
                        first_key = path_params[level]["parent"]
                    printLog(u"进入根节点,first_key:%s"%first_key)
                    # 进入根节点
                    self.redRat3.sendKey(first_key)
                    waitTime = self.getParentWaitTime(path_params[level]["parent"])
                    printLog(u"打开%s界面的等待时间waittime为:%s" % (str(path_params[level]["parent"]), str(waitTime)))
                    time.sleep(waitTime)
                    # 获取ocr列表;
                    self.get_ocr_list(level, option)
                    if self.isFirstOptionShow(level, first_parent, first_option):
                        printLog(u"呼出一级菜单界面")
                        break
                    else:
                        time.sleep(5)
                        self.redRat3.sendKey("return", 1)
                        checkFirstOptionTimes = checkFirstOptionTimes + 1
                # 如果一级界面弹出成功,则退出时候返回按键次数加1
                returnKeyEventCount = returnKeyEventCount + 1

            print u"level:", level, "first_parent:", first_parent

            # 如果 others 字段不为空;
            if path_params[level]["others"].__len__():
                # 如果不是跑马灯处理则按照输入密码处理
                if self.dealOthers(level, path_params[level]) is True:
                    # print u"解锁失败!!!"
                    printLog(u"执行setOptionValue ERROR!option:%s  value:%s ;解锁失败!!!" % (str(option), str(value)))
                    return False

            cur_option_enter_key = path_params[level]["option_enter_key"]
            # 移动到子节点;                
            if cur_option_enter_key.__len__() == 0:
                enter_key = path_params[level]["enter_key"]
            else:
                enter_key = cur_option_enter_key

            move_key = path_params[level]["move_key"]

            if str(move_key) == str([u'up', u'down']) or str(move_key) == str([u'down', u'up']):
                findDirection = str(move_key[1])
            elif str(move_key) == str([u'left', u'right']) or str(move_key) == str([u'right', u'left']):
                findDirection = str(move_key[1])
            else:
                findDirection = 'grid'

            result = self.move2TargetNode(
                level,
                first_parent,
                path_params[level],
                returnKeyEventCount,
                findDirection=findDirection, Max_Try=Max_Try)
            if result is True:
                # 子节点的进入方式默认为ok;
                if enter_key != u'default':
                    self.redRat3.sendKey(enter_key)
                    # 如果执行一次enter_key,则退出时按返回键的次数加一
                    returnKeyEventCount = returnKeyEventCount + 1
            else:
                break
        # end-for
        # 寻路成功,设置叶节点值;
        if result is True:
            # 如果是信源选择   自动选择不需要执行 enter_key
            if self.ocr.cmpOcrStr(option, 'source'):
                return True
            time.sleep(leafNodeValueWaitTime)
            print u"执行设置叶节点:", value_params
            result = self.setLeafNodeValue(
                level,
                first_parent,
                value_params["option"],
                value_params["value"],
                value_params["value_for_ocr"],
                value,
                value_params["move_key"],
                value_params["enter_key"],
                Max_Try=Max_Try)

        # else:
        if returnKeyEventTimes == -1:
            print u"执行退出,执行退出按键次数returnKeyEventCount:", returnKeyEventCount
            # 无论成功失败,要返回到初始界面
            self.redRat3.sendKey("return", returnKeyEventCount, 0.2)
            time.sleep(1)
            # 检测执行回退键是否成功,吐过仍有聚焦效果则继续执行return键
            reCount = 0
            while True:
                if reCount >= returnKeyEventCount:
                    printLog(u"执行了returnKeyEventCount:%s次,仍无法退出到初始界面" % str(returnKeyEventCount))
                    break
                # isFind, text = self.getCurrentFocusText("First", first_parent)
                # if isFind:
                if self.isFirstOptionShow("First", first_parent, first_option):
                    print u"还没有退到初始界面"
                    reCount = reCount + 1
                    # 如果仍然可以检测到聚焦效果,则继续执行return
                    self.redRat3.sendKey("return")
                else:
                    printLog(u"回退到初始界面成功!")
                    break
        else:
            print u"执行退出,执行退出按键次数returnKeyEventTimes:", returnKeyEventTimes
            # 无论成功失败,要返回到初始界面
            self.redRat3.sendKey("return", returnKeyEventTimes, 0.2)

        if result:
            printLog(u"设置option:%s 选中value:%s的值成功!" % (str(option), str(value)))
        else:
            printLog(u"重新设置option:%s 选中value:%s的值失败!" % (str(option), str(value)))
        # 不再执行重试动作
        # else:
        #     if reTryTime < 1:
        #         reTryTime = reTryTime + 1
        #         result = self.setOptionValue(option, value, reTryTime=reTryTime)
        #         if result:
        #             printLog(u"重新设置option:%s 选中value:%s的值成功!" % (str(option), str(value)))
        #             return True
        #         else:
        #             printLog(u"重新设置option:%s 选中value:%s的值失败!" % (str(option), str(value)))
        #             return False
        #     else:
        #         printLog(u"设置option:%s 选中value:%s的值尝试2次仍失败!" % (str(option), str(value)))
        #         return False
        # 返回结果;
        return result

    # 对外接口:检测操作值是否正确;
    def checkOptionValue(self, option, value, Max_Try=15, leafNodeValueWaitTime=0.0):
        # 切黑场;
        self.sourceInput.setPattern(11)
        printLog(u"开始执行checkOptionValue。option:%s  value:%s" % (str(option), str(value)))
        # 寻路结果;
        result = False
        # 获取menu path;
        value_params, path_params = self.uitPathManage.get_menu_paths(option, value)
        printLog(u"获取到达option:%s的路径字典path_params:%s" % (str(option), str(path_params)))
        printLog(u"获取检测value:%s的值字典value_params:%s" % (str(value), str(value_params)))

        checkRunOptionPathResult = self.uitPathManage.checkRunOptionPath(path_params)
        if str(checkRunOptionPathResult) == "NoExit":
            printLog(u"表格中不存在到达Option:   %s   的路径,在表格中排查到达该Option路径" % str(option))
            return False
        if str(checkRunOptionPathResult) == "Fail":
            printLog(u"表格中到达Option:   %s   的路径出现数据断层找不到First层级,在表格中排查到达该Option路径" % str(option))
            return False

        # returnKeyEventCount = path_params.__len__() + 1
        returnKeyEventCount = 0
        print "returnKeyEventCount:", returnKeyEventCount
        # 逆序路径key;
        revpp = reversed(path_params)
        # 根节点是否已进入;
        entry = False
        root = u''
        first_parent = u''
        first_option = u''
        # 遍历路径(已排序,从first开始);
        # print "revpp:", revpp
        for level in revpp:
            # print "level:", level, path_params[level]
            printLog(u"执行路径level:%s  对应路径字典:%s" % (str(level), str(path_params[level])))
            # 是否进入根结点;
            if entry == False:
                # 标记已进入根;
                entry = True
                first_parent = path_params[level]["parent"]
                first_option = path_params[level]["option"]
                checkFirstOptionTimes = 0
                while True:
                    if checkFirstOptionTimes > 2:
                        errorPngName = "menutree_error_" + str(option) + '_' + str(value) + self.currentTime() + ".png"
                        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                        self.ccard.takePicture(error_uiPic)
                        printLog(u"执行checkOptionValue ERROR!option:%s  value:%s ;尝试3次快捷按键仍然没有唤出聚焦焦点界面!!!  出错截图:%s" % (
                            str(option), str(value), str(error_uiPic)))
                        return False
                    printLog(u"第%s次尝试呼出一级界面" % str(checkFirstOptionTimes))
                    # # 进入根节点(根节点名就是遥控键名);
                    # self.redRat3.sendKey(path_params[level]["parent"])

                    # 判断是否存在others字段,others字段中存在first_key,则优先使用first_key进入
                    try:
                        others = json.loads(path_params[level]["others"])
                    except Exception,e:
                        others = {}
                    printLog("section others:%s"%others)
                    if "first_key" in others.keys():
                        first_key = others["first_key"]
                    else:
                        first_key = path_params[level]["parent"]
                    printLog(u"进入根节点,first_key:%s"%first_key)
                    # 进入根节点
                    self.redRat3.sendKey(first_key)
                    waitTime = self.getParentWaitTime(path_params[level]["parent"])
                    printLog(u"打开%s界面的等待时间waittime为:%s" % (str(path_params[level]["parent"]), str(waitTime)))
                    time.sleep(waitTime)
                    # 获取ocr列表;
                    self.get_ocr_list(level, option)
                    if self.isFirstOptionShow(level, first_parent, first_option):
                        printLog(u"呼出一级菜单界面")
                        break
                    else:
                        time.sleep(5)
                        self.redRat3.sendKey("return", 1)
                        checkFirstOptionTimes = checkFirstOptionTimes + 1
                # 如果一级界面弹出成功,则退出时候返回按键次数加1
                returnKeyEventCount = returnKeyEventCount + 1

            # 如果 others 字段不为空;
            if path_params[level]["others"].__len__():
                # 如果不是跑马灯处理则按照输入密码处理
                if self.dealOthers(level, path_params[level]) is True:
                    # print u"解锁失败!!!"
                    printLog(u"执行checkOptionValue ERROR!option:%s  value:%s ;解锁失败!!!" % (str(option), str(value)))
                    return False

            # 移动到子节点;
            cur_option_enter_key = path_params[level]["option_enter_key"]
            # 移动到子节点;                
            if cur_option_enter_key.__len__() == 0:
                enter_key = path_params[level]["enter_key"]
            else:
                enter_key = cur_option_enter_key

            move_key = path_params[level]["move_key"]

            if str(move_key) == str([u'up', u'down']) or str(move_key) == str([u'down', u'up']):
                findDirection = str(move_key[1])
            elif str(move_key) == str([u'left', u'right']) or str(move_key) == str([u'right', u'left']):
                findDirection = str(move_key[1])
            else:
                findDirection = 'grid'

            result = self.move2TargetNode(
                level,
                first_parent,
                path_params[level],
                returnKeyEventCount,
                findDirection=findDirection, Max_Try=Max_Try)

            if result is True:
                # 子节点的进入方式默认为ok;
                # self.redRat3.sendKey('ok')
                # 子节点的进入方式默认为ok;
                if enter_key != u'default':
                    self.redRat3.sendKey(enter_key)
                    # 如果执行一次enter_key,则退出时按返回键的次数加一
                    returnKeyEventCount = returnKeyEventCount + 1
            else:
                break
        # end-for

        # 寻路成功,设置叶节点值;
        if result is True:
            # 如果是信源选择   自动选择不需要执行 enter_key
            if self.ocr.cmpOcrStr(option, 'source') or self.ocr.cmpOcrStr(option, 'ok'):
                return True
            time.sleep(leafNodeValueWaitTime)
            result = self.checkLeafNodeValue(level, root, value_params["option"],
                                             value_params["value"],
                                             value_params["value_for_ocr"],
                                             value)

        print u"执行退出,执行退出按键次数returnKeyEventCount:", returnKeyEventCount
        # 无论成功失败,要返回到初始界面
        self.redRat3.sendKey("return", returnKeyEventCount, 0.2)
        time.sleep(1)
        # 检测执行回退键是否成功,吐过仍有聚焦效果则继续执行return键
        reCount = 0
        while True:
            if reCount >= returnKeyEventCount:
                printLog(u"执行了returnKeyEventCount:%s次,仍无法退出到初始界面" % str(returnKeyEventCount))
                break
            if self.isFirstOptionShow("First", first_parent, first_option):
                reCount = reCount + 1
                # 如果仍然可以检测到聚焦效果,则继续执行return
                self.redRat3.sendKey("return")
            else:
                printLog(u"回退到初始界面成功!")
                break

        if result:
            printLog(u"检测option:%s 选中value:%s的值成功!" % (str(option), str(value)))
        else:
            printLog(u"检测option:%s 选中value:%s的值失败!" % (str(option), str(value)))
        # 返回结果;
        return result

    def checkLeafNodeValue(self, level, parent, option, value_excel, value_for_ocr, value):
        # 获取等待时间
        waitTime = self.getOptionWaitTime(option)
        printLog(u"checkLeafNodeValue:获取到进入叶节点%s,等待时间为%s"%(option, waitTime))
        time.sleep(waitTime)

        value_for_ocr_low = str(value_for_ocr[0]).lower()
        # 判断设置值的类型 是rang类型还是str类型
        if "range(" in value_for_ocr_low:
            isRangeType = True
            str_num = value_for_ocr_low.replace("range", "")
            list_num = eval(str_num)
            min_num = list_num[0]
            max_num = list_num[1]
            try:
                value_num = int(value)
            except Exception:
                printLog(u"传入的值value:%S和option:%s对应的类型不匹配 !" % (str(value), str(option)))
                return False
        else:
            isRangeType = False
        if isRangeType:
            # 设置数值范围类型的处理
            isFind, text, text_num = self.getCurrentFocusOcr_Int(level, parent, option=option, isForValue=True)
            if not isFind:
                errorPngName = "menutree_error_" + str(option) + str(value_excel) + self.currentTime() + ".png"
                error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                self.ccard.takePicture(error_uiPic)
                printLog(u"检测叶子节点值时,当前界面无法找到焦点区域!!!出错界面截图%s" % str(error_uiPic))
                return False
            else:
                pass
                try:
                    list_text_num = getDigitFromString(text)
                    if list_text_num.__len__() < 1:
                        errorPngName = "menutree_error_" + str(option) + '_' + str(
                            value_excel) + self.currentTime() + ".png"
                        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                        self.ccard.takePicture(error_uiPic)
                        printLog(u"检测叶子节点值时,当前option:%s 识别出来的值text:%s 不包含int类型值,截图为:%s" % (
                            str(option), str(text), str(error_uiPic)))
                        return False
                    text_int_str = list_text_num[list_text_num.__len__() - 1]
                    # print 'text_int_str:', text_int_str
                    text_num = int(text_int_str)
                    printLog(u"检测到的值text_num:%s" % str(text_num))
                except Exception:
                    errorPngName = "menutree_error_" + str(option) + '_' + str(
                        value_excel) + self.currentTime() + ".png"
                    error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                    self.ccard.takePicture(error_uiPic)
                    printLog(u"检测叶子节点值时,当前option:%s 识别出来的值text:%s 不能转换成value_for_ocr:%s范围内的int类型,截图为:%s" % (
                        str(option), str(text_int_str), str(value_for_ocr), str(error_uiPic)))
                    return False
                if text_num < min_num or text_num > max_num:
                    errorPngName = "menutree_error_" + str(option) + '_' + str(
                        value_excel) + self.currentTime() + ".png"
                    error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                    self.ccard.takePicture(error_uiPic)
                    printLog(u"检测叶子节点值时,当前option:%s 识别出来的值text:%s 不在value_for_ocr:%s范围内,截图为:%s" % (
                        str(option), str(text), str(value_for_ocr), str(error_uiPic)))
                    return False
                # if abs(text_num) == abs(value_num):
                if text_num == value_num:
                    printLog(u"检测叶子节点值时,聚焦到目标option:%s,检测value:%s选项成功!" % (str(option), str(value_excel)))
                    return True
                else:
                    return False
        else:
            # 设置选项类型的处理
            isFind, text = self.getCurrentFocusTextEx(level, parent, option, value_excel, value_for_ocr,
                                                      isForValue=True)
            if not isFind:
                errorPngName = "menutree_error_" + str(option) + '_' + str(value_excel) + self.currentTime() + ".png"
                error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                self.ccard.takePicture(error_uiPic)
                printLog(u"检测叶子节点值时,当前界面无法找到焦点区域!!!出错界面截图:%s" % str(error_uiPic))
                return False
            # elif (self.ocr.cmpOcrStr(text, value_for_ocr)):
            # 由比较目标文本和识别文本 是否相等  改为 识别文本是否包含目标文本
            else:
                for value_for_ocr_text in value_for_ocr:
                    value_for_ocr_text_low = str(value_for_ocr_text).lower()
                    if value_for_ocr_text_low in text:
                        printLog(u"检测叶子节点值时,聚焦到目标option:%s,检测value:%s选项成功!" % (str(option), str(value_excel)))
                        return True
                errorPngName = "menutree_error_" + str(option) + '_' + str(value_excel) + self.currentTime() + ".png"
                error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                self.ccard.takePicture(error_uiPic)
                printLog(u"检测叶子节点值时,聚焦到目标option:%s,检测value:%s选项失败!出错界面截图:%s" % (
                    str(option), str(value_excel), str(error_uiPic)))
                return False

    
    # 对外接口:信源设置接口;  先切换再识别
    '''
    不允许切换信源,在MenuTree.ini文件中配置:source={"offset":20,"minPeri":0,"maxPeri":0,"minArea":0,"maxArea":0,"enable":0}。
    enable没有,默认值enable=1;enable=0,表示不允许切换信源,仅判断是否为目标信源。
    '''

    def setSourceValue(self, option, value, sourceWaitTime=1.0, Max_Try=10):
        # 切黑场;
        self.sourceInput.setPattern(11)
        return self.tSource.setSourceValue(option, value, sourceWaitTime, Max_Try)

    def inputUnlock(self, std_str, password=''):
        # 如果锁住,按ok会弹出输入密码框;
        self.redRat3.sendKey("ok")
        # 获取密码;
        if password.__len__() == 0:
            password = self.tconfig.get_value("Password", "super")
        # 发送按键;
        for key in list(password):
            self.redRat3.sendKey(key, 1, 0.2)
        time.sleep(1)
        # 发送ok键;
        self.redRat3.sendKey('ok')
        # 判断是否成功输入密码;
        current_uiPic = self.getCurrentUIPath()
        self.get_ocr_list("", "")
        # 遍历ocr类型;
        found = False
        for item in self.ocrDict:
            # 识别ocr;
            ocr_str = self.ocr.getStrWithImgProcess(current_uiPic, {}, item["lan"], item["type"], reconTimes=1)
            ocr_str = unicode(ocr_str).lower()
            # print("lan=%s,type=%d,ocr=%s" % (item["lan"], item["type"], ocr_str))
            printLog("lan=%s,type=%d,ocr=%s" % (item["lan"], item["type"], ocr_str))
            if ocr_str in std_str or std_str == ocr_str:
                found = True
                break
        return not found

    def openOption(self, option, Max_Try=15):
        # 切黑场;
        self.sourceInput.setPattern(11)
        # 获取menu path;
        print "openOption start >>>"
        path_params = self.uitPathManage.get_option_paths(option)
        # print 'openOption=path_params:', path_params
        printLog('openOption=path_params:%s' % str(path_params))

        checkRunOptionPathResult = self.uitPathManage.checkRunOptionPath(path_params)
        if str(checkRunOptionPathResult) == "NoExit":
            printLog(u"表格中不存在到达Option:   %s   的路径,在表格中排查到达该Option路径" % str(option))
            return False
        if str(checkRunOptionPathResult) == "Fail":
            printLog(u"表格中到达Option:   %s   的路径出现数据断层找不到First层级,在表格中排查到达该Option路径" % str(option))
            return False

        # returnKeyEventCount = path_params.__len__() + 1
        returnKeyEventCount = 0
        print "returnKeyEventCount:", returnKeyEventCount
        printLog("openOption=returnKeyEventCount:%s" % str(returnKeyEventCount))
        # 逆序路径key;
        revpp = reversed(path_params)
        # 根节点是否已进入;
        entry = False
        first_parent = u''
        first_option = u''
        # 遍历路径(已排序,从first开始);
        # print "revpp:", revpp
        printLog("openOption=revpp:%s" % str(revpp))
        for level in revpp:
            # print "openOption=level:", path_params[level]
            printLog("openOption=level:", path_params[level])
            # 是否进入根结点;
            if entry == False:
                # 标记已进入根;
                entry = True
                first_parent = path_params[level]["parent"]
                first_option = path_params[level]["option"]
                checkFirstOptionTimes = 0
                while True:
                    if checkFirstOptionTimes > 2:
                        printLog(u"openOption=尝试3次快捷按键没有唤出聚焦焦点界面!!!")
                        return False

                    printLog(u"第%s次尝试呼出一级界面" % str(checkFirstOptionTimes))
                    # # 进入根节点(根节点名就是遥控键名);
                    # self.redRat3.sendKey(path_params[level]["parent"])
                    # 判断是否存在others字段,others字段中存在first_key,则优先使用first_key进入
                    try:
                        others = json.loads(path_params[level]["others"])
                    except Exception,e:
                        others = {}
                    printLog("section others:%s"%others)
                    if "first_key" in others.keys():
                        first_key = others["first_key"]
                    else:
                        first_key = path_params[level]["parent"]
                    printLog(u"进入根节点,first_key:%s"%first_key)
                    # 进入根节点
                    self.redRat3.sendKey(first_key)
                    waitTime = self.getParentWaitTime(path_params[level]["parent"])
                    printLog(u"打开%s界面的等待时间waittime为:%s" % (str(path_params[level]["parent"]), str(waitTime)))
                    time.sleep(waitTime)
                    # 获取ocr列表;
                    self.get_ocr_list(level, option)
                    if self.isFirstOptionShow(level, first_parent, first_option):
                        printLog(u"呼出一级菜单界面")
                        break
                    else:
                        time.sleep(5)
                        self.redRat3.sendKey("return", 2)
                        checkFirstOptionTimes = checkFirstOptionTimes + 1
                # 如果一级界面弹出成功,则退出时候返回按键次数加1
                returnKeyEventCount = returnKeyEventCount + 1

            # 如果 others 字段不为空;
            if path_params[level]["others"].__len__():
                # 如果不是跑马灯处理则按照输入密码处理
                if self.dealOthers(level, path_params[level]) is True:
                    # print u"解锁失败!!!"
                    printLog(u"openOption=解锁失败!!!")
                    return False

            # 移动到子节点;
            cur_option_enter_key = path_params[level]["option_enter_key"]
            # 移动到子节点;                
            if cur_option_enter_key.__len__() == 0:
                enter_key = path_params[level]["enter_key"]
            else:
                enter_key = cur_option_enter_key

            move_key = path_params[level]["move_key"]

            if str(move_key) == str([u'up', u'down']) or str(move_key) == str([u'down', u'up']):
                findDirection = str(move_key[1])
            elif str(move_key) == str([u'left', u'right']) or str(move_key) == str([u'right', u'left']):
                findDirection = str(move_key[1])
            else:
                findDirection = 'grid'

            result = self.move2TargetNode(
                level,
                first_parent,
                path_params[level],
                returnKeyEventCount,
                findDirection=findDirection, Max_Try=Max_Try)

            if result is True:
                # 子节点的进入方式默认为ok;
                self.redRat3.sendKey(enter_key)
                # 如果执行一次enter_key,则退出时按返回键的次数加一
                if enter_key != u'default':
                    returnKeyEventCount = returnKeyEventCount + 1
            else:
                print "openOption end<<<<"
                return False
        # end-for
        print "openOption end <<<<"
        return True

    # 对外接口:检测频道列表;
    def checkChannelList(self, channelList, Max_Try=15):
        failChannelList = []
        checkResult = True
        if channelList == []:
            printLog(u"传入的待检测的频道列表为空!")
            return False, failChannelList
        for channel in channelList:
            isSearched = self.checkOptionValue("ok", channel, Max_Try=Max_Try)
            if not isSearched:
                printLog(u"频道:%s查找失败!" % str(channel))
                failChannelList.append(channel)
                checkResult = False
                # 部分机芯项目(如6586外协松下)按return键无法退出频道,故改为exit键
                # self.redRat3.sendKey("return")
                self.redRat3.sendKey("exit")
            else:
                printLog(u"频道:%s查找成功!" % str(channel))
            self.redRat3.sendKey("exit")
        printLog(u"频道列表检测结果checkResult:%s,检测失败频道列表failChannelLis:%s" % (str(checkResult), str(failChannelList)))
        return checkResult, failChannelList

    # 对外唯一接口:设置操作值;
    def focusOptionValue(self, option, value, Max_Try=15, leafNodeValueWaitTime=0.0):
        # 切黑场;
        self.sourceInput.setPattern(11)
        printLog(u"focusOptionValue。option:%s  value:%s" % (str(option), str(value)))
        # 寻路结果;
        result = False
        # 获取menu path;
        value_params, path_params = self.uitPathManage.get_menu_paths(option, value)
        printLog(u"获取到达option:%s的路径字典path_params:%s" % (str(option), str(path_params)))
        printLog(u"获取聚焦value:%s的值字典value_params:%s" % (str(value), str(value_params)))

        checkRunOptionPathResult = self.uitPathManage.checkRunOptionPath(path_params)
        if str(checkRunOptionPathResult) == "NoExit":
            printLog(u"表格中不存在到达Option:   %s   的路径,在表格中排查到达该Option路径" % str(option))
            return False
        if str(checkRunOptionPathResult) == "Fail":
            printLog(u"表格中到达Option:   %s   的路径出现数据断层找不到First层级,在表格中排查到达该Option路径" % str(option))
            return False

        # returnKeyEventCount = path_params.__len__() + 1
        returnKeyEventCount = 0
        print "returnKeyEventCount:", returnKeyEventCount
        # 逆序路径key;
        revpp = reversed(path_params)
        # 根节点是否已进入;
        entry = False
        root = u''
        first_parent = u''
        first_option = u''
        # 遍历路径(已排序,从first开始);
        # print "revpp:", revpp
        for level in revpp:
            # print "level:", level, path_params[level]
            printLog(u"执行路径level:%s  对应路径字典:%s" % (str(level), str(path_params[level])))
            # 是否进入根结点;
            if entry == False:
                # 标记已进入根;
                entry = True
                first_parent = path_params[level]["parent"]
                first_option = path_params[level]["option"]
                checkFirstOptionTimes = 0
                while True:
                    if checkFirstOptionTimes > 2:
                        errorPngName = "menutree_error_" + str(option) + '_' + str(value) + self.currentTime() + ".png"
                        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                        self.ccard.takePicture(error_uiPic)
                        printLog(u"执行focusOptionValue ERROR!option:%s  value:%s ;尝试3次快捷按键仍然没有唤出聚焦焦点界面!!!  出错截图:%s" % (
                            str(option), str(value), str(error_uiPic)))
                        return False
                    printLog(u"第%s次尝试呼出一级界面" % str(checkFirstOptionTimes))
                    # # 进入根节点(根节点名就是遥控键名);
                    # self.redRat3.sendKey(path_params[level]["parent"])

                    # 判断是否存在others字段,others字段中存在first_key,则优先使用first_key进入
                    try:
                        others = json.loads(path_params[level]["others"])
                    except Exception,e:
                        others = {}
                    printLog("section others:%s"%others)
                    if "first_key" in others.keys():
                        first_key = others["first_key"]
                    else:
                        first_key = path_params[level]["parent"]
                    printLog(u"进入根节点,first_key:%s"%first_key)
                    # 进入根节点
                    self.redRat3.sendKey(first_key)
                    waitTime = self.getParentWaitTime(path_params[level]["parent"])
                    printLog(u"打开%s界面的等待时间waittime为:%s" % (str(path_params[level]["parent"]), str(waitTime)))
                    time.sleep(waitTime)
                    # 获取ocr列表;
                    self.get_ocr_list(level, option)
                    if self.isFirstOptionShow(level, first_parent, first_option):
                        printLog(u"呼出一级菜单界面")
                        break
                    else:
                        time.sleep(5)
                        self.redRat3.sendKey("return", 2)
                        checkFirstOptionTimes = checkFirstOptionTimes + 1
                # 如果一级界面弹出成功,则退出时候返回按键次数加1
                returnKeyEventCount = returnKeyEventCount + 1
            print "level:", level, "root:", root
            # 如果 others 字段不为空;
            if path_params[level]["others"].__len__():
                # 如果不是跑马灯处理则按照输入密码处理
                if self.dealOthers(level, path_params[level]) is True:
                    # print u"解锁失败!!!"
                    printLog(u"执行setOptionValue ERROR!option:%s  value:%s ;解锁失败!!!" % (str(option), str(value)))
                    return False

            # 移动到子节点;
            cur_option_enter_key = path_params[level]["option_enter_key"]
            # 移动到子节点;                
            if cur_option_enter_key.__len__() == 0:
                enter_key = path_params[level]["enter_key"]
            else:
                enter_key = cur_option_enter_key

            move_key = path_params[level]["move_key"]

            if str(move_key) == str([u'up', u'down']) or str(move_key) == str([u'down', u'up']):
                findDirection = str(move_key[1])
            elif str(move_key) == str([u'left', u'right']) or str(move_key) == str([u'right', u'left']):
                findDirection = str(move_key[1])
            else:
                findDirection = 'grid'

            result = self.move2TargetNode(
                level,
                first_parent,
                path_params[level],
                returnKeyEventCount,
                findDirection=findDirection, Max_Try=Max_Try)

            if result is True:
                # 子节点的进入方式默认为ok;
                # self.redRat3.sendKey('ok')
                # 如果只一层,不进行enter_key执行
                if path_params.__len__() != 1:
                    self.redRat3.sendKey(enter_key)
                    # 如果执行一次enter_key,则退出时按返回键的次数加一
                    if enter_key != u'default':
                        returnKeyEventCount = returnKeyEventCount + 1
            else:
                break
        # end-for
        # 如果只一层不进行focusLeafNodeValue设置
        if path_params.__len__() != 1:

            # 寻路成功,设置叶节点值;
            if result is True:
                # 如果是信源选择   自动选择不需要执行 enter_key
                if self.ocr.cmpOcrStr(option, 'source'):
                    return True
                time.sleep(leafNodeValueWaitTime)
                print u"执行设置叶节点:", value_params
                result = self.focusLeafNodeValue(
                    level,
                    root,
                    value_params["option"],
                    value_params["value"],
                    value_params["value_for_ocr"],
                    value,
                    value_params["move_key"],
                    value_params["enter_key"],
                    Max_Try=Max_Try)
        # 无论成功失败,要返回到初始界面

        if result:
            # 如果执行成功则不返回到初始界面
            printLog(u"设置option:%s 选中value:%s的值成功!" % (str(option), str(value)))
        else:
            printLog(u"设置option:%s 选中value:%s的值失败!" % (str(option), str(value)))
            print u"执行退出,执行退出按键次数returnKeyEventCount:", returnKeyEventCount
            # 执行聚焦失败时候,返回到初始界面
            self.redRat3.sendKey("return", returnKeyEventCount, 0.2)
            time.sleep(1)
            # 检测执行回退键是否成功,吐过仍有聚焦效果则继续执行return键
            reCount = 0
            while True:
                if reCount >= returnKeyEventCount:
                    printLog(u"执行了returnKeyEventCount:%s次,仍无法退出到初始界面" % str(returnKeyEventCount))
                    break
                if self.isFirstOptionShow("First", first_parent, first_option):
                    reCount = reCount + 1
                    # 如果仍然可以检测到聚焦效果,则继续执行return
                    self.redRat3.sendKey("return")
                else:
                    printLog(u"回退到初始界面成功!")
                    break

        # 返回结果;
        return result

    # 设置叶子节点值;
    def focusLeafNodeValue(self, level, parent, option, value_excel, value_for_ocr, value, move_key, enter_key,
                           Max_Try=15):
        # 按照传入的方向寻找Max_Try次,如果仍未聚焦到option_for_ocr所在的区域,则按照传入方向的反方向 反向寻找 2*Max_Try 次

        # 正向寻找的次数计数和最大次数
        count = 0
        Max_Try = Max_Try
        # 反向寻找的次数计数和最大次数
        Reversecount = 0
        Reverse_Max_Try = Max_Try * 2
        # 记录上一个焦点识别的文字内容   用于判断是否到达列表的边界 如果到达边界则反向寻找
        old_text = "init_old_text"

        # 正向寻找的遥控器按键值
        findDirection = move_key[1]  # 向右或者向下
        # 反向寻找的遥控器按键值
        findReverseDirection = move_key[0]  # 向左或者向上

        # 获取等待时间
        waitTime = self.getLeafWaitTime(option)
        printLog(u"focusLeafNodeValue:获取到进入叶节点%s,等待时间为%s"%(option, waitTime))
        time.sleep(waitTime)

        value_for_ocr_low = str(value_for_ocr[0]).lower()
        # 判断设置值的类型 是rang类型还是str类型
        if "range(" in value_for_ocr_low:
            isRangeType = True
            str_num = value_for_ocr_low.replace("range", "")
            list_num = eval(str_num)
            min_num = list_num[0]
            max_num = list_num[1]
            try:
                value_num = int(value)
            except Exception:
                printLog(u"传入的值value:%s和option:%s对应的类型不匹配 !" % (str(value), str(option)))
                return False
        else:
            isRangeType = False
        if isRangeType:
            # 如果是数值类型,则直接返回聚焦成功
            return True
        else:
            # 设置选项类型的处理
            while (True):
                print "count:", count
                if count >= Max_Try and Reversecount >= Reverse_Max_Try:
                    break
                isFind, text = self.getCurrentFocusTextEx(level, parent, option, value_excel, value_for_ocr,
                                                          isForValue=True)
                if isFind == -1:
                    errorPngName = "menutree_error_" + str(option) + '_' + str(
                        value_excel) + self.currentTime() + ".png"
                    error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                    self.ccard.takePicture(error_uiPic)
                    printLog(u"聚焦叶子节点值时,当前界面无法找到焦点区域!!!出错界面截图%s" % str(error_uiPic))
                    return False
                # elif (self.ocr.cmpOcrStr(text, value_for_ocr)):
                # 由比较目标文本和识别文本 是否相等  改为 识别文本是否包含目标文本
                else:
                    if isFind == 1:
                        printLog(u"聚焦到目标option:%s,设置value:%s选项成功!" % (str(option), str(value_excel)))
                        # 聚焦到某个焦点成功,由于是聚焦接口调用,不用send  enter_key进入到焦点

                        # if enter_key != 'default':
                        #     self.redRat3.sendKey(enter_key)
                        return True
                        # 判断两次识别
                    # 判断两次识别的text是否相等来判断是否到达边界
                    if self.ocr.cmpOcrStr(text, old_text):
                        # 如果已经到达边界则不再正方向寻找焦点
                        count = Max_Try
                        old_text = "init_old_text"
                    else:
                        old_text = text

                    if count < Max_Try:
                        count = count + 1
                        self.redRat3.sendKey(findDirection)
                    else:
                        Reversecount = Reversecount + 1
                        self.redRat3.sendKey(findReverseDirection)
            errorPngName = "menutree_error_" + str(option) + '_' + str(value_excel) + self.currentTime() + ".png"
            error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
            self.ccard.takePicture(error_uiPic)
            printLog(u"聚焦叶子节点值时,正向遍历%s次,和反向遍历%s次都没有聚焦到option:%s的value:%s选项中,截图为%s" % (
                str(Max_Try), str(Reverse_Max_Try), str(option), str(value_excel), str(error_uiPic)))
            return False

        return True

    def getOptionValue(self, option, is_value_sheet=True):
        # 切黑场;
        self.sourceInput.setPattern(11)
        # 获取路径参数;
        result, option_data = self.uitRunner.uitData.UITree.get_option(option)
        if result is False:
            print(u"getOptionValue.获取option菜单内容失败")
            return False, ''
        first_parent = option_data['first_parent']
        thresholdDict = self.tconfig.getThresholdDict(first_parent)

        # 根据parent打开特定的option;
        if self.openOption(option) is False:
            self.redRat3.sendKey('return', option_data['layers'] + 1, 0.2)
            print(u"getOptionValue.进入指定option失败")
            return False, ''

        # 获取等待时间
        waitTime = self.getOptionWaitTime(option)
        printLog(u"getOptionValue:获取到进入叶节点%s,等待时间为%s"%(option, waitTime))
        time.sleep(waitTime)

        time.sleep(0.5)
        # 截图;
        current_uiPic = self.getCurrentUIPath()
        # 获取焦点框;
        result, opcfg = self.tFocus.getOptionConfig(option, is_value_sheet)
        if result is False:
            self.redRat3.sendKey('return', option_data['layers'] + 1, 0.2)
            print(u"getOptionValue.获取焦点参数失败")
            return False, ''

        dcfg = opcfg['dcfg']
        icon_path = opcfg['icon_path']
        icon_dir_path = opcfg['dir_path']
        # 获取聚集框;
        result, cur_box = self.tFocus.findFocusByIcon(current_uiPic, icon_path, dcfg)
        if result is False:
            self.redRat3.sendKey('return', option_data['layers'] + 1, 0.2)
            print(u"getOptionValue.获取焦点框轮廓失败")
            return False, ''

        # 根据dir计算文本框;
        cur_box = self.getFocusTextBox4(icon_dir_path, option, cur_box, is_value_sheet)

        # 获取文本区域截图;
        ocr_result_text = ''
        txt_pic = os.path.join(getSATTmpDIR(), "meuttree_area_text.png")
        self.imgCMP.saveCropPic(current_uiPic, txt_pic, (cur_box[0], cur_box[1], cur_box[2], cur_box[3]))
        if is_value_sheet is True:
            value_paramters = self.uitRunner.uitData.UITree.get_value(option, '')
            isRangeType = False
            # 判断设置值的类型 是rang类型还是str类型
            if value_paramters['value_for_ocr'].__len__() and "range(" in value_paramters['value_for_ocr'][0].lower():
                isRangeType = True

            if isRangeType is True:
                # 获取ocr列表;
                hasOption,path = self.uitRunner.uitData.UITree.get_option(option)
                if hasOption:
                    self.get_ocr_list(path['level'], option)
                for orc_item in self.ocrDict:
                    # ocr_result = self.ocr.getStr(txt_pic, orc_item["lan"], orc_item["type"])
                    ocr_result = self.ocr.getStrWithImgProcess(txt_pic, thresholdDict, orc_item["lan"],
                                                               orc_item["type"],
                                                               reconTimes=1)
                    # print("getCurrentFocusOcr_Int=ocr识别结果=%s" % (ocr_result))
                    printLog("getCurrentFocusOcr_Int=ocr识别结果=%s" % (ocr_result))
                    if ocr_result == "ERR<Exp>" or ocr_result.__len__() == 0:
                        continue
                    # 字符串去掉末尾">"符号;
                    ocr_result = ocr_result.strip('>')
                    # 按数字分解多组文本;
                    list_ocr = getDigitFromString(ocr_result)
                    # list_ocr = self.strSplit(ocr_result)
                    # 只判断最后一位是否是数字;
                    if list_ocr.__len__() < 1:
                        errorPngName = "menutree_error_" + self.currentTime() + "ocr.png"
                        error_uiPic = os.path.join(getSATTmpDIR(), errorPngName)
                        self.ccard.takePicture(error_uiPic)
                        # print u"当前识别的ocr 不包含int类型值,截图为:%s" % (str(ocr_result))
                        printLog(u"当前识别的ocr 不包含int类型值,截图为:%s" % (str(ocr_result)))
                        continue

                    try:
                        # 获取最右边的文本,如果是数字则退出;
                        text_int_str = list_ocr[list_ocr.__len__() - 1]
                        # print 'text_int_str:', text_int_str
                        printLog('text_int_str:%s' % str(text_int_str))
                        ocr_result_text = float(text_int_str)
                        break
                    except Exception:
                        continue
            else:
                # 普通ocr文本识别;
                # ocr_result_text = self.ocr.getStr(txt_pic, "ChinesePRC+English", 4)
                ocr_result_text = self.ocr.getStrWithImgProcess(txt_pic, thresholdDict, "ENG", 10000,
                                                                reconTimes=1)
        else:
            # 普通ocr文本识别;
            # ocr_result_text = self.ocr.getStr(txt_pic, "ChinesePRC+English", 4)
            ocr_result_text = self.ocr.getStrWithImgProcess(txt_pic, thresholdDict, "ENG", 10000,
                                                            reconTimes=1)
        # 退出菜单;
        self.redRat3.sendKey('return', option_data['layers'] + 1, 0.2)

        # 返回结果;
        return True, ocr_result_text

    def getParentWaitTime(self, parent):
        optionName = parent + "WaitTime"
        try:
            waitTime = float(self.tconfig.get_value("waitTime", optionName))
        except Exception:
            waitTime = 1.0
            # print "获取%s界面的等待界面时间失败,使用默认值1.0s" % str(parent)
        return waitTime

    def getOptionWaitTime(self, option):
        result, option_data = self.uitRunner.uitData.UITree.get_option(option)
        print u"getOptionWaitTime.option_data:",option_data
        if result:
            try:
                others = json.loads(option_data['others'])
                waitTime = float(others['waitTime'])
            except Exception,e:
                print u"获取%s界面的等待时间失败,使用默认值1.0s" % str(option)
                waitTime = 1.0
        else:
            waitTime = 1.0
        return waitTime

    def getLeafWaitTime(self, option):
        leaf_data = self.uitRunner.uitData.UITree.get_value(option)
        print u"getLeafWaitTime.option_data:",leaf_data
        try:
            others = json.loads(leaf_data['others'])
            waitTime = float(others['waitTime'])
        except Exception,e:
            print u"获取%s界面的等待时间失败,使用默认值1.0s" % str(option)
            waitTime = 1.0
        return waitTime


    # channel_count:如果有频道,最大可能的频道数量;
    # black_th:黑色频道背景色RGB单通道值
    # black_rate:图片分割成100块,纯黑色区域占有比
    def getBlackChannel(self, channel_count, black_th=20, black_rate=0.8):
        result = False
        # 根据频道数量遍历;
        for i in range(0, channel_count):
            pass
            # 截图,取左半边;
            pic_path = self.getCurrentUIPath()
            img = cv.imread(pic_path)
            pic_path2 = os.path.join(getSATTmpDIR(), "menutree_focus_area_half.png")
            self.imgCMP.saveCropPic(pic_path, pic_path2, (0, 0, img.shape[1] / 2, img.shape[0]))
            # 是否符合要求;
            result = self.imgCMP.isBlack(pic_path2, black_th, 10, 1 - black_rate)
            if result is True:
                break

            # 下一频道号;
            self.redRat3.sendKey('C+')
            time.sleep(4)
        # endfor

        return result

    # 新增操作接口

    # 聚焦到Option   区别于openOption,focusOption不会执行到option的子界面中
    def focusOption(self, option, Max_Try=15):
        # 切黑场;
        self.sourceInput.setPattern(11)
        # 获取menu path;
        print u"focusOption start >>>"
        path_params = self.uitPathManage.get_option_paths(option)
        # print 'openOption=path_params:', path_params
        printLog('focusOption=path_params:%s' % str(path_params))

        checkRunOptionPathResult = self.uitPathManage.checkRunOptionPath(path_params)
        if str(checkRunOptionPathResult) == "NoExit":
            printLog(u"表格中不存在到达Option:   %s   的路径,在表格中排查到达该Option路径" % str(option))
            return False
        if str(checkRunOptionPathResult) == "Fail":
            printLog(u"表格中到达Option:   %s   的路径出现数据断层找不到First层级,在表格中排查到达该Option路径" % str(option))
            return False
        runPathCount = 0
        pathCount = path_params.__len__()
        printLog("focusOption=pathCount:%s" % str(pathCount))

        # returnKeyEventCount = path_params.__len__() + 1
        returnKeyEventCount = 0
        print "returnKeyEventCount:", returnKeyEventCount
        printLog("focusOption=returnKeyEventCount:%s" % str(returnKeyEventCount))
        # 逆序路径key;
        revpp = reversed(path_params)
        # 根节点是否已进入;
        entry = False
        first_parent = u''
        first_option = u''
        # 遍历路径(已排序,从first开始);
        # print "revpp:", revpp
        printLog("focusOption=revpp:%s" % str(revpp))
        for level in revpp:
            # print "openOption=level:", path_params[level]
            printLog("focusOption=level:", path_params[level])
            # 是否进入根结点;
            if entry == False:
                # 标记已进入根;
                entry = True
                first_parent = path_params[level]["parent"]
                first_option = path_params[level]["option"]
                checkFirstOptionTimes = 0
                while True:
                    if checkFirstOptionTimes > 2:
                        printLog(u"focusOption=尝试3次快捷按键没有唤出聚焦焦点界面!!!")
                        return False

                    printLog(u"第%s次尝试呼出一级界面" % str(checkFirstOptionTimes))
                    # # 进入根节点(根节点名就是遥控键名);
                    # self.redRat3.sendKey(path_params[level]["parent"])
                    # 判断是否存在others字段,others字段中存在first_key,则优先使用first_key进入
                    try:
                        others = json.loads(path_params[level]["others"])
                    except Exception,e:
                        others = {}
                    printLog("section others:%s"%others)
                    if "first_key" in others.keys():
                        first_key = others["first_key"]
                    else:
                        first_key = path_params[level]["parent"]
                    printLog(u"进入根节点,first_key:%s"%first_key)
                    # 进入根节点
                    self.redRat3.sendKey(first_key)
                    waitTime = self.getParentWaitTime(path_params[level]["parent"])
                    printLog(u"打开%s界面的等待时间waittime为:%s" % (str(path_params[level]["parent"]), str(waitTime)))
                    time.sleep(waitTime)
                    # 获取ocr列表;
                    self.get_ocr_list(level, option)
                    if self.isFirstOptionShow(level, first_parent, first_option):
                        printLog(u"呼出一级菜单界面")
                        break
                    else:
                        time.sleep(5)
                        self.redRat3.sendKey("return", 2)
                        checkFirstOptionTimes = checkFirstOptionTimes + 1
                # 如果一级界面弹出成功,则退出时候返回按键次数加1
                returnKeyEventCount = returnKeyEventCount + 1

            # 如果 others 字段不为空;
            if path_params[level]["others"].__len__():
                # 如果不是跑马灯处理则按照输入密码处理
                if self.dealOthers(level, path_params[level]) is True:
                    # print u"解锁失败!!!"
                    printLog(u"focusOption=解锁失败!!!")
                    return False

            # 移动到子节点;
            cur_option_enter_key = path_params[level]["option_enter_key"]
            # 移动到子节点;
            if cur_option_enter_key.__len__() == 0:
                enter_key = path_params[level]["enter_key"]
            else:
                enter_key = cur_option_enter_key

            move_key = path_params[level]["move_key"]

            if str(move_key) == str([u'up', u'down']) or str(move_key) == str([u'down', u'up']):
                findDirection = str(move_key[1])
            elif str(move_key) == str([u'left', u'right']) or str(move_key) == str([u'right', u'left']):
                findDirection = str(move_key[1])
            else:
                findDirection = 'grid'

            result = self.move2TargetNode(
                level,
                first_parent,
                path_params[level],
                returnKeyEventCount,
                findDirection=findDirection, Max_Try=Max_Try)

            if result is True:
                runPathCount = runPathCount + 1
                printLog("focusOption=runPathCount:%s" % str(runPathCount))
                if runPathCount == pathCount:
                    print u"执行到最后一级"
                    pass
                else:
                    # 子节点的进入方式默认为ok;
                    self.redRat3.sendKey(enter_key)
                    # 如果执行一次enter_key,则退出时按返回键的次数加一
                    if enter_key != u'default':
                        returnKeyEventCount = returnKeyEventCount + 1
            else:
                print "focusOption end<<<<"
                return False
        # end-for
        print "focusOption end <<<<"
        return True

    # 假定已经在option所在的页面,逐步移动到目标option,聚焦到option
    def moveToOption(self, option, Max_Try=15):
        # 切黑场;
        # self.sourceInput.setPattern(11)
        # 获取menu path;
        print "moveToOption start >>>"
        path_params = self.uitPathManage.get_option_paths(option)
        # print 'openOption=path_params:', path_params
        printLog('moveToOption=path_params:%s' % str(path_params))

        checkRunOptionPathResult = self.uitPathManage.checkRunOptionPath(path_params)
        if str(checkRunOptionPathResult) == "NoExit":
            printLog(u"表格中不存在到达Option:   %s   的路径,在表格中排查到达该Option路径" % str(option))
            return False
        if str(checkRunOptionPathResult) == "Fail":
            printLog(u"表格中到达Option:   %s   的路径出现数据断层找不到First层级,在表格中排查到达该Option路径" % str(option))
            return False
        runPathCount = 0
        pathCount = path_params.__len__()
        printLog("moveToOption=pathCount:%s" % str(pathCount))

        returnKeyEventCount = path_params.__len__()
        # print "returnKeyEventCount:", returnKeyEventCount
        printLog("moveToOption=returnKeyEventCount:%s" % str(returnKeyEventCount))
        # 逆序路径key;
        revpp = reversed(path_params)
        # 根节点是否已进入;
        entry = False
        first_parent = u''
        # first_option = u''
        # 遍历路径(已排序,从first开始);
        # print "revpp:", revpp
        printLog("moveToOption=revpp:%s" % str(revpp))
        for level in revpp:
            # print "openOption=level:", path_params[level]
            runPathCount = runPathCount + 1
            print "level:", level, type(level)
            print "runPathCount:", runPathCount, type(runPathCount)
            print "pathCount:", pathCount, type(pathCount)

            printLog("openOption=level:", path_params[level])
            # 是否进入根结点;
            if entry == False:
                # 标记已进入根;
                entry = True
                first_parent = path_params[level]["parent"]

            # 由于已经到达option同级界面,只执行最后一层
            if runPathCount == pathCount:
                # 移动到子节点;
                cur_option_enter_key = path_params[level]["option_enter_key"]
                # 移动到子节点;
                if cur_option_enter_key.__len__() == 0:
                    enter_key = path_params[level]["enter_key"]
                else:
                    enter_key = cur_option_enter_key

                move_key = path_params[level]["move_key"]

                if str(move_key) == str([u'up', u'down']) or str(move_key) == str([u'down', u'up']):
                    findDirection = str(move_key[1])
                elif str(move_key) == str([u'left', u'right']) or str(move_key) == str([u'right', u'left']):
                    findDirection = str(move_key[1])
                else:
                    findDirection = 'grid'

                result = self.move2TargetNode(
                    level,
                    first_parent,
                    path_params[level],
                    returnKeyEventCount,
                    findDirection=findDirection, Max_Try=Max_Try)

                if result is True:
                    # runPathCount = runPathCount+1
                    printLog("moveToOption=runPathCount:%s" % str(runPathCount))
                    if runPathCount == pathCount:
                        print "执行到最后一级"
                        pass
                    else:
                        # 子节点的进入方式默认为ok;
                        self.redRat3.sendKey(enter_key)
                else:
                    print "moveToOption end<<<<"
                    return False
        # end-for
        print "moveToOption end <<<<"
        return True

    # 找到两个字符串左边或者右边相同的部分
    def findDuplicateString(self, str1, str2, direction="right"):
        index = 0
        if direction == "right":
            while True:
                index -= 1
                if abs(index) > str1.__len__() or abs(index) > str2.__len__():
                    break
                if not str1[index] == str2[index]:
                    break
            if index == -1:
                return ""
            return str1[index+1:]
        elif direction == "left":
            while True:
                if abs(index) >= str1.__len__() or abs(index) >= str2.__len__():
                    break
                if not str1[index] == str2[index]:
                    break
                index += 1
            return str1[:index]

    # 去掉字符串数组中每个字符串 左边或右边相同的部分
    def removeDuplicateString(self, strList):
        finishedList = strList
        directionList = ["left", "right"]
        for direction in directionList:
            same_str = self.findDuplicateString(strList[0], strList[1], direction)
            if same_str == "":
                continue
            else:
                for i in range(2, strList.__len__()):
                    same_str = self.findDuplicateString(same_str,strList[i], direction)
                    if same_str == "":
                        break
                if same_str != "":
                    finishedList = []
                    for str in strList:
                        if direction == "left":
                            str = str[same_str.__len__():]
                        else:
                            str = str[:-same_str.__len__()]
                        finishedList.append(str)
        return finishedList

if __name__ == "__main__":
    tmenu = CTMenu()
    print "执行开始!"
    # ThresholdDict = tmenu.tconfig.getThresholdDict("factory")
    # ThresholdDict = tmenu.tconfig.getThresholdDict("setting")
    # print "ThresholdDict:", ThresholdDict, type(ThresholdDict)
    # tmenu.getOptionValue("picture_preset")value
    # parent_ocr_dict = tmenu.xlsparser.get_parent_ocr_dict("automatic_search_analogue")
    # print "parent_ocr_dict:",parent_ocr_dict
     # 获取menu path;
    # value_params, path_params = tmenu.xlsparser.get_menu_paths('av', '')
    # print value_params, path_params
    # tmenu.redRat3.sendKey('home')
    # tmenu.move2TargetGridNode_matchTemp('First', 'home', path_params['First'], 1)
    # isSuccessed = tmenu.setOptionValue("picture_preset", "stadium")
    # isSuccessed = tmenu.setOptionValue("backlight", 50)

    # isSuccessed = tmenu.checkOptionValue("picture_preset", "stadium")
    # isSuccessed = tmenu.checkOptionValue("backlight", 50)
    # print u'isSuccessed:', isSuccessed

    # isSuccessed_focusOption = tmenu.focusOption("picture_preset")
    # print u'聚焦到目标Option:auto_volume_control 结果isSuccessed_focusOption:', isSuccessed_focusOption
    # 确保当前焦点是在目标Option同级的
    # if isSuccessed_focusOption:
    #     isSuccessed_moveToOption = tmenu.moveToOption("picture_reset")
    #     print u'焦点移动到目标Option结果isSuccessed_moveToOption:', isSuccessed_moveToOption

    # value_params, path_params = tmenu.xlsparser.get_menu_paths("picture_preset ", "personal")
    # print "value_params:",value_params
    # print "path_params:",path_params
    #
    # path_params_1 = tmenu.xlsparser.get_option_paths("picture_preset ")
    # print "path_params_1:", path_params_1
    # isHasValue, ocr_result_text = tmenu.getOptionValue("backlight")
    # print "isHasValue:",isHasValue,type(isHasValue)
    # print "ocr_result_text:",ocr_result_text,type(ocr_result_text)
    # tmenu.setOptionValue("backlight",ocr_result_text)

    # paths = tmenu.xlsparser.get_option_paths('usb')
    # tmenu.move2TargetGridNode('first', 'usb', paths, 5)
    # isSuccessed = tmenu.setOptionValue("source", "tv")
    # isSuccessed = tmenu.setOptionValue("picture_preset", "stadium")
    # isSuccessed = tmenu.setOptionValue("picture_preset", "dynamic")
    # isSuccessed = tmenu.setOptionValue("gamma", 0)
    # isSuccessed = tmenu.setOptionValue("instant_power_on", "on")
    # isSuccessed = tmenu.setOptionValue("RGB_mode", "green_only")
    # isSuccessed = tmenu.focusOptionValue("option", "enjoy_music")
    # print "isSuccessed:", isSuccessed

    # settingWaitTime = tmenu.getParentWaitTime("setting")
    # print settingWaitTime
    # sourceWaitTime = tmenu.getParentWaitTime("source")
    # print sourceWaitTime

    # print tmenu.setOptionValue('overscan', 'off')
    # print tmenu.getOptionValue('overscan')
    # settings 检测焦点选择类的setOptionValue
    # isSuccessed = tmenu.setOptionValue("backlight", 50)
    # print "isSuccessed:", isSuccessed
    # isSuccessed = tmenu.setOptionValue("500hz", 50)
    # print u'isSuccessed:', isSuccessed

    # settings 检测值设置类的setOptionValue
    # isSuccessed = tmenu.setOptionValue("backlight", 70)
    # isSuccessed = tmenu.setOptionValue("auto_volume_control", "on")
    # print u'isSuccessed:', isSuccessed

    # settings 检测焦点选择类的checkOptionValue
    # isSuccessed = tmenu.checkOptionValue("picture_preset", "movie")
    # print u'isSuccessed:', isSuccessed
    # isSuccessed = tmenu.setOptionValue("picture_preset", "movie", leafNodeValueWaitTime=2.0)
    # print u'isSuccessed:', isSuccessed

    # settings 检测值设置类的checkOptionValue
    # isSuccessed = tmenu.checkOptionValue("backlight", 70)
    # print u'isSuccessed:', isSuccessed

    # 信源切换检测
    # isSuccessed = tmenu.setSourceValue('source', 'hdmi2', sourceWaitTime=1.5)
    # print u'进入信源(hdmi2)isSuccessed:', isSuccessed
    # isSuccessed = tmenu.setSourceValue('source', 'av')
    # print u'进入信源(tv)isSuccessed:', isSuccessed

    # 频道列表检测
    # checkResult,failChannelList=tmenu.checkChannelList(["6", "22"])
    # print u'checkResult,failChannelList:', checkResult,failChannelList

    # 检测自动搜台
    # isSuccessed = tmenu.auto_search("automatic_search",[["as_tuner_mode","air"],["as_channel_type","analog"]])
    # print u'isSuccessed:', isSuccessed
    # isSuccessed =tmenu.auto_search("automatic_search", [["as_tuner_mode", "air"], ["as_channel_type", "analog"]],
    #                   ["as_search", "finished"])
    # print u'isSuccessed:', isSuccessed

    # 检测手动搜台
    # isSuccessed =tmenu.manual_search("manual_tuning", [["mt_tuner_mode", "air"], ["mt_channel_type", "analog"], ["mt_ch", 12]])
    # print u'isSuccessed:', isSuccessed
    # isSuccessed = tmenu.manual_search("manual_tuning",
    #                                   [["mt_tuner_mode", "cable"], ["mt_channel_type", "digital"], ["mt_ch", 12]])
    # print u'isSuccessed:', isSuccessed