Browse Source

Merge branch 'dev'

lhq 4 years ago
parent
commit
8b8e32b29f

+ 3 - 0
Ansjer/config.py

@@ -173,11 +173,14 @@ AWS_IOT_SES_ACCESS_FOREIGN_SECRET = '9Ika2f6wRCZice+0/Z86c0hD7wMd9pyrAuLCsqeV'
 AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA = 'us-east-1'
 AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA = 'ap-southeast-1'
 AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE = 'eu-west-1'
+AWS_IOT_SES_ACCESS_FOREIGN_ROLE = 'arn:aws:iam::697864307463:role/Ansjer_Iot_Admin'
+
 
 # Iot Core国内
 AWS_IOT_SES_ACCESS_CHINA_ID = 'AKIA2MMWBR4DUUYPCFNJ'
 AWS_IOT_SES_ACCESS_CHINA_SECRET = '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'
 AWS_IOT_SES_ACCESS_CHINA_REGION = 'cn-northwest-1'
+AWS_IOT_SES_ACCESS_CHINA_ROLE = 'arn:aws-cn:iam::713816116999:role/service-role/Ansjer_Iot_Admin'
 
 IOT_HOST = {
     1: 'a250bbr0p9u7as-ats.iot.cn-northwest-1.amazonaws.com.cn',

+ 3 - 0
Ansjer/config_local.py

@@ -29,6 +29,9 @@ PAYPAL_CRD = {
     "client_secret": "EGkMCB3RWTcUGJGDYahJ9mCO0AQzEn2AvFfx1GAFjfyyn7-8a0NObcZks89QorlFpvNWTsDXVa2INRNM"
 }
 DETECT_PUSH_DOMAIN = 'http://test.push.dvema.com/'
+DETECT_PUSH_DOMAINS = 'https://test.push.dvema.com/'
+DETECT_PUSH_DOMAIN_JIUAN = 'http://jiuan.push.dvema.com/'
+DETECT_PUSH_DOMAINS_JIUAN = 'https://jiuan.push.dvema.com/'
 # 数据库dyanamo品牌日志数据库
 USER_BRAND = 'test_user_brand'
 USER_BRAND_ALL = 'test_user_brand_all'

+ 1 - 2
Ansjer/formal_settings.py

@@ -170,8 +170,7 @@ CORS_ALLOW_HEADERS = (
 '''
 # 管理员邮箱
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 
 # 非空链接,却发生404错误,发送通知MANAGERS

+ 25 - 7
Ansjer/local_settings.py

@@ -17,6 +17,8 @@ INSTALLED_APPS = [
     'corsheaders',
     'imagekit',
     'Model',
+    'PushModel',
+    'SerialModel',
 ]
 
 MIDDLEWARE = [
@@ -73,17 +75,23 @@ TEMPLATES = [
 WSGI_APPLICATION = 'Ansjer.local_wsgi.application'
 
 # 服务器类型
+#业务数据库
 DATABASE_DATA = 'ansjertest'
 SERVER_HOST = '127.0.0.1'
 DATABASES_USER = 'root'
-DATABASES_PASS = 'mysqlfyzs9wl'
+DATABASES_PASS = 'root'
 
+#推送数据库
 DATABASE_DATA2 = 'ansjerpush'
 SERVER_HOST2 = '127.0.0.1'
 DATABASES_USER2 = 'root'
-DATABASES_PASS2 = '123456'
-
+DATABASES_PASS2 = 'root'
 
+#序列号公共数据库
+DATABASE_DATA3 = 'serial'
+SERVER_HOST3 = '127.0.0.1'
+DATABASES_USER3 = 'root'
+DATABASES_PASS3 = 'root'
 
 DATABASES = {
     'default': {
@@ -105,12 +113,23 @@ DATABASES = {
         'PORT': '3306',
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
-    }
+    },
+    'mysql03': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA3,
+        'USER': DATABASES_USER3,
+        'PASSWORD': DATABASES_PASS3,
+        'HOST': SERVER_HOST3,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
+    },
 }
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
     'Model': 'default',
-    'db2': 'mysql02',
+    'PushModel': 'mysql02',
+    'SerialModel': 'mysql03',
 }
 
 AUTH_PASSWORD_VALIDATORS = [
@@ -171,8 +190,7 @@ CORS_ALLOW_HEADERS = (
 '''
 # 管理员邮箱
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 
 # 非空链接,却发生404错误,发送通知MANAGERS

+ 23 - 3
Ansjer/test_settings.py

@@ -17,6 +17,8 @@ INSTALLED_APPS = [
     'corsheaders',
     'imagekit',
     'Model',
+    'PushModel',
+    'SerialModel',
 ]
 
 MIDDLEWARE = [
@@ -74,16 +76,24 @@ WSGI_APPLICATION = 'Ansjer.test_wsgi.application'
 
 
 # 服务器类型
+#业务数据库
 DATABASE_DATA = 'AnsjerTest'
 SERVER_HOST = 'database-2.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER = 'azrds'
 DATABASES_PASS = 'azrds.x.x'
 
+#推送数据库
 DATABASE_DATA2 = 'AnsjerTest'
 SERVER_HOST2 = 'ansjerpush.clraczw4p0yj.us-west-1.rds.amazonaws.com'
 DATABASES_USER2 = 'azrds'
 DATABASES_PASS2 = 'azrds.x.x'
 
+#序列号公共数据库
+DATABASE_DATA3 = 'AnsjerTest'
+SERVER_HOST3 = 'serial-uid.clraczw4p0yj.us-west-1.rds.amazonaws.com'
+DATABASES_USER3 = 'azrds'
+DATABASES_PASS3 = 't1ApWed1FPPQbWmclZKp'
+
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.mysql',
@@ -104,12 +114,23 @@ DATABASES = {
         'PORT': '3306',
         'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
         'AUTOCOMMIT': True
+    },
+    'mysql03': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': DATABASE_DATA3,
+        'USER': DATABASES_USER3,
+        'PASSWORD': DATABASES_PASS3,
+        'HOST': SERVER_HOST3,
+        'PORT': '3306',
+        'OPTIONS': {'charset': 'utf8mb4', 'use_unicode': True, 'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"},
+        'AUTOCOMMIT': True
     }
 }
 DATABASE_ROUTERS = ['Ansjer.database_router.DatabaseAppsRouter']
 DATABASE_APPS_MAPPING = {
     'Model': 'default',
-    'db2': 'mysql02',
+    'PushModel': 'mysql02',
+    'SerialModel': 'mysql03',
 }
 
 AUTH_PASSWORD_VALIDATORS = [
@@ -170,8 +191,7 @@ CORS_ALLOW_HEADERS = (
 '''
 # 管理员邮箱
 ADMINS = (
-    ('admin', 'chanjunkai@163.com'),
-    ('admin', '1379072853@qq.com'),
+    ('admin', 'sonalh@foxmail.com'),
 )
 
 # 非空链接,却发生404错误,发送通知MANAGERS

+ 32 - 32
Controller/CloudStorage.py

@@ -87,24 +87,24 @@ class CloudStorageView(View):
         response = ResponseObject()
         if operation is None:
             return response.json(444, 'error path')
-        elif operation == 'dopaypalcallback':
+        elif operation == 'dopaypalcallback':  # paypal支付回调
             return self.do_pay_by_paypal_callback(request_dict, response)
-        elif operation == 'doalicallback':
+        elif operation == 'doalicallback':  # 阿里支付回调
             return self.do_pay_by_ali_callback(request)
-        elif operation == 'dowechatnotify':
+        elif operation == 'dowechatnotify':  # 微信支付回调
             return self.do_pay_by_wechat_callback(request, response)
-        elif operation == 'getsignsts':
+        elif operation == 'getsignsts':  # 设备调用,获取sts令牌
             ip = CommonService.get_ip_address(request)
             return self.do_get_sign_sts(request_dict, ip, response)
-        elif operation == 'storeplaylist':
+        elif operation == 'storeplaylist':  # 设备调用,设备把视频上传到s3,同时把视频数据信息传给服务器,服务器存储播放内容
             return self.do_store_playlist(request_dict, response)
-        elif operation == 'signplaym3u8':
+        elif operation == 'signplaym3u8':  # 根据sts播放m3u8 视频流
             return self.do_sign_play_m3u8(request_dict, response)
-        elif operation == 'payOK':
+        elif operation == 'payOK':  # 支付成功
             return self.do_pay_ok(request_dict)
-        elif operation == 'vodMsgEnd':
+        elif operation == 'vodMsgEnd':  # 云存到期续费提醒   提前1天
             return self.do_vod_msg_end(request_dict)
-        elif operation == 'vodMsgNotice':
+        elif operation == 'vodMsgNotice':  # 云存操作系统消息
             return self.do_vod_msg_Notice(request_dict)
 
         else:
@@ -115,31 +115,31 @@ class CloudStorageView(View):
             if tko.code != 0:
                 return response.json(tko.code)
             userID = tko.userID
-            if operation == 'createpayorder':
+            if operation == 'createpayorder':  # 创建支付订单
                 ip = CommonService.get_ip_address(request)
                 return self.do_create_pay_order(request_dict, userID, ip, response)
-            elif operation == 'changevodstatus':
+            elif operation == 'changevodstatus':  # 修改云存状态,传送两个url,即getsignsts接口和storeplaylist接口
                 return self.do_change_vod_status(request_dict, userID, response)
-            elif operation == 'queryvodlist':
+            elif operation == 'queryvodlist':  # 获取视频播放列表
                 return self.do_query_vod_list(request_dict, userID, response)
-            elif operation == 'commoditylist':
+            elif operation == 'commoditylist':  # 查询套餐列表
                 return self.do_commodity_list(request_dict, userID, response)
-            elif operation == 'queryorder':
+            elif operation == 'queryorder':  # 查询订单列表
                 return self.do_query_order(request_dict, userID, response)
-            elif operation == 'experienceorder':
+            elif operation == 'experienceorder':  # 生成体验订单
                 return self.do_experience_order(request_dict, userID, response)
-            elif operation == 'experiencereset':
+            elif operation == 'experiencereset':  # 重置设备云存体验
                 return self.do_experience_reset(request_dict, userID, response)
-            elif operation == 'deletevodlist':
+            elif operation == 'deletevodlist':  # 删除播放列表
                 return self.deleteVodList(request_dict, userID, response)
-            elif operation == 'devicecommodity':
+            elif operation == 'devicecommodity':  # 设备关联套餐列表
                 return self.device_commodity(request_dict, userID, response)
-            elif operation == 'switchdevicecommodity':
+            elif operation == 'switchdevicecommodity':  # 提前使用设备关联套餐
                 return self.switch_device_commodity(request_dict, userID, response)
             else:
                 return response.json(414)
 
-    def do_query_order(self, request_dict, userID, response):
+    def do_query_order(self, request_dict, userID, response):  # 查询订单列表
         status = request_dict.get('status', None)
         page = int(request_dict.get('page', None))
         line = int(request_dict.get('line', None))
@@ -178,7 +178,7 @@ class CloudStorageView(View):
                     data.append(d)
         return response.json(0, {'data': data, 'count': count})
 
-    def do_commodity_list(self, request_dict, userID, response):
+    def do_commodity_list(self, request_dict, userID, response):  # 查询套餐列表
         mold = request_dict.get('mold', None)
         uid = request_dict.get('uid', None)
         lang = request_dict.get('lang', 'en')
@@ -230,7 +230,7 @@ class CloudStorageView(View):
         else:
             return response.json(0)
 
-    def do_sign_play_m3u8(self, request_dict, response):
+    def do_sign_play_m3u8(self, request_dict, response):  # 根据sts播放m3u8 视频流
         uid = request_dict.get('uid', None)
         uid = jwt.decode(uid, OAUTH_ACCESS_TOKEN_SECRET, algorithms='HS256').get('uid', '')
         channel = request_dict.get('channel', None)
@@ -292,7 +292,7 @@ class CloudStorageView(View):
         # response = HttpResponse(playlist, content_type="application/octet-stream")
         # return response
 
-    def do_get_sign_sts(self, request_dict, ip, response):
+    def do_get_sign_sts(self, request_dict, ip, response):  # 获取sts令牌
         uidToken = request_dict.get('uidToken', None)
         utko = UidTokenObject(uidToken)
         if utko.flag is False:
@@ -382,7 +382,7 @@ class CloudStorageView(View):
         res = {'code': 405, 'msg': 'Not purchased or expired!'}
         return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
 
-    def do_query_vod_list(self, request_dict, userID, response):
+    def do_query_vod_list(self, request_dict, userID, response):  # 获取视频播放列表
         startTime = int(request_dict.get('startTime', None))
         endTime = int(request_dict.get('endTime', None))
         uid = request_dict.get('uid', None)
@@ -442,7 +442,7 @@ class CloudStorageView(View):
             }),
         return response.json(0, vod_play_list)
 
-    def do_store_playlist(self, request_dict, response):
+    def do_store_playlist(self, request_dict, response):  # 设备调用,上传视频到s3,同时把视频数据信息传给服务器,服务器存储播放内容
         uidToken = request_dict.get('uidToken', None)
         storeTime = request_dict.get('time', None)
         sec = request_dict.get('sec', None)
@@ -495,7 +495,7 @@ class CloudStorageView(View):
             res = {'code': 404, 'msg': '设备未购买'}
             return HttpResponse(json.dumps(res, ensure_ascii=False), content_type="application/json,charset=utf-8")
 
-    def do_change_vod_status(self, request_dict, userID, response):
+    def do_change_vod_status(self, request_dict, userID, response):  # 修改云存状态
         uid = request_dict.get('uid', None)
         status = request_dict.get('status', None)
         channel = request_dict.get('channel', None)
@@ -601,7 +601,7 @@ class CloudStorageView(View):
                 '''
         return response
 
-    def do_pay_ok(self, request_dict):
+    def do_pay_ok(self, request_dict):  # 支付成功
         response = HttpResponse()
         paytype = request_dict.get('paytype', None)
         lang = request_dict.get('lang', 'en')
@@ -704,7 +704,7 @@ class CloudStorageView(View):
         '''
         return response
 
-    def do_pay_by_ali_callback(self, request):
+    def do_pay_by_ali_callback(self, request):  # 阿里支付回调
         response = ResponseObject()
         data = request.POST.dict()
         # logger = logging.getLogger('log')
@@ -801,7 +801,7 @@ class CloudStorageView(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             return HttpResponseRedirect(red_url)
 
-    def do_pay_by_paypal_callback(self, request_dict, response):
+    def do_pay_by_paypal_callback(self, request_dict, response):  # paypal支付回调
         paymentId = request_dict.get('paymentId', None)
         PayerID = request_dict.get('PayerID', None)
         orderID = request_dict.get('orderID', None)
@@ -914,7 +914,7 @@ class CloudStorageView(View):
                 red_url = "{SERVER_DOMAIN_SSL}web/paid2/en_fail.html".format(SERVER_DOMAIN_SSL=SERVER_DOMAIN_SSL)
             return HttpResponseRedirect(red_url)
 
-    def do_pay_by_wechat_callback(self, request, response):
+    def do_pay_by_wechat_callback(self, request, response):  # 微信支付回调
 
         logger = logging.getLogger('log')
         try:
@@ -1007,7 +1007,7 @@ class CloudStorageView(View):
                 order_qs.update(status=10)
             return HttpResponse(pay.xml_to_dict({'return_code': 'FAIL', 'return_msg': repr(e)}))
 
-    def do_create_pay_order(self, request_dict, userID, ip, response):
+    def do_create_pay_order(self, request_dict, userID, ip, response):  # 创建支付订单
         uid = request_dict.get('uid', None)
         channel = request_dict.get('channel', None)
         pay_type = int(request_dict.get('pay_type', None))
@@ -1324,7 +1324,7 @@ class CloudStorageView(View):
 
         return response.json(0, '重置云存体验成功')
 
-    def deleteVodList(self, request_dict, userID, response):
+    def deleteVodList(self, request_dict, userID, response):  # 删除播放列表
         uid = request_dict.get('uid', None)
         dv_qs = Device_Info.objects.filter(userID_id=userID, UID=uid, isShare=False, isExist=1) \
             .values('vodPrimaryUserID')

+ 17 - 6
Controller/CompanyController.py

@@ -138,24 +138,34 @@ class CompanyView(View):
 
             if not company_qs.exists():
                 return response.json(444)
+            p2p_sum_Serial = SerialNumberModel.objects.filter(p2p=p2p).count()
+            p2p_sum_Serial_company = CompanySerialModel.objects.filter(p2p=p2p).count()
+            p2p_sum_bind = p2p_sum_Serial - p2p_sum_Serial_company
+            if int(quantity) > int(p2p_sum_bind):
+                return response.json(10041)
 
             savePoint = transaction.savepoint()
             try:
                 try:
 
                     company = company_qs[0]
-                    start = company.quantity
-                    end = start + int(quantity)
-                    serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start:end]
+                    # start = company.quantity
+                    # start = int(start)
+                    # end = start + int(quantity)
+                    # serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start:end]
+                    start_1 = p2p_sum_Serial_company
+                    end_1 = int(start_1) + int(quantity)
+                    serial_qs = SerialNumberModel.objects.filter(p2p=p2p)[start_1:end_1]
                     if serial_qs.exists():
                         data = []
                         now_time = int(time.time())
                         for item in serial_qs:
                             data.append(CompanySerialModel(
                                 company_id=company.id,
-                                serial_number_id=item.id,
+                                serial_number=item.serial_number,
                                 add_time=now_time,
-                                update_time=now_time
+                                update_time=now_time,
+                                p2p=p2p
                             ))
 
                             if len(data) == 5000:
@@ -165,7 +175,8 @@ class CompanyView(View):
                             CompanySerialModel.objects.bulk_create(data)
                             data.clear()
 
-                        company.quantity = company.quantity + end - start
+                        # company.quantity = company.quantity + end - start
+                        company.quantity =CompanySerialModel.objects.filter(company_id=id).count()
                         company.save()
                         return response.json(0)
                     else:

+ 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)

+ 4 - 4
Controller/EquipmentManager.py

@@ -494,7 +494,7 @@ def addInterface(request):
                         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.serial_number + uid_serial.company_serial.company.mark)
+                                                                   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)
@@ -524,7 +524,7 @@ def addInterface(request):
 
 
                     # 新增获取IOT证书内容
-                    iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number=dvql[0]['serial_number'])
+                    iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
                     if iotqs.exists():
                         res['iot'].append(
                             {
@@ -882,7 +882,7 @@ def queryInterface(request):
 
 
         #新增获取IOT证书内容
-        iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number__in=serial_number_list)
+        iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -904,7 +904,7 @@ def queryInterface(request):
             #新增IOT
             p['iot'] = []
             for iot in iotqs:
-                if p['serial_number'][0:6] == iot.serial_number.serial_number:
+                if p['serial_number'][0:6] == iot.serial_number:
                         p['iot'].append(
                             {
                                 'endpoint':iot.endpoint,

+ 3 - 3
Controller/EquipmentManagerV2.py

@@ -163,7 +163,7 @@ class EquipmentManagerV2(View):
                 serial_number_list.append(dvl['serial_number'][0:6])
 
             # 新增获取IOT证书内容
-            iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number__in=serial_number_list)
+            iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
             ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                 values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -188,7 +188,7 @@ class EquipmentManagerV2(View):
                 # 新增云分配UID
                 p['iot'] = []
                 for iot in iotqs:
-                    if p['serial_number'][0:6] == iot.serial_number.serial_number:
+                    if p['serial_number'][0:6] == iot.serial_number:
                         p['iot'].append(
                             {
                                 'endpoint': iot.endpoint,
@@ -250,7 +250,7 @@ class EquipmentManagerV2(View):
             serial_number_list.append(dvl['serial_number'])
 
         # 新增获取IOT证书内容
-        iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number__in=serial_number_list)
+        iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
         ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
             values('bucket__content', 'status', 'channel', 'endTime', 'uid')

+ 200 - 208
Controller/EquipmentManagerV3.py

@@ -38,29 +38,29 @@ class EquipmentManagerV3(View):
         token = request_dict.get('token', None)
         # 设备主键uid
         tko = TokenObject(token)
-        if tko.code == 0:
-            response.lang = tko.lang
-            userID = tko.userID
-            # 手机端添加设备,查询,修改
-            if operation == 'add':
-                return self.do_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)
-            elif operation == 'getDeviceFeatures':
-                return self.do_get_device_features(request_dict, response)
-            else:
-                return response.json(414)
-        else:
+        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)
+        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 == 'modifyChannelName':
+            return self.do_modify_channel_name(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)
+        elif operation == 'getDeviceFeatures':
+            return self.do_get_device_features(request_dict, response)
+        else:
+            return response.json(414)
 
     def do_add(self, userID, request_dict, response, request):
-        token = request_dict.get('token', None)
         UID = request_dict.get('UID', None)
         NickName = request_dict.get('NickName', None)
         View_Account = request_dict.get('View_Account', None)
@@ -68,196 +68,174 @@ class EquipmentManagerV3(View):
         encrypt_pass = View_Password
         print("准备解密")
         View_Password = self.decode_pwd(View_Password)
-        Type = request_dict.get('Type', None)
-        ChannelIndex = request_dict.get('ChannelIndex', None)
+        Type = int(request_dict.get('Type', None))
+        ChannelIndex = int(request_dict.get('ChannelIndex', None))
         version = request_dict.get('version', '')
         isCheckMainUser = request_dict.get('isCheckMainUser', None)
         isMainUserExists = False
-        if all([UID, NickName, View_Account, Type, ChannelIndex]):
-            tko = TokenObject(token)
-            response.lang = tko.lang
-            if tko.code == 0:
-                userID = tko.userID
-                re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
-                if re_uid.match(UID):
-                    is_exist = Device_Info.objects.filter(UID=UID, userID_id=userID)
-                    if is_exist:
-                        # 判断设备是否已存在
-                        if is_exist[0].isExist == 1:
-                            return response.json(174)
-                        else:
-                            is_exist.delete()
-                    if UID == '98UXAA8BRPA35VAL111A':
-                        asy = threading.Thread(target=ModelService.add_log,
-                                               args=(CommonService.get_ip_address(request), userID, 'addV3'))
-                        asy.start()
-                        return response.json(10, 'illegal uid: {uid}'.format(uid=UID))
-
-                    pk = CommonService.getUserID(getUser=False)
-
-
-
-
-                    userName = Device_User.objects.get(userID=userID).username
-                    main_exist = Device_Info.objects.filter(UID=UID)
-                    main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
-                    vodPrimaryUserID = userID
-                    vodPrimaryMaster = userName
-                    if main_exist.exists():
-                        vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
-                        vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
-
-                    is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'vodPrimaryUserID')
-                    isvodPrimaryUserID = ''
-
-                    for forbind in is_bind:
-                        if forbind['vodPrimaryUserID'] != '':
-                            isvodPrimaryUserID = forbind['vodPrimaryUserID']
-
-                    if isCheckMainUser != '1' :
-                        if main_exist.exists():
-                            vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
-                            vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
-                        else:
-                            vodPrimaryUserID = ''
-                            vodPrimaryMaster = ''
-
-                    isusermain = False
-                    if is_bind and isvodPrimaryUserID != userID and isvodPrimaryUserID != '':
-                        isusermain = True
-
-                    # uid_main_exist = UIDMainUser.objects.filter(UID=UID).values('UID', 'user_id')
-                    # if uid_main_exist.exists():
-                    #     vodPrimaryUserID = uid_main_exist[0]['user_id']
-                    #     vodPrimaryMaster = Device_User.objects.get(userID=vodPrimaryUserID).username
-                    #
-                    #     if vodPrimaryUserID != userID:
-                    #         isusermain = True
-
-
-
-                    # 判断是否有已绑定用户
-                    if isCheckMainUser == '1' and isusermain:
-                        res = {
-                            'id': pk,
-                            'userID': userID,
-                            'NickName': NickName,
-                            'UID': UID,
-                            'View_Account': View_Account,
-                            'View_Password': View_Password,
-                            'ChannelIndex': ChannelIndex,
-                            'Type': Type,
-                            'isShare': False,
-                            'primaryUserID': '',
-                            '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)
-
-                    try:
-                        # 判断是否有用户绑定
-                        nowTime = int(time.time())
-                        us_qs = UidSetModel.objects.filter(uid=UID)
-                        if not us_qs.exists():
-                            uid_set_create_dict = {
-                                'uid': UID,
-                                'addTime': nowTime,
-                                'updTime': nowTime,
-                                'ip': CommonService.get_ip_address(request_dict),
-                                'channel': ChannelIndex,
-                                'nickname': NickName,
-                                'version': version,
-                            }
-                            UidSetModel.objects.create(**uid_set_create_dict)
-                        else:
-                            us_qs.update(nickname=NickName)
-
-                        userDevice = Device_Info(id=pk, 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()
-                        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.serial_number + uid_serial.company_serial.company.mark)
-                        else:
-                            Device_Info.objects.filter(UID=UID).update(vodPrimaryUserID=vodPrimaryUserID,
-                                                                       vodPrimaryMaster=vodPrimaryMaster)
-
-                        # if isCheckMainUser == '1':
-                        #     uid_main_dict = {
-                        #         'UID': UID,
-                        #         'user_id': vodPrimaryUserID
-                        #     }
-                        #     UIDMainUser.objects.create(**uid_main_dict)
-
-                        if not us_qs.exists():
-                            us_qs = UidSetModel.objects.filter(uid=UID)
-
-                        if us_qs.exists() and us_qs[0].is_alexa == 1:
-                            asy = threading.Thread(target=ModelService.notify_alexa_add,
-                                                   args=(UID, userID, NickName, encrypt_pass))
-                            asy.start()
-
-                        # redisObj = RedisObject(db=8)
-                        # redisObj.del_data(key='uid_qs_' + userID)
-                    except Exception as e:
-                        return response.json(10, repr(e))
-                    else:
-                        dvqs = Device_Info.objects.filter(id=pk).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__serial_number=dvql[0]['serial_number'])
-                        if iotqs.exists():
-                            res['iot'].append(
-                                {
-                                    'endpoint': iotqs[0].endpoint,
-                                    'token_iot_number': iotqs[0].endpoint
+        if not all([UID, NickName, View_Account]):  # Type和ChannelIndex可能为0
+            return response.json(444, {'param': 'UID, NickName, View_Account'})
+
+        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()
+
+        id = CommonService.getUserID(getUser=False)
+        userName = Device_User.objects.get(userID=userID).username
+        main_exist = Device_Info.objects.filter(UID=UID)
+        main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
+        vodPrimaryUserID = userID
+        vodPrimaryMaster = userName
+        if main_exist.exists():
+            vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+            vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+
+        is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'vodPrimaryUserID')
+        isvodPrimaryUserID = ''
+
+        for forbind in is_bind:
+            if forbind['vodPrimaryUserID'] != '':
+                isvodPrimaryUserID = forbind['vodPrimaryUserID']
+
+        if isCheckMainUser != '1' :
+            if main_exist.exists():
+                vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
+                vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
+            else:
+                vodPrimaryUserID = ''
+                vodPrimaryMaster = ''
+
+        isusermain = False
+        if is_bind and isvodPrimaryUserID != userID and isvodPrimaryUserID != '':
+            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': False,
+                'primaryUserID': '',
+                '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)
 
-                                }
-                            )
+        try:
+            # 判断是否有用户绑定
+            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:
+                uid_set_create_dict = {
+                    'uid': UID,
+                    'addTime': nowTime,
+                    'updTime': nowTime,
+                    'ip': CommonService.get_ip_address(request_dict),
+                    'channel': ChannelIndex,
+                    'nickname': NickName,
+                    'version': version,
+                }
+                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()
+            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)
 
-                        return response.json(0, res)
+            if not us_qs.exists():
+                us_qs = UidSetModel.objects.filter(uid=UID)
 
-                else:
-                    return response.json(444, {'param': 'UID'})
-            else:
-                return response.json(tko.code)
+            if us_qs.exists() and us_qs[0].is_alexa == 1:
+                asy = threading.Thread(target=ModelService.notify_alexa_add,
+                                       args=(UID, userID, NickName, encrypt_pass))
+                asy.start()
+
+        except Exception as e:
+            return response.json(10, repr(e))
         else:
-            return response.json(444, {'param': 'UID,NickName,View_Account,View_Password,Type,ChannelIndex,version'})
+            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'].append(
+                    {
+                        'endpoint': iotqs[0].endpoint,
+                        'token_iot_number': iotqs[0].endpoint
+
+                    }
+                )
+
+            return response.json(0, res)
+
 
     def do_modify(self, userID, request_dict, response, request):
         token = request_dict.get('token', None)
@@ -328,6 +306,17 @@ class EquipmentManagerV3(View):
             # redisObj.del_data(key='uid_qs_' + userID)
             return response.json(0, res)
 
+    # 编辑通道名
+    def do_modify_channel_name(self, userID, request_dict, response):
+        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)
+        # 更新通道名
+        UidChannelSetModel.objects.filter(uid__uid=uid).update(channel_name=channel_name)
+        return response.json(0)
+
     # 新查询设备字段
     def do_query(self, userID, request_dict, response):
         token = request_dict.get('token', None)
@@ -367,7 +356,7 @@ class EquipmentManagerV3(View):
                 serial_number_list.append(dvl['serial_number'][0:6])
 
             # 新增获取IOT证书内容
-            iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number__in=serial_number_list)
+            iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
             ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                 values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -411,7 +400,8 @@ class EquipmentManagerV3(View):
                     'is_custom_voice': us['is_custom_voice']
                 }
                 # 从uid_channel里面取出通道配置信息
-                ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values('channel', 'pir_audio', 'mic_audio',
+                ucs_qs = UidChannelSetModel.objects.filter(uid__id=us['id']).values('channel', 'channel_name',
+                                                                                    'pir_audio', 'mic_audio',
                                                                                     'battery_status', 'battery_level',
                                                                                     'sleep_status', 'sleep_time',
                                                                                     'light_night_model',
@@ -425,6 +415,7 @@ class EquipmentManagerV3(View):
                 for ucs in ucs_qs:
                     channels_dict = {
                         'channel': ucs['channel'],
+                        'channel_name': ucs['channel_name'],
                         'pir_audio': ucs['pir_audio'],
                         'mic_audio': ucs['mic_audio'],
                         'battery_status': ucs['battery_status'],
@@ -445,7 +436,7 @@ class EquipmentManagerV3(View):
                 # 新增IOT
                 p['iot'] = []
                 for iot in iotqs:
-                    if p['serial_number'][0:6] == iot.serial_number.serial_number:
+                    if p['serial_number'][0:6] == iot.serial_number:
                         p['iot'].append(
                             {
                                 'endpoint': iot.endpoint,
@@ -559,7 +550,7 @@ class EquipmentManagerV3(View):
                     serial_number_list.append(dvl['serial_number'][0:6])
 
                 # 新增获取IOT证书内容
-                iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number__in=serial_number_list)
+                iotqs = iotdeviceInfoModel.objects.filter(serial_number__in=serial_number_list)
 
                 ubqs = UID_Bucket.objects.filter(uid__in=uid_list). \
                     values('bucket__content', 'status', 'channel', 'endTime', 'uid')
@@ -606,6 +597,7 @@ class EquipmentManagerV3(View):
                     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'],
@@ -626,7 +618,7 @@ class EquipmentManagerV3(View):
                     # 新增IOT
                     p['iot'] = []
                     for iot in iotqs:
-                        if p['serial_number'][0:6] == iot.serial_number.serial_number:
+                        if p['serial_number'][0:6] == iot.serial_number:
                             p['iot'].append(
                                 {
                                     'endpoint': iot.endpoint,

+ 122 - 11
Controller/IotCoreController.py

@@ -1,20 +1,26 @@
 #!/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
 from Object.IOTCore.IotObject import IOTClient
 from Object.ResponseObject import ResponseObject
+from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 
+import OpenSSL.crypto as ct
+
 
 class IotCoreView(View):
 
@@ -31,16 +37,22 @@ 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)
+        if operation == 'requestPublishMessage':
+            return self.request_publish_message(request_dict, response, request)
         elif operation == 'thingRegroup':
             return self.thing_regroup(request_dict, response, request)
         else:
-            return response.json(404)
-
+            if token.code != 0:
+                return response.json(token.code)
+            if operation == 'clearIotCerm':
+                return self.clear_Iot_Cerm(request_dict, response)
+            else:
+                return response.json(404)
 
     # CVM注册  :正使用
     def create_keys_and_certificate(self, request_dict, response, request):
@@ -48,7 +60,7 @@ class IotCoreView(View):
         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:
@@ -65,7 +77,7 @@ class IotCoreView(View):
 
             serial = serial_number[0:6]
 
-            iotqs = iotdeviceInfoModel.objects.filter(serial_number__serial_number=serial)
+            iotqs = iotdeviceInfoModel.objects.filter(serial_number=serial)
 
             # 判断设备是否已注册证书
             if not iotqs.exists():
@@ -73,13 +85,17 @@ 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()
 
-                sn = SerialNumberModel.objects.get(serial_number=serial)
+                # sn = SerialNumberModel.objects.get(serial_number=serial)
+                try:
+                    sn = SerialNumberModel.objects.get(serial_number=serial)
+                except:
+                    return response.json(444)
 
-                iotdeviceInfoModel.objects.create(serial_number=sn,
+                iotdeviceInfoModel.objects.create(serial_number=serial,
                                                   endpoint=res[0]['endpoint'],
                                                   certificate_id=res[0]['certificateId'],
                                                   certificate_pem=res[0]['certificatePem'],
@@ -132,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'
@@ -168,3 +184,98 @@ class IotCoreView(View):
         except Exception as e:
             print(e)
             return response.json(500, repr(e))
+
+    def clear_Iot_Cerm(self, userID, request_dict, response):
+        serial_number = request_dict.get('serial_number', None)
+
+        if serial_number:
+
+            iot = iotdeviceInfoModel.objects.filter(thing_name="Ansjer_Device_" + serial_number)
+            if iot.exists():
+                iot.delete()
+            return response.json(0)
+
+        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

+ 25 - 11
Controller/SerialNumberController.py

@@ -42,6 +42,8 @@ class SerialNumberView(View):
             return self.do_get_serial_number(request_dict, response)
         elif operation == 'attachUID':
             return self.do_attach_uid(request_dict, response, request)
+        elif operation == 'detachUID':
+            return self.do_detach_uid(request_dict, response)
         else:
             if token.code != 0:
                 return response.json(token.code)
@@ -52,8 +54,6 @@ class SerialNumberView(View):
                 return self.do_list(token.userID, request_dict, response)
             elif operation == 'update':
                 return self.do_update(token.userID, request_dict, response)
-            elif operation == 'detachUID':
-                return self.do_detach_uid(token.userID, request_dict, response)
             else:
                 return response.json(404)
 
@@ -69,7 +69,10 @@ class SerialNumberView(View):
         algorithm = AlgorithmBaseOn35()
 
         for i in range(quantity):
-            sum = SerialNumberModel.objects.last().id + 1
+            try:
+                sum = SerialNumberModel.objects.last().id
+            except:
+                sum = 0
             serial_number = algorithm.getLetter(sum)
             tmp_len = 6 - len(serial_number)
             # 前面补0
@@ -119,8 +122,7 @@ class SerialNumberView(View):
 
             quantity = int(quantity)
 
-            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, status=0,
-                                                                  serial_number__p2p=p2p_type)
+            company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id, status=0, p2p=p2p_type)
             if not company_serial_qs.exists():
                 redisObject.rpush(key, value)
                 return response.json(373)
@@ -133,7 +135,7 @@ class SerialNumberView(View):
             ids = []
             for serial in company_serial_qs:
                 ids.append(serial.id)
-                data.append(serial.serial_number.serial_number + serial.company.mark)
+                data.append(serial.serial_number + serial.company.mark)
             CompanySerialModel.objects.filter(id__in=ids).update(status=1)
             redisObject.rpush(key, value)
             return response.json(0, data)
@@ -208,7 +210,7 @@ class SerialNumberView(View):
 
                     # 判断序列号是否已和企业关联
                     company_serial_qs = CompanySerialModel.objects.filter(company__secret=company_id,
-                                                                          serial_number__serial_number=serial)
+                                                                          serial_number=serial)
                     if not company_serial_qs.exists():
                         return response.json(173)
 
@@ -334,17 +336,29 @@ class SerialNumberView(View):
         else:
             return response.json(444)
 
-    def do_detach_uid(self, userID, request_dict, response):
+    def do_detach_uid(self, request_dict, response):
         serial_number = request_dict.get('serial_number', None)
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if token and time_stamp and serial_number and len(serial_number) == 9:
+            token = int(CommonService.decode_data(token))
+            time_stamp = int(time_stamp)
+
+            now_time = int(time.time())
+            distance = now_time - time_stamp
+
+            if token != time_stamp or distance > 60000 or distance < -60000:  # 为了全球化时间控制在一天内
+                return response.json(404)
 
-        if serial_number:
             serial = serial_number[0:6]
 
             uid_serial_qs = UIDCompanySerialModel.objects.filter(company_serial__serial_number__serial_number=serial)
             if uid_serial_qs.exists():
                 uid_serial = uid_serial_qs[0]
 
-                iot = iotdeviceInfoModel.objects.filter(serial_number__serial_number=serial)
+                #iot = iotdeviceInfoModel.objects.filter(serial_number__serial_number=serial)
+                iot = iotdeviceInfoModel.objects.filter(thing_name="Ansjer_Device_" + serial_number)
                 if iot.exists():
                     iot.delete()
 
@@ -361,7 +375,7 @@ class SerialNumberView(View):
                     uid.save()
                 uid_serial.delete()
 
-                dev = Device_Info.objects.filter(UID=uid.uid)
+                dev = Device_Info.objects.filter(serial_number=serial_number)
                 if dev.exists():
                     dev.update(serial_number='')
                 return response.json(0)

+ 4 - 1
Controller/TestApi.py

@@ -42,7 +42,7 @@ from django.views.generic.base import View
 from django.contrib.auth.hashers import make_password, check_password  # 对密码加密模块
 from Ansjer.config import OSS_STS_ACCESS_KEY, OSS_STS_ACCESS_SECRET, OSS_ROLE_ARN, SERVER_DOMAIN, PAYPAL_CRD, \
     SERVER_DOMAIN_SSL
-from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket
+from Model.models import Device_Info, Order_Model, Store_Meal, VodHlsModel, OssCrdModel, UID_Bucket, CompanySerialModel, SerialNumberModel, CompanyModel, VPGModel
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UidTokenObject import UidTokenObject
@@ -699,6 +699,9 @@ class testView(View):
 
 
     def test_upload_s3(self,request_dict):
+        res = CompanyModel.objects.filter(id=3).delete()
+        exit(res)
+
         testd = hmac.new('AWS4rf/xnQ3jIgY8bj7Sz4An4KbYct2sq2MbrfmP8rVV'.encode("utf-8"), '20210223'.encode("utf-8"), hashlib.sha256).digest()
         region_sign = hmac.new(testd, 'cn-northwest-1'.encode("utf-8"), hashlib.sha256).hexdigest()
         exit(region_sign)

+ 10 - 6
Model/models.py

@@ -734,7 +734,7 @@ class SysMsgModel(models.Model):
         verbose_name = '系统消息'
         verbose_name_plural = verbose_name
         ordering = ('-id',)
-        app_label = "db2"
+        app_label = "PushModel"
 
 
 # 设备推送重构
@@ -810,6 +810,7 @@ class UidChannelSetModel(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     uid = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     channel = models.IntegerField(default=1, verbose_name='通道号')
+    channel_name = models.CharField(blank=True, default='', max_length=20, verbose_name=u'通道名')
     pir_audio = models.SmallIntegerField(default=0, verbose_name='pir声音。0:关闭,1:开启')
     mic_audio = models.SmallIntegerField(default=0, verbose_name='mic声音。0:关闭,1:开启')
     battery_status = models.SmallIntegerField(default=0, verbose_name='低电量提醒状态。0:关闭,1:开启')
@@ -818,8 +819,8 @@ class UidChannelSetModel(models.Model):
     sleep_time = models.SmallIntegerField(default=0, verbose_name='摄像机进入休眠时间。0:不休眠;1:10秒;2:20秒;3:30秒')
     light_night_model = models.IntegerField(default=0, verbose_name='夜视模式')  # 0:全彩模式,1:黑白模式,2:智能夜视模式
     light_alarm_type = models.IntegerField(default=0, verbose_name='警报人形类型')  # 0为人形,1为移动,3是人形和移动侦测0x0f
-    light_alarm_level = models.IntegerField(default=0,
-                                            verbose_name='声光报警级别')  # 0: 关闭,1:强烈声光告警,2:轻微声光告警,3: 强烈声告警,4:轻微声告警,5:强烈光告警
+    # 声光报警级别: 0: 关闭,1:强烈声光告警,2:轻微声光告警,3: 强烈声告警,4:轻微声告警,5:强烈光告警
+    light_alarm_level = models.IntegerField(default=0, verbose_name='声光报警级别')
     light_alarm_man_en = models.IntegerField(default=0, verbose_name='人为告警状态')  # 0:关,1:开
     light_alarm_vol = models.IntegerField(default=0, verbose_name='报警音量')  # 音量值0-100
     light_long_light = models.IntegerField(default=0, verbose_name='长亮')
@@ -1507,13 +1508,15 @@ class SerialNumberModel(models.Model):
         db_table = 'tb_serial_number'
         verbose_name = '序列号表'
         verbose_name_plural = verbose_name
+        app_label = 'SerialModel'
 
 
 class CompanySerialModel(models.Model):
     id = models.AutoField(primary_key=True)
     company = models.ForeignKey(CompanyModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联企业表的id')
-    serial_number = models.ForeignKey(SerialNumberModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联序列号表的id')
+    serial_number = models.CharField(max_length=11, db_index=True, blank=True, default='', verbose_name=u'6位数序列号')
     status = models.SmallIntegerField(default=0, verbose_name='序列号的状态。0:未使用,1:已使用,2:已和UID关联')
+    p2p = models.SmallIntegerField(default=0, verbose_name='p2p类型。0:无,1:宸云,2:tutk')
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
     update_time = models.IntegerField(default=0, verbose_name='更新时间')
 
@@ -1526,7 +1529,7 @@ class CompanySerialModel(models.Model):
 class UIDCompanySerialModel(models.Model):
     id = models.AutoField(primary_key=True)
     uid = models.ForeignKey(UIDModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联UID表')
-    company_serial = models.ForeignKey(CompanySerialModel, to_field='id', on_delete=models.CASCADE, verbose_name='关联【企业关联序列号表】的id')
+    company_serial = models.ForeignKey(CompanySerialModel, to_field='id', on_delete=models.CASCADE, verbose_name='6位数序列号')
     add_time = models.IntegerField(default=0, verbose_name='添加时间')
     update_time = models.IntegerField(default=0, verbose_name='更新时间')
 
@@ -1538,7 +1541,7 @@ class UIDCompanySerialModel(models.Model):
 
 class iotdeviceInfoModel(models.Model):
     id = models.AutoField(primary_key=True)
-    serial_number = models.ForeignKey(SerialNumberModel, to_field='id', default='', on_delete=models.CASCADE, verbose_name='关联序列号表的id')
+    serial_number = models.CharField(max_length=11, blank=True, default='', db_index=True, verbose_name=u'关联序列号表的id')
     certificate_id = models.CharField(blank=True, max_length=256, default='', verbose_name=u'证书id')
     certificate_pem = models.TextField(blank=True, default='', verbose_name=u'证书项目')
     public_key = models.TextField(blank=True, default='', verbose_name=u'公有密钥')
@@ -1551,6 +1554,7 @@ class iotdeviceInfoModel(models.Model):
         verbose_name = 'iot设备信息表'
         verbose_name_plural = verbose_name
 
+
 class UIDMainUser(models.Model):
     id = models.AutoField(primary_key=True)
     UID = models.CharField(blank=True, max_length=32, verbose_name=u'设备UID', default='')

+ 26 - 3
Object/IOTCore/IotObject.py

@@ -7,7 +7,8 @@ import boto3
 
 from Ansjer.config import AWS_IOT_SES_ACCESS_CHINA_REGION, AWS_IOT_SES_ACCESS_CHINA_ID, AWS_IOT_SES_ACCESS_CHINA_SECRET, \
     AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA, AWS_IOT_SES_ACCESS_FOREIGN_ID, AWS_IOT_SES_ACCESS_FOREIGN_SECRET, \
-    AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE, AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA
+    AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE, AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA, AWS_IOT_SES_ACCESS_CHINA_ROLE, \
+    AWS_IOT_SES_ACCESS_FOREIGN_ROLE
 
 
 class IOTObject(metaclass=ABCMeta):
@@ -30,24 +31,28 @@ class IOTClient(IOTObject):
                                        aws_access_key_id=AWS_IOT_SES_ACCESS_CHINA_ID,
                                        aws_secret_access_key=AWS_IOT_SES_ACCESS_CHINA_SECRET)
             self.endpoint = 'a250bbr0p9u7as-ats.iot.cn-northwest-1.amazonaws.com.cn'
+            self.iotrole = AWS_IOT_SES_ACCESS_CHINA_ROLE
 
         if region_id == 2:
             self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_ASIA,
                                        aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
                                        aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
             self.endpoint = 'a2rqy12o004ad8-ats.iot.ap-southeast-1.amazonaws.com'
+            self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
 
         if region_id == 3:
             self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_AMERICA,
                                        aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
                                        aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
             self.endpoint = 'a2rqy12o004ad8-ats.iot.us-east-1.amazonaws.com'
+            self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
 
         if region_id == 4:
             self.client = boto3.client('iot', region_name=AWS_IOT_SES_ACCESS_FOREIGN_REGION_EUROPE,
                                        aws_access_key_id=AWS_IOT_SES_ACCESS_FOREIGN_ID,
                                        aws_secret_access_key=AWS_IOT_SES_ACCESS_FOREIGN_SECRET)
             self.endpoint = 'a2rqy12o004ad8-ats.iot.eu-west-1.amazonaws.com'
+            self.iotrole = AWS_IOT_SES_ACCESS_FOREIGN_ROLE
 
 
 
@@ -64,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 = {
@@ -151,7 +156,25 @@ class IOTClient(IOTObject):
                 templateBody=templateBody,
                 parameters=parameters
             )
+            topicsql = "SELECT * FROM 'my/things/Ansjer_Device_" + serial_number + "/shadow/update_lwt'"
+            self.client.create_topic_rule(
+                ruleName= 'Ansjer_Device_' + serial_number+'_LWT',
+                topicRulePayload={
+                    "sql": topicsql,
+                    "ruleDisabled": False,
+                    "awsIotSqlVersion": "2016-03-23",
+                    'actions': [
+                        {
+                            'republish': {
+                                'roleArn': self.iotrole,
+                                'topic': '$$aws/things/'+ 'Ansjer_Device_' + serial_number+'/shadow/update',
+                                'qos': 1
+                            }
+                        }
+                    ]
+                }
+            )
             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

+ 2 - 0
Object/uidManageResponseObject.py

@@ -50,6 +50,7 @@ class uidManageResponseObject(object):
             444: '请确认参数的正确性!',
             1112: '您输入的两次密码不一致!',
             208: '只能预定当天的或者以后的!',
+            10041: '已超出序列号剩余可绑定数'
         }
         data_en = {
             0: 'Success',
@@ -92,6 +93,7 @@ class uidManageResponseObject(object):
             404: 'You don not have permission to access this!',
             444: 'Please confirm the correctness of the parameters!',
             1112: 'The two passwords you entered do not match!',
+            10041: 'The remaining number of serial numbers that can be bound has exceeded'
         }
 
         if self.lang == 'cn':

+ 0 - 0
PushModel/__init__.py


+ 3 - 0
PushModel/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
PushModel/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class PushmodelConfig(AppConfig):
+    name = 'PushModel'

+ 0 - 0
PushModel/migrations/__init__.py


+ 3 - 0
PushModel/models.py

@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.

+ 3 - 0
PushModel/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
PushModel/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.

+ 0 - 0
SerialModel/__init__.py


+ 3 - 0
SerialModel/admin.py

@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.

+ 5 - 0
SerialModel/apps.py

@@ -0,0 +1,5 @@
+from django.apps import AppConfig
+
+
+class SerialmodelConfig(AppConfig):
+    name = 'SerialModel'

+ 0 - 0
SerialModel/migrations/__init__.py


+ 3 - 0
SerialModel/models.py

@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.

+ 3 - 0
SerialModel/tests.py

@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.

+ 3 - 0
SerialModel/views.py

@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.