Example #1
0
class WifiSetup(object):
    def __init__(self, ip, product_name, wifi_setting, socketio):
        self.socketio = socketio
        self.wifi_ini = wifi_setting
        self.log = Logger("wifi_speaker").logger()
        self.wifi = WindowsWifi(socketio=socketio)
        self.ase_info = AseInfo()
        self.total_times = 0
        self.success_times = 0
        self.ip = ip
        self.product_name = product_name

    def print_log(self, info, color='white'):
        try:
            self.log.info(info)
            if self.socketio is not None:
                self.socketio.sleep(
                    0.01
                )  # Avoid sockeit network block leads to cannot print on page
                self.socketio.emit('print_msg', {
                    'data': info,
                    'color': color
                },
                                   namespace='/wifi_speaker/test')
            else:
                print(info)
        except Exception as e:
            self.log.debug("Error when print_log: {}".format(e))
            sys.exit()

    def delay(self, t):
        if self.socketio is not None:
            self.socketio.sleep(t)
        else:
            sleep(t)

    def reset_and_wait(self, ip, t):
        self.ase_info.reset(ip)
        self.print_log("Doing factory reset. Waiting %ss..." % t)
        self.delay(t)

    def check_wifi_status(self, ip):
        try:
            response = urllib.request.urlopen(ip, timeout=20)
            status = response.status
            if status == 200:
                return True
            else:
                return False
        except Exception as e:
            self.print_log("Cannot connect {}: {}".format(ip, e))
            return False

    def setup(self):
        try:
            with open(self.wifi_ini) as json_file:
                data = json.load(json_file)
                # parent_path = os.path.realpath(os.path.join(os.getcwd(), ".."))
            times = int(data.get("total_times"))
            time_reset = int(data.get("time_reset"))
            dhcp = data.get("dhcp")
            ssid = data.get("ssid")
            key = data.get("password")
            # encryption = wifi_setting.cfg.get("Wifi", "encryption")
            ip = data.get("static_ip")
            gateway = data.get("gateway")
            netmask = data.get("netmask")
        except Exception as e:
            self.log.error(e)
            sys.exit()
        # hostName = "beoplay-{model}-{SN}.local".format(model=model, SN=SN)
        host_url = "http://{}/index.fcgi"

        DHCP = []
        if dhcp == "True" or dhcp == "true":
            DHCP.append(True)
        elif dhcp == "False" or dhcp == "false":
            DHCP.append(False)
        else:
            DHCP.extend([True, False, True])
        self.total_times = times

        for cycle in range(1, times + 1):
            self.print_log("This is the %d times " % cycle)
            for index in DHCP:
                dhcp = index
                static_ip, static_gateway, static_netmask = '', '', ''
                if not dhcp:
                    static_ip, static_gateway, static_netmask = ip, gateway, netmask
                self.print_log("Set DHCP={}".format(dhcp))
                self.reset_and_wait(self.ip, time_reset)
                while True:
                    if self.wifi.find_wifi(self.product_name):
                        self.wifi.connect_wifi(self.product_name)
                        self.delay(15)  # Give wifi connect some time
                        if self.wifi.check_wifi(self.product_name):
                            break
                    self.delay(3)

                if not self.check_wifi_status(
                        "http://192.168.1.1/index.fcgi#Fts/Network"):
                    return
                if self.ase_info.setup_wifi(ssid, key, dhcp, static_ip,
                                            static_gateway, static_netmask,
                                            "192.168.1.1"):
                    self.print_log("Wifi setup command has been sent!")
                    if self.wifi.find_wifi(ssid):
                        self.wifi.connect_wifi(ssid)
                        self.delay(15)  # Give wifi connect some time
                        if self.wifi.check_wifi(ssid):
                            scan_result = 0
                            for i in range(0, 10):
                                if scan_result == 1:
                                    break
                                devices = self.scan_devices()
                                for d in devices:
                                    if self.product_name in d:
                                        scan_result = 1
                                        self.ip = re.findall('\((.*)\)', d)[0]
                                        break
                            if scan_result == 0:
                                self.print_log(
                                    "Something wrong when scan devices!")
                                sys.exit()
                            if self.check_wifi_status(host_url.format(
                                    self.ip)):
                                if not dhcp:
                                    if ip == self.ip:
                                        self.print_log(
                                            "Your static ip[{}] setup successfully!"
                                            .format(ip))
                                    else:
                                        self.print_log(
                                            "Your static ip[{}] setup Failed!".
                                            format(ip))
                                        return
                                else:
                                    self.print_log(
                                        "Wifi[{}] setup successfully!".format(
                                            ssid))
                                self.success_times = self.success_times + 1
                        else:
                            self.print_log("Cannot connect wifi %s" % ssid)
                            break
                self.socketio.emit(
                    "wifi_setup_pass_ratio",
                    {"data": "{}/{}".format(self.success_times, cycle)},
                    namespace="/wifi_speaker/test")

            if self.success_times >= self.total_times:
                finish_print = "**********All finished*********"
                self.print_log(finish_print)

    def scan_devices(self):
        self.print_log("Scanning devices")
        self.ase_info.get_ase_devices_list()
        while True:
            status = self.ase_info.status
            if status == 1:
                return self.ase_info.devices_list
