import base64
import json
import logging
import re
import threading
import time

import oss2
import requests
from django.db import transaction
from django.db.models import Q
from django.views.generic.base import View

from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, CONFIG_INFO, CONFIG_US
from Controller.CheckUserData import RandomStr
from Controller.DeviceConfirmRegion import Device_Region
from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
from Controller.UnicomCombo.UnicomComboController import UnicomComboView
from Controller.UnicomCombo.WXTechController import WXTechControllerView
from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
    Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UnicomDeviceInfo, CountryModel, \
    DeviceCloudPhotoInfo, UidPushModel, ExperienceContextModel, LogModel, UserAudioVideoPush, UIDModel
from Object.RedisObject import RedisObject
from Object.ResponseObject import ResponseObject
from Object.TokenObject import TokenObject
from Service.CommonService import CommonService
from Service.EquipmentInfoService import EquipmentInfoService
from Service.ModelService import ModelService
from Service.UserDeviceService import UserDeviceService

LOGGER = logging.getLogger('info')


class EquipmentManagerV3(View):

    def get(self, request, *args, **kwargs):
        request.encoding = 'utf-8'
        operation = kwargs.get('operation')
        return self.validation(request.GET, request, operation)

    def post(self, request, *args, **kwargs):
        request.encoding = 'utf-8'

        operation = kwargs.get('operation')
        return self.validation(request.POST, request, operation)

    def validation(self, request_dict, request, operation):
        response = ResponseObject()

        if operation == 'notLoginMainUserDevice':
            return self.not_login_do_mainUserDevice(request_dict, response)
        elif operation == 'notLoginMainDelDevice':
            return self.test_tool_del_device(request_dict, response)
        elif operation == 'changeDevicePassword':
            return self.change_device_password(request_dict, response)
        elif operation == 'modifyChannelName':
            return self.do_modify_channel_name(request_dict, response)

        token = request_dict.get('token', None)
        tko = TokenObject(token)
        if tko.code != 0:
            return response.json(tko.code)
        response.lang = tko.lang
        userID = tko.userID
        # 手机端添加设备，查询，修改
        if operation == 'add':
            return self.do_add(userID, request_dict, response, request)
        if operation == 'batchAdd':
            return self.do_batch_add(userID, request_dict, response, request)
        elif operation == 'query':
            return self.do_query(userID, request_dict, response)
        elif operation == 'modify':
            return self.do_modify(userID, request_dict, response, request)
        elif operation == 'fuzzyQuery':
            return self.do_fuzzy_query(userID, request_dict, response)
        elif operation == 'mainUserDevice':
            return self.do_mainUserDevice(request_dict, response, userID)
        elif operation == 'getDeviceFeatures':
            return self.do_get_device_features(request_dict, response)
        elif operation == 'deviceRouse':
            return self.device_rouse(request_dict, response)
        elif operation == 'saveButtonUser':
            return self.save_button_user(request_dict, response)
        elif operation == 'getButtonUser':
            return self.get_button_user(request_dict, response)
        elif operation == 'verifyCode':
            return self.verify_code(request_dict, response)
        elif operation == 'viewDevicePassword':
            return self.view_device_password(request_dict, response)
        else:
            return response.json(414)

    @classmethod
    def device_rouse(cls, request_dict, response):
        """
        设备唤醒
        """
        serial_number = request_dict.get('serialNumber', None)
        if not serial_number:
            return response.json(444)
        try:
            # 主题名称
            topic_name = f'/wakeup/{serial_number}_0'
            # 发布消息内容
            msg = {'payload': 'A'}
            result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
            if not result:
                return response.json(10044)
            return response.json(0)
        except Exception as e:
            LOGGER.info('****设备唤醒发布消息异常:{},{}'.format(serial_number, repr(e)))
            return response.json(500, repr(e))

    def do_add(self, userID, request_dict, response, request):
        UID = request_dict.get('UID', None)
        NickName = request_dict.get('NickName', None)
        View_Account = request_dict.get('View_Account', None)
        View_Password = request_dict.get('View_Password', '')
        encrypt_pass = View_Password
        Type = request_dict.get('Type', None)
        ChannelIndex = request_dict.get('ChannelIndex', None)
        version = request_dict.get('version', '')
        isCheckMainUser = request_dict.get('isCheckMainUser', None)

        family_id = request_dict.get('familyId', None)
        room_id = request_dict.get('roomId', None)

        m_code = request_dict.get('m_code', None)
        appBundleId = request_dict.get('appBundleId', None)
        app_type = request_dict.get('app_type', None)
        push_type = request_dict.get('push_type', None)
        token_val = request_dict.get('token_val', None)
        jg_token_val = request_dict.get('jg_token_val', '')
        lang = request_dict.get('lang', 'en')
        tz = request_dict.get('tz', '0')

        if not NickName:
            NickName = UID[:6]

        if not all([UID, NickName, View_Account, Type, ChannelIndex]):  # Type和ChannelIndex可能为0
            return response.json(444, {'param': 'UID, NickName, View_Account, Type, ChannelIndex'})

        if tz == '':
            tz = 0
        else:
            tz = tz.replace("GMT", "")
        Type = int(Type)
        ChannelIndex = int(ChannelIndex)

        re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
        if not re_uid.match(UID):
            return response.json(444, {'param': 'UID'})

        device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
        if device_info_qs:
            # 判断设备是否已存在
            if device_info_qs[0].isExist == 1:
                return response.json(174)
            else:
                device_info_qs.delete()

        dvr_type_list = [1, 2, 3, 4, 300, 10001]
        View_Password = '' if Type in dvr_type_list else 'admin'

        id = CommonService.getUserID(getUser=False)
        device_user_qs = Device_User.objects.filter(userID=userID).values('username')
        if not device_user_qs.exists():
            return response.json(173)

        uid_status = UIDModel.objects.filter(uid=UID).values('status').first()
        if uid_status and uid_status['status'] == 0:
            return response.json(10076)

        userName = device_user_qs[0]['username']
        main_exist = Device_Info.objects.filter(UID=UID)
        main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')

        vodPrimaryUserID = userID
        vodPrimaryMaster = userName
        primaryUserID = ''
        primaryMaster = ''
        isShare = False

        is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
                                                                            'primaryMaster')

        if main_exist.exists():
            vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
            vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']

        if is_bind.exists():
            primaryUserID = is_bind[0]['primaryUserID']
            primaryMaster = is_bind[0]['primaryMaster']
            isShare = True

        isusermain = False
        if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
            isusermain = True

        # 判断是否有已绑定用户
        if isCheckMainUser == '1' and isusermain:
            res = {
                'id': id,
                'userID': userID,
                'NickName': NickName,
                'UID': UID,
                'View_Account': View_Account,
                'View_Password': View_Password,
                'ChannelIndex': ChannelIndex,
                'Type': Type,
                'isShare': isShare,
                'primaryUserID': primaryUserID,
                'primaryMaster': primaryMaster,
                'vodPrimaryUserID': vodPrimaryUserID,
                'vodPrimaryMaster': vodPrimaryMaster,
                'data_joined': '',
                'version': version,
                'isVod': 0,
                'isExist': 1,
                'userID__userEmail': ''
            }
            res['vod'] = [
                {
                    "status": 1,
                    "channel": ChannelIndex,
                    "endTime": '',
                    "bucket__content": '',
                    "uid": UID
                }
            ]
            res['isMainUserExists'] = 1
            return response.json(0, res)

        # 日志数据
        username = CommonService.get_username(userID)
        nowTime = int(time.time())
        ip = CommonService.get_ip_address(request)
        content = json.loads(json.dumps(request_dict))
        log = {
            'ip': ip,
            'user_id': 1,
            'status': 200,
            'time': nowTime,
            'content': json.dumps(content),
            'url': 'v3/equipment/add',
            'operation': '{}添加{}成功'.format(username, UID)
        }

        try:
            with transaction.atomic():
                # 判断是否有用户绑定
                us_qs = UidSetModel.objects.filter(uid=UID)
                if us_qs.exists():
                    us_qs.update(nickname=NickName, device_type=Type)
                    UidSet_id = us_qs.first().id
                else:
                    ipInfo = CommonService.getIpIpInfo(ip, 'CN')
                    country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
                    country = country_qs.exists() if country_qs[0]['id'] else 0
                    region_id = Device_Region().get_device_region(ip)
                    region_alexa = 'CN' if region_id == 1 else 'ALL'
                    uid_set_create_dict = {
                        'uid': UID,
                        'addTime': nowTime,
                        'updTime': nowTime,
                        'ip': ip,
                        'channel': ChannelIndex,
                        'nickname': NickName,
                        'version': version,
                        'region_alexa': region_alexa,
                        'device_type': Type,
                        'tb_country': country
                    }
                    UidSet = UidSetModel.objects.create(**uid_set_create_dict)
                    UidSet_id = UidSet.id

                if all([token_val, m_code, appBundleId, app_type]):
                    uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=UID)
                    if uid_push_qs.exists():
                        uid_push_update_dict = {
                            'appBundleId': appBundleId,
                            'app_type': app_type,
                            'push_type': push_type,
                            'token_val': token_val,
                            'jg_token_val': jg_token_val,
                            'updTime': nowTime,
                            'lang': lang,
                            'tz': tz
                        }
                        uid_push_qs.update(**uid_push_update_dict)
                    else:
                        uid_push_create_dict = {
                            'uid_set_id': UidSet_id,
                            'userID_id': userID,
                            'appBundleId': appBundleId,
                            'app_type': app_type,
                            'push_type': push_type,
                            'token_val': token_val,
                            'jg_token_val': jg_token_val,
                            'm_code': m_code,
                            'addTime': nowTime,
                            'updTime': nowTime,
                            'lang': lang,
                            'tz': tz
                        }
                        # 绑定设备推送
                        UidPushModel.objects.create(**uid_push_create_dict)
                # 查询uid_channel表有无该uid的数据
                uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
                if not uid_channel_set.exists():
                    # 多通道设备设置通道名
                    if Type in dvr_type_list:
                        UidChannelSet_bulk = []
                        for i in range(1, ChannelIndex + 1):
                            channel_name = 'channel' + str(i)  # channel1,channel2...
                            UidChannelSet = UidChannelSetModel(uid_id=UidSet_id, channel=i, channel_name=channel_name)
                            UidChannelSet_bulk.append(UidChannelSet)
                        UidChannelSetModel.objects.bulk_create(UidChannelSet_bulk)

                userDevice = Device_Info(id=id, userID_id=userID, UID=UID, NickName=NickName, View_Account=View_Account,
                                         View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
                                         version=version,
                                         vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
                userDevice.save()
                # 保存用户推送按钮信息
                button_qs = UserAudioVideoPush.objects.filter(uid=UID)
                if button_qs.exists():
                    button_qs.update(buttonUser1=userID, buttonUser2=userID)
                else:
                    UserAudioVideoPush.objects.create(uid=UID, buttonUser1=userID, buttonUser2=userID,
                                                      created_time=nowTime, updated_time=nowTime)
                # 添加到家庭房间
                if family_id:
                    EquipmentFamilyView.family_room_device_save(family_id, room_id, userDevice.id, Type)

                uid_serial_qs = UIDCompanySerialModel.objects.filter(uid__uid=UID)
                if uid_serial_qs.exists():
                    uid_serial = uid_serial_qs[0]
                    serial_number = uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark
                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
                                                               vodPrimaryMaster=vodPrimaryMaster,
                                                               serial_number=serial_number)
                    self.unicom_user_info_save(userID, serial_number)
                else:
                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
                                                               vodPrimaryMaster=vodPrimaryMaster)

                if not us_qs.exists():
                    us_qs = UidSetModel.objects.filter(uid=UID)

                if us_qs.exists() and us_qs[0].is_alexa == 1:
                    if us_qs[0].channel > 1:
                        data_list = []
                        uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id). \
                            values('channel', 'channel_name')
                        if uid_channel_set_qs.exists():
                            # 多通道设备名为 UidChannelSetModel 的 channel_name
                            for uid_channel_set in uid_channel_set_qs:
                                data_list.append(
                                    {'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
                                     'channel': uid_channel_set['channel'], 'password': encrypt_pass})
                    else:
                        data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': encrypt_pass}]

                    # 请求Alexa服务器更新事件网关
                    CommonService.update_alexa_events(data_list)

                # 记录添加日志
                LogModel.objects.create(**log)
        except Exception as e:
            # 记录添加失败日志
            error_msg = 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e))
            operation = '{}添加{}失败:{}'.format(username, UID, error_msg)
            log['operation'] = operation
            LogModel.objects.create(**log)
            return response.json(10, error_msg)
        else:
            dvqs = Device_Info.objects.filter(id=id).values('id', 'userID', 'NickName', 'UID',
                                                            'View_Account',
                                                            'View_Password', 'ChannelIndex', 'Type',
                                                            'isShare',
                                                            'primaryUserID', 'primaryMaster',
                                                            'vodPrimaryUserID', 'vodPrimaryMaster',
                                                            'userID__userEmail',
                                                            'data_joined', 'version',
                                                            'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
            dvql = CommonService.qs_to_list(dvqs)
            ubqs = UID_Bucket.objects.filter(uid=UID). \
                values('bucket__content', 'status', 'channel', 'endTime', 'uid')
            res = dvql[0]
            res['vod'] = list(ubqs)

            iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
            if iotqs.exists():
                res['iot'] = {
                    'endpoint': iotqs[0].endpoint,
                    'token_iot_number': iotqs[0].endpoint
                }

            # 存在序列号返回完整序列号
            if res['serial_number']:
                res['serial_number'] = CommonService.get_full_serial_number(UID, res['serial_number'], Type)

            return response.json(0, res)

    @classmethod
    def unicom_user_info_save(cls, user_id, serial_number):
        """
        保存联通与用户信息绑定
        @param user_id: 用户id
        @param serial_number: 序列号
        @return: True | False
        """
        try:
            # 根据序列号查询联通iccid
            unicom_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number, card_type=0)
            if not unicom_device_info_qs.exists():
                return False
            unicom_device_info_qs.update(user_id=user_id, updated_time=int(time.time()))
            LOGGER.info('{}更新4G用户信息成功:{}'.format(serial_number, user_id))

            # if unicom_device_info_qs.first().status == 1:  # 已测试
            #     # 领取4G体验套餐
            #     res = UnicomComboView.user_activate_flow(unicom_device_info_qs[0].iccid)
            #     logging.info('{}联通领取体验流量:{}'.format(unicom_device_info_qs[0].iccid, res))
            #     WXTechControllerView.activate_flow_package(serial_number, 'system', user_id)
            # if not unicom_device_info_qs[0].user_id:
            #     # 生成4G免费订单
            #     UnicomComboView.experience_order_4G(unicom_device_info_qs[0].iccid,
            #                                         serial_number, user_id, False)
            #     UnicomDeviceInfo.objects.filter(iccid=unicom_device_info_qs[0].iccid) \
            #         .update(user_id=user_id, updated_time=int(time.time()))
            return True
        except Exception as e:
            logging.info('创建体验4G订单异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            return False

    def do_batch_add(self, userID, request_dict, response, request):
        # 批量添加设备
        uidContent = request_dict.get('uidContent', None)
        family_id = request_dict.get('familyId', None)
        room_id = request_dict.get('roomId', None)

        if not uidContent:
            return response.json(444, {'param': 'uidContent'})

        try:
            deviceNumber = 0  # 添加成功数量
            add_success_flag = False  # 添加成功标识
            exception_flag = False  # 异常标识
            exists_flag = False  # 已存在标识
            uid_content_list = eval(uidContent)
            print('uidContent: ', uid_content_list)
            re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
            for uid_content in uid_content_list:
                exception_flag = False  # 重置异常标识
                exists_flag = False  # 已存在标识
                UID = uid_content['uid']
                NickName = uid_content['nickName']
                Type = uid_content['type']
                ChannelIndex = uid_content['channelIndex']
                version = uid_content['version']
                isCheckMainUser = uid_content['isCheckMainUser']
                View_Account = uid_content['viewAccount']
                encryptPassword = uid_content['encryptPassword']
                View_Password = self.decode_pwd(encryptPassword)
                if not all([UID, NickName, View_Account]):  # Type和ChannelIndex可能为0
                    return response.json(444, {'param': 'UID, NickName, View_Account'})

                if not re_uid.match(UID):  # 检查uid长度
                    return response.json(444, {'error uid length': UID})

                device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
                if device_info_qs:
                    # 判断设备是否已存在
                    if device_info_qs[0].isExist == 1:
                        exists_res = {UID: 'device already exists!'}
                        exists_flag = True
                        continue
                    else:
                        device_info_qs.delete()

                id = CommonService.getUserID(getUser=False)
                device_user_qs = Device_User.objects.filter(userID=userID).values('username')
                if not device_user_qs.exists():
                    return response.json(173)
                userName = device_user_qs[0]['username']
                main_exist = Device_Info.objects.filter(UID=UID)
                main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')

                vodPrimaryUserID = userID
                vodPrimaryMaster = userName
                primaryUserID = ''
                primaryMaster = ''
                isShare = False

                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
                                                                                    'primaryMaster', 'Type')

                if main_exist.exists():
                    vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
                    vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']

                if is_bind.exists():
                    primaryUserID = is_bind[0]['primaryUserID']
                    primaryMaster = is_bind[0]['primaryMaster']
                    isShare = True

                isusermain = False
                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (
                        primaryUserID != userID and primaryUserID != ''):
                    isusermain = True

                # 判断是否有已绑定用户
                if isCheckMainUser == 1 and isusermain:
                    res = {
                        'id': id,
                        'userID': userID,
                        'NickName': NickName,
                        'UID': UID,
                        'View_Account': View_Account,
                        'View_Password': View_Password,
                        'ChannelIndex': ChannelIndex,
                        'Type': Type,
                        'isShare': isShare,
                        'primaryUserID': primaryUserID,
                        'primaryMaster': primaryMaster,
                        'vodPrimaryUserID': vodPrimaryUserID,
                        'vodPrimaryMaster': vodPrimaryMaster,
                        'data_joined': '',
                        'version': version,
                        'isVod': 0,
                        'isExist': 1,
                        'userID__userEmail': ''
                    }
                    res['vod'] = [
                        {
                            "status": 1,
                            "channel": ChannelIndex,
                            "endTime": '',
                            "bucket__content": '',
                            "uid": UID
                        }
                    ]
                    res['isMainUserExists'] = 1
                    continue

                # 判断是否有用户绑定
                nowTime = int(time.time())
                us_qs = UidSetModel.objects.filter(uid=UID)
                if us_qs.exists():
                    us_qs.update(nickname=NickName)
                    UidSet_id = us_qs.first().id
                else:
                    ip = CommonService.get_ip_address(request)
                    ipInfo = CommonService.getIpIpInfo(ip, 'CN')
                    country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
                    country = country_qs.exists() if country_qs[0]['id'] else 0
                    region_id = Device_Region().get_device_region(ip)
                    region_alexa = 'CN' if region_id == 1 else 'ALL'
                    uid_set_create_dict = {
                        'uid': UID,
                        'addTime': nowTime,
                        'updTime': nowTime,
                        'ip': CommonService.get_ip_address(request_dict),
                        'channel': ChannelIndex,
                        'nickname': NickName,
                        'version': version,
                        'region_alexa': region_alexa,
                        'device_type': is_bind[0]['Type'] if is_bind.exists() else int(Type),
                        'tb_country': country
                    }
                    UidSet = UidSetModel.objects.create(**uid_set_create_dict)
                    UidSet_id = UidSet.id

                # 查询uid_channel表有无该uid的数据
                uid_channel_set = UidChannelSetModel.objects.filter(uid_id=UidSet_id)
                if not uid_channel_set.exists():
                    # 多通道设备设置通道名
                    multi_channel_list = [1, 2, 3, 4, 10001]
                    if Type in multi_channel_list:
                        UidChannelSet_bulk = []
                        for i in range(1, ChannelIndex + 1):
                            channel_name = 'channel' + str(i)  # channel1,channel2...
                            UidChannelSet = UidChannelSetModel(uid_id=UidSet_id, channel=i, channel_name=channel_name)
                            UidChannelSet_bulk.append(UidChannelSet)
                        UidChannelSetModel.objects.bulk_create(UidChannelSet_bulk)

                userDevice = Device_Info(id=id, userID_id=userID, UID=UID, NickName=NickName, View_Account=View_Account,
                                         View_Password=View_Password, Type=Type, ChannelIndex=ChannelIndex,
                                         version=version,
                                         vodPrimaryUserID=vodPrimaryUserID, vodPrimaryMaster=vodPrimaryMaster)
                userDevice.save()
                # 添加到家庭房间
                if family_id:
                    EquipmentFamilyView.family_room_device_save(family_id, room_id, userDevice.id, Type)
                uid_serial_qs = UIDCompanySerialModel.objects.filter(uid__uid=UID)
                if uid_serial_qs.exists():
                    uid_serial = uid_serial_qs[0]
                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
                                                               vodPrimaryMaster=vodPrimaryMaster,
                                                               serial_number=uid_serial.company_serial.serial_number + uid_serial.company_serial.company.mark)
                else:
                    Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
                                                               vodPrimaryMaster=vodPrimaryMaster)

                if not us_qs.exists():
                    us_qs = UidSetModel.objects.filter(uid=UID)

                if us_qs.exists() and us_qs[0].is_alexa == 1:
                    if us_qs[0].channel > 1:
                        data_list = []
                        uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id). \
                            values('channel', 'channel_name')
                        if uid_channel_set_qs.exists():
                            # 多通道设备名为 UidChannelSetModel 的 channel_name
                            for uid_channel_set in uid_channel_set_qs:
                                data_list.append(
                                    {'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
                                     'channel': uid_channel_set['channel'], 'password': encryptPassword})
                    else:
                        data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': encryptPassword}]

                    # 请求Alexa服务器更新事件网关
                    CommonService.update_alexa_events(data_list)

                dvqs = Device_Info.objects.filter(id=id).values('id', 'userID', 'NickName', 'UID',
                                                                'View_Account',
                                                                'View_Password', 'ChannelIndex', 'Type',
                                                                'isShare',
                                                                'primaryUserID', 'primaryMaster',
                                                                'vodPrimaryUserID', 'vodPrimaryMaster',
                                                                'userID__userEmail',
                                                                'data_joined', 'version',
                                                                'isVod', 'isExist', 'isCameraOpenCloud',
                                                                'serial_number')
                dvql = CommonService.qs_to_list(dvqs)
                ubqs = UID_Bucket.objects.filter(uid=UID). \
                    values('bucket__content', 'status', 'channel', 'endTime', 'uid')
                success_res = dvql[0]
                success_res['vod'] = list(ubqs)
                iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
                if iotqs.exists():
                    success_res['iot'] = {'endpoint': iotqs[0].endpoint, 'token_iot_number': iotqs[0].endpoint}
                deviceNumber += 1
                success_res['deviceNumber'] = deviceNumber
                add_success_flag = True
        except Exception as e:
            LOGGER.info('异常详情,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
            print(e)
            error_res = repr(e)
            exception_flag = True
            pass
        finally:
            if add_success_flag:  # 有一台添加成功则返回成功
                return response.json(0, success_res)
            if exists_flag:  # 全部设备已存在
                return response.json(174, exists_res)
            if exception_flag:
                return response.json(500, error_res)
            return response.json(0, res)

    def do_modify(self, userID, request_dict, response, request):
        token = request_dict.get('token', None)
        deviceContent = request_dict.get('content', None)
        id = request_dict.get('id', None)
        if not deviceContent or not id:
            return response.json(444, 'content,id')
        tko = TokenObject(token)
        response.lang = tko.lang
        if tko.code != 0:
            return response.json(tko.code)
        userID = tko.userID
        if userID is None:
            return response.json(309)

        try:
            deviceData = eval(deviceContent)
            if deviceData.__contains__('userID_id'):
                asy = threading.Thread(target=ModelService.update_log,
                                       args=(CommonService.get_ip_address(request), userID, 'modifyV3', deviceData, id))
                asy.start()
                return response.json(10, '110')

            if deviceData.__contains__('UID'):
                del deviceData['UID']

            dev_info_qs = Device_Info.objects.filter(userID_id=userID, id=id).values('UID')
            if not dev_info_qs.exists():
                return response.json(173)

            view_password = ''
            if deviceData.__contains__('View_Password'):
                encrypt_pwd = deviceData['View_Password']
                view_password = self.decode_pwd(deviceData['View_Password'])
                deviceData['View_Password'] = view_password
                # 记录修改密码日志
                uid = dev_info_qs[0]['UID']
                ip = CommonService.get_ip_address(request)
                content = json.loads(json.dumps(request_dict))
                log = {
                    'user_id': 2,
                    'status': 200,
                    'time': int(time.time()),
                    'url': 'v3/equipment/modify',
                    'content': json.dumps(content),
                    'ip': ip,
                    'operation': '{}修改设备密码:{}'.format(uid, view_password),
                }
                LogModel.objects.create(**log)
            # 更新数据
            dev_info_qs.update(**deviceData)
        except Exception as e:
            print(e)
            return response.json(177, repr(e))
        else:
            qs = Device_Info.objects.filter(userID_id=userID, id=id)
            res = CommonService.qs_to_dict(qs)
            if qs.exists():
                uid = qs[0].UID
                nickname = qs[0].NickName
                # 增加设备影子信息修改昵称 start
                us_qs = UidSetModel.objects.filter(uid=uid)
                if us_qs.exists():
                    if deviceData.__contains__('NickName'):
                        us_qs.update(nickname=nickname)
                else:
                    ip = CommonService.get_ip_address(request)
                    ipInfo = CommonService.getIpIpInfo(ip, 'CN')
                    country_qs = CountryModel.objects.filter(country_code=ipInfo['country_code']).values('id')
                    country = country_qs.exists() if country_qs[0]['id'] else 0
                    ChannelIndex = qs[0].ChannelIndex
                    nowTime = int(time.time())
                    uid_set_create_dict = {
                        'uid': uid,
                        'addTime': nowTime,
                        'updTime': nowTime,
                        'ip': CommonService.get_ip_address(request),
                        'channel': ChannelIndex,
                        'nickname': nickname,
                        'device_type': qs[0].Type,
                        'tb_country': country,
                    }
                    UidSetModel.objects.create(**uid_set_create_dict)
                di_qs = Device_Info.objects.filter(UID=uid)
                di_qs.update(NickName=nickname)

                if deviceData is not None and deviceData.__contains__('NickName') and us_qs[0].is_alexa == 1:
                    # 异步请求Alexa服务器更新事件网关
                    password = encrypt_pwd if deviceData.__contains__('View_Password') else ''
                    data_list = [{'userID': userID, 'UID': uid, 'uid_nick': nickname, 'password': password}]
                    # 请求Alexa服务器更新事件网关
                    CommonService.update_alexa_events(data_list)

            return response.json(0, res)

    @staticmethod
    def do_modify_channel_name(request_dict, response):
        """
        修改通道名
        @param request_dict:
        @param response:
        @return:
        """
        uid = request_dict.get('uid', None)
        channel = request_dict.get('channel', None)
        channel_name = request_dict.get('channel_name', None)
        if not all([uid, channel, channel_name]):
            return response.json(444)
        try:
            # 更新通道名
            channel = int(channel) + 1
            uid_channel_set_qs = UidChannelSetModel.objects.filter(uid__uid=uid, channel=channel)
            if not uid_channel_set_qs.exists():
                return response.json(173)
            uid_channel_set_qs.update(channel_name=channel_name)
            return response.json(0)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def do_query(self, userID, request_dict, response):
        """
        首页查询设备列表
        @param userID: 用户id
        @param request_dict: 请求参数
        @param response: 响应结果
        """
        token = request_dict.get('token', None)
        page = request_dict.get('page', None)
        line = request_dict.get('line', None)
        NickName = request_dict.get('NickName', None)
        if not token or not page or not line:
            return response.json(444)
        page = int(page)
        line = int(line)
        uid = request_dict.get('uid', None)
        tko = TokenObject(token)
        response.lang = tko.lang
        if page <= 0:
            return response.json(0)
        if tko.code != 0:
            return response.json(tko.code)
        userID = tko.userID
        # 查询设备列表以及设备uid集合
        dv_list, uid_list = UserDeviceService.query_device_list(userID, uid, NickName, page, line)
        ub_qs = UserDeviceService.query_device_uid_bucket(uid_list)  # 根据uid集合查询云存套餐
        up_qs = UserDeviceService.query_device_preview(uid_list)  # 根据uid集合查询设备预览图
        auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
        bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
        nowTime = int(time.time())
        data = []
        uv_dict = UserDeviceService.query_device_channel(uid_list)  # 查询设备uid通道配置属性
        # 遍历设备列表，查询设备关联数据详情
        for p in dv_list:
            p['UID'] = p['UID'].replace('\n', '').replace('\r', '')
            p_uid = p['UID'].upper()
            UserDeviceService.get_sim_by_serial_number(p)  # 获取SIM卡属性
            p['cloudPhoto'] = self.get_cloud_photo_status(p['UID'])
            # 获取云存使用状态
            p['vod_use_status'] = self.get_vod_use_status(p_uid, nowTime)
            # 获取iot_deviceInfo表的endpoint和token_iot_number
            p['iot'] = []
            if p['serial_number']:  # 存在序列号根据序列号查询
                iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
            else:  # 根据uid查询
                iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p_uid)
            if iotdeviceInfo_qs.exists():
                iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
                p['iot'].append({
                    'endpoint': iotdeviceInfo[0]['endpoint'],
                    'token_iot_number': iotdeviceInfo[0]['token_iot_number']
                })

            p['vod'] = []
            for dm in ub_qs:
                if p_uid == dm['uid']:
                    if dm['endTime'] > nowTime:
                        p['vod'].append(dm)
            p['preview'] = []
            for up in up_qs:
                if p_uid == up['uid']:
                    obj = 'uid_preview/{uid}/channel_{channel}.png'.format(uid=up['uid'], channel=up['channel'])
                    img_sign = bucket.sign_url('GET', obj, 300)
                    p['preview'].append(img_sign)
            UserDeviceService.get_uid_info(p, p_uid)  # 获取uid初始化信息

            if p_uid in uv_dict:
                # 获取设备信息DTO
                UserDeviceService.get_device_info_dto(p, p_uid, uv_dict, userID)
            else:
                # 设备版本号
                p['uid_version'] = ''
                p['ucode'] = ''
            p['View_Password'] = self.encrypt_pwd(p['View_Password'])

            # 判断设备是否支持4G和查询移动侦测状态
            uid_set_qs = UidSetModel.objects.filter(uid=p['UID']).values('detect_status')
            if uid_set_qs.exists():
                uid_set_qs = uid_set_qs.first()
                p['NotificationMode'] = uid_set_qs['detect_status']
            data.append(p)
        result = data
        return response.json(0, result)

    @staticmethod
    def get_vod_use_status(uid, now_time):
        """
        根据UID获取云存使用状态
        @param uid: 设备uid
        @param now_time: 现在时间戳
        @return: 0：未体验；1：使用中；2：已过期
        """
        experience_context_qs = ExperienceContextModel.objects.filter(uid=uid, experience_type=0)
        if not experience_context_qs.exists():
            return 0
        uid_bucket_qs = UID_Bucket.objects.filter(uid=uid, endTime__gt=now_time, use_status=1)
        if uid_bucket_qs.exists():
            return 1
        else:
            return 2

    @staticmethod
    def get_cloud_photo_status(uid):
        """
        根据UID获取云相册开关状态
        @param uid: 设备uid
        @return: 0 or 1
        """
        cloud_photo_qs = DeviceCloudPhotoInfo.objects.filter(uid=uid).values('status')
        if not cloud_photo_qs.exists():
            return 0
        return cloud_photo_qs[0]['status']

    def do_fuzzy_query(self, userID, request_dict, response):
        fuzzy = request_dict.get('fuzzy', None)
        page = request_dict.get('page', None)
        line = request_dict.get('line', None)

        if not all([page, line]):
            return response.json(444)

        page = int(page)
        line = int(line)
        try:
            device_qs = Device_Info.objects.filter(userID=userID)
            device_qs = device_qs.filter(~Q(isExist=2))
            if not device_qs.exists():
                return response.json(0, [])
            if fuzzy:
                device_qs = device_qs.filter(Q(UID__icontains=fuzzy) | Q(NickName__icontains=fuzzy))
            device_qs = device_qs.values('id', 'userID', 'NickName', 'UID', 'View_Account',
                                         'View_Password', 'ChannelIndex', 'Type', 'isShare',
                                         'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID',
                                         'vodPrimaryMaster', 'userID__userEmail',
                                         'version', 'isVod', 'isExist', 'NotificationMode', 'isCameraOpenCloud',
                                         'serial_number')

            dvls = CommonService.qs_to_list(device_qs)
            uid_list = []
            for dvl in dvls:
                uid_list.append(dvl['UID'])

            ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                values('bucket__content', 'status', 'channel', 'endTime', 'uid')
            upqs = UID_Preview.objects.filter(uid__in=uid_list).order_by('channel').values('id', 'uid', 'channel')
            auth = oss2.Auth(OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET)
            bucket = oss2.Bucket(auth, 'oss-cn-hongkong.aliyuncs.com', 'statres')
            nowTime = int(time.time())
            data = []
            # 设备拓展信息表
            us_qs = UidSetModel.objects.filter(uid__in=uid_list).values('id', 'uid', 'version', 'nickname', 'ucode',
                                                                        'detect_status', 'detect_group',
                                                                        'detect_interval',
                                                                        'region_alexa', 'is_alexa', 'deviceModel',
                                                                        'TimeZone', 'TimeStatus', 'SpaceUsable',
                                                                        'SpaceSum', 'MirrorType', 'RecordType',
                                                                        'OutdoorModel', 'WIFIName', 'isDetector',
                                                                        'DetectorRank')
            uv_dict = {}
            for us in us_qs:
                uv_dict[us['uid']] = {
                    'version': us['version'],
                    'nickname': us['nickname'],
                    'ucode': us['ucode'],
                    'detect_interval': us['detect_interval'],
                    'detect_group': us['detect_group'],
                    'detect_status': us['detect_status'],
                    'region_alexa': us['region_alexa'],
                    'is_alexa': us['is_alexa'],
                    'deviceModel': us['deviceModel'],
                    'TimeZone': us['TimeZone'],
                    'TimeStatus': us['TimeStatus'],
                    'SpaceUsable': us['SpaceUsable'],
                    'SpaceSum': us['SpaceSum'],
                    'MirrorType': us['MirrorType'],
                    'RecordType': us['RecordType'],
                    'OutdoorModel': us['OutdoorModel'],
                    'WIFIName': us['WIFIName'],
                    'isDetector': us['isDetector'],
                    'DetectorRank': us['DetectorRank']
                }
                # 从uid_channel里面取出通道配置信息
                ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values()
                channels = []
                for ucs in ucs_qs:
                    channel = {
                        'channel': ucs['channel'],
                        'channel_name': ucs['channel_name'],
                        'pir_audio': ucs['pir_audio'],
                        'mic_audio': ucs['mic_audio'],
                        'battery_status': ucs['battery_status'],
                        'battery_level': ucs['battery_level'],
                        'sleep_status': ucs['sleep_status'],
                        'sleep_time': ucs['sleep_time'],
                        'light_night_model': ucs['light_night_model'],
                        'light_alarm_type': ucs['light_alarm_type'],
                        'light_alarm_level': ucs['light_alarm_level'],
                        'light_alarm_man_en': ucs['light_alarm_man_en'],
                        'light_alarm_vol': ucs['light_alarm_vol'],
                        'light_long_light': ucs['light_long_light']
                    }
                    channels.append(channel)
                uv_dict[us['uid']]['channels'] = channels

            for p in dvls:
                # 获取iot_deviceInfo表的endpoint和token_iot_number
                p['iot'] = []
                if p['serial_number']:  # 存在序列号根据序列号查询
                    # 摄像头设备返回完整序列号
                    if p['UID'] != p['serial_number']:
                        p['serial_number'] = CommonService.get_full_serial_number(p['UID'], p['serial_number'],
                                                                                  p['Type'])
                    iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
                else:  # 根据uid查询
                    iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p['UID'])
                if iotdeviceInfo_qs.exists():
                    iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
                    p['iot'].append({
                        'endpoint': iotdeviceInfo[0]['endpoint'],
                        'token_iot_number': iotdeviceInfo[0]['token_iot_number']
                    })

                p['vod'] = []
                for dm in ubqs:
                    if p['UID'] == dm['uid']:
                        if dm['endTime'] > nowTime:
                            p['vod'].append(dm)
                p['preview'] = []
                for up in upqs:
                    if p['UID'] == up['uid']:
                        obj = 'uid_preview/{uid}/channel_{channel}.png'.format(uid=up['uid'], channel=up['channel'])
                        img_sign = bucket.sign_url('GET', obj, 300)
                        p['preview'].append(img_sign)
                p_uid = p['UID']
                if p_uid in uv_dict:
                    # 设备版本号
                    p['uid_version'] = uv_dict[p_uid]['version']
                    p['ucode'] = uv_dict[p_uid]['ucode']
                    p['detect_interval'] = uv_dict[p_uid]['detect_interval']
                    p['detect_status'] = uv_dict[p_uid]['detect_status']
                    p['detect_group'] = uv_dict[p_uid]['detect_group']
                    p['region_alexa'] = uv_dict[p_uid]['region_alexa']
                    p['is_alexa'] = uv_dict[p_uid]['is_alexa']
                    p['deviceModel'] = uv_dict[p_uid]['deviceModel']
                    p['TimeZone'] = uv_dict[p_uid]['TimeZone']
                    p['TimeStatus'] = uv_dict[p_uid]['TimeStatus']
                    p['SpaceUsable'] = uv_dict[p_uid]['SpaceUsable']
                    p['SpaceSum'] = uv_dict[p_uid]['SpaceSum']
                    p['MirrorType'] = uv_dict[p_uid]['MirrorType']
                    p['RecordType'] = uv_dict[p_uid]['RecordType']
                    p['OutdoorModel'] = uv_dict[p_uid]['OutdoorModel']
                    p['WIFIName'] = uv_dict[p_uid]['WIFIName']
                    p['isDetector'] = uv_dict[p_uid]['isDetector']
                    p['DetectorRank'] = uv_dict[p_uid]['DetectorRank']
                    p['channels'] = uv_dict[p_uid]['channels']
                    # 设备昵称 调用影子信息昵称，先阶段不可
                    if uv_dict[p_uid]['nickname']:
                        p['NickName'] = uv_dict[p_uid]['nickname']
                else:
                    # 设备版本号
                    p['uid_version'] = ''
                    p['ucode'] = ''
                data.append(p)
            items = []
            for index, item in enumerate(data):
                if (page - 1) * line <= index:
                    if index < page * line:
                        # 加密
                        item['View_Password'] = self.encrypt_pwd(item['View_Password'])
                        items.append(item)
            return response.json(0, items)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    # 加密
    def encrypt_pwd(self, userPwd):
        for i in range(1, 4):
            if i == 1:
                userPwd = RandomStr(3, False) + userPwd + RandomStr(3, False)
                userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
            if i == 2:
                userPwd = RandomStr(2, False) + str(userPwd) + RandomStr(2, False)
                userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
            if i == 3:
                userPwd = RandomStr(1, False) + str(userPwd) + RandomStr(1, False)
                userPwd = base64.b64encode(str(userPwd).encode("utf-8")).decode('utf8')
        return userPwd

    # 解密
    def decode_pwd(self, password):
        for i in range(1, 4):
            if i == 1:
                # 第一次先解密
                password = base64.b64decode(password)
                password = password.decode('utf-8')
                # 截去第一位，最后一位
                password = password[1:-1]
            if i == 2:
                # 第2次先解密
                password = base64.b64decode(password)
                password = password.decode('utf-8')
                # 去前2位，后2位
                password = password[2:-2]
            if i == 3:
                # 第3次先解密
                password = base64.b64decode(password)
                password = password.decode('utf-8')
                # 去前3位，后3位
                password = password[3:-3]
        return password

    @staticmethod
    def do_mainUserDevice(request_dict, response, user_id):
        """
        根据UID或序列号获取云存主用户信息
        """
        try:
            UID = request_dict.get('UID')
            serial_number = request_dict.get('serial_number')
            if UID:
                dvq = Device_Info.objects.filter(UID=UID)
            elif serial_number:
                serial_number = serial_number[:9]
                uid = CommonService.get_uid_by_serial_number(serial_number)
                if serial_number == uid:  # 没查到绑定对应的UID
                    dvq = Device_Info.objects.filter(serial_number=serial_number)
                else:  # 根据序列号查到了对应的UID
                    dvq = Device_Info.objects.filter(UID=uid)
            else:
                return response.json(444)
            dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
            if not dvq.exists():
                return response.json(0, [])
            qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']) \
                .values('userID', 'NickName', 'username', 'userEmail', 'phone')
            if not qs.exists():
                return response.json(0, [])
            nickname = qs[0]['username']
            phone = qs[0]['phone']
            username = qs[0]['username']
            sys_user_id = qs[0]['userID']

            qs = CommonService.qs_to_list(qs)
            if nickname == '':
                qs[0]['NickName'] = username
            if phone == '':
                qs[0]['phone'] = nickname

            # 查询主用户并且返回主用户是否是当前账户标识
            qs[0]['isOwnUser'] = sys_user_id and user_id and sys_user_id == user_id
            return response.json(0, qs)
        except Exception as e:
            LOGGER.info('异常详情,userID:{}, errLine:{}, errMsg:{}'.format(user_id, e.__traceback__.tb_lineno, repr(e)))
            return response.json(500)

    def not_login_do_mainUserDevice(self, request_dict, response):
        UID = request_dict.get('UID')
        token = request_dict.get('token', None)
        time_stamp = request_dict.get('time_stamp', None)

        if not all([token, time_stamp]):
            return response.json(444)

        # 时间戳token校验
        if not CommonService.check_time_stamp_token(token, time_stamp):
            return response.json(13)

        dvq = Device_Info.objects.filter(UID=UID)
        dvq = dvq.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID')
        qs = {}
        if dvq.exists():
            qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username',
                                                                                      'userEmail', 'phone')
            NickName = qs[0]['NickName']
            phone = qs[0]['phone']
            username = qs[0]['username']
            qs = CommonService.qs_to_list(qs)
            if NickName == '':
                qs[0]['NickName'] = username
            if phone == '':
                qs[0]['phone'] = NickName
        return response.json(0, qs)

    @staticmethod
    def test_tool_del_device(request_dict, response):
        """
        测试工具删除设备
        @param request_dict: 请求数据
        @request_dict uid: uid
        @request_dict time_stamp: 时间戳
        @request_dict time_stamp_token: 时间戳token
        @param response: 响应
        @return: response
        """
        uid = request_dict.get('uid')
        time_stamp = request_dict.get('time_stamp', None)
        time_stamp_token = request_dict.get('time_stamp_token', None)

        if not all([uid, time_stamp, time_stamp_token]):
            return response.json(444)

        try:
            # 时间戳token校验
            if not CommonService.check_time_stamp_token(time_stamp_token, time_stamp):
                return response.json(13)

            with transaction.atomic():
                Device_Info.objects.filter(UID=uid).delete()
                UidPushModel.objects.filter(uid_set__uid=uid).delete()
                LOGGER.info(f'PC删除设备&删除APP推送token{uid}成功')
                asy = threading.Thread(target=EquipmentManagerV3.async_del_message, args=(uid,))
                asy.start()
            return response.json(0, {'msg': 'Delete the device and delete the push token successfully'})
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    def change_device_password(self, request_dict, response):
        """
        修改设备密码
        @return:
        """
        uid = request_dict.get('uid', None)
        version = request_dict.get('version', None)
        encrypt_pwd = request_dict.get('encrypt_pwd', None)
        if not all([uid, version, encrypt_pwd]):
            return response.json(444)
        try:
            # 异步请求其他服
            if CONFIG_INFO == CONFIG_US:
                change_pwd_thread = threading.Thread(target=self.change_pwd, args=(request_dict.dict(),))
                change_pwd_thread.start()

            view_password = self.decode_pwd(encrypt_pwd)
            Device_Info.objects.filter(UID=uid).update(View_Password=view_password)
            UidSetModel.objects.filter(uid=uid).update(pwd=view_password)
            content = json.loads(json.dumps(request_dict))
            log = {
                'user_id': 2,
                'status': 200,
                'time': int(time.time()),
                'url': 'v3/equipment/changeDevicePassword',
                'content': json.dumps(content),
                'operation': '{}上报设备密码:{}'.format(uid, view_password),
            }
            LogModel.objects.create(**log)
            return response.json(0)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def change_pwd(data):
        """
        请求更新密码线程
        @param data: 请求数据
        """
        orders_domain_name_list = CommonService.get_orders_domain_name_list()
        for domain_name in orders_domain_name_list:
            url = '{}v3/equipment/changeDevicePassword'.format(domain_name)
            requests.post(url=url, data=data, timeout=30)


    def do_get_device_features(self, request_dict, response):
        uid = request_dict.get('uid', None)

        if uid:
            uid = CommonService.decode_data(uid)

            if uid:
                uid_qs = UidSetModel.objects.filter(uid=uid)
                if uid_qs.exists():
                    uid_qs = uid_qs.values('is_alexa', 'is_human', 'is_custom_voice', 'double_wifi', 'mobile_4g')
                    return response.json(0, uid_qs[0])
                else:
                    return response.json(173)
            else:
                return response.json(444)

        else:
            return response.json(444)

    @classmethod
    def async_del_message(cls, uid):
        try:
            # 删除推送消息
            EquipmentInfoService.delete_all_equipment_info(device_uid=uid)
            serial_number = CommonService.get_serial_number_by_uid(uid)
            # 删除iccid用户信息
            iccid_info_qs = UnicomDeviceInfo.objects.filter(serial_no=serial_number)
            if iccid_info_qs:
                iccid_info_qs.update(status=2, updated_time=int(time.time()), user_id='')
        except Exception as e:
            LOGGER.info('EquipmentManagerV3.async_del_message,{},error_line:{}, error_msg:{}'
                        .format(uid, e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def save_button_user(request_dict, response):
        """
        设置推送按钮用户
        """
        uid = request_dict.get('uid', None)
        button_user1 = request_dict.get('buttonUser1', None)
        button_user2 = request_dict.get('buttonUser2', None)
        if not uid:
            return response.json(444)
        try:
            now_time = int(time.time())
            if button_user1:
                button_qs = UserAudioVideoPush.objects.filter(uid=uid)
                if button_qs.exists():
                    button_qs.update(buttonUser1=button_user1, updated_time=now_time)
                else:
                    UserAudioVideoPush.objects.create(uid=uid, buttonUser1=button_user1, created_time=now_time,
                                                      updated_time=now_time)
            if button_user2:
                button_qs = UserAudioVideoPush.objects.filter(uid=uid)
                if button_qs.exists():
                    button_qs.update(buttonUser2=button_user2, updated_time=now_time)
                else:
                    UserAudioVideoPush.objects.create(uid=uid, buttonUser2=button_user2, created_time=now_time,
                                                      updated_time=now_time)
            return response.json(0)
        except Exception as e:
            return response.json(500, repr(e))

    @staticmethod
    def get_button_user(request_dict, response):
        """
        获取推送按钮用户
        """
        uid = request_dict.get('uid', None)
        if not uid:
            return response.json(444)
        try:
            device_qs = Device_Info.objects.filter(UID=uid).values('userID', 'userID__NickName', 'noteName')
            button_qs = UserAudioVideoPush.objects.filter(uid=uid).values('buttonUser1', 'buttonUser2')
            res = []
            for item in device_qs:
                noteName = item['noteName'] if item['noteName'] else item['userID__NickName']
                temp_dict = {'userId': item['userID'], 'username': item['userID__NickName'],
                             'noteName': noteName}
                if not button_qs.exists():
                    res.append(temp_dict)
                    continue
                if item['userID'] == button_qs[0]['buttonUser1']:
                    temp_dict['audioVideoButton'] = '1'
                if item['userID'] == button_qs[0]['buttonUser2']:
                    temp_dict['audioVideoButton'] = '2'
                if item['userID'] == button_qs[0]['buttonUser1'] and item['userID'] == button_qs[0]['buttonUser2']:
                    temp_dict['audioVideoButton'] = '1,2'
                res.append(temp_dict)
            return response.json(0, res)
        except Exception as e:
            return response.json(500, repr(e))

    @staticmethod
    def verify_code(request_dict, response):
        """
        校验验证码(查看设备密码)
        @param request_dict:
        @param response:
        @return:
        """
        email = request_dict.get('email', None)
        phone = request_dict.get('phone', None)
        uid = request_dict.get('uid', None)
        authcode = request_dict.get('authcode', None)
        if not any([email, phone]):
            return response.json(444)
        if not all([uid, authcode]):
            return response.json(444)
        try:
            authcode = CommonService.decode_data(authcode.strip())
            if authcode is None:
                return response.json(444, 'authcode')
            user_info = email if email is not None else phone
            redis = RedisObject()
            redis_key = '{}_{}_GetDevicePassword'.format(user_info, uid)
            reset_code = redis.get_data(key=redis_key)
            if reset_code is False:
                return response.json(90)
            if authcode != reset_code:
                return response.json(121)
            if not redis.del_data(redis_key):
                return response.json(10, '删除缓存失败')
            return response.json(0)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))

    @staticmethod
    def view_device_password(request_dict, response):
        """
        查看设备密码
        @param request_dict:
        @param response:
        @return:
        """
        uid = request_dict.get('uid', None)
        if not all([uid]):
            return response.json(444)
        try:
            uid_set_qs = UidSetModel.objects.filter(uid=uid).values('pwd')
            if uid_set_qs.exists():
                device_password = uid_set_qs[0]['pwd']
            else:
                device_info_qs = Device_Info.objects.filter(UID=uid).values('View_Password')
                if not device_info_qs.exists():
                    return response.json(173)
                device_password = device_info_qs[0]['View_Password']
            device_password = CommonService.encode_data(device_password)
            res = {
                'device_password': device_password
            }
            return response.json(0, res)
        except Exception as e:
            return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
