瀏覽代碼

Merge branch 'test' of ssh://192.168.136.99:10022/servers/ASJServer into ghl

guanhailong 3 年之前
父節點
當前提交
8c2696f764

+ 26 - 27
AdminController/ServeManagementController.py

@@ -538,31 +538,29 @@ class serveManagement(View):
         cdk_list = []
         sm_qs = Store_Meal.objects.filter(
             pay_type__payment='cdk_pay', bucket__mold=mold, is_show=0)
-        if sm_qs.exists:
-            rank = sm_qs[0].id
-            for i in range(int(cdk_num)):
-                nowTime = int(time.time())
-                cdk = hashlib.md5((str(uuid.uuid1()) +
-                                   str(nowTime)).encode('utf-8')).hexdigest()
-                cdk_model = CDKcontextModel(
-                    cdk=cdk,
-                    create_time=nowTime,
-                    valid_time=0,
-                    is_activate=0,
-                    is_down=0,
-                    rank_id=rank,
-                    order=order,
-                )
-                cdk_list.append(cdk_model)
-            try:
-                CDKcontextModel.objects.bulk_create(cdk_list)
-            except Exception as e:
-                print(repr(e))
-                return response.json(404, repr(e))
-            else:
-                return response.json(0)
-
-        return response.json(0)
+        if not sm_qs.exists():
+            return response.json(173)
+        rank = sm_qs[0].id
+        for i in range(int(cdk_num)):
+            nowTime = int(time.time())
+            cdk = hashlib.md5((str(uuid.uuid1()) +
+                               str(nowTime)).encode('utf-8')).hexdigest()
+            cdk_model = CDKcontextModel(
+                cdk=cdk,
+                create_time=nowTime,
+                valid_time=0,
+                is_activate=0,
+                is_down=0,
+                rank_id=rank,
+                order=order,
+            )
+            cdk_list.append(cdk_model)
+        try:
+            CDKcontextModel.objects.bulk_create(cdk_list)
+        except Exception as e:
+            return response.json(404, repr(e))
+        else:
+            return response.json(0)
 
     def deleteCdk(self, request_dict, response):
         cdk_id = request_dict.get("id", None)
@@ -893,8 +891,9 @@ class serveManagement(View):
                     data['playcount'] = cg_qs.filter(
                         operation='cloudstorage/queryvodlist', uid=order['UID']).count()
 
-                data['ucode'] = uid_set_dict[uid]['ucode']
-                data['version'] = uid_set_dict[uid]['version']
+                if uid in uid_set_dict:
+                    data['ucode'] = uid_set_dict[uid]['ucode']
+                    data['version'] = uid_set_dict[uid]['version']
 
                 list_data.append(data)
             return response.json(

+ 2 - 2
Controller/AiController.py

@@ -369,8 +369,8 @@ class AiView(View):
             device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
             serial_number = device_info_qs[0]['serial_number']
             device_type = device_info_qs[0]['Type']
-            if serial_number and device_type == 101:
-                ai_service_data['uid'] = CommonService.get_full_serial_number(uid, serial_number, device_type)
+            if serial_number:
+                ai_service_data['serial_number'] = CommonService.get_full_serial_number(uid, serial_number, device_type)
 
             ai_service_data['endTime'] = sum_end_time
             return response.json(0, [ai_service_data])

+ 6 - 6
Controller/CloudStorage.py

@@ -743,7 +743,7 @@ class CloudStorageView(View):
                     device_info_qs = Device_Info.objects.filter(UID=UID).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
                     device_type = device_info_qs[0]['Type']
-                    if serial_number and device_type == 101:
+                    if serial_number:
                         device_name = CommonService.get_full_serial_number(UID, serial_number, device_type)
                     else:
                         device_name = UID
@@ -898,7 +898,7 @@ class CloudStorageView(View):
                 device_info_qs = Device_Info.objects.filter(UID=UID).values('serial_number', 'Type')
                 serial_number = device_info_qs[0]['serial_number']
                 device_type = device_info_qs[0]['Type']
-                if serial_number and device_type == 101:
+                if serial_number:
                     device_name = CommonService.get_full_serial_number(UID, serial_number, device_type)
                 else:
                     device_name = UID
@@ -1033,7 +1033,7 @@ class CloudStorageView(View):
                     device_info_qs = Device_Info.objects.filter(UID=UID).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
                     device_type = device_info_qs[0]['Type']
-                    if serial_number and device_type == 101:
+                    if serial_number:
                         device_name = CommonService.get_full_serial_number(UID, serial_number, device_type)
                     else:
                         device_name = UID
@@ -1387,7 +1387,7 @@ class CloudStorageView(View):
                 device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                 serial_number = device_info_qs[0]['serial_number']
                 device_type = device_info_qs[0]['Type']
-                if serial_number and device_type == 101:
+                if serial_number:
                     device_name = CommonService.get_full_serial_number(uid, serial_number, device_type)
                 else:
                     device_name = uid
@@ -1489,7 +1489,7 @@ class CloudStorageView(View):
         device_id = uid
         serial_number = dv_qs[0]['serial_number']
         device_type = dv_qs[0]['Type']
-        if serial_number and device_type == 101:
+        if serial_number:
             device_id = CommonService.get_full_serial_number(uid, serial_number, device_type)
 
         uid_bucket[0]['uid'] = device_id
@@ -1638,7 +1638,7 @@ class CloudStorageView(View):
                     device_info_qs = Device_Info.objects.filter(UID=uid).values('serial_number', 'Type')
                     serial_number = device_info_qs[0]['serial_number']
                     device_type = device_info_qs[0]['Type']
-                    if serial_number and device_type == 101:
+                    if serial_number:
                         device_name = CommonService.get_full_serial_number(uid, serial_number, device_type)
                     else:
                         device_name = uid

+ 2 - 2
Controller/EquipmentManagerV2.py

@@ -326,8 +326,8 @@ class EquipmentManagerV2(View):
 
         for p in dvls:
             # 如果存在序列号返回完整序列号
-            if p['serial_number'] and p['Type'] == 101:
-                p['UID'] = CommonService.get_full_serial_number(p['UID'], p['serial_number'], p['Type'])
+            if p['serial_number']:
+                p['serial_number'] = CommonService.get_full_serial_number(p['UID'], p['serial_number'], p['Type'])
             # 新增IOT
             p['iot'] = []
             for iot in iotqs:

+ 57 - 52
Controller/EquipmentManagerV3.py

@@ -1,24 +1,23 @@
+import json
 import re
 import threading
 import time
-import traceback
 
+import base64
+import oss2
 import requests
-
-from Controller.CheckUserData import RandomStr
-import oss2, base64
 from django.db.models import Q
 from django.views.generic.base import View
+
+from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
+from Controller.CheckUserData import RandomStr
 from Controller.DeviceConfirmRegion import Device_Region
-from Object.RedisObject import RedisObject
-from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, BASE_DIR
-from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidPushModel, UidChannelSetModel, \
-    Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UIDMainUser, UIDModel
+from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
+    Device_User, iotdeviceInfoModel, UIDCompanySerialModel, UIDModel, UnicomDeviceInfo
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Service.CommonService import CommonService
 from Service.ModelService import ModelService
-import time, json
 
 
 class EquipmentManagerV3(View):
@@ -61,7 +60,7 @@ class EquipmentManagerV3(View):
         elif operation == 'fuzzyQuery':
             return self.do_fuzzy_query(userID, request_dict, response)
         elif operation == 'mainUserDevice':
-            return self.do_mainUserDevice( request_dict, response)
+            return self.do_mainUserDevice(request_dict, response)
         elif operation == 'getDeviceFeatures':
             return self.do_get_device_features(request_dict, response)
         else:
@@ -111,19 +110,18 @@ class EquipmentManagerV3(View):
         primaryMaster = ''
         isShare = False
 
-        is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID', 'primaryMaster')
+        is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
+                                                                            'primaryMaster')
 
         if main_exist.exists():
             vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
             vodPrimaryMaster = main_exist[0]['vodPrimaryMaster']
 
-
         if is_bind.exists():
             primaryUserID = is_bind[0]['primaryUserID']
             primaryMaster = is_bind[0]['primaryMaster']
             isShare = True
 
-
         isusermain = False
         if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
             isusermain = True
@@ -192,8 +190,8 @@ class EquipmentManagerV3(View):
                 # 多通道设备设置通道名
                 if Type in dvr_type_list:
                     UidChannelSet_bulk = []