Example #2
0
class WindowsWifi(object):
    def __init__(self, socketio=None):
        self.socketio = socketio
        self.log = Logger("wifi_speaker").logger()
        # *************************************************************
        # Chinese: 0x804
        # English: 0x409
        dll_handle = windll.kernel32
        id = hex(dll_handle.GetSystemDefaultUILanguage())
        if id == "0x804":
            system_language = "Chinese"
        elif id == "0x409":
            system_language = "English"
        else:
            system_language = ""
        self.log.debug("system language: "+system_language)
        # *************************************************************
        p = subprocess.Popen("chcp", shell=True, stdout=subprocess.PIPE)
        try:
            code = p.stdout.read().decode("GB2312")
        except:
            code = p.stdout.read().decode("utf-8")
        # if system_language == "Chinese":
        if self.contain_zh(code) is not None:
            self.wifi_state = "已连接"
            self.wifi_state_find = "状态"
            self.ipType = "动态"
        else:
            self.wifi_state = "connected"
            self.wifi_state_find = "State"
            self.ipType = "dynamic"

    def print_log(self, info):
        try:
            self.log.info(info)
            if self.socketio is not None:
                self.socketio.sleep(0.01)
                self.socketio.emit('print_msg',
                                   {'data': info},
                                   namespace='/test')
            else:
                print(info)
        except Exception as e:
            self.log.debug("Error when print_log: {}".format(e))
            sys.exit()

    def delay(self, t):
        if self.socketio is not None:
            self.socketio.sleep(t)
        else:
            sleep(t)

    @staticmethod
    def contain_zh(word):
        """:return None: no"""
        zh_pattern = re.compile(u'[\u4e00-\u9fa5]+')
        match = zh_pattern.search(word)
        return match

    def connect_wifi(self, name):
        self.print_log("Try to connect wifi --> %s" % name)
        p = os.popen("netsh wlan connect name=\"{name}\"".format(name=name))
        content = p.read()
        self.print_log(content)
        # os.system("netsh wlan connect name=%s" % name)

    def wifi_status(self):
        self.print_log("Checking wifi status...")
        p = os.popen("netsh wlan show interfaces")
        content = p.read()
        return content

    def check_wifi(self, wifi_name):
        # self.print_log(content)
        for i in range(0, 5):
            content = self.wifi_status()
            try:
                wifi_ssid = re.findall(u"SSID(.*)", content)[0].split(": ")[1]
                wifi_state = re.findall(u"%s(.*)" % self.wifi_state_find, content)[0].split(": ")[1]
                # self.print_log(wifi_state)
                if wifi_ssid == wifi_name:
                    if wifi_state == self.wifi_state:
                        self.print_log("Wifi %s connected!" % wifi_name)
                        return True
                self.print_log("Wifi [%s] did not connected!" % wifi_name)
            except Exception as e:
                self.log.error("Check wifi:{}".format(e))
            self.delay(1)
        return False

    def find_wifi(self, str):
        self.print_log("Finding wifi %s  ..." % str)
        p = subprocess.Popen("netsh wlan disconnect",
                             shell=True)  # win10 system cannot auto refresh wifi list, so disconnect it first
        p.wait()
        # p = os.popen("netsh wlan show networks") #netsh wlan show networks mode=bssid
        # content = p.read().decode("gbk", "ignore")
        p = subprocess.Popen("netsh wlan show networks | find \"%s\"" % str, shell=True, stdout=subprocess.PIPE)
        try:
            content = p.stdout.read().decode("GB2312")  # byte decode to str, and GB2312 is avoid Chinese strings.
        except:
            content = p.stdout.read().decode("utf-8")
        if content != "":
            self.print_log("Find [%s]" % str)
            return True
        else:
            return False

    """
    @staticmethod
    def get_network_status():
        network_status = {}
        network_status['gateway'] = netifaces.gateways()['default'][netifaces.AF_INET][0]
        network_status['nicName'] = netifaces.gateways()['default'][netifaces.AF_INET][1]

        for interface in netifaces.interfaces():
            if interface == network_status['nicName']:
                network_status['mac'] = netifaces.ifaddresses(interface)[netifaces.AF_LINK][0]['addr']
                try:
                    network_status['ip'] = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['addr']
                    network_status['netMask'] = netifaces.ifaddresses(interface)[netifaces.AF_INET][0]['netmask']
                except KeyError as e:
                    self.log.debug(e)
        return network_status
    """

    def discover_ips(self):
        """
        gateway = self.get_network_status()['gateway']
        ip = self.get_network_status()['ip']
        netmask = self.get_network_status()['netMask']
        # count_bit = lambda count_str: len([i for i in count_str if i == '1'])
        # count_bit("111111")
        netmask_bit = 0
        for n in netmask.split('.'):
            netmask_bit = netmask_bit + bin(int(n)).count('1')
        """
        ip = socket.gethostbyname(socket.gethostname())
        tmp = ip.rsplit(".", 1)[0]
        gateway = "{}.1".format(tmp)
        # netmask_bit = 24
        # path = "{}\config\\NBTscan-Ipanto.exe".format(os.getcwd())
        # cmd = r"{} {}/{}".format(path, gateway, netmask_bit)
        # self.log.debug(cmd)
        text = ""
        try:
            p = subprocess.Popen('net view', shell=True, stdout=subprocess.PIPE)
            p.wait()
            sleep(0.1)
            p = subprocess.Popen("arp -a", shell=True, stdout=subprocess.PIPE)
            text = p.stdout.readlines()
        except Exception as e:
            self.log.debug(e)
        ip_address = []
        for t in text:
            try:
                content = t.decode("GB2312")
            except:
                content = t.decode("utf-8")
            if self.ipType in content:
                # re.findall(r'(?:(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])\.){3}(?:[0,1]?\d?\d|2[0-4]\d|25[0-5])')
                ip_filter = re.findall(r'\d+\.\d+\.\d+\.\d+', content)
                if len(ip_filter) != 0:
                    if gateway != ip_filter[0] and ip != ip_filter[0]:
                        ip_address.append(ip_filter[0])
        return {'ip': ip_address, 'gateway': gateway}
