Pārlūkot izejas kodu

Merge branch 'master' of http://192.168.136.99:3000/SERVER/AnsjerServer

chenshibin 4 gadi atpakaļ
vecāks
revīzija
13660cd65e

+ 155 - 6
Controller/DetectControllerV2.py

@@ -24,7 +24,7 @@ from Object.RedisObject import RedisObject
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, DETECT_PUSH_DOMAIN, \
     JPUSH_CONFIG, \
     FCM_CONFIG, APNS_CONFIG, BASE_DIR, APNS_MODE, DETECT_PUSH_DOMAINS, DETECT_PUSH_DOMAIN_JIUAN, \
-    DETECT_PUSH_DOMAINS_JIUAN
+    DETECT_PUSH_DOMAINS_JIUAN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_ARN
 from Model.models import Device_Info, VodHlsModel, Equipment_Info, UidSetModel, UidPushModel, CompanyModel
 from Object.ETkObject import ETkObject
 from Object.RedisObject import RedisObject
@@ -33,6 +33,9 @@ from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
+import boto3
+import botocore
+from botocore import client
 
 '''
 http://test.push.dvema.com/notify/push?uidToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiJUNEFaM0NVS0NFUkg5RlpBMTExQSJ9.GtrXeq5gb2Z9M3mKECxi9eNQbPxqC-6PtgJkOOg6PwI&n_time=1598456451&channel=1&event_type=1&is_st=1
@@ -73,12 +76,17 @@ class DetectControllerViewV2(View):
             if operation == 'changeStatus':
                 print("进入changeStatus")
                 return self.do_change_status(userID, request_dict, response)
+            # 查询推送信息
+            elif operation == 'queryInfo':
+                return self.do_query(request_dict, response, userID)
+            # 更新推送延迟
+            elif operation == 'updateInterval':
+                return self.do_update_interval(userID, request_dict, response)
             else:
                 return response.json(414)
         else:
             return response.json(tko.code)
 
-
     def do_change_status(self, userID, request_dict, response):
         token_val = request_dict.get('token_val', None)
         appBundleId = request_dict.get('appBundleId', None)
@@ -91,6 +99,10 @@ class DetectControllerViewV2(View):
         lang = request_dict.get('lang', 'en')
         tz = request_dict.get('tz', '0')
         company_secrete = request_dict.get('company_secrete', None)
+        region = request_dict.get('region', None)  # app必须传:2:国内 1:国外
+        if not region:
+            return response.json(444, 'region')
+        region = int(region)
         # 消息提醒功能新增
 
         # 如果传空上来,就默认为0
@@ -225,10 +237,10 @@ class DetectControllerViewV2(View):
                 else:
                     url = DETECT_PUSH_DOMAIN_JIUAN
                     urls = DETECT_PUSH_DOMAINS_JIUAN
-                detectUrl = "{DETECT_PUSH_DOMAIN}notifyV2/push?etk={etk}&company_secrete={company_secrete}". \
-                    format(etk=etk, company_secrete=company_secrete, DETECT_PUSH_DOMAIN=url)
-                detectUrls = "{DETECT_PUSH_DOMAIN_V2}notifyV2/push?etk={etk}&company_secrete={company_secrete}". \
-                    format(etk=etk, company_secrete=company_secrete, DETECT_PUSH_DOMAIN_V2=urls)
+                detectUrl = "{DETECT_PUSH_DOMAIN}notifyV2/push?etk={etk}&company_secrete={company_secrete}&region={region}". \
+                    format(etk=etk, company_secrete=company_secrete, DETECT_PUSH_DOMAIN=url, region=region)
+                detectUrls = "{DETECT_PUSH_DOMAIN_V2}notifyV2/push?etk={etk}&company_secrete={company_secrete}&region={region}". \
+                    format(etk=etk, company_secrete=company_secrete, DETECT_PUSH_DOMAIN_V2=urls, region=region)
                 return response.json(0, {'detectUrl': detectUrl, 'detectUrls': detectUrls})
         else:
             return response.json(14)
@@ -248,3 +260,140 @@ class DetectControllerViewV2(View):
                     redisObj.set_data(key=key, val=1, expire=detect_interval)
                 else:
                     redisObj.del_data(key=key)
+
+    def do_query(self, request_dict, response, userID):
+        page = int(request_dict.get('page', None))
+        line = int(request_dict.get('line', None))
+        if not page or not line:
+            return response.json(444, 'page,line')
+        startTime = request_dict.get('startTime', None)
+        endTime = request_dict.get('endTime', None)
+        eventType = request_dict.get('eventType', None)
+        region = request_dict.get('region', None)
+        if not region:
+            return response.json(444, 'region')
+        region = int(region)
+        qs = Equipment_Info.objects.filter(userID_id=userID).order_by('-eventTime')
+        if startTime and endTime:
+            qs = qs.filter(eventTime__range=(startTime, endTime))
+        if eventType:
+            qs = qs.filter(eventType=eventType)
+        uids = request_dict.get('uids', None)
+        if uids:
+            uid_list = uids.split(',')
+            qs = qs.filter(devUid__in=uid_list)
+            dvqs = Device_Info.objects.filter(UID__in=uid_list, userID_id=userID).values('UID', 'Type', 'NickName')
+            uid_type_dict = {}
+            for dv in dvqs:
+                uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
+        else:
+            dvqs = Device_Info.objects.filter(userID_id=userID).values('UID', 'Type', 'NickName')
+            uid_type_dict = {}
+            for dv in dvqs:
+                uid_type_dict[dv['UID']] = {'type': dv['Type'], 'NickName': dv['NickName']}
+        # print(uid_type_dict)
+        if not qs.exists():
+            return response.json(0, {'datas': [], 'count': 0})
+        qs = qs.values('id', 'devUid', 'devNickName', 'Channel', 'eventType', 'status', 'alarm', 'eventTime',
+                       'receiveTime', 'is_st', 'addTime')
+
+        count = qs.count()
+        qr = qs[(page - 1) * line:page * line]
+        res = []
+        aws_s3_guonei = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[0],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[0],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='cn-northwest-1'
+        )
+        aws_s3_guowai = boto3.client(
+            's3',
+            aws_access_key_id=AWS_ACCESS_KEY_ID[1],
+            aws_secret_access_key=AWS_SECRET_ACCESS_KEY[1],
+            config=botocore.client.Config(signature_version='s3v4'),
+            region_name='us-east-1'
+        )
+        # vod_time_list = []
+        for p in qr:
+            devUid = p['devUid']
+            eventTime = p['eventTime']
+            channel = p['Channel']
+            if p['is_st'] == 1:
+                thumbspng = '{uid}/{channel}/{time}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime)
+                if region == 2:  # 2:国内
+                    response_url = aws_s3_guonei.generate_presigned_url(
+                        'get_object',
+                        Params={'Bucket': 'push', 'Key': thumbspng}, ExpiresIn=3600)
+                    p['img'] = response_url
+                    p['img_list'] = [response_url]
+                else:   # 1:国外
+                    response_url = aws_s3_guowai.generate_presigned_url(
+                        'get_object',
+                        Params={'Bucket': 'foreignpush', 'Key': thumbspng}, ExpiresIn=3600)
+                    p['img'] = response_url
+                    p['img_list'] = [response_url]
+
+            elif p['is_st'] == 2:
+                # 列表装载回放时间戳标记
+                vodqs = VodHlsModel.objects.filter(uid=devUid, channel=channel, time=int(eventTime)) \
+                    .values("bucket__bucket", "bucket__endpoint")
+                # print(vodqs)
+                if vodqs.exists():
+                    bucket_name = vodqs[0]['bucket__bucket']
+                    endpoint = vodqs[0]['bucket__endpoint']
+                    # bucket = oss2.Bucket(auth, endpoint, bucket_name)
+                    ts = '{uid}/vod{channel}/{etime}/ts0.ts'.format(uid=devUid, channel=p['Channel'], etime=eventTime)
+                    if region == 2:     # 2:国内
+                        thumb = aws_s3_guonei.generate_presigned_url(
+                            'get_object',
+                            Params={'Bucket': 'push', 'Key': ts}, ExpiresIn=3600)
+                    else:   # 1:国外
+                        thumb = aws_s3_guowai.generate_presigned_url(
+                            'get_object',
+                            Params={'Bucket': 'foreignpush', 'Key': ts}, ExpiresIn=3600)
+                    p['img_list'] = [thumb]
+                    # thumb0 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_0000,w_700'})
+                    # thumb1 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_1000,w_700'})
+                    # thumb2 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_2000,w_700'})
+                    # thumb3 = bucket.sign_url('GET', ts, 3600, params={'x-oss-process': 'video/snapshot,t_3000,w_700'})
+                    # p['img_list'] = [thumb0, thumb1, thumb2]
+            elif p['is_st'] == 3:
+                # 列表装载回放时间戳标记
+                p['img_list'] = []
+                for i in range(p['is_st']):
+                    thumbspng = '{uid}/{channel}/{time}_{st}.jpeg'.format(uid=devUid, channel=p['Channel'], time=eventTime, st=i)
+                    if region == 2:  # 2:国内
+                        response_url = aws_s3_guonei.generate_presigned_url(
+                            'get_object',
+                            Params={'Bucket': 'push', 'Key': thumbspng}, ExpiresIn=3600)
+                        img = response_url
+                    else:   # 1:国外
+                        response_url = aws_s3_guowai.generate_presigned_url(
+                            'get_object',
+                            Params={'Bucket': 'foreignpush', 'Key': thumbspng}, ExpiresIn=3600)
+                        img = response_url
+                    p['img_list'].append(img)
+            if devUid in uid_type_dict.keys():
+                p['uid_type'] = uid_type_dict[devUid]['type']
+                p['devNickName'] = uid_type_dict[devUid]['NickName']
+            else:
+                p['uid_type'] = ''
+            res.append(p)
+        return response.json(0, {'datas': res, 'count': count})
+
+    def do_update_interval(self, userID, request_dict, response):
+        uid = request_dict.get('uid', None)
+        interval = request_dict.get('interval', None)
+        dvqs = Device_Info.objects.filter(userID_id=userID, UID=uid)
+        if dvqs.exists():
+            uid_set_qs = UidSetModel.objects. \
+                filter(uid=uid, uidpushmodel__userID_id=userID)
+            # redisObj = RedisObject(db=8)
+            # redisObj.del_data(key='uid_qs_' + userID)
+            if uid_set_qs.exists():
+                uid_set_qs.update(interval=int(interval))
+            else:
+                return response.json(173)
+        else:
+            return response.json(0)

+ 2 - 5
Controller/EquipmentManager.py

@@ -526,13 +526,10 @@ def addInterface(request):
                     # 新增获取IOT证书内容
                     iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
                     if iotqs.exists():
-                        res['iot'].append(
-                            {
+                        res['iot'] = {
                                 'endpoint': iotqs[0].endpoint,
                                 'token_iot_number': iotqs[0].endpoint
-
-                            }
-                        )
+                        }
 
                     if isMainUserExists:
                         res['isMainUserExists'] = 1

+ 9 - 9
Controller/EquipmentManagerV3.py

@@ -68,13 +68,16 @@ class EquipmentManagerV3(View):
         encrypt_pass = View_Password
         print("准备解密")
         View_Password = self.decode_pwd(View_Password)
-        Type = int(request_dict.get('Type', None))
-        ChannelIndex = int(request_dict.get('ChannelIndex', None))
+        Type = request_dict.get('Type', None)
+        ChannelIndex = request_dict.get('ChannelIndex', None)
         version = request_dict.get('version', '')
         isCheckMainUser = request_dict.get('isCheckMainUser', None)
         isMainUserExists = False
-        if not all([UID, NickName, View_Account]):  # Type和ChannelIndex可能为0
-            return response.json(444, {'param': 'UID, NickName, View_Account'})
+        if not all([UID, NickName, View_Account, Type, ChannelIndex]):  # Type和ChannelIndex可能为0
+            return response.json(444, {'param': 'UID, NickName, View_Account, Type, ChannelIndex'})
+
+        Type = int(Type)
+        ChannelIndex = int(ChannelIndex)
 
         re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
         if not re_uid.match(UID):
@@ -226,13 +229,10 @@ class EquipmentManagerV3(View):
 
             iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
             if iotqs.exists():
-                res['iot'].append(
-                    {
+                res['iot'] = {
                         'endpoint': iotqs[0].endpoint,
                         'token_iot_number': iotqs[0].endpoint
-
-                    }
-                )
+                }
 
             return response.json(0, res)
 

+ 95 - 7
Controller/IotCoreController.py

@@ -1,13 +1,16 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
+import os
 import hashlib
 import json
 import time
 import uuid
-
 import boto3
-from django.views import View
+import requests
 
+from django.views import View
+from Ansjer.config import BASE_DIR
+from base64 import b64encode, encodebytes
 from Controller.DeviceConfirmRegion import Device_Region
 from Model.models import Device_User, Device_Info, iotdeviceInfoModel, UIDCompanySerialModel, \
     SerialNumberModel
@@ -16,6 +19,8 @@ from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 
+import OpenSSL.crypto as ct
+
 
 class IotCoreView(View):
 
@@ -32,14 +37,16 @@ class IotCoreView(View):
         return self.validate(operation, request_dict, request)
 
     def validate(self, operation, request_dict, request):
-        token = TokenObject(request_dict.get('token', None))
         response = ResponseObject()
 
         if operation == 'createKeysAndCertificate':
             return self.create_keys_and_certificate(request_dict, response, request)
+        elif operation == 'requestPublishMessage':
+            return self.request_publish_message(request_dict, response, request)
         elif operation == 'thingRegroup':
             return self.thing_regroup(request_dict, response, request)
         else:
+            token = TokenObject(request_dict.get('token', None))
             if token.code != 0:
                 return response.json(token.code)
             if operation == 'clearIotCerm':
@@ -47,14 +54,13 @@ class IotCoreView(View):
             else:
                 return response.json(404)
 
-
     # CVM注册  :正使用
     def create_keys_and_certificate(self, request_dict, response, request):
         serial_number = request_dict.get('serial_number', None)
         serial_number_code = request_dict.get('serial_number_code', None)
         token = request_dict.get('token', None)
         time_stamp = request_dict.get('time_stamp', None)
-        device_version = request_dict.get('device_version', None).replace('.', '_') # 物品组命名不能包含'.'
+        device_version = request_dict.get('device_version', None).replace('.', '_')  # 物品组命名不能包含'.'
         language = request_dict.get('language', None)
 
         if serial_number and token and time_stamp and serial_number_code and device_version and language:
@@ -79,7 +85,7 @@ class IotCoreView(View):
                 region_id = Device_Region().get_device_region(ip)
 
                 iotClient = IOTClient(region_id)
-                res = iotClient.create_keys_and_certificate(serial_number, thingGroup)
+                res = iotClient.create_keys_and_certificate(serial_number, thingGroup, response)
                 nowTime = int(time.time())
                 token_iot_number = hashlib.md5((str(uuid.uuid1()) + str(nowTime)).encode('utf-8')).hexdigest()
 
@@ -142,7 +148,7 @@ class IotCoreView(View):
         region_id = Device_Region().get_device_region(ip)
 
         thingName = 'Ansjer_Device_' + serial_number
-        new_thingGroupName = (device_version + '_' + language).replace('.', '_')    # 物品组命名不能包含'.'
+        new_thingGroupName = (device_version + '_' + language).replace('.', '_')  # 物品组命名不能包含'.'
         # 调试参数
         # thingName = 'Ansjer_Device_00EBEX'
         # new_thingGroupName = 'C1Pro_V1_0_1_cn'
@@ -191,3 +197,85 @@ class IotCoreView(View):
 
         else:
             return response.json(444)
+
+    def request_publish_message(self, request_dict, response, request):
+        UID = request_dict.get('UID', None)
+        MSG = request_dict.get('MSG', None)
+
+        if not all([UID, MSG]):
+            return response.json(444)
+
+        try:
+            # 获取检查uid的序列号,如果没有序列号,不使用MQTT下发消息
+            device_info_qs = Device_Info.objects.filter(UID=UID).values('serial_number')
+            serial_number = device_info_qs[0]['serial_number']
+            if serial_number == '':
+                return response.json(10043)
+
+            # 获取数据组织将要请求的url
+            thing_name = 'Ansjer_Device_' + serial_number
+            iot = iotdeviceInfoModel.objects.filter(thing_name__contains=thing_name).values('thing_name', 'endpoint',
+                                                                                            'token_iot_number')
+            thing_name = iot[0]['thing_name']  # IoT core上的物品名: Ansjer_Device_+序列号+企业编码
+            endpoint = iot[0]['endpoint']
+            Token = iot[0]['token_iot_number']
+            # Token = '297a601b3925e04daab5a60280650e09'
+            topic_name = thing_name + '_rtsp_topic'
+
+            # rtsp://rtsp.zositech.org:8554/ZFdqWldXRFpMTkVaYVZEaEJXRXhUV0RFeE1VRT1B
+            # api doc: https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/http.html
+            # https://IoT_data_endpoint/topics/url_encoded_topic_name?qos=1
+            # POST请求url来发布消息
+            url = 'https://{}/topics/{}?rtsp_command={}'.format(endpoint, topic_name, MSG)
+            authorizer_name = 'Ansjer_Iot_Auth'
+            signature = self.rsa_sign(Token)  # Token签名
+            headers = {'x-amz-customauthorizer-name': authorizer_name, 'Token': Token,
+                       'x-amz-customauthorizer-signature': signature}
+            params = {'rtsp_command': MSG}
+            r = requests.post(url=url, headers=headers, json=params, timeout=2)
+            if r.status_code == 200:
+                return response.json(0)
+            else:
+                # print('发布失败')
+                return response.json(10044)
+        except Exception as e:
+            # print(e)
+            return response.json(500, repr(e))
+
+    def rsa_sign(self, Token):
+        # 私钥签名Token
+        private_key_file = '''-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA5iJzEDPqtGmFMggekVro6C0lrjuC2BjunGkrFNJWpDYzxCzE
+X5jf4/Fq7hcIaQd5sqHugDxPVollSLPe9zNilbrd0sZfU+Ed8gRVuKW9KwfE9XFr
+L0pt6bKRQ0IIRfiZ9TuR0tsQysvcO1GZSXcYfPue3tGM1zOnWFThWDqZ06+sOxzt
+RMRl4yNfbpCG4MfxG3itNXOfrjZv2OMLSXrxmzubSvRpUYSvQPs4fm9302SAnySY
+0MKzx6H6528ZQm/IDDSZy6EmNBIyTRDfxC56vnYcXvqedAQh7jJnjdvt6Q4MhASH
+eIYi1FBSdu2NT6wgpnrqXzx5pq9kR/lnsLID0wIDAQABAoIBAQCiF4GT1/1oNSpr
+ouxk1PNXFPWFUsVGD8mAwVJmx//eiY7MjfuCmdqYYmI+cFqsH2fIOeYSzGfVO9Dq
+9EYHN1oovAWhf7eFDPpajFMUSyiCNmazub8VAAeKowtNpCTPo9pMsDh1m3aoYA4u
+ebrN0+Sbo16y8kWRDgDAZoiR7DSMs8lczk16hwfv5mw8XpNDbaL3Coi4Koe2S1Yh
+2SX3vWFlpd7qF1ZYXuZIp+b8JPrV7n9eUKoFgzj0gqgwQK80CoexIjiOrNMPvkQa
+q+8kCvFjAzKxOK7e8gjM8lMRiGodb61kmYZkkJzFwWO4EaGbl34lfVECd1Ixp3tF
+be0OWAGBAoGBAPSteXDzzToD8ovM7LL11x0jWwI6HOiHu89kZtW566rIezjWBuA2
+TxrcYKM3h9jQRXS3CsMdoIv6XGk5lqM8ADtjn23FBWe/THYLh8bm8JOgh5RRWQDg
+SvkLfi9Ih2mM4NJfmuuDOh3Nze2efLM7+kOZWUQwF2Zx9mL5jvRBk351AoGBAPDI
+sYmT2Li+i5+0vykA2m5uPF8ZOW8BGtAfCZv0suW7BNzSgin78g9WapRd/4p0NNiL
+/nVMqPPCpd1akCUpV+GDWQt0hV+HZjxANE0KWhciQRyo2qvo51j8SWILJSgh0tXC
+aTF8qt6oGw3VN3m57vKhbrlDaz0J/NDJFci6msAnAoGBAOuG6bXPGijUj+//DYKf
+n7jOxdZ49kboEePrtAncdHzri6IEdI3z+WXT6bpzw/LzWUimwldb96WHFNm9s8Hi
+Ch8hIODbnP5naUTgiIzw1XhmONyPCewL/F+LrqX5XVA/alNX8JrwsUrrR2WLAGLQ
+Q3I69XDsEjptTU2tCO0bCs3ZAoGBAJ2lCHfm0JHET230zONvp5N9oREyVqQSuRdh
++syc3TQDyh85w/bw+X6JOaaCFHj1tFPC9Iqf8k4GNspCLPXnp54CfR4+38O3xnvU
+HWoDSRC0YKT++IxtJGriYrlKSr2Hx54kdvLriIPW1D+uRW/xCDza7L9nIKMKEvgv
+b4/IfOEpAoGAeKM9Te7T1VzlAkS0CJOwanzwYV/zrex84WuXxlsGgPQ871lTs5AP
+H1QLfLfFXH+UVrCEC2yv4eml/cqFkpB3gE5i4MQ8GPVIOSs5tsIyl8YUA03vdNdB
+GCqvlyw5dfxNA+EtxNE2wCW/LW7ENJlACgcfgPlBZtpLheWoZB/maw4=
+-----END RSA PRIVATE KEY-----'''
+        # 使用密钥文件方式
+        # private_key_file_path = os.path.join(BASE_DIR, 'static/iotCore/private.pem')#.replace('\\', '/')
+        # private_key_file = open(private_key_file_path, 'r')
+        private_key = ct.load_privatekey(ct.FILETYPE_PEM, private_key_file)
+        signature = ct.sign(private_key, Token.encode('utf8'), 'sha256')
+        signature = encodebytes(signature).decode('utf8').replace('\n', '')
+        # print('signature:', signature)
+        return signature

+ 2 - 2
Object/IOTCore/IotObject.py

@@ -69,7 +69,7 @@ class IOTClient(IOTObject):
         }
         return res
 
-    def create_keys_and_certificate(self, serial_number, thingGroup):
+    def create_keys_and_certificate(self, serial_number, thingGroup, response):
         try:
             result = self.client.create_keys_and_certificate(setAsActive=True)
             res = {
@@ -177,4 +177,4 @@ class IOTClient(IOTObject):
             return res, parameters
         except Exception as e:
             print(e)
-            # return response.json(500, repr(e))
+            return response.json(500, repr(e))

+ 6 - 2
Object/ResponseObject.py

@@ -95,7 +95,9 @@ class ResponseObject(object):
             10039: 'Activation code has been used',
             10040: 'Invalid activation code',
             10041: 'This device has purchased a domestic cloud storage package, and cannot purchase a foreign cloud storage package',
-            10042: 'The device has registered a certificate'
+            10042: 'The device has registered a certificate',
+            10043: 'The device does not have a serial number',
+            10044: 'Request to publish MQTT topic message failed',
         }
         data_cn = {
             0: '成功',
@@ -185,7 +187,9 @@ class ResponseObject(object):
             10039: '激活码已被使用过',
             10040: '无效激活码',
             10041: '此设备已购买过国内云存套餐,无法购买国外云存套餐',
-            10042: '此设备已注册证书'
+            10042: '此设备已注册证书',
+            10043: '此设备没有序列号',
+            10044: '请求发布MQTT主题消息失败',
         }
         if self.lang == 'cn':
             msg = data_cn