-                    for i in range(1, ChannelIndex+1):
-                        channel_name = 'channel'+str(i)  # channel1,channel2...
+                    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)
@@ -218,7 +216,7 @@ class EquipmentManagerV3(View):
             if us_qs.exists() and us_qs[0].is_alexa == 1:
                 if us_qs[0].channel > 1:
                     data_list = []
-                    uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id).\
+                    uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id). \
                         values('channel', 'channel_name')
                     if uid_channel_set_qs.exists():
                         # 多通道设备名为 UidChannelSetModel 的 channel_name
@@ -255,15 +253,13 @@ class EquipmentManagerV3(View):
             iotqs = iotdeviceInfoModel.objects.filter(serial_number=dvql[0]['serial_number'])
             if iotqs.exists():
                 res['iot'] = {
-                        'endpoint': iotqs[0].endpoint,
-                        'token_iot_number': iotqs[0].endpoint
+                    'endpoint': iotqs[0].endpoint,
+                    'token_iot_number': iotqs[0].endpoint
                 }
 
-            # 除C1的序列号暂时返回''
-            if res['serial_number'] and Type == 101:
+            # 存在序列号返回完整序列号
+            if res['serial_number']:
                 res['serial_number'] = CommonService.get_full_serial_number(UID, res['serial_number'], Type)
-            else:
-                res['serial_number'] = ''
 
             return response.json(0, res)
 
@@ -275,16 +271,16 @@ class EquipmentManagerV3(View):
             return response.json(444, {'param': 'uidContent'})
 
         try:
-            deviceNumber = 0            # 添加成功数量
-            add_success_flag = False    # 添加成功标识
-            exception_flag = False      # 异常标识
-            exists_flag = False         # 已存在标识
+            deviceNumber = 0  # 添加成功数量
+            add_success_flag = False  # 添加成功标识
+            exception_flag = False  # 异常标识
+            exists_flag = False  # 已存在标识
             uid_content_list = eval(uidContent)
             print('uidContent: ', uid_content_list)
             re_uid = re.compile(r'^[A-Za-z0-9]{14,20}$')
             for uid_content in uid_content_list:
                 exception_flag = False  # 重置异常标识
-                exists_flag = False     # 已存在标识
+                exists_flag = False  # 已存在标识
                 UID = uid_content['uid']
                 NickName = uid_content['nickName']
                 Type = uid_content['type']
@@ -297,7 +293,7 @@ class EquipmentManagerV3(View):
                 if not all([UID, NickName, View_Account]):  # Type和ChannelIndex可能为0
                     return response.json(444, {'param': 'UID, NickName, View_Account'})
 
-                if not re_uid.match(UID):   # 检查uid长度
+                if not re_uid.match(UID):  # 检查uid长度
                     return response.json(444, {'error uid length': UID})
 
                 device_info_qs = Device_Info.objects.filter(UID=UID, userID_id=userID)
@@ -321,7 +317,8 @@ class EquipmentManagerV3(View):
                 primaryMaster = ''
                 isShare = False
 
-                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID', 'primaryMaster')
+                is_bind = Device_Info.objects.filter(UID=UID, isShare=False).values('userID__userID', 'primaryUserID',
+                                                                                    'primaryMaster')
 
                 if main_exist.exists():
                     vodPrimaryUserID = main_exist[0]['vodPrimaryUserID']
@@ -333,7 +330,8 @@ class EquipmentManagerV3(View):
                     isShare = True
 
                 isusermain = False
-                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (primaryUserID != userID and primaryUserID != ''):
+                if (vodPrimaryUserID != userID and vodPrimaryUserID != '') or (
+                        primaryUserID != userID and primaryUserID != ''):
                     isusermain = True
 
                 # 判断是否有已绑定用户
@@ -400,14 +398,15 @@ class EquipmentManagerV3(View):
                     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...
+                        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,
+                                         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)
@@ -426,13 +425,14 @@ class EquipmentManagerV3(View):
                 if us_qs.exists() and us_qs[0].is_alexa == 1:
                     if us_qs[0].channel > 1:
                         data_list = []
-                        uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id).\
+                        uid_channel_set_qs = UidChannelSetModel.objects.filter(uid_id=us_qs[0].id). \
                             values('channel', 'channel_name')
                         if uid_channel_set_qs.exists():
                             # 多通道设备名为 UidChannelSetModel 的 channel_name
                             for uid_channel_set in uid_channel_set_qs:
-                                data_list.append({'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
-                                                  'channel': uid_channel_set['channel'], 'password': encryptPassword})
+                                data_list.append(
+                                    {'userID': userID, 'UID': UID, 'uid_nick': uid_channel_set['channel_name'],
+                                     'channel': uid_channel_set['channel'], 'password': encryptPassword})
                     else:
                         data_list = [{'userID': userID, 'UID': UID, 'uid_nick': NickName, 'password': encryptPassword}]
 
@@ -449,7 +449,8 @@ class EquipmentManagerV3(View):
                                                                 'vodPrimaryUserID', 'vodPrimaryMaster',
                                                                 'userID__userEmail',
                                                                 'data_joined', 'version',
-                                                                'isVod', 'isExist', 'isCameraOpenCloud', 'serial_number')
+                                                                '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')
@@ -467,9 +468,9 @@ class EquipmentManagerV3(View):
             exception_flag = True
             pass
         finally:
-            if add_success_flag:    # 有一台添加成功则返回成功
+            if add_success_flag:  # 有一台添加成功则返回成功
                 return response.json(0, success_res)
-            if exists_flag:         # 全部设备已存在
+            if exists_flag:  # 全部设备已存在
                 return response.json(174, exists_res)
             if exception_flag:
                 return response.json(500, error_res)
@@ -579,7 +580,7 @@ class EquipmentManagerV3(View):
         dvqs = Device_Info.objects.filter(userID_id=userID)
         # # 过滤已重置的设备
         dvqs = dvqs.filter(~Q(isExist=2))
-        dvql = dvqs.values('id', 'userID', 'NickName', 'UID', 'View_Account','View_Password', 'ChannelIndex',
+        dvql = dvqs.values('id', 'userID', 'NickName', 'UID', 'View_Account', 'View_Password', 'ChannelIndex',
                            'Type', 'isShare', 'primaryUserID', 'primaryMaster', 'data_joined', 'vodPrimaryUserID',
                            'vodPrimaryMaster', 'userID__userEmail', 'version', 'isVod', 'isExist', 'NotificationMode',
                            'isCameraOpenCloud', 'serial_number')
@@ -607,7 +608,8 @@ class EquipmentManagerV3(View):
                                                                     'TimeZone', 'TimeStatus', 'SpaceUsable',
                                                                     'SpaceSum', 'MirrorType', 'RecordType',
                                                                     'OutdoorModel', 'WIFIName', 'isDetector',
-                                                                    'DetectorRank', 'is_human', 'is_custom_voice', 'is_ptz', 'double_wifi', 'is_ai')
+                                                                    'DetectorRank', 'is_human', 'is_custom_voice',
+                                                                    'is_ptz', 'double_wifi', 'is_ai', 'mobile_4g')
         uv_dict = {}
         for us in us_qs:
             uv_dict[us['uid']] = {
@@ -634,6 +636,7 @@ class EquipmentManagerV3(View):
                 'is_custom_voice': us['is_custom_voice'],
                 'is_ptz': us['is_ptz'],
                 'double_wifi': us['double_wifi'],
+                'mobile4G': us['mobile_4g'],
                 'is_ai': us['is_ai']
             }
             # 从uid_channel里面取出通道配置信息
@@ -670,14 +673,16 @@ class EquipmentManagerV3(View):
             uv_dict[us['uid']]['channels'] = channels
 
         for p in dvls:
-            # C1返回序列号
-            if p['Type'] != 101:
-                p['serial_number'] = ''
+            if p['serial_number']:
+                u_device_info_qs = UnicomDeviceInfo.objects.filter(serial_no=p['serial_number'])
+                if u_device_info_qs.exists():
+                    p['iccid'] = u_device_info_qs.first().iccid
+
             # 获取iot_deviceInfo表的endpoint和token_iot_number
             p['iot'] = []
             if p['serial_number']:  # 存在序列号根据序列号查询
                 iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(serial_number=p['serial_number'][0:6])
-            else:   # 根据uid查询
+            else:  # 根据uid查询
                 iotdeviceInfo_qs = iotdeviceInfoModel.objects.filter(uid=p['UID'])
             if iotdeviceInfo_qs.exists():
                 iotdeviceInfo = iotdeviceInfo_qs.values('endpoint', 'token_iot_number')