Example #3
0
class AseInfo(object):
    def __init__(self):
        self.log = Logger("wifi_speaker").logger()
        self.ip = 'NA'
        self.device = 'NA'
        self.urlSetData = "http://{}/api/setData?{}"
        self.urlGetData = "http://{}/api/getData?{}"
        self.urlGetRows = "http://{}/api/getRows?{}"
        self.devices_list = []
        self.status = 0
        self.threads = []
        self.INFO = {}
        self.saved_ip = []

    def transfer_data(self, request_way, ip, value, timeout=6):
        """
        :param request_way:
        :param ip:
        :param value:
        :param timeout:
        :return:
        %27 = ', %22 = ", + = 'space'
        """
        value_str = parse.urlencode(value, encoding="utf-8")
        if "+" in value_str:
            value_str = value_str.replace('+', '')
        if "True" in value_str:
            value_str = value_str.replace('True', 'true')
        if "False" in value_str:
            value_str = value_str.replace('False', 'false')
        if "%27" in value_str:
            value_str = value_str.replace('%27', '%22')
        if white_space in value_str:
            value_str = value_str.replace(white_space, '+')
        if request_way == "get":
            url = self.urlGetData.format(ip, value_str)
        elif request_way == "getRows":
            url = self.urlGetRows.format(ip, value_str)
        elif request_way == "set":
            url = self.urlSetData.format(ip, value_str)
        else:
            self.log.error("No such request method: {}".format(request_way))
            return
        return requests_url(url, 'get', timeout=timeout)

    @staticmethod
    def ota_update(ip, ota_file):
        """
        ASE OTA Update
        :param ip: Device ip
        :param ota_file: Must be dict
        :return: Number type(post status)
        """
        url = "http://{}/page_setup_swupdate.fcgi?firmwareupdate=1".format(ip)
        req = requests.post(url=url, files=ota_file)
        return req.status_code

    def trigger_update(self, ip):
        return self.transfer_data("set", ip, update_para)["status"]

    def get_info(self, x, ip):
        try:
            if x == 'basicInfo':
                r = request_url('http://{0}/index.fcgi'.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                text = re.findall('dataJSON = \'(.*)\';', r.get('content'))[0]
                data = json.loads(text, encoding='utf-8')
                '''
                r = request_url('http://{0}/page_status.fcgi'.format(ip))['text']
                product_id = re.findall('var productId = \'(.*)\';', r)[0]
                jd = json.loads(product_id, encoding='utf-8')
                sn = ''
                for i in jd["beoGphProductIdData"]["serialNumber"]:
                    sn = sn + str(i)
                '''
                beo_machine = data.get('beoMachine')
                fep_versions = beo_machine.get('fepVersions')
                info = {'modelName': beo_machine.get('modelName'),
                        'model': beo_machine.get('model'),
                        'productName': beo_machine.get('setup').get('productName'),
                        'bootloaderVersion': fep_versions.get('bootloaderVersion'),
                        'appVersion': fep_versions.get('appVersion')
                        }
                self.INFO['appVersion'] = info['appVersion']
                return info
            elif x == 'BeoDevice':
                r = request_url(beo_device.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                beo_info = data.get('beoDevice')
                beo_productid = beo_info.get('productId')
                info = {'productType': beo_productid.get('productType'),
                        'serialNumber': beo_productid.get('serialNumber'),
                        'productFriendlyName': beo_info.get('productFriendlyName').get('productFriendlyName'),
                        'version': beo_info.get('software').get('version')
                        }
                self.INFO["sn"] = info['serialNumber']
                self.INFO["deviceName"] = info['productFriendlyName']
                self.INFO["version"] = info['version']
                return info
            elif x == 'modulesInformation':
                r = request_url(modules_info.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                module = data.get('profile').get('module')
                info = {
                    'fep_application': module[0].get('application').get('version'),
                    'fep_bootloader': module[0].get('bootloader').get('version'),
                    # 'AP': module[2].get('application').get('version'),
                    # 'GoogleCast': module[3].get('application').get('version')
                }
                self.INFO['fep_app'] = info.get('fep_application')
                self.INFO['bootloader'] = info.get('fep_bootloader')
                return info
            elif x == 'bluetoothSettings':
                r = request_url(bluetooth_settings.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')  # GBK? Chinese string
                bluetooth = data.get('profile').get('bluetooth')
                device_settings = bluetooth.get('deviceSettings')
                always_open = device_settings.get('alwaysOpen')
                reconnect_mode = device_settings.get('reconnectMode')
                devices = bluetooth.get('devices')
                bt_devices = devices.get('device')
                info = {'bt_open': always_open,
                        'bt_reconnect_mode': reconnect_mode,
                        'bt_devices': bt_devices}
                self.INFO['bluetoothSettings'] = info
                return info
            elif x == 'network_settings':
                r = request_url(network_settings.format(ip), timeout=8)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                network_info = data.get('profile').get('networkSettings')
                interfaces = network_info.get('interfaces')
                active_interface = network_info.get('activeInterface')
                # wired = interfaces.get('wired')
                wireless = interfaces.get('wireless')
                active_network = wireless.get('activeNetwork')
                internet_reachable = 'Yes' if network_info.get('internetReachable') else 'No'
                dhcp = 'Yes' if active_network.get('dhcp') else 'No'
                if active_interface == 'wireless':
                    info = {
                        'Active Interface': 'Wi-Fi',
                        'Internet Reachable': internet_reachable,
                        'SSID': active_network.get('ssid'),
                        'DHCP': dhcp,
                        'Frequency': active_network.get('frequency').replace('ghz', ' GHz'),
                        'Quality': active_network.get('quality'),
                        'RSSI': active_network.get('rssi'),
                        'Encryption': active_network.get('encryption').replace('Psk', '-PSK').replace(
                            'Tkip', '(TKIP)').upper()
                    }
                else:
                    info = {
                        'Active Interface': 'Ethernet',
                        'Internet Reachable': internet_reachable,
                        'Wifi configured': 'Yes' if active_network.get('configured') else 'No',
                        'DHCP': dhcp
                    }
                self.INFO['network_settings'] = info
                return info
            elif x == 'volume':
                r = requests_url(volume_speaker.format(ip), 'get')
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                speaker = data.get('speaker')
                volume_range = speaker.get('range')
                speaker_volume = {
                    'Current Level': speaker.get('level'),
                    'Default Level': speaker.get('defaultLevel'),
                    'Muted': 'Yes' if speaker.get('muted') else 'No',
                    'Min': volume_range.get('minimum'),
                    'Max': volume_range.get('maximum')
                }
                self.INFO['speaker_volume'] = speaker_volume
                return speaker_volume
            elif x == 'current_source':
                r = request_url(current_source.format(ip), timeout=5)
                if r.get('status') != 200:
                    self.INFO['current_source'] = 'error'
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                if len(data) == 0:
                    source = 'None'
                else:
                    source = data.get('friendlyName')
                self.INFO['current_source'] = source
                return source
            elif x == 'get_standby':
                r = request_url(standby_status.format(ip), timeout=5)
                if r.get('status') != 200:
                    self.INFO['standby_status'] = 'error'
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                status = data.get('standby').get('powerState')
                status = status.replace(status[0], status[0].upper())
                self.INFO['standby_status'] = status
                return status
            elif x == 'regional_settings':
                r = request_url(regional_settings.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                data_region = data.get('profile').get('regionalSettings')
                info = {
                    'Country': data_region.get('country').get('country'),
                    'Date Time': data_region.get('dateTime').get('dateTime'),
                    'Time Zone': data_region.get('timeZone').get('inTimeZone')
                }
                return info
            elif x == 'power_management':
                r = request_url(power_management.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                data_power = data.get('profile').get('powerManagement')
                info = {
                    'Idle Timeout': data_power.get('idleTimeout').get('timeout'),
                    'Play Timeout': data_power.get('playTimeout').get('timeout')
                }
                return info
            elif x == 'muted':
                r = request_url(volume_speaker.format(ip) + '/Muted', timeout=5)
                if r.get('status') != 200:
                    self.INFO['muted'] = 'error'
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                muted = data.get('muted')
                self.INFO['muted'] = muted
                return muted
            elif x == 'stream_state':
                r = request_url(sys_products.format(ip), timeout=5)
                if r.get('status') != 200:
                    return 'error'
                data = json.loads(r.get('content'), encoding='utf-8')
                products = data.get('products')
                for k, v in enumerate(products):
                    name = self.get_info('BeoDevice', ip).get('productFriendlyName')
                    if v.get('friendlyName') == name:
                        state = v.get('primaryExperience').get('state')
                        source_type = v.get('primaryExperience').get('source').get('sourceType').get('type')
                        break
                info = {
                    'state': state,
                    'source_type': source_type
                }
                return info
            elif x == 'get_product_status':
                return self.get_product_status(ip)
            else:
                return 'NA'
        except Exception as e:
            self.log.debug('cmd = {0}, error: {1}'.format(x, e))
            return 'NA'

    def get_other_info(self, ip):
        li = ['power_management', 'regional_settings']
        title = {
            'power_management': 'Power Management',
            'regional_settings': 'Regional Settings'
        }
        info = {}
        for i in li:
            tmp = self.get_info(i, ip)
            if tmp == 'NA' or tmp == 'error':
                return {'error': 'error'}
            info[title[i]] = tmp
        return info

    @staticmethod
    def standby(ip):
        url = power_management.format(ip) + '/standby'
        payload = json.dumps({"standby": {"powerState": "standby"}})
        return requests_url(url, 'put', data=payload).get('status')

    @staticmethod
    def set_volume(ip, value=None):
        url = volume_speaker.format(ip) + '/Level'
        payload = json.dumps({"level": int(value)})
        return requests_url(url, 'put', data=payload).get('status')

    @staticmethod
    def stream(ip, mode):
        """Player Stream
        mode = 'Play', 'Pause', 'Wind', 'Rewind', 'Forward', 'Backward'
        """
        url = zone_stream.format(ip, mode)
        return requests_url(url, 'post').get('status')

    @staticmethod
    def mute(ip):
        url = volume_speaker.format(ip) + '/Muted'
        payload = json.dumps({"muted": False})
        return requests_url(url, 'put', data=payload).get('status')

    def get_product_status(self, ip):
        info = ['get_standby', 'current_source', 'muted']
        for i in info:
            self.get_info(i, ip)
        self.INFO['product_status'] = {
            'Power': self.INFO.get('standby_status'),
            'Source': self.INFO.get('current_source'),
            'Muted': 'Yes' if self.INFO.get('muted') else 'No'
        }
        return self.INFO["product_status"]

    def scan_wifi(self, ip):
        data = self.transfer_data("getRows", ip, network_scan_results_para)
        return data

    def pair_bt(self, pair, ip):
        if pair == 'pair':
            para = pairBT_para
        # elif pair == 'cancel':
        else:
            para = pairCancelBT_para
        return self.transfer_data("set", ip, para)['status']

    def reset(self, ip):
        return self.transfer_data("set", ip, factoryResetRequest_para)['status']

    def change_product_name(self, name, ip):
        return self.transfer_data("set", ip, set_device_name(name))['status']

    def log_submit(self, ip):
        return self.transfer_data("set", ip, logReport_para, timeout=80)["status"]

    def log_clear(self, ip):
        return self.transfer_data("set", ip, clearLogs_para)['status']

    def bt_open_set(self, open_enable, ip):
        return self.transfer_data("set", ip, set_pairing_mode(open_enable))['status']

    def bt_remove(self, bt_mac, ip):
        bt_mac = bt_mac.replace(":", "_")
        return self.transfer_data("set", ip, bt_remove_para(bt_mac))['status']

    def bt_reconnect_set(self, mode, ip):
        if mode == 'disabled':
            mode = 'none'
        return self.transfer_data("set", ip, set_bt_mode(mode))['status']
    # ==================================================================================================================

    def setup_wifi(self, ssid="", key="", dhcp=True, ip="", gateway="", netmask="", originalIp=""):
        # logging.log(logging.INFO, "Setup wifi ssid=%s key=%s"%(wifissid,pwd))
        encryption = "wpa_psk"
        if key == "":
            encryption = "none"
        wifi_value = wifi_settings(ssid, key, encryption, dhcp, ip, gateway, netmask)
        try:
            self.transfer_data("set", originalIp, wifi_value)
        except Exception as e:
            self.log.info(e)
            return False
        else:
            return True

    # ==================================================================================================================
    @staticmethod
    def get_ase(ip, info):
        """For unblock device"""
        # info = 'readinfo'
        cmd = r'"{}\\config\\thrift\\thrift2.exe"'.format(os.getcwd()) + " {} 1 {}".format(ip, info)
        s = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        pipe = s.stdout.readlines()
        return pipe

    def unblock_device(self, ip):
        if not check_url_status(beo_device.format(ip), timeout=5):
            return False
        self.log.debug('Start unblock...')
        try:
            status = str(self.get_ase(ip, 'readinfo')[-1], 'utf-8')
        except Exception as e:
            self.log.error(e)
            return False
        if 'Successful' in status:
            self.log.debug('Unblock successfully!')
            return True
        self.log.debug('Unblock failed!')
        return False

    # ==================================================================================================================
    def get_ase_devices_list(self):
        # self.devices_list.clear()
        self.devices_list = []
        self.status = 0
        self.saved_ip = self.load_ip()
        ip_info = WindowsWifi().discover_ips()
        scanned_ip = ip_info.get('ip')
        gateway = ip_info.get('gateway')
        ips = []
        ips.extend(self.saved_ip)
        for ip in scanned_ip:
            if ip not in self.saved_ip:
                ips.append(ip)
        # ips = list(set(self.saved_ip + scanned_ip))  # method set will not keep list order
        for ip in ips:
            tmp = ip.rsplit('.', 1)[0]
            if tmp not in gateway:
                ips = [i for i in filter(lambda x: x != ip, ips)]
        self.log.debug(ips)
        self.thread_scan_devices(ips)

        # For show device info in real-time(one by one) when scanning
        thread_status = Thread(target=self.scan_status, args=())
        thread_status.setDaemon(True)
        thread_status.start()

    def thread_scan_devices(self, ips: list):
        self.threads = []
        for ip in ips:
            t = Thread(target=self.scan_devices, args=(ip,))
            t.setDaemon(True)
            t.start()
            self.threads.append(t)
            sleep(0.005)    # avoid network block

    @staticmethod
    def load_ip():
        return load(saved_ip_path).get('ip')

    @staticmethod
    def store_ip(ips):
        # If saved ips are more than 20, then remove the oldest one (first in first out).
        if len(ips) > 20:
            ips = [i for i in filter(lambda x: x != ips[0], ips)]
        store(saved_ip_path, {"ip": ips})

    def scan_status(self):
        for td in self.threads:
            td.join()
        self.status = 1
        self.store_ip(self.saved_ip)

    def scan_devices(self, ip):
        r = requests_url(beo_device.format(ip), 'get', timeout=6)
        # if not self.check_url_status("http://{}/index.fcgi".format(ip), timeout=6):  # timeout need modify
        if r.get('status') != 200:
            return
        try:
            data = json.loads(r.get('content'), encoding='utf-8')
            beo_info = data.get('beoDevice')
            device_name = beo_info.get('productFriendlyName').get('productFriendlyName')
            model_name = beo_info.get('productId').get('productType')
            # device_name = self.get_info("device_name", ip)
            # model_name = self.get_info("basicInfo", ip)['modelName']

            """
            result = socket.gethostbyaddr(ip)
            try:
                host_name = result[0].replace(".lan", "")
            except Exception as e:
                self.log.error("host name not contain .lan" + e)
                return
            """
            if lock.acquire():
                if ip not in self.saved_ip:
                    self.saved_ip.append(ip)
                self.devices_list.append("{} ({}) [{}]".format(device_name, ip, model_name))
                # self.devices_list.append("{} ({})".format(host_name, ip))
                lock.release()
        # except socket.herror as e:
        except Exception as e:
            self.log.debug("Something wrong when scanning {}: {}".format(ip, e))
    # ==================================================================================================================

    def thread_get_info(self, ip):
        if not check_url_status(beo_device.format(ip), timeout=5):
            return {"error": "error", "ip": ip}
        # self.devices_list.clear()
        # basic_info = ase_info.get_info("basicInfo", ip)
        # beo_device_info = ase_info.get_info('BeoDevice', ip)
        self.INFO["ip"] = ip
        info = ['BeoDevice', 'modulesInformation', 'bluetoothSettings', 'get_product_status']
        # threads = []
        for i in info:
            self.get_info(i, ip)
        '''
            t = Thread(target=self.get_info, args=(i, ip))
            t.setDaemon(True)
            t.start()
            threads.append(t)
            # sleep(0.02)    # avoid network block
        for td in threads:
            td.join()
        '''
        self.INFO["ase_version"] = '{} ({})'.format(
            self.INFO.get('version'), self.INFO.get('sn'))
        self.INFO["fep_versions"] = '{} ({})'.format(
            self.INFO.get('fep_app'), self.INFO.get('bootloader'))
        return self.INFO

    # ==================================================================================================================

    def send_cmd(self, ip, cmd):
        user = '******'
        ssh_rsa = './data/ssh-rsa'
        ssh_path = '{}/config/OpenSSH/'.format(os.getcwd())
        ssh = SshHelper(ip, user, ssh_rsa, ssh_path)
        content = ssh.execute(cmd)
        if len(content) == 0:
            if self.unblock_device(ip):
                content = ssh.execute(cmd)
            else:
                self.log.error('Cannot communicate with your sample!')
        return content

    def get_log_files(self, ip, sn, cmd, save_path):
        save_path = os.path.abspath(save_path)
        if not os.path.exists(save_path):
            os.mkdir(save_path)
        path = os.path.join(save_path, '{}_{}_{}.log'.format(
            cmd.rsplit('/', 1)[1], sn, datetime.datetime.now().strftime('%m%d_%H_%M_%S')))
        try:
            content = self.send_cmd(ip, cmd)
            with open(path, 'w', encoding='utf-8') as f:
                f.write(content)
        except Exception as e:
            self.log.error(e)
            path = ""
        return path

    def download_log(self, ip, sn, script_path, save_path):
        save_path = os.path.abspath(save_path)
        if not os.path.exists(save_path):
            os.mkdir(save_path)
        path, content = '', ''
        with open(script_path, 'r') as f:
            for l in f.readlines():
                cmd = l.replace('\n', '')
                content = self.send_cmd(ip, cmd)
            # url = re.findall(r'http:.*tgz', content)
            url = 'http://{}/{}'.format(ip, content)
            path = os.path.join(save_path, 'log_{}.tgz'.format(sn))
            try:
                request.urlretrieve(url, path)
            except Exception as e:
                self.log.error(e)
                path = ''
        return path
Example #4
0
class AseUpdate(object):
    def __init__(self, socketio, ota_setting_path):
        self.socketio = socketio
        self.log = Logger("wifi_speaker").logger()
        with open(ota_setting_path) as json_file:
            data = json.load(json_file)
            # parent_path = os.path.realpath(os.path.join(os.getcwd(), ".."))
        self.low_version_path = data["low_version_path"]
        self.high_version_path = data["high_version_path"]
        self.low_version = data["low_version"]
        self.high_version = data["high_version"]
        self.cycle = int(data["total_times"])
        self.IP = "http://" + data["ip"]
        self.title = " auto update OTA Test"

        self.shot_path = ''
        self.pageTimeout = 15
        self.update_times = 0
        self.downgrade_times = 0
        self.Network_Error = 0
        self.Run_status = ''
        # driver = webdriver.Chrome("%s\chromedriver2.9.exe"%os.getcwd())
        self.print_log("Start to Auto Update Test!")
        try:
            self.print_log("Open Setting Page by browser Firefox...")
            self.driver = webdriver.Firefox()
            self.driver.get(self.IP)
        except Exception as e:
            self.print_log(e, 'red')
            sys.exit()
            # s = unicode ("成 ", "utf-8")

    def print_log(self, info, color='white'):
        try:
            self.log.info(info)
            self.socketio.sleep(
                0.01
            )  # Avoid sockeit network block leads to cannot print on page
            self.socketio.emit('print_msg', {
                'data': info,
                'color': color
            },
                               namespace='/wifi_speaker/test')
        except Exception as e:
            self.log.debug("Error when print_log: {}".format(e))
            self.driver.quit()
            sys.exit()

    def screen_shot(self, info):
        self.print_log("%s\%s_%s.png" %
                       (self.shot_path, info,
                        time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime())))
        self.driver.get_screenshot_as_file(
            "%s/%s_%s.png" %
            (self.shot_path, info,
             time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime())))

    def check_network(self, url):
        try:
            # r = requests.get(url, allow_redirects = False)
            # status = r.status_code
            self.log.debug(url)
            req = urllib.request.Request(url)
            res = urllib.request.urlopen(req, timeout=8)
            status = res.status
            # r = urllib.request.urlopen(url, timeout=8)
            # status = r.getcode()
            if status == 200:
                self.print_log('Network is ok')
                return True
            else:
                self.screen_shot("Network error")
                self.log.error('Network error!!!!')
                return False
        except:
            self.screen_shot("Network error")
            self.log.error('Network error!!!!')
            return False

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """"""

    # make screen shot directory
    @staticmethod
    def make_shot_dir():
        # shot_conf = dict(root_run = os.getcwd())
        run_shot_dir = os.path.realpath(
            os.path.join(os.getcwd(), "./log", 'error_shot'))
        if not os.path.exists(run_shot_dir):
            os.makedirs(run_shot_dir)
        return run_shot_dir
        # shot_conf['runshot_dir'] = run_shot_dir
        # return shot_conf

    """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """
    """ """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """""" """"""

    def switch_frame(self, frame_type):
        try:
            if frame_type == "default":
                self.driver.switch_to_default_content()
            elif frame_type == "rightFrame":
                self.driver.switch_to_frame("rightFrame")
            elif frame_type == "leftFrame":
                self.driver.switch_to_frame("leftFrame")
            else:
                self.print_log("No such frame {}".format(frame_type), 'red')
        # except NotImplementedError as e:
        except Exception as e:
            self.log.error("Error when switch frame {}: {}".format(
                frame_type, e))
            sys.exit()
        else:
            return True

    def find_element(self, ele_type, timeout, value):
        """
        Args:
            ele_type(str): element type
            timeout(int): max time at finding element
            value(str): element attribute value
        Returns:
            ele(WebElement): return object of found element
        """
        ele = None
        try:
            if ele_type == "id":
                WebDriverWait(self.driver, timeout).until(
                    lambda driver: driver.find_element_by_id(value))
                ele = self.driver.find_element_by_id(value)
            elif ele_type == "name":
                WebDriverWait(self.driver, timeout).until(
                    lambda driver: driver.find_element_by_name(value))
                ele = self.driver.find_element_by_name(value)
            elif ele_type == "class_name":
                WebDriverWait(self.driver, timeout).until(
                    lambda driver: driver.find_element_by_class_name(value))
                ele = self.driver.find_element_by_class_name(value)
            elif ele_type == "link_text":
                WebDriverWait(self.driver, timeout).until(
                    lambda driver: driver.find_element_by_link_text(value))
                ele = self.driver.find_element_by_link_text(value)
            elif ele_type == "partial_link_text":
                WebDriverWait(
                    self.driver,
                    timeout).until(lambda driver: driver.
                                   find_element_by_partial_link_text(value))
                ele = self.driver.find_element_by_partial_link_text(value)
            elif ele_type == "tag_name":
                WebDriverWait(self.driver, timeout).until(
                    lambda driver: driver.find_element_by_tag_name(value))
                ele = self.driver.find_element_by_tag_name(value)
            elif ele_type == "xpath":
                WebDriverWait(self.driver, timeout).until(
                    lambda driver: driver.find_element_by_xpath(value))
                ele = self.driver.find_element_by_xpath(value)
            else:
                self.print_log(
                    "No such locate element way {}".format(ele_type))
        except NotImplementedError as e:
            self.print_log(e, 'red')
        except TimeoutError as e:
            self.log.debug(e)
            sys.exit()
            # else:
            # return ele
        finally:
            return ele

    def update_percentage(self):
        time.sleep(20)
        while True:
            # time.sleep(8)
            if not self.check_popup():
                self.switch_frame("default")
                self.switch_frame("rightFrame")
                try:
                    confirm_update_done = self.find_element(
                        "xpath", 10, "//*[@id='ConfirmUpdateDone']")
                    confirm_update_done.click()
                    return True
                except:
                    pass
            else:
                return False

    def check_version(self, v):
        self.switch_frame("default")
        self.switch_frame("rightFrame")
        software_version = self.find_element("xpath", self.pageTimeout,
                                             "//*[@id='softwareVersion']")
        if software_version is None:
            return False
        version = software_version.text
        self.print_log("DUT current version is %s" % version)
        if v == version:
            # success_time=success_time+1
            self.print_log("Update successfully!")
            return True
        else:
            self.print_log("Update fail!", "red")
            return False

    def check_popup(self):
        """Check popup box when Uploading or updatings
        Returns:
                True: Appear popup
                False: No popup
        """
        self.switch_frame("default")
        try:
            popup = self.find_element("class_name", 1, "imgButtonYes")
            popup.is_displayed()
            # driver.find_element_by_class_name("imgButtonYes").is_displayed()
            self.screen_shot("%s_popup" % self.Network_Error)
            popup.click()
            self.print_log("Network unavailable")
            self.Network_Error += 1
            return True
        except:
            return False

    def agreement_page(self):
        time.sleep(2)
        self.switch_frame("default")
        self.switch_frame("rightFrame")
        self.log.debug('Checking if there is agreement page!')
        if self.find_element("xpath", self.pageTimeout,
                             "//*[@id='BtnOK1']") is None:
            return False
        self.log.debug('Start to click agreement page!')
        self.find_element("xpath", self.pageTimeout,
                          "//*[@id='BtnOK1']").click()
        time.sleep(3)
        self.find_element("xpath", self.pageTimeout,
                          "//*[@id='BtnOK2']").click()
        time.sleep(3)
        self.switch_frame("default")
        self.switch_frame("rightFrame")
        self.find_element("xpath", self.pageTimeout,
                          "//*[@id=\"Accept\"]").click()
        time.sleep(3)
        self.find_element("xpath", self.pageTimeout,
                          "//*[@id='NoThanks']").click()
        time.sleep(7)
        return True

    def update_local(self, local_file):
        self.log.debug("Ready to uploade on local")
        self.switch_frame("default")
        self.switch_frame("rightFrame")
        time.sleep(1)

        self.log.debug("Click LocalUpdateButton")
        local_update_button = self.find_element(
            "xpath", self.pageTimeout, "//*[@id='LocalUpdateButton']")
        local_update_button.click()
        time.sleep(2)

        datafile = self.find_element("xpath", self.pageTimeout,
                                     "//*[@id='datafile']")
        try:
            datafile.send_keys('%s' % local_file)
        except Exception as e:
            self.log.debug(e)
            sys.exit()
        time.sleep(3)

        loadfile_button = self.find_element("xpath", self.pageTimeout,
                                            "//*[@id='LoadFileButton']")
        loadfile_button.click()

        self.print_log("Uploading %s file..." % local_file)
        while True:
            time.sleep(5)
            if self.check_popup():
                return False
            self.switch_frame("rightFrame")
            try:
                confirm_yes = self.find_element(
                    "xpath", self.pageTimeout,
                    "//*[@id='LocalUpdateConfirmYes']")
                confirm_yes.click()
                self.print_log("Uploading success!")
                self.print_log("Start burn into...!")
                if not self.update_percentage():
                    return False
                else:
                    return True
            except:
                self.log.debug('Wait for Yes button')

    def update_server(self, current_version):
        local_file = self.low_version_path
        if current_version == self.high_version:
            self.print_log("Downgrade from local")
            if not self.update_local(local_file):
                return False
            time.sleep(10)
            if self.check_version(self.low_version):
                self.print_log(
                    "Downgrade successfully from %s to version %s on local" %
                    (self.high_version, self.low_version))
                self.downgrade_times += 1
                return True
        else:
            self.print_log("Update from server")
            time.sleep(2)
            self.switch_frame("default")
            self.switch_frame("rightFrame")
            time.sleep(10)
            try:
                new_sw_version = self.find_element("xpath", self.pageTimeout,
                                                   "//*[@id='NewSWVersion']")
            except:
                return False  # Cannot check new version
            if new_sw_version.text == self.high_version:
                update_from_network_button = self.find_element(
                    "xpath", self.pageTimeout,
                    "//*[@id='UpdateFromNetworkButton']")
                update_from_network_button.click()
                time.sleep(3)
                network_update_confirm_yes = self.find_element(
                    "xpath", self.pageTimeout,
                    "//*[@id='NetworkUpdateConfirmYes']")
                network_update_confirm_yes.click()
                self.print_log("Start update!")
            if not self.update_percentage():
                return False
            time.sleep(10)
            if self.check_version(self.high_version):
                self.print_log(
                    "Update successfully from %s to version %s on internet" %
                    (self.low_version, self.high_version))
                self.update_times += 1
                return True

    def update_full(self):
        try:
            self.print_log(self.driver.title + "(" + self.IP + ")")
        except Exception as e:
            self.print_log(e, 'red')
            sys.exit()
        for i in range(0, 15):
            try:
                if self.agreement_page():
                    break
                else:
                    self.switch_frame("default")
                    self.switch_frame("rightFrame")
                    if self.find_element(
                            "xpath", self.pageTimeout,
                            "//*[@id='softwareVersion']") is not None:
                        break
            except:
                continue
        time.sleep(2)
        self.switch_frame("default")
        self.switch_frame("rightFrame")
        current_version = self.find_element("xpath", self.pageTimeout,
                                            "//*[@id='softwareVersion']").text

        self.print_log("DUT current version is %s" % current_version)
        self.switch_frame("default")

        time.sleep(2)
        self.switch_frame("leftFrame")
        sw_update_page = self.find_element("xpath", self.pageTimeout,
                                           "//*[@id='SwUpdatePage']/span")
        sw_update_page.click()
        time.sleep(3)  # wait page
        # if current version is not high or low version, force updating to high version
        if (current_version != self.low_version) and (current_version !=
                                                      self.high_version):
            self.update_local(self.high_version_path)
            time.sleep(10)
            self.check_version(self.high_version)
            return True

        # Update from server
        if self.low_version_path == self.high_version_path:
            if not self.update_server(current_version):
                return False
            return True

        # Update from local
        else:
            if current_version == self.high_version:
                local_file = self.low_version_path
                version_check = self.low_version
                self.print_log("Downgrade to version %s just with local file" %
                               version_check)
            else:
                local_file = self.high_version_path
                version_check = self.high_version
                self.print_log("Update to version %s just with local file" %
                               version_check)

            if not self.update_local(local_file):
                return False
            time.sleep(10)
            if self.check_version(version_check):
                if version_check == self.low_version:
                    self.print_log(
                        "Downgrade successfully from %s to version %s on local"
                        % (self.high_version, self.low_version))
                    self.downgrade_times += 1
                elif version_check == self.high_version:
                    self.print_log(
                        "Update successfully from %s to version %s on local" %
                        (self.low_version, self.high_version))
                    self.update_times += 1
                else:
                    self.print_log("No such version! Error", 'red')
                    return False
            return True

    def start_ota(self):
        self.Run_status = "Running"
        self.shot_path = self.make_shot_dir()
        # start_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
        # start = time.time()

        for i in range(1, self.cycle + 1):
            self.print_log(
                "This is {} times----------------------------------------".
                format(i))
            for j in range(0, 2):
                if self.check_network(self.IP + "/index.fcgi"):
                    # when version file have been download from server(on updating),but the net disconnect
                    if not self.update_full():
                        self.print_log(
                            "Maybe Network trouble, so wait 100 second, then open setting page again"
                        )
                        time.sleep(
                            100
                        )  # why is 100s, as sometimes, update still can go on by DUT self
                        self.driver.quit()
                        # self.driver = webdriver.Chrome("%s\chromedriver.exe" % os.getcwd())
                        self.driver = webdriver.Firefox()
                        self.driver.get(self.IP)
                    if i == self.cycle:
                        self.Run_status = "Running Over"
                    # end = time.time()
                    # diff_time = int(end-start)
                    # duration="%sh:%sm:%ss"%(int((end-start)/3600),int((end-start)/60),int((end-start)%60))
                    # duration = str(datetime.timedelta(seconds=int(time.time() - start)))
                    # self.print_log("Success update times is %d"%self.update_times)
                    self.socketio.emit('refresh_update_status', {
                        "network_error":
                        self.Network_Error,
                        "pass_upgrade":
                        '{0}/{1} (Upgrade)'.format(self.update_times, i),
                        "pass_downgrade":
                        '{0}/{1} (Downgrade)'.format(self.downgrade_times, i)
                    },
                                       namespace='/wifi_speaker/test')
                    # CreateHTMLRpt.report_result(self.title,start_time,duration,str(i),self.Run_status,update,str(self.update_times),downgrade,str(self.downgrade_times),'self.Network_Error',str(self.Network_Error))

        self.driver.quit()
Example #5
0
class Automate(object):
    def __init__(self, cfg, state_path, socketio=None):
        cfg.cfg_load()
        self.cfg = cfg.cfg
        self.ase_info = AseInfo()
        self.socketio = socketio
        self.state_path = os.path.abspath(state_path)
        self.bp_relay_init = None
        self.log = Logger("automate").logger()
        self.button = Relay(self.log)
        self.ac_power = Relay(self.log)

    def print_log(self, info, color='white'):
        try:
            self.log.info(info)
            self.socketio.sleep(
                0.02
            )  # Avoid sockeit network block leads to cannot print on page
            self.socketio.emit('print_msg', {
                'data': info,
                'color': color
            },
                               namespace='/automate/test')
        except Exception as e:
            self.log.debug("Error when print_log: {}".format(e))
            sys.exit()

    def delay(self, t):
        if self.socketio is not None:
            self.socketio.sleep(t)
        else:
            time.sleep(t)

    @staticmethod
    def _split(para):
        info = []
        if ',' in para:
            values = re.findall('[^()]+', para)[1].split(',')
            for v in values:
                info.append(v.split(':')[1])
        else:
            values = re.findall('[^()]+', para)[1].split(':')[1]
            info.append(values)
        return info

    def get_ase_info(self, name):
        ip = self.cfg.get('ASE', 'ip')
        info = self.ase_info.get_info(name, ip)
        if info == 'error' or info == 'NA':
            self.print_log('Seems disconnected with your product!', 'red')
            return False
        return info

    def do_check(self, name, name_exp, name_get):
        name_exp = self._split(name_exp)[0]
        if str(name_exp).lower() != str(name_get).lower():
            self.print_log(
                'Current {}[{}] is unequal with expected[{}]'.format(
                    name, name_get, name_exp), 'red')
            return False
        else:
            self.print_log('Checked current {} = {}'.format(name, name_get))
        return True

    def send_command(self, cmd):
        ip = self.cfg.get('ASE', 'ip')
        playback = ['Pause', 'Play']
        self.print_log('Send {} --> {}'.format(cmd, ip))
        if cmd in playback and self.ase_info.stream(ip, cmd) == 200:
            self.delay(1)
            return True
        elif cmd == 'Standby' and self.ase_info.standby(ip) == 200:
            return True
        self.print_log('Seems disconnected with your product!', 'red')
        return False

    def send_pause(self):
        if not self.send_command('Pause'):
            return False
        return True

    def send_play(self):
        if not self.send_command('Play'):
            return False
        return True

    def set_standby(self):
        if not self.send_command('Standby'):
            return False
        return True

    def set_volume(self, steps_para):
        ip = self.cfg.get('ASE', 'ip')
        value = self._split(steps_para)[0]
        self.print_log('Set volume to {}'.format(value))
        if self.ase_info.set_volume(ip, value) != 200:
            self.print_log('Seems disconnected with your product!', 'red')
            return False
        return True

    def do_check_network(self, steps_para):
        ip = self.cfg.get('ASE', 'ip')
        value = self._split(steps_para)[0].lower()
        beo_device = self.ase_info.get_info('BeoDevice', ip)
        if beo_device == 'error' and value == 'no':
            self.print_log('Current network is off')
        elif beo_device != 'error' and value == 'yes':
            self.print_log('Current network is on')
        else:
            self.print_log('Current network is not [{}]'.format(value), 'red')
            return False
        return True

    def do_check_volume(self, steps_para):
        volume_info = self.get_ase_info('volume')
        if volume_info is False:
            return False
        vol_get = volume_info.get('Current Level')
        if not self.do_check('volume', steps_para, vol_get):
            return False
        return True

    def do_check_playback(self, steps_para):
        stream_info = self.get_ase_info('stream_state')
        if stream_info is False:
            return False
        current_state = stream_info.get('state').lower()
        #   stream_info.get('source_type')
        if not self.do_check('playback', steps_para, current_state):
            return False
        return True

    def do_check_source(self, steps_para):
        source = self.get_ase_info('current_source')
        if source is False:
            return False
        if not self.do_check('source', steps_para, source.lower()):
            return False
        return True

    def do_check_power_state(self, steps_para):
        standby = self.get_ase_info('get_standby')
        if standby is False:
            return False
        if not self.do_check('power state', steps_para, standby.lower()):
            return False
        return True

    def do_check_bt_connection(self, steps_para):
        bt_setting = self.get_ase_info('bluetoothSettings')
        if bt_setting is False:
            return False
        bt_devices = bt_setting.get('bt_devices')
        state = 'no'
        if len(bt_devices) > 0:
            for d in bt_devices:
                if d.get('connected'):
                    self.print_log('BT connected device: [{}]'.format(
                        d.get('deviceName')))
                    state = 'yes'
                    break
        if not self.do_check('BT connection', steps_para, state):
            return False
        return True

    def button_press(self, steps_para):
        if self.bp_relay_init:
            values = self._split(steps_para)
            key = values[0]
            t = values[1]
            key = key.split('&') if '&' in key else [key]
            self.print_log(steps_para)
            self.button.press(key, t)
        else:
            self.print_log('Something wrong with your relay!', 'red')
            return False
        return True

    def _ac_power(self, steps_para):
        state = self._split(steps_para)[0]
        if not self.ac_power.ac_power(state):
            self.print_log('Something wrong with your Relay!!!', 'red')
            return False
        self.print_log(steps_para)
        return True

    def process_steps(self, steps):
        for i in range(1, len(steps)):
            with open(self.state_path) as f:
                status_running = json.load(f)
            if status_running["run_state"] == 0:
                self.socketio.emit("stop_confirm", namespace='/automate/test')
                sys.exit()
            action = steps[str(i)]
            for k, v in action.items():
                if k == 'send_pause':
                    if not self.send_pause():
                        return False
                elif k == 'send_play':
                    if not self.send_play():
                        return False
                elif k == 'set_standby':
                    if not self.set_standby():
                        return False
                elif k == 'delay':
                    t = self._split(v)[0]
                    self.print_log('Delay {} s'.format(t))
                    self.delay(float(t))
                elif k == 'set_volume':
                    if not self.set_volume(v):
                        return False
                elif k == 'do_check_network':
                    if not self.do_check_network(v):
                        return False
                elif k == 'do_check_volume':
                    if not self.do_check_volume(v):
                        return False
                elif k == 'do_check_playback':
                    if not self.do_check_playback(v):
                        return False
                elif k == 'do_check_source':
                    if not self.do_check_source(v):
                        return False
                elif k == 'do_check_power_state':
                    if not self.do_check_power_state(v):
                        return False
                elif k == 'do_check_bt_connection':
                    if not self.do_check_bt_connection(v):
                        return False
                elif k == 'button_press':
                    if not self.button_press(v):
                        return False
                elif k == 'ac_power':
                    if not self._ac_power(v):
                        return False
        return True

    def run(self, steps):
        total_times = int(steps['total_times'])
        for x in steps:
            if 'button_press' in steps[x]:
                usb_port = 'com' + self.cfg.get('Button_Press', 'bp_usb_port')
                self.button.init_relay(usb_port)
                self.bp_relay_init = self.button.init_button()
            elif 'ac_power' in steps[x]:
                usb_port = 'com' + self.cfg.get('AC_Power', 'ac_usb_port')
                self.ac_power.init_relay(usb_port)
        c_time = 0
        while c_time < total_times:
            c_time += 1
            txt = '**************This is the {} times**************'.format(
                c_time)
            self.print_log(txt)
            self.socketio.emit("show_running_info", {'current_times': c_time},
                               namespace='/automate/test')
            if not self.process_steps(steps):
                self.delay(0.2)
                self.socketio.emit("run_stopped", namespace='/automate/test')
                break
        if self.button.ser is not None:
            self.button.stop_relay()
        if self.ac_power.ser is not None:
            self.ac_power.stop_relay()
        if c_time >= total_times:
            self.socketio.emit('running_over', namespace='/automate/test')
        sys.exit()
Example #6
0
class SerialTool(object):
    def __init__(self, state_path, socketio=None):
        self.socketio = socketio
        self.log = Logger("power_cycle").logger()
        self.ini = None
        self.port_list = []
        self.ser = None
        self.port_selected = None
        self.port_disconnect = False
        self.state_path = os.path.abspath(state_path)

    def print_log(self, msg, color='white'):
        try:
            self.log.info(msg)
            if self.socketio is not None:
                self.socketio.sleep(
                    0.01
                )  # Avoid sockeit network block leads to cannot print on page
                self.socketio.emit('print_log', {
                    'msg': msg,
                    'color': color
                },
                                   namespace='/power_cycle/test')
        except Exception as e:
            self.log.debug("Error when print_log: {}".format(e))
            sys.exit()

    def add_port(self, port_info):
        try:
            self.socketio.sleep(0.005)
            self.socketio.emit('add_port', {'data': port_info},
                               namespace='/power_cycle/test')
        except Exception as e:
            self.log.debug("Error when add_port: {}".format(e))
            sys.exit()

    def del_port(self, port_info):
        try:
            self.socketio.sleep(0.005)
            self.socketio.emit('del_port', {'data': port_info},
                               namespace='/power_cycle/test')
        except Exception as e:
            self.log.debug("Error when del_port: {}".format(e))
            sys.exit()

    def delay(self, t):
        if self.socketio is not None:
            self.socketio.sleep(t)
        else:
            sleep(t)

    def find_all_serial(self):
        """Get serial list
        :param self:
        :return:
        """
        try:
            temp_serial = list()
            for com in list_ports.comports():
                str_com = com[0] + ": " + com[
                    1][:
                       -7]  # + ": " + com[1][:-7].decode("gbk").encode("utf-8")
                temp_serial.append(str_com)
            for item in temp_serial:
                if item not in self.port_list:
                    self.add_port(item)
                    self.port_list.append(item)
            for item in self.port_list:
                if item not in temp_serial:
                    self.port_list = [
                        i for i in filter(lambda x: x != item, self.port_list)
                    ]
                    self.del_port(item)
            self.port_list = temp_serial
            if self.port_selected is not None:
                if self.port_selected not in self.port_list:
                    self.port_disconnect = True
                    msg = "Disconnected [{0}]!".format(self.port_selected)
                    self.socketio.emit('port_status', {
                        'msg': msg,
                        'color': "red"
                    },
                                       namespace='/power_cycle/test')
                    self.port_selected = None
        except Exception as e:
            self.log.error(e)
            sys.exit()

    def open_port(self, port_set):
        try:
            self.port_selected = port_set["port_info"]
            port = port_set["port_info"].split(":")[0]
            baud_rate = port_set["baud_rate"]
            parity = port_set["parity"]
            data_bit = port_set["data_bit"]
            stop_bit = port_set["stop_bit"]
            self.ser = SerialHelper(Port=port,
                                    BaudRate=baud_rate,
                                    ByteSize=data_bit,
                                    Parity=parity,
                                    Stopbits=stop_bit)
            self.ser.start()
            if self.ser.alive:
                self.port_disconnect = False
                msg = "Open [{0}] Successfully!".format(port_set["port_info"])
                font_color = "green"
            else:
                msg = "Something wrong with your serial port!"
                font_color = "red"
        except Exception as e:
            self.log.error(e)
            msg = "Open [{0}] Failed!".format(port_set["port_info"])
            font_color = "red"
        self.socketio.emit('port_status', {
            'msg': msg,
            'color': font_color
        },
                           namespace='/power_cycle/test')

    def close_port(self):
        try:
            self.ser.stop()
            self.port_selected = None
            if not self.ser.alive:
                msg = "Ready"
                self.socketio.emit('port_status', {
                    'msg': msg,
                    'color': "white"
                },
                                   namespace='/power_cycle/test')
        except Exception as e:
            self.log.error(e)

    def send_msg(self, msg, is_hex):
        self.ser.write(msg.encode('utf-8'), isHex=is_hex)

    def power(self, status):
        with open(self.state_path) as f:
            status_running = json.load(f)
        if status_running["power_cycle_status"] == 0:
            self.print_log("You stopped running!!!", "red")
            self.socketio.emit("stop_confirm", namespace='/power_cycle/test')
            sys.exit()
        if status == "on":
            time_delay = float(self.ini["time_on"])
            if "-" in self.ini["button_press_on"]:
                val = self.ini["button_press_on"].split("-")
                button_press_delay = round(
                    random.uniform(float(val[0]), float(val[1])), 4)
            else:
                button_press_delay = float(self.ini["button_press_on"])
            ac_address = 'B'
        else:
            time_delay = float(self.ini["time_off"])
            if "-" in self.ini["button_press_off"]:
                val = self.ini["button_press_off"].split("-")
                button_press_delay = round(
                    random.uniform(float(val[0]), float(val[1])), 4)
            else:
                button_press_delay = float(self.ini["button_press_off"])
            ac_address = 'A'
        self.print_log('Powering {}...'.format(status))
        if not self.port_disconnect:
            try:
                if self.ini["relay_type"] == 'Button':
                    self.ser.write(self.ini["port_address"].encode('utf-8'),
                                   isHex=True)
                    self.print_log(
                        "button press delay = {}s".format(button_press_delay))
                    self.delay(button_press_delay)
                    self.ser.write("00".encode('utf-8'), isHex=True)
                else:
                    self.ser.write(ac_address.encode('utf-8'))
                self.print_log('Waiting {} seconds'.format(time_delay))
                self.delay(time_delay)
            except Exception as e:
                self.print_log('Error when powering on: {0}'.format(e), 'red')
                return False
        else:
            self.print_log('Serial Port seems disconnected......', 'red')
            return False
        return True

    def stop_confirm(self):
        self.socketio.emit('stop_confirm', {'data': "stopped"},
                           namespace='/power_cycle/test')

    def power_cycle(self, ini):
        self.ini = ini
        if self.ser.alive:
            if self.ini["relay_type"] == 'Button':
                self.delay(0.5)
                self.ser.write('50'.encode('utf-8'), isHex=True)
                self.delay(0.5)
                self.ser.write('51'.encode('utf-8'), isHex=True)
                self.delay(0.5)
                self.ser.write('00'.encode('utf-8'), isHex=True)

            for i in range(1, int(self.ini["total_count"]) + 1):
                self.print_log('This is >>>>>>>>>> %i<<<<<<<<<< times' % i)
                if not self.power('on'):
                    return False
                if not self.power('off'):
                    return False
            self.print_log('Power on your device...')
            self.power('on')
            self.print_log('-' * 37)
            self.print_log('*********Running over*********')
            self.print_log('-' * 37)
            self.delay(0.5)
        else:
            return False
        return True