@@ -710,8 +715,8 @@ class EquipmentManagerV3(View):
             if p_uid in uv_dict:
                 # 设备版本号
                 uidversion = uv_dict[p_uid]['version']
-                if len(uidversion) >6:
-                    uidversion = uidversion[0 : uidversion.rfind('.')]
+                if len(uidversion) > 6:
+                    uidversion = uidversion[0: uidversion.rfind('.')]
                 p['uid_version'] = uidversion
                 p['ucode'] = uv_dict[p_uid]['ucode']
                 p['detect_interval'] = uv_dict[p_uid]['detect_interval']
@@ -735,6 +740,7 @@ class EquipmentManagerV3(View):
                 p['is_ptz'] = uv_dict[p_uid]['is_ptz']
                 p['channels'] = uv_dict[p_uid]['channels']
                 p['double_wifi'] = uv_dict[p_uid]['double_wifi']
+                p['mobile4G'] = uv_dict[p_uid]['mobile4G']
                 p['is_ai'] = uv_dict[p_uid]['is_ai']
                 # 设备昵称 调用影子信息昵称,先阶段不可
                 if uv_dict[p_uid]['nickname']:
@@ -987,16 +993,15 @@ class EquipmentManagerV3(View):
             phone = qs[0]['phone']
             username = qs[0]['username']
             qs = CommonService.qs_to_list(qs)
-            if NickName =='':
+            if NickName == '':
                 qs[0]['NickName'] = username
 
             # if userEmail =='':
             #     qs[0]['userEmail'] = NickName
 
-            if phone =='':
+            if phone == '':
                 qs[0]['phone'] = NickName
 
-
         # if not qs:
         #     uidq = UIDMainUser.objects.filter(UID=UID).values('user_id')
         #     if uidq.exists():
@@ -1027,9 +1032,9 @@ class EquipmentManagerV3(View):
             phone = qs[0]['phone']
             username = qs[0]['username']
             qs = CommonService.qs_to_list(qs)
-            if NickName =='':
+            if NickName == '':
                 qs[0]['NickName'] = username
-            if phone =='':
+            if phone == '':
                 qs[0]['phone'] = NickName
         return response.json(0, qs)
 

+ 4 - 0
Controller/IotCoreController.py

@@ -129,8 +129,12 @@ class IotCoreView(View):
                 }
                 return response.json(0, {'res': res})
             else:
+                # 获取并判断region_id是否有效
                 region_id = request_dict.get('region_id', None)
                 region_id = int(region_id) if region_id else CommonService.confirm_region_id(request)
+                if region_id not in [1, 2, 3, 4]:
+                    return response.json(444, {'invalid region_id': region_id})
+
                 iotClient = IOTClient(region_id)
                 # 拼接物品名
                 thingName = CommonService.get_thing_name(company_mark, thing_name_suffix)

+ 2 - 2
Controller/OrderContrller.py

@@ -128,8 +128,8 @@ class OrderView(View):
                     d['did'] = did['id']
                     d['Type'] = did['Type']
                     # 如果存在序列号返回完整序列号
-                    if did['serial_number'] and did['Type'] == 101:
-                        d['UID'] = CommonService.get_full_serial_number(d['UID'], did['serial_number'], did['Type'])
+                    if did['serial_number']:
+                        d['serial_number'] = CommonService.get_full_serial_number(d['UID'], did['serial_number'], did['Type'])
                     data.append(d)
             d['rank__content'] = d['rank__lang__content']
             del d['rank__lang__content']

+ 6 - 2
Controller/SensorGateway/GatewayDeviceController.py

@@ -12,7 +12,7 @@ from django.views.generic.base import View
 
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
 from Model.models import FamilyRoomDevice, FamilyRoom, GatewaySubDevice, Device_Info, UserFamily, FamilyMember, \
-    UidSetModel, iotdeviceInfoModel
+    UidSetModel, iotdeviceInfoModel, SmartScene
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 
@@ -228,10 +228,12 @@ class GatewayDeviceView(View):
             family_device_qs = family_device_qs.filter(~Q(sub_device=0)).order_by('-created_time')
 
             sub_device = []
+            sub_id_list = []
             if family_device_qs.exists():
                 family_device_qs = family_device_qs.values()
                 for item in family_device_qs:
                     sub_id = item['sub_device']
+                    sub_id_list.append(sub_id)
                     gateway_sub_qs = GatewaySubDevice.objects.filter(device_id=device_id, id=sub_id).values(
                         'id', 'device_type',
                         'nickname',
@@ -255,7 +257,9 @@ class GatewayDeviceView(View):
                         'ieeeAddr': gateway_sub_qs['ieee_addr'],
                         'familyId': family_id,
                     })
-            res = {'gateway': gateway, 'sub_device': sub_device, 'sub_device_count': len(sub_device), 'scene_count': 0}
+            scene_count = SmartScene.objects.filter(Q(device_id=device_id) | Q(sub_device_id__in=sub_id_list)).count()
+            res = {'gateway': gateway, 'sub_device': sub_device, 'sub_device_count': len(sub_device),
+                   'scene_count': scene_count}
             return response.json(0, res)
 
         except Exception as e:

+ 153 - 42
Controller/SensorGateway/SmartSceneController.py

@@ -4,13 +4,13 @@
 @Time : 2022/6/29 9:31
 @File :SmartSceneController.py
 """
-import time
 import json
+import time
 
 from django.core.exceptions import ObjectDoesNotExist
+from django.db import transaction
 from django.db.models import F, Q
 from django.views import View
-from django.db import transaction
 
 from Model.models import FamilyRoomDevice, GatewaySubDevice, FamilyRoom, SmartScene, EffectiveTime, Device_Info
 from Service.CommonService import CommonService
@@ -211,30 +211,52 @@ class SmartSceneView(View):
                 'created_time': now_time,
                 'updated_time': now_time,
             }
-
+            msg = {}
             # 处理设置时间
-            if is_all_day:
+            if is_all_day is not None:
                 is_all_day = int(is_all_day)
                 smart_scene_dict['is_all_day'] = is_all_day
 
             # 处理传网关设备id和子设备id的情况
-            if device_id:
+            if conditions_dict['type'] == 1:  # 网关设置时间
+                if not device_id:
+                    return response.json(444, {'error param': 'deviceId'})
                 smart_scene_dict['device_id'] = device_id
                 device_info_qs = Device_Info.objects.filter(id=device_id).values('serial_number')
                 if not device_info_qs.exists():
                     return response.json(173)
                 serial_number = device_info_qs[0]['serial_number']
-            else:
+            else:  # 子设备设置场景
+                if not sub_device_id:
+                    return response.json(444, {'error param': 'subDeviceId'})
                 smart_scene_dict['sub_device_id'] = sub_device_id
-                sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('device__serial_number')
+                sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('device__serial_number',
+                                                                                         'src_addr')
                 if not sub_device_qs.exists():
                     return response.json(173)
                 serial_number = sub_device_qs[0]['device__serial_number']
+                msg['scene_status'] = 1
+                msg['sensor_type'] = conditions_dict['sensor']['device_type']
+                msg['sensor_src'] = int(sub_device_qs[0]['src_addr'], 16)
+                msg['sensor_status'] = int(conditions_dict['sensor']['eventValues'][0]['value'])
 
             with transaction.atomic():
-                if not is_all_day or is_all_day == 1:  # 不设置时间或全天
+                if is_all_day is None:  # 不设置时间
                     smart_scene_qs = SmartScene.objects.create(**smart_scene_dict)
-                elif is_all_day == 2:
+                    # 设备的time数据
+                    hour, minute = conditions_dict['time']['minutes'] / 60, conditions_dict['time']['minutes'] % 60
+                    start_time = int(hour * 3600 + minute * 60)
+                    time_dict = {
+                        'start_time': start_time,
+                        'repeat': conditions_dict['time']['repeat']
+                    }
+                elif is_all_day == 1:  # 全天
+                    smart_scene_qs = SmartScene.objects.create(**smart_scene_dict)
+                    # 设备的time数据
+                    time_dict = {
+                        'is_all_day': is_all_day
+                    }
+                elif is_all_day == 2:  # 非全天
                     start_time = int(request_dict.get('startTime', None))
                     end_time = int(request_dict.get('endTime', None))
                     repeat = int(request_dict.get('repeat', None))
@@ -247,18 +269,24 @@ class SmartSceneView(View):
                                                                          repeat=repeat).id
                     smart_scene_dict['effective_time_id'] = effective_time_id
                     smart_scene_qs = SmartScene.objects.create(**smart_scene_dict)
+
+                    # 设备的time数据
+                    start_hour, start_minute, end_hour, end_minute = \
+                        start_time / 60, start_time % 60, end_time / 60, end_time % 60
+                    start_time, end_time = \
+                        int(start_hour * 3600 + start_minute * 60), \
+                        int(end_hour * 3600 + end_minute * 60)
+                    time_dict = {
+                        'is_all_day': is_all_day,
+                        'start_time': start_time,
+                        'end_time': end_time,
+                        'repeat': repeat
+                    }
                 else:
                     return response.json(444, {'error param': 'invalid isAllDay'})
 
-                msg = {}
-                if conditions_dict['type'] == '2':
-                    sub_device_id = conditions_dict['sensor']['subDeviceId']
-                    sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('src_addr').first()
-                    msg['smart_scene_id'] = smart_scene_qs.id
-                    msg['sensor_type'] = conditions_dict['sensor']['device_type']
-                    msg['sensor_src'] = int(sub_device_qs['src_addr'], 16)
-                    msg['sensor_status'] = conditions_dict['sensor']['eventValues'][0]['value']
-
+                msg['time'] = time_dict
+                msg['smart_scene_id'] = smart_scene_qs.id
                 task_list = []
                 for task in tasks_list:
                     task_temp = {
@@ -271,14 +299,17 @@ class SmartSceneView(View):
                         task_temp['sensor_src'] = int(sub_device_qs['src_addr'], 16)
                     task_list.append(task_temp)
                 msg['task'] = task_list
+
                 smart_scene_qs.device_data = json.dumps(msg)
                 smart_scene_qs.save()
                 # 发布MQTT消息通知网关设备
                 thing_name = serial_number
-                topic_name = 'loocam/gateway_sensor/{}/smart_scene'.format(serial_number)
+                topic_name = 'loocam/gateway_sensor/smart_scene/{}'.format(serial_number)
 
                 success = CommonService.req_publish_mqtt_msg(thing_name, topic_name, msg)
-                if not success:
+                try:
+                    assert success
+                except AssertionError:
                     return response.json(10044)
 
             return response.json(0)
@@ -303,7 +334,9 @@ class SmartSceneView(View):
             return response.json(444, {'error param': 'deviceId or subDeviceId'})
         try:
             if device_id:
-                smart_scene_qs = SmartScene.objects.filter(user_id=user_id, device_id=device_id)
+                sub_device_id = GatewaySubDevice.objects.filter(device_id=device_id).values('id')
+                smart_scene_qs = SmartScene.objects.filter(
+                    Q(user_id=user_id) & Q(device_id=device_id) | Q(sub_device_id__in=sub_device_id))
             else:
                 smart_scene_qs = SmartScene.objects.filter(user_id=user_id, sub_device_id=sub_device_id)
             if not smart_scene_qs.exists():
@@ -349,7 +382,8 @@ class SmartSceneView(View):
             return response.json(444, {'error param': 'smartSceneId'})
         try:
             smart_scene_qs = SmartScene.objects.filter(id=smart_scene_id).values('id', 'scene_name', 'conditions',
-                                                                                 'tasks', 'effective_time_id')
+                                                                                 'tasks', 'effective_time_id',
+                                                                                 'is_all_day')
             if not smart_scene_qs.exists():
                 return response.json(173)
             res = {
@@ -359,21 +393,21 @@ class SmartSceneView(View):
             }
 
             # 如果存在关联的时间数据,组织时间数据
-            try:
-                effective_time_qs = EffectiveTime.objects.get(id=smart_scene_qs[0]['effective_time_id'])
-            except ObjectDoesNotExist:
-                return response.json(0, res)
-
-            if effective_time_qs.is_all_day:  # 全天
-                time_dict = {'all_day': 1}
-            else:
-                time_dict = {
-                    'start_time': effective_time_qs.start_time,
-                    'end_time': effective_time_qs.end_time,
-                    'repeat': effective_time_qs.repeat,
-                }
-            res['time'] = time_dict
+            is_all_day = smart_scene_qs[0]['is_all_day']
+            effectiveTime = {}
+            if is_all_day != 0:
+                effectiveTime['isAllDay'] = is_all_day
+            if is_all_day == 2:
+                try:
+                    effective_time_qs = EffectiveTime.objects.get(id=smart_scene_qs[0]['effective_time_id'])
+                    effectiveTime['startTime'] = effective_time_qs.start_time
+                    effectiveTime['endTime'] = effective_time_qs.end_time
+                    effectiveTime['repeat'] = effective_time_qs.repeat
+                except ObjectDoesNotExist:
+                    return response.json(0, res)
+            res['effectiveTime'] = effectiveTime
             return response.json(0, res)
+
         except Exception as e:
             return response.json(500, repr(e))
 
@@ -387,15 +421,93 @@ class SmartSceneView(View):
         @return: response
         """
         smart_scene_id = request_dict.get('smartSceneId', None)
+        device_id = request_dict.get('deviceId', None)
+        sub_device_id = request_dict.get('subDeviceId', None)
+        scene_name = request_dict.get('sceneName', None)
+        conditions = request_dict.get('conditions', None)
+        tasks = request_dict.get('tasks', None)
+        is_all_day = request_dict.get('isAllDay', None)
 
-        if not smart_scene_id:
-            return response.json(444, {'error param': 'smartSceneId'})
+        conditions_dict = eval(conditions)
+        tasks_list = eval(tasks)
+        now_time = int(time.time())
+        res = {
+            'scene_name': scene_name,
+            'conditions': conditions_dict,
+            'tasks': tasks_list
+        }
+        effective_time = {}
+
+        if is_all_day:
+            is_all_day = int(is_all_day)
+            effective_time['is_all_day'] = is_all_day
+        else:
+            is_all_day = 0
+
+        if not all([smart_scene_id, scene_name, conditions, tasks]):
+            return response.json(444, {'error param': 'smartSceneId,sceneName,conditions or tasks'})
         try:
-            smart_scene_qs = SmartScene.objects.filter(id=smart_scene_id).values('id', 'scene_name', 'conditions',
-                                                                                 'tasks', 'effective_time_id')
+            smart_scene_qs = SmartScene.objects.filter(id=smart_scene_id)
             if not smart_scene_qs.exists():
                 return response.json(173)
-            return response.json(0, list(smart_scene_qs))
+
+            msg = {}
+            if conditions_dict['type'] == 2:  # 条件为选择子设备
+                if not sub_device_id:
+                    return response.json(444, {'error param': 'subDeviceId'})
+                device_id = ''
+                sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('src_addr').first()
+                msg['smart_scene_id'] = smart_scene_id
+                msg['scene_status'] = 1
+                msg['sensor_type'] = conditions_dict['sensor']['device_type']
+                msg['sensor_src'] = int(sub_device_qs['src_addr'], 16)
+                msg['sensor_status'] = int(conditions_dict['sensor']['eventValues'][0]['event_type'])
+            else:
+                if not device_id:
+                    return response.json(444, {'error param': 'deviceId'})
+                sub_device_id = 0
+
+            task_list = []
+            for task in tasks_list:
+                task_temp = {
+                    'sensor_type': task['device_type'],
+                    'sensor_action': task['event_type']
+                }
+                task_sub_device_id = task.get('subDeviceId', None)
+                if task_sub_device_id:
+                    sub_device_qs = GatewaySubDevice.objects.filter(id=task_sub_device_id).values('src_addr').first()
+                    task_temp['sensor_src'] = int(sub_device_qs['src_addr'], 16)
+                task_list.append(task_temp)
+            msg['task'] = task_list
+
+
+            with transaction.atomic():
+                smart_scene_qs.update(scene_name=scene_name, conditions=conditions, tasks=tasks,
+                                      device_data=json.dumps(msg), updated_time=now_time, device_id=device_id,
+                                      sub_device_id=sub_device_id)
+
+                if is_all_day == 0 or is_all_day == 1:  # 不设置时间或全天
+                    smart_scene_qs.update(effective_time_id=0, is_all_day=is_all_day)
+                else:
+                    start_time = int(request_dict.get('startTime', None))
+                    end_time = int(request_dict.get('endTime', None))
+                    repeat = int(request_dict.get('repeat', None))
+                    effective_time_qs = EffectiveTime.objects.filter(start_time=start_time, end_time=end_time,
+                                                                     repeat=repeat).values('id')
+                    if effective_time_qs.exists():
+                        effective_time_id = effective_time_qs[0]['id']
+                    else:
+                        effective_time_id = EffectiveTime.objects.create(start_time=start_time, end_time=end_time,
+                                                                         repeat=repeat).id
+                    smart_scene_qs.update(effective_time_id=effective_time_id, is_all_day=is_all_day)
+                    effective_time = {
+                        'isAllDay': is_all_day,
+                        'startTime': start_time,
+                        'endTime': end_time,
+                        'repeat': repeat
+                    }
+            res['effectiveTime'] = effective_time
+            return response.json(0, res)
 
         except Exception as e:
             return response.json(500, repr(e))
@@ -419,4 +531,3 @@ class SmartSceneView(View):
             return response.json(500, repr(e))
         else:
             return response.json(0)
-

+ 108 - 75
Controller/SensorGateway/SubDeviceController.py

@@ -192,14 +192,14 @@ class GatewaySubDeviceView(View):
         except Exception as e:
             return response.json(500, repr(e))
 
-    @staticmethod
-    def records_tem_hum(request_dict, response):
+    @classmethod
+    def records_tem_hum(cls, request_dict, response):
         """
         查询温湿度传感器记录
         @param request_dict: 请求参数
         @request_dict gatewaySubId: 子设备id
         @request_dict cycle: 时间周期
-        @request_dict eventType: 事件类型, 18:温度,19:湿度
+        @request_dict eventType: 事件类型, 2200:温度,2201:湿度
         @param response: 响应对象
         @return: response
         """
@@ -208,78 +208,20 @@ class GatewaySubDeviceView(View):
         event_type = request_dict.get('eventType', None)
         if not all([sub_device_id, cycle, event_type]):
             return response.json(444, {'error param': 'gatewaySubId or cycle or eventType'})
+
         now_time = int(time.time())
+        # 判断event_type
+        event_type = int(event_type)
+        if event_type != 2200 or event_type != 2201:
+            return response.json(444, {'invalid eventType': event_type})
+
         try:
-            record_dict = OrderedDict()
+            record_dict = cls.get_record_dict(cycle, now_time, sub_device_id, event_type)
             record_list = []
-            if cycle == 'Hours':
-                start_time = now_time - 24 * 60 * 60
-                sensor_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
-                                                               event_type=event_type,
-                                                               created_time__range=(start_time, now_time)). \
-                    values('alarm', 'created_time').order_by('created_time')
-                if not sensor_record_qs.exists():
-                    return response.json(0, {'records': [], 'time': now_time})
-
-                for sensor_record in sensor_record_qs:
-                    created_time = time.strftime('%m/%d %H:%M %w', time.localtime(sensor_record['created_time']))
-                    hour = int(created_time[-7:-5])
-                    minute = int(created_time[-4:-2])
-                    if hour != 23 and minute > 30:  # 不为23时且分钟大于30,hour+1
-                        hour += 1
-                    alarm = float(sensor_record['alarm'])
-                    # 组织数据,record_dict:{"0": [1.0, 2.0, 3.0], "1": [1.0, 2.0, 3.0]...}
-                    if str(hour) in record_dict:
-                        record_dict[str(hour)].append(alarm)
-                    else:
-                        record_dict[str(hour)] = [alarm]
-
-            elif cycle == 'Week':
-                start_time = now_time - 24 * 60 * 60 * 7
-                sensor_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
-                                                               event_type=event_type,
-                                                               created_time__range=(start_time, now_time)). \
-                    values('alarm', 'created_time').order_by('created_time')
-                if not sensor_record_qs.exists():
-                    return response.json(0, {'records': [], 'time': now_time})
-
-                for sensor_record in sensor_record_qs:
-                    created_time = time.strftime('%m/%d %H:%M %w', time.localtime(sensor_record['created_time']))
-                    week = int(created_time[-1:])
-                    alarm = float(sensor_record['alarm'])
-                    # 组织数据,record_dict:{"0": [1.0, 2.0, 3.0], "1": [1.0, 2.0, 3.0]...}
-                    if str(week) in record_dict:
-                        record_dict[str(week)].append(alarm)
-                    else:
-                        record_dict[str(week)] = [alarm]
-
-            elif cycle == 'Month':
-                start_time = now_time - 24 * 60 * 60 * 30
-                sensor_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
-                                                               event_type=event_type,
-                                                               created_time__range=(start_time, now_time)). \
-                    values('alarm', 'created_time').order_by('created_time')
-                if not sensor_record_qs.exists():
-                    return response.json(0, {'records': [], 'time': now_time})
-
-                for sensor_record in sensor_record_qs:
-                    created_time = time.strftime('%m/%d %H:%M %w', time.localtime(sensor_record['created_time']))
-                    month = int(created_time[:2])
-                    day = int(created_time[3:5])
-                    date = str(month) + '/' + str(day)
-                    alarm = float(sensor_record['alarm'])
-                    # 组织数据,record_dict:{"0": [1.0, 2.0, 3.0], "1": [1.0, 2.0, 3.0]...}
-                    if date in record_dict:
-                        record_dict[date].append(alarm)
-                    else:
-                        record_dict[date] = [alarm]
-
-            else:
-                return response.json(444, {'error param': 'invalid cycle'})
-
-            # 组织响应数据列表,value为每 小时/天 的平均值
-            for k, v in record_dict.items():
-                record_list.append({'key': k, 'value': round(sum(v) / len(v), 1)})
+            if record_dict:
+                # 组织响应数据列表,value为每 小时/天 的平均值
+                for k, v in record_dict.items():
+                    record_list.append({'key': k, 'value': round(sum(v) / len(v), 1)})
 
             res = {
                 'records': record_list,
@@ -289,6 +231,81 @@ class GatewaySubDeviceView(View):
         except Exception as e:
             return response.json(500, repr(e))
 
+    @staticmethod
+    def get_record_dict(cycle, now_time, sub_device_id, event_type):
+        """
+        获取记录数据
+        @param cycle: 时间周期
+        @param now_time: 当前时间
+        @param sub_device_id: 子设备id
+        @param event_type: 事件类型, 2200:温度,2201:湿度
+        @return: record_dict: 记录数据
+        """
+        record_dict = OrderedDict()
+        if cycle == 'Hours':
+            start_time = now_time - 24 * 60 * 60
+            sensor_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
+                                                           event_type=event_type,
+                                                           created_time__range=(start_time, now_time)). \
+                values('alarm', 'created_time').order_by('created_time')
+            if not sensor_record_qs.exists():
+                return record_dict
+
+            for sensor_record in sensor_record_qs:
+                created_time = time.strftime('%m/%d %H:%M %w', time.localtime(sensor_record['created_time']))
+                hour = int(created_time[-7:-5])
+                minute = int(created_time[-4:-2])
+                if hour != 23 and minute > 30:  # 不为23时且分钟大于30,hour+1
+                    hour += 1
+                alarm = float(sensor_record['alarm'])
+                # 组织数据,record_dict:{"0": [1.0, 2.0, 3.0], "1": [1.0, 2.0, 3.0]...}
+                if str(hour) in record_dict:
+                    record_dict[str(hour)].append(alarm)
+                else:
+                    record_dict[str(hour)] = [alarm]
+
+        elif cycle == 'Week':
+            start_time = now_time - 24 * 60 * 60 * 7
+            sensor_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
+                                                           event_type=event_type,
+                                                           created_time__range=(start_time, now_time)). \
+                values('alarm', 'created_time').order_by('created_time')
+            if not sensor_record_qs.exists():
+                return record_dict
+
+            for sensor_record in sensor_record_qs:
+                created_time = time.strftime('%m/%d %H:%M %w', time.localtime(sensor_record['created_time']))
+                week = int(created_time[-1:])
+                alarm = float(sensor_record['alarm'])
+                # 组织数据,record_dict:{"0": [1.0, 2.0, 3.0], "1": [1.0, 2.0, 3.0]...}
+                if str(week) in record_dict:
+                    record_dict[str(week)].append(alarm)
+                else:
+                    record_dict[str(week)] = [alarm]
+
+        elif cycle == 'Month':
+            start_time = now_time - 24 * 60 * 60 * 30
+            sensor_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
+                                                           event_type=event_type,
+                                                           created_time__range=(start_time, now_time)). \
+                values('alarm', 'created_time').order_by('created_time')
+            if not sensor_record_qs.exists():
+                return record_dict
+
+            for sensor_record in sensor_record_qs:
+                created_time = time.strftime('%m/%d %H:%M %w', time.localtime(sensor_record['created_time']))
+                month = int(created_time[:2])
+                day = int(created_time[3:5])
+                date = str(month) + '/' + str(day)
+                alarm = float(sensor_record['alarm'])
+                # 组织数据,record_dict:{"1/1": [1.0, 2.0, 3.0], "1/2": [1.0, 2.0, 3.0]...}
+                if date in record_dict:
+                    record_dict[date].append(alarm)
+                else:
+                    record_dict[date] = [alarm]
+
+        return record_dict
+
     @staticmethod
     def records(request_dict, response):
         """
@@ -374,15 +391,31 @@ class GatewaySubDeviceView(View):
             return response.json(444, {'error param': 'gatewaySubId'})
 
         try:
-            sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('status', 'is_tampered')
+            sub_device_qs = GatewaySubDevice.objects.filter(id=sub_device_id).values('device_type', 'status',
+                                                                                     'is_tampered')
             if not sub_device_qs.exists():
                 return response.json(173)
             scene_count = SmartScene.objects.filter(sub_device_id=sub_device_id).count()
             res = {
                 'scene_count': scene_count,
-                'status': sub_device_qs[0]['status'],
-                'is_tampered': sub_device_qs[0]['is_tampered']
+                'status': sub_device_qs[0]['status']
             }
+
+            device_type = sub_device_qs[0]['device_type']
+            if device_type == 215 or device_type == 218 or device_type == 219:  # 门磁,烟雾,人体传感器返回拆动状态
+                res['is_tampered'] = sub_device_qs[0]['is_tampered']
+            elif device_type == 220:  # 温湿度传感器返回温湿度数据
+                tem_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
+                                                            event_type=2200).order_by('-created_time').values('alarm')[
+                                :1]
+                hum_record_qs = SensorRecord.objects.filter(gateway_sub_device_id=sub_device_id,
+                                                            event_type=2201).order_by('-created_time').values('alarm')[
+                                :1]
+                temperature = tem_record_qs[0]['alarm'] if tem_record_qs.exists() else ''
+                humidity = hum_record_qs[0]['alarm'] if tem_record_qs.exists() else ''
+                res['temperature'] = temperature
+                res['humidity'] = humidity
+
             return response.json(0, res)
         except Exception as e:
             return response.json(500, repr(e))

+ 33 - 0
Controller/SerialNumberController.py

@@ -50,6 +50,8 @@ class SerialNumberView(View):
             return self.do_create(request_dict, response)
         elif operation == 'changeSerialNumberStatus':
             return self.changeSerialNumberStatus(request_dict, response)
+        elif operation == 'getRegionInfo':
+            return self.get_region_info(request_dict, response)
         else:
             if token.code != 0:
                 return response.json(token.code)
@@ -163,8 +165,11 @@ class SerialNumberView(View):
                 if not isLock:
                     return response.json(5)
 
+                # 获取并判断region_id
                 region_id = request_dict.get('region_id', None)
                 region_id = int(region_id) if region_id else CommonService.confirm_region_id(request)
+                if region_id not in [1, 2, 3, 4]:
+                    return response.json(444, {'invalid region_id': region_id})
 
                 p2p_type = request_dict.get('p2ptype', 1)
                 if serial_number[9:10]:
@@ -431,3 +436,31 @@ class SerialNumberView(View):
             djangoLogger = logging.getLogger('django')
             djangoLogger.exception(repr(e))
             return response.json(500, str(e))
+
+    @staticmethod
+    def get_region_info(request_dict, response):
+        """
+        根据序列号状态确认uid地区
+        @param request_dict: 请求参数
+        @param response: 响应对象
+        @request_dict endTime: 结束时间
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        if not serial_number:
+            return response(444)
+        company_serial_qs = CompanySerialModel.objects.filter(serial_number=serial_number[:6]).values('status')
+        if not company_serial_qs.exists():
+            return response.json(173)
+        status = company_serial_qs[0]['status']
+        if status == 2:
+            if CONFIG_INFO == CONFIG_CN:
+                return response.json(0, {'region': 1})
+            elif CONFIG_INFO == CONFIG_US:
+                return response.json(0, {'region': 3})
+        elif status == 3:
+            if CONFIG_INFO == CONFIG_CN:
+                return response.json(0, {'region': 3})
+            elif CONFIG_INFO == CONFIG_US:
+                return response.json(0, {'region': 1})
+        return response.json(0)

+ 3 - 0
Controller/ShadowController.py

@@ -102,6 +102,7 @@ def update_device_shadow(request):
         is_human = request_dict.get('is_human', None)
         is_custom_voice = request_dict.get('is_custom', None)
         double_wifi = request_dict.get('double_wifi', None)
+        mobile_4g = request_dict.get('mobile4G', None)
         is_ptz = request_dict.get('is_ptz', None)
         us_qs = UidSetModel.objects.filter(uid=uid)
         is_ai = request_dict.get('is_ai', None)
@@ -139,6 +140,8 @@ def update_device_shadow(request):
             qs_dict['is_custom_voice'] = is_custom_voice
         if double_wifi:
             qs_dict['double_wifi'] = double_wifi
+        if mobile_4g:
+            qs_dict['mobile_4g'] = int(mobile_4g)
         if is_ptz:
             qs_dict['is_ptz'] = is_ptz
         if is_ai:

+ 34 - 6
Controller/UnicomCombo/UnicomComboController.py

@@ -18,7 +18,7 @@ from django.http import HttpResponse, JsonResponse
 from django.views.generic.base import View
 
 from Model.models import UnicomDeviceInfo, UnicomCombo, Pay_Type, Order_Model, Store_Meal, AiStoreMeal, \
-    UnicomComboOrderInfo, UnicomComboExperienceHistory
+    UnicomComboOrderInfo, UnicomComboExperienceHistory, UnicomDeviceStatusChangePush, SysMsgModel, UnicomFlowPush
 from Object.ResponseObject import ResponseObject
 from Object.TokenObject import TokenObject
 from Object.UnicomObject import UnicomObjeect
@@ -106,6 +106,7 @@ class UnicomComboView(View):
             if combo_order_qs.exists():
                 combo_order = combo_order_qs.first()
                 flow_details = {
+                    'flowInvalid': 0,
                     'iccid': iccid,
                     'status': combo_order['status'],
                     'comboName': combo_order['combo__combo_name'],
@@ -134,12 +135,16 @@ class UnicomComboView(View):
                     flow_details['usableFlow'] = flow_details['flowTotal'] - flow
 
                 flow_details['usableFlow'] = \
-                    flow_details['flowTotal'] if flow_details['usableFlow'] <= 0 else flow_details['usableFlow']
+                    0.00 if flow_details['usableFlow'] <= 0 else flow_details['usableFlow']
                 flow_details['usableFlow'] = Decimal(flow_details['usableFlow']).quantize(Decimal('0.00'))
                 flow_details.pop('flowTotalUsage')
                 cls.update_combo_order_sort(iccid)
                 flow_details['comboList'] = cls.get_combo_order_list(iccid)
                 return response.json(0, flow_details)
+            else:
+                flow_details = {'iccid': iccid, 'flowInvalid': 1, 'comboList': cls.get_combo_order_list(iccid)}
+                cls.update_combo_order_sort(iccid)
+                return response.json(0, flow_details)
         except Exception as e:
             print(e.args)
             ex = traceback.format_exc()
@@ -157,7 +162,7 @@ class UnicomComboView(View):
         combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid, is_del=False) \
             .values('iccid', 'status', 'combo__combo_name', 'combo__flow_total',
                     'combo__remark', 'combo__expiration_days', 'combo__expiration_type', 'flow_total_usage',
-                    'expire_time').order_by('sort', 'created_time')
+                    'expire_time').order_by('sort')
         for item in combo_order_qs:
             combo_list.append({
                 'iccid': iccid,
@@ -214,13 +219,21 @@ class UnicomComboView(View):
             with transaction.atomic():
                 device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid, serial_no=serial_no)
                 if device_info_qs.exists():
-                    device_info_qs.update(status=1, updated_time=now_time)
+                    flow_push_qs = UnicomFlowPush.objects.filter(serial_no=serial_no)
+                    if flow_push_qs.exists():
+                        flow_push_qs.delete()
+                    sys_msg_qs = SysMsgModel.objects.filter(uid=serial_no)
+                    if sys_msg_qs.exists():
+                        sys_msg_qs.delete()
+                    device_info_qs.update(status=1, updated_time=now_time, user_id='')
+
                     combo_order_qs = UnicomComboOrderInfo.objects.filter(iccid=iccid)
                     if combo_order_qs.exists():
                         combo_order_qs.delete()
                     combo_experience_history_qs = UnicomComboExperienceHistory.objects.filter(iccid=iccid)
                     if combo_experience_history_qs.exists():
                         combo_experience_history_qs.delete()
+
                 return response.json(0)
         except Exception as e:
             print(e.args)
@@ -587,8 +600,23 @@ class UnicomComboView(View):
                 dict_data.pop('sign')
                 unicom_obj = UnicomObjeect()
                 generate_sign = unicom_obj.createSign(**dict_data)
-                logger.info('设备状态变更推送请求签名{}'.format(sign))
-                logger.info('设备状态变更推送生成签名{}'.format(generate_sign))
+                logger.info('联通设备状态变更推送请求签名{}'.format(sign))
+                logger.info('联通设备状态变更推送生成签名{}'.format(generate_sign))
+                assert generate_sign == sign
+                now_time = int(time.time())
+                re_data = {
+                    'iccid': dict_data['iccid'],
+                    'serial_no': dict_data['serialNo'],
+                    'sign': sign,
+                    'type': dict_data['type'],
+                    'previous_val': dict_data['previousVal'],
+                    'current_val': dict_data['currentVal'],
+                    'reason': dict_data['reason'],
+                    'time': dict_data['time'],
+                    'updated_time': now_time,
+                    'created_time': now_time
+                }
+                UnicomDeviceStatusChangePush.objects.create(**re_data)
             r_data = {'success': True, 'msg': '成功'}
             return HttpResponse(json.dumps(r_data, ensure_ascii=False), content_type="application/json,charset=utf-8")
         except Exception as e:

+ 82 - 40
Controller/UnicomCombo/UnicomComboTaskController.py

@@ -14,7 +14,7 @@ from django.db import transaction
 from django.db.models import Q
 from django.views import View
 
-from Model.models import UnicomComboOrderInfo, UnicomCombo, Order_Model, UnicomDeviceInfo
+from Model.models import UnicomComboOrderInfo, UnicomCombo, Order_Model, UnicomDeviceInfo, UnicomFlowPush
 from Object.ResponseObject import ResponseObject
 from Object.UnicomObject import UnicomObjeect
 
@@ -94,7 +94,7 @@ class UnicomComboTaskView(View):
                         logger.info('激活成功,订单编号:{}'.format(order_id))
             return response.json(0)
         except Exception as e:
-            logger.info('次月激活套餐异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            logger.info('出错了~次月激活套餐异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(177, repr(e))
 
     @classmethod
@@ -106,59 +106,101 @@ class UnicomComboTaskView(View):
         logger = logging.getLogger('info')
         logger.info('--->进入监控流量使用情况')
         try:
+            unicom_api = UnicomObjeect()
             combo_order_qs = UnicomComboOrderInfo.objects.filter(status=1, is_del=False).values()
             if not combo_order_qs.exists():
                 return response.json(0)
             today = datetime.datetime.today()
             year = today.year
             month = today.month
-            unicom_api = UnicomObjeect()
             now_time = int(time.time())
             for item in combo_order_qs:
                 iccid = item['iccid']
+                u_device_info_qs = UnicomDeviceInfo.objects.filter(iccid=iccid)
+                if not u_device_info_qs.exists():
+                    continue
+                u_device_info_qs = u_device_info_qs.first()
                 usage_flow = float(item['flow_total_usage']) if item['flow_total_usage'] else 0.0
                 combo_id = item['combo_id']
                 combo_qs = UnicomCombo.objects.filter(id=combo_id).values()
-                if combo_qs.exists():
-                    combo_qs = combo_qs.first()
-                    flow_total = combo_qs['flow_total']
-                    # 查询当前月用量历史
-                    month_usage_flow = unicom_api.get_flow_usage_total(year, month, iccid)
-                    logger.info('--->{}-{},iccid:{};套餐总值:{},激活时当月用量值:{},月已用量:{}'
-                                .format(year, month, iccid, flow_total, usage_flow, month_usage_flow))
-                    is_expire = False
-                    if item['year'] == year and item['month'] == month:
-                        if month_usage_flow > 0:
-                            # 初始套餐已使用流量 + 套餐总流量
-                            flow = usage_flow + flow_total
-                            if month_usage_flow >= flow:
-                                is_expire = True
-                    else:
-                        activate_year = item['year']
-                        activate_month = item['month']
-                        # 上月使用流量
-                        last_usage_flow = unicom_api.get_flow_usage_total(activate_year, activate_month, iccid)
-                        # 上月套餐实际使用量
-                        actual_usage_flow = last_usage_flow - usage_flow
-                        # 剩余
-                        surplus_flow = flow_total - actual_usage_flow
-                        if month_usage_flow > 0:
-                            if month_usage_flow >= surplus_flow:
-                                is_expire = True
-                    # 检查是否有当月未使用套餐 没有则停卡
-                    if is_expire:
-                        UnicomComboOrderInfo.objects.filter(id=item['id']).update(status=2, updated_time=now_time)
-                        activate_status = cls.query_unused_combo_and_activate(iccid, year, month,
-                                                                              month_usage_flow)
-                        if not activate_status:
-                            # 停用
-                            unicom_api.change_device_to_disable(iccid)
+                if not combo_qs.exists():
+                    continue
+                combo_qs = combo_qs.first()
+                flow_total = combo_qs['flow_total']
+                # 查询当前月用量历史
+                month_usage_flow = unicom_api.get_flow_usage_total(year, month, iccid)
+                logger.info('--->{}-{},iccid:{};套餐总值:{},激活时当月用量值:{},月已用量:{}'
+                            .format(year, month, iccid, flow_total, usage_flow, month_usage_flow))
+                is_expire = False
+                if item['year'] == year and item['month'] == month:
+                    if month_usage_flow > 0:
+                        # 初始套餐已使用流量 + 套餐总流量
+                        flow = usage_flow + flow_total
+                        if month_usage_flow >= flow:
+                            is_expire = True
+                    usage = (month_usage_flow - usage_flow) if month_usage_flow > usage_flow else 0
+                    cls.flow_warning_push(u_device_info_qs.user_id, u_device_info_qs.serial_no, item['id'], flow_total,
+                                          usage)
+                else:
+                    activate_year = item['year']
+                    activate_month = item['month']
+                    # 上月使用流量
+                    last_usage_flow = unicom_api.get_flow_usage_total(activate_year, activate_month, iccid)
+                    # 上月套餐实际使用量
+                    actual_usage_flow = last_usage_flow - usage_flow
+                    # 剩余
+                    surplus_flow = flow_total - actual_usage_flow
+                    if month_usage_flow > 0:
+                        if month_usage_flow >= surplus_flow:
+                            is_expire = True
+                    usage = (month_usage_flow + last_usage_flow - usage_flow) \
+                        if (month_usage_flow + last_usage_flow) > usage_flow else 0
+                    cls.flow_warning_push(u_device_info_qs.user_id, u_device_info_qs.serial_no, item['id'], flow_total,
+                                          usage)
+                # 检查是否有当月未使用套餐 没有则停卡
+                if is_expire:
+                    UnicomComboOrderInfo.objects.filter(id=item['id']).update(status=2, updated_time=now_time)
+                    activate_status = cls.query_unused_combo_and_activate(iccid, year, month,
+                                                                          month_usage_flow)
+                    if not activate_status:
+                        # 停用
+                        unicom_api.change_device_to_disable(iccid)
 
             return response.json(0)
         except Exception as e:
-            logger.info('检测流量用量详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            logger.info('出错了~检测流量用量详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(177, repr(e))
 
+    @staticmethod
+    def flow_warning_push(app_user_id, serial_no, combo_order_id, flow_total, flow_usage):
+        """
+        监控流量使用大于85%and小于96%进行消息推送提醒
+        @param app_user_id: app用户id
+        @param serial_no: 序列号
+        @param combo_order_id: 当前套餐订单id
+        @param flow_total: 流量总量
+        @param flow_usage: 已使用流量
+        @return:
+        """
+        logger = logging.getLogger('info')
+        try:
+            if not app_user_id:
+                return False
+            if 0 < flow_total and 0 < flow_usage < flow_total:
+                res = flow_usage / flow_total * 100
+                if 85 < res <= 95:
+                    flow_push = UnicomFlowPush.objects.filter(serial_no=serial_no, combo_order_id=combo_order_id)
+                    if not flow_push.exists():
+                        now_time = int(time.time())
+                        push_data = {'combo_order_id': str(combo_order_id), 'serial_no': serial_no,
+                                     'flow_total_usage': flow_usage, 'flow_total': flow_total, 'status': 0,
+                                     'updated_time': now_time,
+                                     'created_time': now_time, 'user_id': app_user_id}
+                        UnicomFlowPush.objects.create(**push_data)
+            return True
+        except Exception as e:
+            logger.info('出错了~异常流量监控,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+
     @staticmethod
     def query_unused_combo_and_activate(iccid, year, month, usage_flow):
         """
@@ -194,7 +236,7 @@ class UnicomComboTaskView(View):
             UnicomComboOrderInfo.objects.filter(id=combo_order.id).update(**upd_data)
             return True
         except Exception as e:
-            logger.info('检测流量用量详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            logger.info('出错了~检测流量用量详情异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return False
 
     @classmethod
@@ -226,7 +268,7 @@ class UnicomComboTaskView(View):
                     iccid_list.append(icc_id)
                     logger.info('--->当前流量套餐已过期,iccid:{}'.format(icc_id))
                 except Exception as e:
-                    logger.info('监控流量到期异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+                    logger.info('出错了~监控流量到期异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
                     continue
         # set无序不重复元素集
         iccid_list = list(set(iccid_list))

+ 27 - 4
Model/models.py

@@ -1184,6 +1184,7 @@ class UidSetModel(models.Model):
     is_human = models.IntegerField(default=0, verbose_name='是否支持人形追踪。0:不支持,1:支持')
     is_custom_voice = models.IntegerField(default=0, verbose_name='是否支持自定义语音。0:不支持,1:支持')
     double_wifi = models.IntegerField(default=0, verbose_name='是否支持双频wifi。0:不支持,1:支持')
+    mobile_4g = models.IntegerField(default=0, verbose_name='是否支持4g。0:不支持,1:支持')
     is_ptz = models.IntegerField(default=0, verbose_name='是否支持云台。0:不支持,1:支持')
     is_ai = models.IntegerField(default=2, verbose_name='是否支持ai')  # 0,关闭,1开启,2,不支持
     is_notification = models.IntegerField(blank=True, default=1, verbose_name='新加-消息提醒开关')  # 0:关闭,1:开启
@@ -2630,11 +2631,11 @@ class SmartScene(models.Model):
     sub_device_id = models.IntegerField(default=0, verbose_name=u'关联子设备表id')
     scene_name = models.CharField(default='', max_length=100, verbose_name=u'场景名称')
     conditions = models.TextField(default='', verbose_name=u'条件')
-    tasks = models.TextField(default='',  verbose_name=u'任务')
+    tasks = models.TextField(default='', verbose_name=u'任务')
     is_all_day = models.SmallIntegerField(default=0, verbose_name=u'是否全天')  # 0: 不设置时间, 1: 全天, 2: 非全天
     effective_time_id = models.IntegerField(default=0, verbose_name=u'关联场景执行时间id')
     is_enable = models.BooleanField(default=True, verbose_name=u'是否开启')
-    device_data = models.CharField(default='', max_length=255, verbose_name=u'设备场景数据')
+    device_data = models.TextField(default='', verbose_name=u'设备场景数据')
     created_time = models.IntegerField(default=0, verbose_name='创建时间')
     updated_time = models.IntegerField(default=0, verbose_name='更新时间')
 
@@ -2668,6 +2669,7 @@ class UnicomCombo(models.Model):
     expiration_type = models.SmallIntegerField(default=0, verbose_name=u'有效期类型,0=天,1=月,2=年')
     pay_type = models.ManyToManyField(to='Pay_Type', verbose_name='付款类型', db_table='unicom_combo_pay_type')
     price = models.CharField(blank=True, max_length=32, verbose_name=u'价格')
+    is_unlimited = models.SmallIntegerField(default=0, verbose_name=u'是否无限流量,,0:有限流量,1:无限流量')
     sort = models.IntegerField(default=0, blank=True, verbose_name=u'排序,越小越靠前')
     remark = models.TextField(blank=True, default='', verbose_name=u'描述信息')
     updated_time = models.IntegerField(default=0, verbose_name='更新时间')
@@ -2712,6 +2714,7 @@ class UnicomDeviceInfo(models.Model):
     status = models.SmallIntegerField(default=0, verbose_name=u'状态{0:可测试,1:测试完成,2:已使用}')
     serial_no = models.CharField(default='', max_length=32, verbose_name=u'设备序列号')
     user_id = models.CharField(blank=True, max_length=32, verbose_name=u'用户id')
+    card_type = models.SmallIntegerField(default=0, verbose_name=u'状态{0:联通,1:电信,2:移动}')
     main_card = models.SmallIntegerField(default=0, verbose_name=u'状态{0:主卡,1:拔插卡}')
     updated_time = models.IntegerField(default=0, verbose_name='更新时间')
     created_time = models.IntegerField(default=0, verbose_name='创建时间')
@@ -2726,7 +2729,7 @@ class UnicomDeviceQueueMonitoringPush(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记Id')
     iccid = models.CharField(default='', max_length=32, verbose_name=u'完整的20位纯数字ICCID')
     serial_no = models.CharField(default='', max_length=32, verbose_name=u'序列号')
-    sign = models.CharField(default='', max_length=32, verbose_name=u'验证签名')
+    sign = models.CharField(default='', max_length=128, verbose_name=u'验证签名')
     time = models.CharField(default='', max_length=32, verbose_name=u'推送时间(yyyymmddhhmiss)')
     type = models.CharField(default='', max_length=32, verbose_name=u'推送类型:DEVICE_QUEUE_MONITORING:设队列监控;')
     current_renew_list_id = models.CharField(default='', max_length=32, verbose_name=u'队列ID')
@@ -2744,7 +2747,7 @@ class UnicomDeviceStatusChangePush(models.Model):
     id = models.AutoField(primary_key=True, verbose_name=u'自增标记Id')
     iccid = models.CharField(default='', max_length=32, verbose_name=u'完整的20位纯数字ICCID')
     serial_no = models.CharField(default='', max_length=32, verbose_name=u'序列号')
-    sign = models.CharField(default='', max_length=32, verbose_name=u'验证签名')
+    sign = models.CharField(default='', max_length=128, verbose_name=u'验证签名')
     time = models.CharField(default='', max_length=32, verbose_name=u'推送时间(yyyymmddhhmiss)')
     # 变更类型: DEVICE_REAL_NAME_STATUS_CHANGE:实名状态变更;DEVICE_STATUS_CHANGE:设备状态变更;
     type = models.CharField(default='', max_length=32, verbose_name=u'变更类型')
@@ -2773,3 +2776,23 @@ class UnicomComboExperienceHistory(models.Model):
         db_table = 'unicom_combo_experience_history'
         verbose_name = '联通套餐体验历史表'
         verbose_name_plural = verbose_name
+
+
+class UnicomFlowPush(models.Model):
+    id = models.AutoField(primary_key=True)
+    user_id = models.CharField(default='', max_length=32, verbose_name=u'用户id')
+    # 0: 剩余10%流量预警, 1: 流量到期
+    type = models.SmallIntegerField(default=0, verbose_name='流量推送类型')
+    combo_order_id = models.CharField(max_length=32, default='', verbose_name='当前订单套餐id')
+    serial_no = models.CharField(max_length=32, default='', verbose_name='序列号')
+    flow_total_usage = models.DecimalField(default=0, max_digits=10, decimal_places=2, verbose_name=u'当月实际流量用量 单位(MB)')
+    flow_total = models.DecimalField(default=0, max_digits=10, decimal_places=2, verbose_name=u'流量总量 单位(MB)')
+    status = models.SmallIntegerField(default=0, verbose_name=u'状态{0:待推送,1:已推送}')
+    updated_time = models.IntegerField(default=0, verbose_name='更新时间')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 'unicom_flow_push'
+        verbose_name = '联通流量用量推送'
+        verbose_name_plural = verbose_name
+        app_label = "PushModel"

+ 2 - 2
Object/ResponseObject.py

@@ -100,7 +100,7 @@ class ResponseObject(object):
             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',
             10043: 'The device does not registered a certificate',
-            10044: 'Request to publish MQTT topic message failed',
+            10044: 'Failed to publish MQTT message',
             10045: 'Already the latest version',
             10046: 'Sorry, users who have activated cloud storage packages do not support logout at the moment, please contact customer service',
             10047: 'Please delete all devices under your account first',
@@ -207,7 +207,7 @@ class ResponseObject(object):
             10041: '此设备已购买过国内云存套餐,无法购买国外云存套餐',
             10042: '此设备已注册证书',
             10043: '此设备没有注册证书',
-            10044: '请求发布MQTT主题消息失败',
+            10044: '发布MQTT消息失败',
             10045: '当前为最新版本',
             10046: '已开通云存的用户,暂不支持注销,请联系客服',
             10047: '请先删除您当前帐户下的所有设备',