Browse Source

Merge branch 'test' of http://192.168.136.99:3000/servers/ASJServer into locky

locky 2 years ago
parent
commit
51e02b478f

+ 2 - 1
Ansjer/server_urls/loocam_url.py

@@ -9,7 +9,7 @@
 from django.urls import re_path
 from django.urls import re_path
 
 
 from Controller.SensorGateway import GatewayFamilyRoomController, SubDeviceController, GatewayFamilyMemberController, \
 from Controller.SensorGateway import GatewayFamilyRoomController, SubDeviceController, GatewayFamilyMemberController, \
-    EquipmentFamilyController, GatewayDeviceController, SmartSceneController
+    EquipmentFamilyController, GatewayDeviceController, SmartSceneController, SmartSocketController
 
 
 urlpatterns = [
 urlpatterns = [
     re_path(r'^sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
     re_path(r'^sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
@@ -19,4 +19,5 @@ urlpatterns = [
     re_path(r'^gateway/subdevice/(?P<operation>.*)$', SubDeviceController.GatewaySubDeviceView.as_view()),
     re_path(r'^gateway/subdevice/(?P<operation>.*)$', SubDeviceController.GatewaySubDeviceView.as_view()),
     re_path(r'^gateway/device/info/(?P<operation>.*)$', GatewayDeviceController.GatewayDeviceView.as_view()),
     re_path(r'^gateway/device/info/(?P<operation>.*)$', GatewayDeviceController.GatewayDeviceView.as_view()),
     re_path(r'^smartscene/(?P<operation>.*)$', SmartSceneController.SmartSceneView.as_view()),
     re_path(r'^smartscene/(?P<operation>.*)$', SmartSceneController.SmartSceneView.as_view()),
+    re_path(r'^open/socket/(?P<operation>.*)$', SmartSocketController.SmartSocketView.as_view()),
 ]
 ]

+ 2 - 1
Ansjer/urls.py

@@ -25,7 +25,7 @@ from Controller import FeedBack, EquipmentOTA, EquipmentInfo, AdminManage, AppIn
     DeviceLogController, CouponController, AiController, ShadowController, SuperPasswordTool
     DeviceLogController, CouponController, AiController, ShadowController, SuperPasswordTool
 from Controller.Cron import CronTaskController
 from Controller.Cron import CronTaskController
 from Controller.MessagePush import EquipmentMessagePush
 from Controller.MessagePush import EquipmentMessagePush
-from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController
+from Controller.SensorGateway import SensorGatewayController, EquipmentFamilyController, SmartSocketStatisticsController
 from Controller.Surveys import CloudStorageController
 from Controller.Surveys import CloudStorageController
 from Controller.UserDevice import UserDeviceShareController
 from Controller.UserDevice import UserDeviceShareController
 
 
@@ -248,6 +248,7 @@ urlpatterns = [
     re_path(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
     re_path(r'^api/device/share/(?P<operation>.*)$', UserDeviceShareController.UserDeviceShareView.as_view()),
     re_path(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
     re_path(r'^app/sensor/gateway/(?P<operation>.*)$', EquipmentFamilyController.EquipmentFamilyView.as_view()),
     re_path(r'^loocam/', include("Ansjer.server_urls.loocam_url")),
     re_path(r'^loocam/', include("Ansjer.server_urls.loocam_url")),
+    re_path(r'^api/loocam/', include("Ansjer.server_urls.loocam_url")),
     re_path(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
     re_path(r'^unicom/', include("Ansjer.server_urls.unicom_url")),
     re_path(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
     re_path(r'^algorithm-shop/', include("Ansjer.server_urls.algorithm_shop_url")),
     re_path(r'^kvs/', include("Ansjer.server_urls.kvs_url")),
     re_path(r'^kvs/', include("Ansjer.server_urls.kvs_url")),

+ 28 - 15
Controller/DetectControllerV2.py

@@ -161,21 +161,34 @@ class DetectControllerViewV2(View):
 
 
             # 初始化UidPushModel推送表
             # 初始化UidPushModel推送表
             if electricity_status:
             if electricity_status:
-                uid_push_create_dict = {
-                    'uid_set_id': uid_set_id,
-                    'userID_id': userID,
-                    'appBundleId': appBundleId,
-                    'app_type': app_type,
-                    'push_type': push_type,
-                    'token_val': token_val,
-                    'm_code': m_code,
-                    'addTime': nowTime,
-                    'updTime': nowTime,
-                    'lang': lang,
-                    'tz': tz
-                }
-                # 绑定设备推送
-                UidPushModel.objects.create(**uid_push_create_dict)
+                uid_push_qs = UidPushModel.objects.filter(userID_id=userID, m_code=m_code, uid_set__uid=uid)
+                if uid_push_qs.exists():
+                    uid_push_update_dict = {
+                        'appBundleId': appBundleId,
+                        'app_type': app_type,
+                        'push_type': push_type,
+                        'token_val': token_val,
+                        'updTime': nowTime,
+                        'lang': lang,
+                        'tz': tz
+                    }
+                    uid_push_qs.update(**uid_push_update_dict)
+                else:
+                    uid_push_create_dict = {
+                        'uid_set_id': uid_set_id,
+                        'userID_id': userID,
+                        'appBundleId': appBundleId,
+                        'app_type': app_type,
+                        'push_type': push_type,
+                        'token_val': token_val,
+                        'm_code': m_code,
+                        'addTime': nowTime,
+                        'updTime': nowTime,
+                        'lang': lang,
+                        'tz': tz
+                    }
+                    # 绑定设备推送
+                    UidPushModel.objects.create(**uid_push_create_dict)
                 return response.json(0)
                 return response.json(0)
 
 
             if status == 0:
             if status == 0:

+ 62 - 4
Controller/EquipmentManagerV3.py

@@ -11,7 +11,8 @@ from django.db import transaction
 from django.db.models import Q
 from django.db.models import Q
 from django.views.generic.base import View
 from django.views.generic.base import View
 
 
-from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
+from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY, SERVER_DOMAIN_LIST, SERVER_DOMAIN_TEST, \
+    SERVER_DOMAIN_CN, SERVER_DOMAIN_US, SERVER_DOMAIN_EUR
 from Controller.CheckUserData import RandomStr
 from Controller.CheckUserData import RandomStr
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
 from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView
@@ -47,6 +48,10 @@ class EquipmentManagerV3(View):
 
 
         if operation == 'notLoginMainUserDevice':
         if operation == 'notLoginMainUserDevice':
             return self.not_login_do_mainUserDevice(request_dict, response)
             return self.not_login_do_mainUserDevice(request_dict, response)
+        elif operation == 'notLoginUserDevice':
+            return self.not_login_get_mainUserDevice(request_dict, response)
+        elif operation == 'notLoginGlobalUserDevice':
+            return self.not_login_get_global_mainUserDevice(request_dict, response)
         elif operation == 'notLoginMainDelDevice':
         elif operation == 'notLoginMainDelDevice':
             return self.test_tool_del_device(request_dict, response)
             return self.test_tool_del_device(request_dict, response)
 
 
@@ -116,7 +121,10 @@ class EquipmentManagerV3(View):
         View_Password = '' if Type in dvr_type_list else 'admin'
         View_Password = '' if Type in dvr_type_list else 'admin'
 
 
         id = CommonService.getUserID(getUser=False)
         id = CommonService.getUserID(getUser=False)
-        userName = Device_User.objects.get(userID=userID).username
+        device_user_qs = Device_User.objects.filter(userID=userID).values('username')
+        if not device_user_qs.exists():
+            return response.json(173)
+        userName = device_user_qs[0]['username']
         main_exist = Device_Info.objects.filter(UID=UID)
         main_exist = Device_Info.objects.filter(UID=UID)
         main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
         main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
 
 
@@ -359,7 +367,10 @@ class EquipmentManagerV3(View):
                         device_info_qs.delete()
                         device_info_qs.delete()
 
 
                 id = CommonService.getUserID(getUser=False)
                 id = CommonService.getUserID(getUser=False)
-                userName = Device_User.objects.get(userID=userID).username
+                device_user_qs = Device_User.objects.filter(userID=userID).values('username')
+                if not device_user_qs.exists():
+                    return response.json(173)
+                userName = device_user_qs[0]['username']
                 main_exist = Device_Info.objects.filter(UID=UID)
                 main_exist = Device_Info.objects.filter(UID=UID)
                 main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
                 main_exist = main_exist.filter(~Q(vodPrimaryUserID='')).values('vodPrimaryUserID', 'vodPrimaryMaster')
 
 
@@ -955,7 +966,7 @@ class EquipmentManagerV3(View):
         if dvq.exists():
         if dvq.exists():
             qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username',
             qs = Device_User.objects.filter(userID=dvq[0]['vodPrimaryUserID']).values('userID', 'NickName', 'username',
                                                                                       'userEmail', 'phone')
                                                                                       'userEmail', 'phone')
-            NickName = qs[0]['username']
+            NickName = qs[0]['NickName']
             phone = qs[0]['phone']
             phone = qs[0]['phone']
             username = qs[0]['username']
             username = qs[0]['username']
             qs = CommonService.qs_to_list(qs)
             qs = CommonService.qs_to_list(qs)
@@ -965,6 +976,53 @@ class EquipmentManagerV3(View):
                 qs[0]['phone'] = NickName
                 qs[0]['phone'] = NickName
         return response.json(0, qs)
         return response.json(0, qs)
 
 
+    def not_login_get_mainUserDevice(self, request_dict, response):
+        UID = request_dict.get('UID')
+        token = request_dict.get('token', None)
+        time_stamp = request_dict.get('time_stamp', None)
+
+        if not all([token, time_stamp]):
+            return response.json(444)
+
+        # 时间戳token校验
+        if not CommonService.check_time_stamp_token(token, time_stamp):
+            return response.json(13)
+
+        dvq = Device_Info.objects.filter(UID=UID).values('userID', 'userID__NickName', 'userID__username',
+                                                         'userID__userEmail', 'userID__phone',
+                                                         'vodPrimaryUserID')
+        qs = []
+        for item in dvq:
+            user_dict = {
+                'userID': item['userID'],
+                'NickName': item['userID__NickName'] if item['userID__NickName'] else item['userID__username'],
+                'username': item['userID__username'],
+                'userEmail': item['userID__userEmail'],
+                'phone': item['userID__phone'] if item['userID__phone'] else item['userID__NickName'],
+                'vodPrimaryUserID': item['vodPrimaryUserID']
+            }
+            qs.append(user_dict)
+        return response.json(0, qs)
+
+    def not_login_get_global_mainUserDevice(self, request_dict, response):
+        orders_domain_name_list = SERVER_DOMAIN_LIST
+        if SERVER_DOMAIN_TEST in orders_domain_name_list:
+            orders_domain_name_list.remove(SERVER_DOMAIN_TEST)
+        uid_list = []
+        try:
+            for orders_domain_name in orders_domain_name_list:
+                url = orders_domain_name + 'v3/equipment/notLoginUserDevice'
+                res = requests.post(url=url, data=request_dict)
+                result = res.json()
+                if result['result_code'] != 0:
+                    return response.json(result['result_code'])
+                for item in result['result']:
+                    item['domain_name'] = orders_domain_name
+                    uid_list.append(item)
+            return response.json(0, uid_list)
+        except Exception as e:
+            return response.json(500, repr(e))
+
     @staticmethod
     @staticmethod
     def test_tool_del_device(request_dict, response):
     def test_tool_del_device(request_dict, response):
         """
         """

+ 9 - 1
Controller/SensorGateway/EquipmentFamilyController.py

@@ -17,6 +17,7 @@ from django.views.generic.base import View
 
 
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Ansjer.config import OSS_STS_ACCESS_SECRET, OSS_STS_ACCESS_KEY
 from Controller.DeviceConfirmRegion import Device_Region
 from Controller.DeviceConfirmRegion import Device_Region
+from Controller.SensorGateway.SmartSocketController import SmartSocketView
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
 from Model.models import Device_Info, UID_Bucket, UID_Preview, UidSetModel, UidChannelSetModel, \
     iotdeviceInfoModel, UIDModel, Device_User, UserFamily, FamilyMember, FamilyMemberPermission, \
     iotdeviceInfoModel, UIDModel, Device_User, UserFamily, FamilyMember, FamilyMemberPermission, \
     FamilyRoomDevice, FamilyRoom, FamilyMemberJoin, GatewaySubDevice, CountryModel
     FamilyRoomDevice, FamilyRoom, FamilyMemberJoin, GatewaySubDevice, CountryModel
@@ -216,7 +217,14 @@ class EquipmentFamilyView(View):
                         'tb_country': country
                         'tb_country': country
                     }
                     }
                     UidSetModel.objects.create(**uid_set_create_dict)
                     UidSetModel.objects.create(**uid_set_create_dict)
-                return response.json(0)
+                if device_type == 201:  # 添加插座信息
+                    SmartSocketView.save_socket_switch(device_id, serial_number, 0)
+                res = {
+                    'deviceId': device_id,
+                    'nickName': nick_name,
+                    'serialNumber': serial_number
+                }
+                return response.json(0, res)
         except Exception as e:
         except Exception as e:
             print(e)
             print(e)
             return response.json(177, repr(e))
             return response.json(177, repr(e))

+ 599 - 0
Controller/SensorGateway/SmartSocketController.py

@@ -0,0 +1,599 @@
+# -*- encoding: utf-8 -*-
+"""
+@File    : SmartSocketController.py
+@Time    : 2023/3/17 11:52
+@Author  : stephen
+@Email   : zhangdongming@asj6.wecom.work
+@Software: PyCharm
+"""
+import datetime
+import logging
+import time
+from decimal import Decimal
+
+from django.db import transaction
+from django.http import QueryDict
+from django.views import View
+
+from Model.models import SocketInfo, SocketSchedule, Device_Info, UidSetModel, SocketPowerStatistics
+from Object.ResponseObject import ResponseObject
+from Object.utils import LocalDateTimeUtil
+from Service.CommonService import CommonService
+
+LOGGER = logging.getLogger('info')
+SOCKET_TOPIC_NAME = 'loocam/smart-socket/{}'  # 插座发布消息主题(因设备当前版本只能订阅一个主题)
+
+
+class SmartSocketView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def delete(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        delete = QueryDict(request.body)
+        if not delete:
+            delete = request.GET
+        return self.validation(delete, request, operation)
+
+    def put(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        put = QueryDict(request.body)
+        return self.validation(put, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        ResponseObject('cn')
+        if operation == 'savePowerStatistics':  # 保存电量上报统计
+            return self.save_power_statistics(request_dict, ResponseObject('cn'))
+        token_code, user_id, response = CommonService \
+            .verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        if operation == 'saveSwitch':  # 添加插座开关
+            return self.save_switch(request_dict, response)
+        elif operation == 'saveCountDown':  # 添加插座倒计时
+            return self.save_count_down(request_dict, response)
+        elif operation == 'saveSchedule':  # 添加插座排程
+            return self.save_socket_schedule(request_dict, response)
+        elif operation == 'get-today-scene':  # 查询当天插座电量
+            return self.get_today_scene(request_dict, response)
+        elif operation == 'get-all-scene':  # 统计智能插座电量
+            return self.get_all_scene(request_dict, response)
+        elif operation == 'get-socket-schedule':  # 智能插座排程记录查询
+            return self.get_socket_schedule(request_dict, response)
+        elif operation == 'get-log':  # 智能插座开关日志记录查询
+            return self.get_log(request_dict, response, user_id)
+        elif operation == 'editor-socket-device':  # 编辑设备信息
+            return self.editor_socket_device(request_dict, response, user_id)
+        return response.json(404)
+
+    @classmethod
+    def save_power_statistics(cls, request_dict, response):
+        """
+        保存设备上报电量统计
+        """
+        try:
+            serial_number = request_dict.get('serialNumber', None)
+            electricity = request_dict.get('electricity', 0.00)
+            power = request_dict.get('power', 0.00)
+            accumulated_time = request_dict.get('accumulatedTime', None)
+            device_time = request_dict.get('deviceTime', None)
+            LOGGER.info('{}上报电量统计data:{}'.format(serial_number, request_dict))
+            if not all([serial_number, electricity, power, accumulated_time, device_time]):
+                return response.json(444)
+            device_time = int(device_time)
+            electricity = Decimal(electricity).quantize(Decimal("0.00"))
+            power = Decimal(power).quantize(Decimal("0.00"))
+            accumulated_time = int(accumulated_time)
+            now_time = int(time.time())
+            start_time, end_time = LocalDateTimeUtil.get_today_date(True)
+            # 查询当前序列号当天是否有上传过电量统计
+            power_qs = SocketPowerStatistics.objects.filter(serial_number=serial_number,
+                                                            created_time__gt=start_time,
+                                                            created_time__lte=end_time)
+            data = {
+                'electricity': electricity,
+                'power': power,
+                'accumulated_time': accumulated_time,
+                'updated_time': now_time
+            }
+            if not power_qs.exists():  # 添加插座上报电量统计
+                socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number).values('device_id')
+                if not socket_info_qs.exists():
+                    return response.json(173)
+                data['device_id'] = socket_info_qs[0]['device_id']
+                data['created_time'] = device_time
+                data['serial_number'] = serial_number
+                SocketPowerStatistics.objects.create(**data)
+                return response.json(0)
+            # 更新当天电量统计
+            power_qs.update(**data)
+            return response.json(0)
+        except Exception as e:
+            LOGGER.info('智能插座电量存库异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return response.json(177)
+
+    @staticmethod
+    def get_serial_number_by_device_id(deviceId):
+        """
+        根据设备ID获取序列号
+        """
+        device_info = Device_Info.objects.get(id=deviceId)
+        return device_info.serial_number
+
+    @classmethod
+    def save_switch(cls, request_dict, response):
+        """
+        添加开关
+        """
+        device_id = request_dict.get('deviceId', None)
+        status = request_dict.get('status', None)
+        if not all([device_id, status]):
+            return response.json(444)
+        serial_number = cls.get_serial_number_by_device_id(device_id)
+        # 保存数据库并下发MQTT消息到插座设备
+        result = cls.save_socket_switch(device_id, serial_number, int(status))
+        if not result:
+            return response.json(177)
+        return response.json(0)
+
+    @staticmethod
+    def save_socket_switch(device_id, serial_number, status, type_switch=0):
+        """
+        保存插座开关信息
+        @param device_id: 设备ID
+        @param serial_number: 序列号
+        @param status: 状态 0关,1开
+        @param type_switch: 0:总开关,1倒计时开关
+        @return: True | False
+        """
+        if not device_id:
+            return False
+        socket_info_qs = SocketInfo.objects.filter(device_id=device_id, type_switch=type_switch)
+        now_time = int(time.time())
+        try:
+            with transaction.atomic():
+                # 创建插座开关信息
+                if not socket_info_qs.exists():
+                    socket_dict = {"device_id": device_id,
+                                   "serial_number": serial_number,
+                                   "status": status,
+                                   "type_switch": type_switch,
+                                   "created_time": now_time,
+                                   "updated_time": now_time,
+                                   "online": True}
+                    SocketInfo.objects.create(**socket_dict)
+                    return True
+                if socket_info_qs.first().status == status:
+                    return True
+                socket_info_qs.update(status=status, updated_time=now_time)
+                # 主题名称
+                topic_name = SOCKET_TOPIC_NAME.format(serial_number)
+                # 发布消息内容
+                msg = {'type': 1, 'data': {'deviceSwitch': status}}
+                result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+                LOGGER.info('智能插座开关设置发布MQTT消息结果{}'.format(result))
+                return True
+        except Exception as e:
+            LOGGER.info('智能插座异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @classmethod
+    def save_count_down(cls, request_dict, response):
+        """
+        添加倒计时
+        """
+        device_id = request_dict.get('deviceId', None)
+        status = request_dict.get('status', None)
+        start = request_dict.get('start', None)
+        count_down_time = request_dict.get('countDownTime', None)
+        if not all([device_id, status, count_down_time]):
+            return response.json(444)
+        serial_number = cls.get_serial_number_by_device_id(device_id)
+        # 保存数据库并下发MQTT消息到插座设备
+        result = cls.save_socket_count_down(device_id, serial_number, int(status), int(start), int(count_down_time))
+        if not result:
+            return response.json(177)
+        return response.json(0)
+
+    @staticmethod
+    def save_socket_count_down(device_id, serial_number, status, start, count_down_time, type_switch=1):
+        """
+        保存插座倒计时信息
+        @param count_down_time: 倒计时时间戳
+        @param start: 是否启动倒计时 0:关闭,1:开始
+        @param device_id: 设备ID
+        @param serial_number: 序列号
+        @param status: 倒计时电源状态 0关,1开
+        @param type_switch: 0:总开关,1倒计时开关
+        @return:
+        """
+        if not device_id:
+            return False
+        socket_info_qs = SocketInfo.objects.filter(device_id=device_id, type_switch=type_switch)
+        now_time = int(time.time())
+        try:
+            with transaction.atomic():
+                # 创建插座倒计时信息
+                if not socket_info_qs.exists():
+                    socket_dict = {"device_id": device_id,
+                                   "serial_number": serial_number,
+                                   "status": status,
+                                   "type_switch": type_switch,
+                                   "created_time": now_time,
+                                   "updated_time": now_time,
+                                   "online": True,
+                                   "count_down_time": count_down_time}
+                    socket_info_qs = SocketInfo.objects.create(**socket_dict)
+                    count_down_id = socket_info_qs.id
+                else:
+                    socket_info_qs.update(status=status, count_down_time=count_down_time,
+                                          updated_time=now_time)
+                    count_down_id = socket_info_qs.first().id
+                # 主题名称
+                topic_name = SOCKET_TOPIC_NAME.format(serial_number)
+                # 发布消息内容
+                msg = {'type': 2,
+                       'data': {'powerType': status,
+                                'countDownId': count_down_id,
+                                'time': count_down_time,
+                                'start': start}}
+                result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+                LOGGER.info('智能插座倒计时发布MQTT消息结果{}'.format(result))
+                return True
+        except Exception as e:
+            LOGGER.info('智能插座异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @classmethod
+    def save_socket_schedule(cls, request_dict, response):
+        """
+        插座添加排程
+        """
+        try:
+            device_id = request_dict.get('deviceId', None)
+            task_type = request_dict.get('timeType', None)
+            start_time = request_dict.get('startTime', None)
+            end_time = request_dict.get('endTime', None)
+            repeat = request_dict.get('repeat', None)
+            task_id = request_dict.get('taskId', None)
+            device_switch = request_dict.get('deviceSwitch', None)
+            task_switch = request_dict.get('taskSwitch', None)
+            if not all([task_type, start_time, end_time, repeat, device_switch, task_switch]):
+                return response.json(444)
+            device_switch = int(device_switch)
+            task_switch = int(task_switch)
+            now_time = int(time.time())
+            data = {'time_type': int(task_type), 'start_time': int(start_time), 'repeat': int(repeat),
+                    'switch_status': True if device_switch == 1 else False,
+                    'task_status': True if task_switch == 1 else False}
+            serial_number = cls.get_serial_number_by_device_id(device_id)
+            if task_id:  # 修改排程
+                task_id = int(task_id)
+                socket_schedule_qs = SocketSchedule.objects.filter(id=task_id)
+                if not socket_schedule_qs.exists():
+                    return response.json(174)
+                if end_time:
+                    data['end_time'] = int(end_time)
+                data['updated_time'] = now_time
+                socket_schedule_qs.update(**data)
+            else:
+                # 排查是否已设置过当前排程
+                socket_s_qs = SocketSchedule.objects.filter(device_id=device_id,
+                                                            start_time=int(start_time),
+                                                            end_time=int(end_time),
+                                                            time_type=int(task_type))
+                if socket_s_qs.exists():
+                    return response.json(174)
+                # 添加排程
+                data['device_id'] = device_id
+                data['serial_number'] = serial_number
+                data['updated_time'] = now_time
+                data['created_time'] = now_time
+                socket_schedule = SocketSchedule.objects.create(**data)
+                task_id = socket_schedule.id
+            # 将排程任务下发给设备
+            cls.send_socket_schedule(serial_number, task_id, int(task_type), int(start_time),
+                                     int(end_time), int(repeat), device_switch,
+                                     task_switch)
+            return response.json(0)
+        except Exception as e:
+            LOGGER.info('智能插座异常,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+            return False
+
+    @staticmethod
+    def send_socket_schedule(serial_number, task_id, time_type, start_time, end_time, repeat, device_switch,
+                             task_switch):
+        """
+        排程下发设备
+        @param serial_number: 序列号
+        @param task_id: 当前排程任务id
+        @param time_type: 任务类型 0:设定时间,1:设定时间段
+        @param start_time: 开启时间
+        @param end_time: 结束时间
+        @param repeat: 重复日期
+        @param device_switch: 任务执行后期望设备状态,0:关闭,1:开启
+        @param task_switch: 任务执行状态 0:不执行,1:执行
+        @return: True | False
+        """
+        msg = {
+            'type': 3,
+            'data': {'taskId': task_id, 'timeType': time_type,
+                     'startTime': start_time, 'endTime': end_time,
+                     'repeat': repeat,
+                     'deviceSwitch': device_switch,
+                     'taskSwitch': task_switch}
+        }
+        # 主题名称
+        topic_name = SOCKET_TOPIC_NAME.format(serial_number)
+        result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
+        LOGGER.info('智能插座排程任务发布MQTT消息结果{}'.format(result))
+        return result
+
+    # 以下是查询智能插座接口
+
+    @staticmethod
+    def get_today_scene(request_dict, response):
+        """
+        查询当天插座电量
+        @request_dict serialNumber: 序列号
+        @param request_dict: 请求数据
+        @param response: 响应
+        @return: response
+        """
+        serial_number = request_dict.get('serialNumber', None)
+        if not all([serial_number]):
+            return response.json(444)
+        socket_power_qs = SocketPowerStatistics.objects.filter(serial_number=serial_number).values('power',
+                                                                                                   'accumulated_time',
+                                                                                                   'electricity')
+        if not socket_power_qs.exists():
+            return response.json(173)
+        socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number).values('status', 'online',
+                                                                                       'count_down_time')
+        if not socket_info_qs.exists():
+            return response.json(173)
+        try:
+            data = {}
+            data['serialNumber'] = serial_number
+            data['power'] = socket_power_qs[0]['power'] if socket_power_qs[0]['power'] else 0.00
+            data['electricity'] = socket_power_qs[0]['electricity'] if socket_power_qs[0]['electricity'] else 0.00
+            data['accumulatedTime'] = socket_power_qs[0]['accumulated_time'] if socket_power_qs[0][
+                'accumulated_time'] else '0:00'
+            data['status'] = socket_info_qs[0]['status'] if socket_info_qs[0]['status'] else False
+            data['online'] = socket_info_qs[0]['online'] if socket_info_qs[0]['online'] else False
+            data['count_down_time'] = socket_info_qs[0]['count_down_time'] if socket_info_qs[0][
+                'count_down_time'] else '00:00:00'
+            return response.json(0, data)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @classmethod
+    def get_all_scene(cls, request_dict, response):
+        '''
+        统计智能插座电量
+        @request_dict serialNumber: 序列号
+        @request_dict unit: 时间单位
+        @param request_dict: 请求数据
+        @param response: 响应
+        @return: response
+        '''
+        serial_number = request_dict.get('serialNumber', None)
+        unit = request_dict.get('unit', None)
+        # 确定是否会传值
+        startTime = request_dict.get('startTime', None)
+        endTime = request_dict.get('endTime', None)
+        if not all([unit, serial_number]):
+            return response.json(444)
+        socket_power_qs = SocketPowerStatistics.objects.filter(serial_number=serial_number).values(
+            'electricity', 'accumulated_time', 'power')
+        if not socket_power_qs.exists():
+            return response.json(173)
+        data = {}
+        # for device_info in device_info_qs:
+        #     device_id = device_info['id']
+        #     device_list.append(device_id)
+        try:
+            data = {
+                'electricityToday': '',
+                'accumulated_time': '',
+                'power': '',
+                'electricityYesterday': '',
+                'electricityMonth': '',
+                'allElectricity': '',
+                'accumulatedTime': '',
+                'accumulatedPower': '',
+            }
+            nowTime = endTime
+            data['electricity'] = socket_power_qs[0]['electricity'] if socket_power_qs[0]['electricity'] else 0.00
+            # 昨天使用电量
+            # data['electricityYesterday'] = socket_power_qs[1]['electricity'] if socket_power_qs[1][
+            #     'electricity'] else 0.00
+            data['accumulated_time'] = socket_power_qs[0]['accumulated_time'] if socket_power_qs[0][
+                'accumulated_time'] else 0.00
+            data['power'] = socket_power_qs[0]['power'] if socket_power_qs[0]['power'] else 0.00
+            time_list = []
+            if not endTime:
+                nowTime = 1679241600
+            if unit == 'week':
+                startTime = startTime
+                if not startTime:
+                    startTime = datetime.datetime.fromtimestamp(int(nowTime)) - datetime.timedelta(days=7)
+                end_time = datetime.datetime.fromtimestamp(int(nowTime))
+                time_list = CommonService.cutting_time(startTime, end_time, time_unit='day')
+            elif unit == 'month':
+                startTime = startTime
+                if not startTime:
+                    startTime = datetime.datetime.fromtimestamp(int(nowTime)) - datetime.timedelta(days=30)
+                end_time = datetime.datetime.fromtimestamp(int(nowTime))
+                time_list = CommonService.cutting_time(startTime, end_time, time_unit='day')
+            elif unit == 'year':
+                startTime = startTime
+                if not startTime:
+                    startTime = datetime.datetime.fromtimestamp(int(nowTime)) - datetime.timedelta(days=365)
+                end_time = datetime.datetime.fromtimestamp(int(nowTime))
+                time_list = CommonService.cutting_time(startTime, end_time, time_unit='month')
+            # all_time_list = []
+            new_list = []
+            for item in time_list:
+                socket_power_qs = socket_power_qs.filter(created_time__gte=item[0], created_time__lt=item[1])
+                time_tuple = time.localtime(item[-1])  # 把时间戳转换成时间元祖
+                items = time.strftime('%Y-%m-%d', time_tuple)
+                electricity = 0.00
+                new_list.append({
+                    'time': items,
+                    'electricity': electricity
+                })
+                # #字典key相同则value放一起
+                # socket_list = list(socket_power_qs)
+                # new_list.append(socket_list[0])
+                # for socket in range(1,len(socket_list)):
+                #     for new in new_list:
+                #         if operator.eq(new.keys(), socket_list[socket].keys()):
+                #             for key in new.keys():
+                #                 new[key] += socket_list[socket][key]
+                #             break
+                #         elif operator.eq(new, new_list[-1]):
+                #             new_list.append(socket_list[socket])
+                #             break
+            # data['dict'] = new_list
+            data['week_or_month_or_year'] = new_list
+            return response.json(0, data)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_socket_schedule(request_dict, response):
+        """
+        智能插座排程记录查询
+        @param request_dict: 请求参数
+        @request_dict page: 页数
+        @request_dict size: 条数
+        @request_dict serialNumber: 设备序列号
+        @param response: 响应对象
+        @return: response
+        """
+        page = request_dict.get('pageNo', None)
+        size = request_dict.get('pageSize', None)
+        serial_number = request_dict.get('serialNumber', None)
+
+        if not all([page, size, serial_number]):
+            return response.json(444)
+        page, size = int(page), int(size)
+        socket_schedule_qs = SocketSchedule.objects.filter(serial_number=serial_number).values('switch_status',
+                                                                                               'start_time', 'end_time',
+                                                                                               'repeat', 'task_status')
+        count = socket_schedule_qs.count()
+        socket_schedule_qs = socket_schedule_qs[(page - 1) * size:page * size]
+        if not socket_schedule_qs.exists():
+            return response.json(173)
+        try:
+            schedule_list = []
+            for socket_schedule in socket_schedule_qs:
+                schedule_list.append({
+                    'start_time': socket_schedule['start_time'],
+                    'end_time': socket_schedule['end_time'],
+                    'switch_status': socket_schedule['switch_status'] if socket_schedule['switch_status'] else False,
+                    'task_status': socket_schedule['task_status'] if socket_schedule['task_status'] else False,
+                    # 需转换进制
+                    'repeat': socket_schedule['repeat']
+                })
+            return response.json(0, {'list': schedule_list, 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_log(request_dict, response, user_id):
+        """
+        智能插座开关日志记录查询
+        @param request_dict: 请求参数
+        @param user_id: 用户ID
+        @request_dict page: 页数
+        @request_dict size: 条数
+        @request_dict serialNumber: 设备序列号
+        @request_dict startTime: 开始时间
+        @request_dict endTime: 结束时间
+        @param response: 响应对象
+        @return: response
+        """
+        page = request_dict.get('pageNo', None)
+        size = request_dict.get('pageSize', None)
+        serial_number = request_dict.get('serialNumber', None)
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+
+        if not all([page, size, serial_number]):
+            return response.json(444)
+
+        socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number)
+        device_id_list = []
+        pass
+
+    @staticmethod
+    def editor_socket_device(request_dict, response, user_id):
+        """
+        编辑设备
+        """
+        # 编辑插座信息
+        serial_number = request_dict.get('serialNumber', None)
+        NickName = request_dict.get('NickName', None)
+        # room_save
+        # familyRoom = request_dict.get('familyRoom', None)
+        type_switch = request_dict.get('typeSwitch', None)  # 1:倒计时开关
+        status = request_dict.get('status', None)  # 开关状态 0:关闭,1:开启'
+
+        # 编辑插座排程
+        count_down_time = request_dict.get('countDownTime', None)  # 倒计时时间戳
+        time_type = request_dict.get('timeType', None)  # 排查时间类型 0:按时间 1:按时间段划分'
+        switch_status = request_dict.get('switchStatus', None)  # 开关状态 0:关闭,1:开启
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        repeat = request_dict.get('repeat', None)  # 重复周期用数值表示
+
+        if not all([serial_number]):
+            return response.json(444)
+        socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number)
+        if not socket_info_qs.exists():
+            return response.json(173)
+        try:
+            with transaction.atomic():
+                if NickName:
+                    Device_Info.objects.update(NickName=NickName)
+                    UidSetModel.objects.update(nickname=NickName)
+                elif type_switch:
+                    socket_info_qs.update(type_switch=type_switch)
+                elif status:
+                    socket_info_qs.update(status=status)
+                elif count_down_time:
+                    socket_info_qs.update(count_down_time=count_down_time)
+                socket_qs = SocketSchedule.objects.filter(serial_number=serial_number)
+                if not socket_qs.exists():
+                    socket_info_qs.save()
+                    return response(0)
+                elif time_type:
+                    socket_qs.update(time_type=time_type)
+                elif switch_status:
+                    socket_qs.update(switch_status=switch_status)
+                elif start_time:
+                    socket_qs.update(start_time=start_time)
+                elif end_time:
+                    socket_qs.update(end_time=end_time)
+                elif repeat:
+                    socket_qs.update(repeat=repeat)
+                socket_info_qs.save()
+                socket_qs.save()
+                return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500)

+ 300 - 0
Controller/SensorGateway/SmartSocketStatisticsController.py

@@ -0,0 +1,300 @@
+import operator
+import time
+import datetime
+
+from django.db import transaction
+from django.forms import model_to_dict
+from django.http import JsonResponse
+from django.views import View
+
+from Model.models import SocketPowerStatistics, SocketInfo, Device_User, Device_Info, SocketSchedule, \
+    CompanySerialModel, UIDCompanySerialModel, SocketRecordsLog, UidSetModel
+from Object.ResponseObject import ResponseObject
+from Service.CommonService import CommonService
+
+
+class SmartSocketStatisticsView(View):
+    def get(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.GET, request, operation)
+
+    def post(self, request, *args, **kwargs):
+        request.encoding = 'utf-8'
+        operation = kwargs.get('operation')
+        return self.validation(request.POST, request, operation)
+
+    def validation(self, request_dict, request, operation):
+        token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
+        if token_code != 0:
+            return response.json(token_code)
+        elif operation == 'get-today-scene':  # 查询当天插座电量
+            return self.get_today_scene(request_dict, response)
+        elif operation == 'get-all-scene':  # 统计智能插座电量
+            return self.get_all_scene(request_dict, response)
+        elif operation == 'get-socket-schedule':  # 智能插座排程记录查询
+            return self.get_socket_schedule(request_dict, response)
+        elif operation == 'get-log':  # 智能插座开关日志记录查询
+            return self.get_log(request_dict, response, user_id)
+        elif operation == 'editor-socket-device':  # 编辑设备信息
+            return self.editor_socket_device(request_dict, response, user_id)
+        else:
+            return response.json(414)
+
+    @staticmethod
+    def get_today_scene(request_dict, response):
+        """
+        查询当天插座电量
+        @request_dict serialNumber: 序列号
+        @param request_dict: 请求数据
+        @param response: 响应
+        @return: response
+        """
+        serial_number = request_dict.get('serialNumber', None)
+        if not all([serial_number]):
+            return response.json(444)
+        socket_power_qs = SocketPowerStatistics.objects.filter(serial_number=serial_number).values('power',
+                                                                                                   'accumulated_time',
+                                                                                                   'electricity')
+        if not socket_power_qs.exists():
+            return response.json(173)
+        socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number).values('status', 'online',
+                                                                                       'count_down_time')
+        if not socket_info_qs.exists():
+            return response.json(173)
+        try:
+            data = {}
+            data['serialNumber'] = serial_number
+            data['power'] = socket_power_qs[0]['power'] if socket_power_qs[0]['power'] else 0.00
+            data['electricity'] = socket_power_qs[0]['electricity'] if socket_power_qs[0]['electricity'] else 0.00
+            data['accumulatedTime'] = socket_power_qs[0]['accumulated_time'] if socket_power_qs[0][
+                'accumulated_time'] else '0:00'
+            data['status'] = socket_info_qs[0]['status'] if socket_info_qs[0]['status'] else False
+            data['online'] = socket_info_qs[0]['online'] if socket_info_qs[0]['online'] else False
+            data['count_down_time'] = socket_info_qs[0]['count_down_time'] if socket_info_qs[0][
+                'count_down_time'] else '00:00:00'
+            return response.json(0, data)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @classmethod
+    def get_all_scene(cls, request_dict, response):
+        '''
+        统计智能插座电量
+        @request_dict serialNumber: 序列号
+        @request_dict unit: 时间单位
+        @param request_dict: 请求数据
+        @param response: 响应
+        @return: response
+        '''
+        serial_number = request_dict.get('serialNumber', None)
+        unit = request_dict.get('unit', None)
+        # 确定是否会传值
+        startTime = request_dict.get('startTime', None)
+        endTime = request_dict.get('endTime', None)
+        if not all([unit, serial_number]):
+            return response.json(444)
+        socket_power_qs = SocketPowerStatistics.objects.filter(serial_number=serial_number).values(
+                    'electricity', 'accumulated_time', 'power')
+        if not socket_power_qs.exists():
+            return response.json(173)
+        data = {}
+        # for device_info in device_info_qs:
+        #     device_id = device_info['id']
+        #     device_list.append(device_id)
+        try:
+            data = {
+                'electricityToday': '',
+                'accumulated_time': '',
+                'power': '',
+                'electricityYesterday': '',
+                'electricityMonth': '',
+                'allElectricity': '',
+                'accumulatedTime': '',
+                'accumulatedPower': '',
+                }
+            nowTime = endTime
+            data['electricity'] = socket_power_qs[0]['electricity'] if socket_power_qs[0]['electricity'] else 0.00
+            # 昨天使用电量
+            # data['electricityYesterday'] = socket_power_qs[1]['electricity'] if socket_power_qs[1][
+            #     'electricity'] else 0.00
+            data['accumulated_time'] = socket_power_qs[0]['accumulated_time'] if socket_power_qs[0][
+                'accumulated_time'] else 0.00
+            data['power'] = socket_power_qs[0]['power'] if socket_power_qs[0]['power'] else 0.00
+            time_list = []
+            if not endTime:
+                nowTime = 1679241600
+            if unit == 'week':
+                startTime = startTime
+                if not startTime:
+                    startTime = datetime.datetime.fromtimestamp(int(nowTime)) - datetime.timedelta(days=7)
+                end_time = datetime.datetime.fromtimestamp(int(nowTime))
+                time_list = CommonService.cutting_time(startTime, end_time, time_unit='day')
+            elif unit == 'month':
+                startTime = startTime
+                if not startTime:
+                    startTime = datetime.datetime.fromtimestamp(int(nowTime)) - datetime.timedelta(days=30)
+                end_time = datetime.datetime.fromtimestamp(int(nowTime))
+                time_list = CommonService.cutting_time(startTime, end_time, time_unit='day')
+            elif unit == 'year':
+                startTime = startTime
+                if not startTime:
+                    startTime = datetime.datetime.fromtimestamp(int(nowTime)) - datetime.timedelta(days=365)
+                end_time = datetime.datetime.fromtimestamp(int(nowTime))
+                time_list = CommonService.cutting_time(startTime, end_time, time_unit='month')
+            # all_time_list = []
+            new_list = []
+            for item in time_list:
+                socket_power_qs = socket_power_qs.filter(created_time__gte=item[0], created_time__lt=item[1])
+                time_tuple = time.localtime(item[-1])  # 把时间戳转换成时间元祖
+                items = time.strftime('%Y-%m-%d', time_tuple)
+                electricity = 0.00
+                new_list.append({
+                    'time': items,
+                    'electricity': electricity
+                })
+                # #字典key相同则value放一起
+                # socket_list = list(socket_power_qs)
+                # new_list.append(socket_list[0])
+                # for socket in range(1,len(socket_list)):
+                #     for new in new_list:
+                #         if operator.eq(new.keys(), socket_list[socket].keys()):
+                #             for key in new.keys():
+                #                 new[key] += socket_list[socket][key]
+                #             break
+                #         elif operator.eq(new, new_list[-1]):
+                #             new_list.append(socket_list[socket])
+                #             break
+            # data['dict'] = new_list
+            data['week_or_month_or_year'] = new_list
+            return response.json(0, data)
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_socket_schedule(request_dict, response):
+        """
+        智能插座排程记录查询
+        @param request_dict: 请求参数
+        @request_dict page: 页数
+        @request_dict size: 条数
+        @request_dict serialNumber: 设备序列号
+        @param response: 响应对象
+        @return: response
+        """
+        page = request_dict.get('pageNo', None)
+        size = request_dict.get('pageSize', None)
+        serial_number = request_dict.get('serialNumber', None)
+
+        if not all([page, size, serial_number]):
+            return response.json(444)
+        page, size = int(page), int(size)
+        socket_schedule_qs = SocketSchedule.objects.filter(serial_number=serial_number).values('switch_status',
+                                                                                               'start_time', 'end_time',
+                                                                                               'repeat', 'task_status')
+        count = socket_schedule_qs.count()
+        socket_schedule_qs = socket_schedule_qs[(page - 1) * size:page * size]
+        if not socket_schedule_qs.exists():
+            return response.json(173)
+        try:
+            schedule_list = []
+            for socket_schedule in socket_schedule_qs:
+                schedule_list.append({
+                    'start_time': socket_schedule['start_time'],
+                    'end_time': socket_schedule['end_time'],
+                    'switch_status': socket_schedule['switch_status'] if socket_schedule['switch_status'] else False,
+                    'task_status': socket_schedule['task_status'] if socket_schedule['task_status'] else False,
+                    # 需转换进制
+                    'repeat': socket_schedule['repeat']
+                })
+            return response.json(0, {'list': schedule_list, 'total': count})
+        except Exception as e:
+            print(e)
+            return response.json(500)
+
+    @staticmethod
+    def get_log(request_dict, response, user_id):
+        """
+        智能插座开关日志记录查询
+        @param request_dict: 请求参数
+        @param user_id: 用户ID
+        @request_dict page: 页数
+        @request_dict size: 条数
+        @request_dict serialNumber: 设备序列号
+        @request_dict startTime: 开始时间
+        @request_dict endTime: 结束时间
+        @param response: 响应对象
+        @return: response
+        """
+        page = request_dict.get('pageNo', None)
+        size = request_dict.get('pageSize', None)
+        serial_number = request_dict.get('serialNumber', None)
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+
+        if not all([page, size, serial_number]):
+            return response.json(444)
+
+        socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number)
+        device_id_list = []
+        pass
+
+    @staticmethod
+    def editor_socket_device(request_dict, response, user_id):
+        """
+        编辑设备
+        """
+        # 编辑插座信息
+        serial_number = request_dict.get('serialNumber', None)
+        NickName = request_dict.get('NickName', None)
+        #room_save
+        # familyRoom = request_dict.get('familyRoom', None)
+        type_switch = request_dict.get('typeSwitch', None)  # 1:倒计时开关
+        status = request_dict.get('status', None)  # 开关状态 0:关闭,1:开启'
+
+        # 编辑插座排程
+        count_down_time = request_dict.get('countDownTime', None)  # 倒计时时间戳
+        time_type = request_dict.get('timeType', None)  # 排查时间类型 0:按时间 1:按时间段划分'
+        switch_status = request_dict.get('switchStatus', None)  # 开关状态 0:关闭,1:开启
+        start_time = request_dict.get('startTime', None)
+        end_time = request_dict.get('endTime', None)
+        repeat = request_dict.get('repeat', None)  # 重复周期用数值表示
+
+        if not all([serial_number]):
+            return response.json(444)
+        socket_info_qs = SocketInfo.objects.filter(serial_number=serial_number)
+        if not socket_info_qs.exists():
+            return response.json(173)
+        try:
+            with transaction.atomic():
+                if NickName:
+                    Device_Info.objects.update(NickName=NickName)
+                    UidSetModel.objects.update(nickname=NickName)
+                elif type_switch:
+                    socket_info_qs.update(type_switch=type_switch)
+                elif status:
+                    socket_info_qs.update(status=status)
+                elif count_down_time:
+                    socket_info_qs.update(count_down_time=count_down_time)
+                socket_qs = SocketSchedule.objects.filter(serial_number=serial_number)
+                if not socket_qs.exists():
+                    socket_info_qs.save()
+                    return response(0)
+                elif time_type:
+                    socket_qs.update(time_type=time_type)
+                elif switch_status:
+                    socket_qs.update(switch_status=switch_status)
+                elif start_time:
+                    socket_qs.update(start_time=start_time)
+                elif end_time:
+                    socket_qs.update(end_time=end_time)
+                elif repeat:
+                    socket_qs.update(repeat=repeat)
+                socket_info_qs.save()
+                socket_qs.save()
+                return response.json(0)
+        except Exception as e:
+            print(e)
+            return response.json(500)

+ 65 - 1
Controller/SerialNumberController.py

@@ -8,7 +8,8 @@ from django.db import transaction
 from django.views import View
 from django.views import View
 
 
 from Ansjer.config import CRCKey, CONFIG_INFO, CONFIG_TEST, CONFIG_US, \
 from Ansjer.config import CRCKey, CONFIG_INFO, CONFIG_TEST, CONFIG_US, \
-    CONFIG_CN, USED_SERIAL_REDIS_LIST, UNUSED_SERIAL_REDIS_LIST, SERVER_DOMAIN_US, REGION_ID_LIST
+    CONFIG_CN, USED_SERIAL_REDIS_LIST, UNUSED_SERIAL_REDIS_LIST, SERVER_DOMAIN_US, REGION_ID_LIST, SERVER_DOMAIN_TEST, \
+    SERVER_DOMAIN_LIST, SERVER_DOMAIN_CN, SERVER_DOMAIN_EUR
 from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, UIDModel, Device_Info, \
 from Model.models import SerialNumberModel, CompanySerialModel, UIDCompanySerialModel, UIDModel, Device_Info, \
     iotdeviceInfoModel, LogModel, UidSetModel, UID_Bucket, \
     iotdeviceInfoModel, LogModel, UidSetModel, UID_Bucket, \
     Unused_Uid_Meal, Order_Model, StsCrdModel, VodHlsModel, ExperienceContextModel, UidUserModel, ExperienceAiModel, \
     Unused_Uid_Meal, Order_Model, StsCrdModel, VodHlsModel, ExperienceContextModel, UidUserModel, ExperienceAiModel, \
@@ -62,6 +63,10 @@ class SerialNumberView(View):
             return self.reset_region_id(request_dict, response)
             return self.reset_region_id(request_dict, response)
         elif operation == 'get-status':  # 重置地区id
         elif operation == 'get-status':  # 重置地区id
             return self.check_serial_status(request_dict, response)
             return self.check_serial_status(request_dict, response)
+        elif operation == 'getUidRegion':  # 根据序列号获取uid地区
+            return self.get_uid_region(request_dict, response)
+        elif operation == 'getGlobalUidRegion':  # 获取序列号在全球服绑定uid的地区
+            return self.get_global_uid_region(request_dict, response)
         else:
         else:
             return response.json(414)
             return response.json(414)
 
 
@@ -748,3 +753,62 @@ class SerialNumberView(View):
             return response.json(0)
             return response.json(0)
         except Exception as e:
         except Exception as e:
             return response.json(500, repr(e))
             return response.json(500, repr(e))
+
+    @staticmethod
+    def get_uid_region(request_dict, response):
+        """
+        根据序列号获取uid地区
+        @param request_dict: 请求参数
+        @param response: 响应对象
+        @request_dict serial_number: 序列号
+        @return: response
+        """
+        serial_number = request_dict.get('serial_number', None)
+        if not serial_number:
+            return response(444)
+        try:
+            serial_number = serial_number[:6]
+            uid_company_serial_qs = UIDCompanySerialModel.objects.filter(
+                company_serial__serial_number=serial_number).values('uid__uid')
+            res = []
+            for item in uid_company_serial_qs:
+                res.append({'uid': item['uid__uid']})
+            return response.json(0, res)
+        except Exception as e:
+            return response.json(500, repr(e))
+
+    @staticmethod
+    def get_global_uid_region(request_dict, response):
+        """
+        获取序列号在全球服绑定uid的地区
+        @param request_dict: 请求参数
+        @param response: 响应对象
+        @request_dict serial_number: 序列号
+        @return: response
+        """
+        orders_domain_name_list = SERVER_DOMAIN_LIST
+        if SERVER_DOMAIN_TEST in orders_domain_name_list:
+            orders_domain_name_list.remove(SERVER_DOMAIN_TEST)
+        uid_list = []
+        try:
+            for orders_domain_name in orders_domain_name_list:
+                url = orders_domain_name + 'serialNumber/getUidRegion'
+                res = requests.post(url=url, data=request_dict)
+                result = res.json()
+                if result['result_code'] != 0:
+                    return response.json(result['result_code'])
+                if orders_domain_name == SERVER_DOMAIN_CN:
+                    for item in result['result']:
+                        item['region'] = 1
+                        uid_list.append(item)
+                elif orders_domain_name == SERVER_DOMAIN_US:
+                    for item in result['result']:
+                        item['region'] = 3
+                        uid_list.append(item)
+                elif orders_domain_name == SERVER_DOMAIN_EUR:
+                    for item in result['result']:
+                        item['region'] = 4
+                        uid_list.append(item)
+            return response.json(0, uid_list)
+        except Exception as e:
+            return response.json(500, repr(e))

+ 37 - 3
Controller/TestApi.py

@@ -162,7 +162,10 @@ class testView(View):
             return self.generate_video(request_dict, response)
             return self.generate_video(request_dict, response)
         elif operation == 'serial-repetition':  # 用与测试序列号重复接口
         elif operation == 'serial-repetition':  # 用与测试序列号重复接口
             response = ResponseObject('cn')
             response = ResponseObject('cn')
-            return self.serial_repetition_test(request_dict, response)
+            return response.json(475)
+        elif operation == 'v2/serial-repetition':  # 用与测试序列号重复接口
+            response = ResponseObject('cn')
+            return self.serial_repetition_test_v2(request_dict, response)
         elif operation == 'getSerialNumberInfo':  # 序列号信息查询
         elif operation == 'getSerialNumberInfo':  # 序列号信息查询
             return self.getSerialNumberInfo(request_dict, response)
             return self.getSerialNumberInfo(request_dict, response)
         elif operation == 'get-serial-details':  # 序列号信息查询
         elif operation == 'get-serial-details':  # 序列号信息查询
@@ -171,20 +174,27 @@ class testView(View):
             return 123
             return 123
 
 
     @classmethod
     @classmethod
-    def serial_repetition_test(cls, request_dict, response):
+    def serial_repetition_test_v2(cls, request_dict, response):
         try:
         try:
             serial_no = request_dict.get('serialNo', None)
             serial_no = request_dict.get('serialNo', None)
+            phone_model = request_dict.get('phoneModel', None)
             if not serial_no:
             if not serial_no:
                 return response.json(444)
                 return response.json(444)
             with transaction.atomic():
             with transaction.atomic():
                 first_serial = serial_no[:6]
                 first_serial = serial_no[:6]
                 first_serial_qs = TestSerialRepetition.objects.filter(serial_number__icontains=first_serial)
                 first_serial_qs = TestSerialRepetition.objects.filter(serial_number__icontains=first_serial)
                 if first_serial_qs.exists():
                 if first_serial_qs.exists():
-                    return response.json(174)
+                    result = {'serialNumber': first_serial_qs.first().serial_number,
+                              'phoneModel': first_serial_qs.first().phone_model,
+                              'createdTime': first_serial_qs.first().created_time}
+                    return response.json(174, result)
+
                 serial_qs = TestSerialRepetition.objects.filter(serial_number=serial_no)
                 serial_qs = TestSerialRepetition.objects.filter(serial_number=serial_no)
                 if not serial_qs.exists():
                 if not serial_qs.exists():
                     n_time = int(time.time())
                     n_time = int(time.time())
                     params = {'serial_number': serial_no, 'created_time': n_time}
                     params = {'serial_number': serial_no, 'created_time': n_time}
+                    if phone_model:
+                        params['phone_model'] = phone_model
                     TestSerialRepetition.objects.create(**params)
                     TestSerialRepetition.objects.create(**params)
                     return response.json(0)
                     return response.json(0)
                 else:
                 else:
@@ -193,6 +203,30 @@ class testView(View):
             logging.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             logging.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
             return response.json(178, e)
             return response.json(178, e)
 
 
+    @classmethod
+    def serial_repetition_test(cls, request_dict, response):
+        return response.json()
+        # try:
+        #     serial_no = request_dict.get('serialNo', None)
+        #     if not serial_no:
+        #         return response.json(444)
+        #     with transaction.atomic():
+        #         first_serial = serial_no[:6]
+        #         first_serial_qs = TestSerialRepetition.objects.filter(serial_number__icontains=first_serial)
+        #         if first_serial_qs.exists():
+        #             return response.json(174)
+        #         serial_qs = TestSerialRepetition.objects.filter(serial_number=serial_no)
+        #         if not serial_qs.exists():
+        #             n_time = int(time.time())
+        #             params = {'serial_number': serial_no, 'created_time': n_time}
+        #             TestSerialRepetition.objects.create(**params)
+        #             return response.json(0)
+        #         else:
+        #             return response.json(174)
+        # except Exception as e:
+        #     logging.info('异常错误,errLine:{}, errMsg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
+        #     return response.json(178, e)
+
     @classmethod
     @classmethod
     def generate_video(cls, request_dict, response):
     def generate_video(cls, request_dict, response):
         # 设计抽取图片规则通过消息随机还是时间随机,调试copy S3对象查询是否携带失效时间
         # 设计抽取图片规则通过消息随机还是时间随机,调试copy S3对象查询是否携带失效时间

+ 81 - 2
Model/models.py

@@ -1377,7 +1377,8 @@ class UidPushModel(models.Model):
     uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     uid_set = models.ForeignKey(UidSetModel, to_field='id', on_delete=models.CASCADE)
     appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
     appBundleId = models.CharField(blank=True, max_length=32, verbose_name=u'appID')
     app_type = models.IntegerField(default=0, verbose_name=u'app类型 1:ios,2:安卓')
     app_type = models.IntegerField(default=0, verbose_name=u'app类型 1:ios,2:安卓')
-    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
+    push_type = models.IntegerField(default=0,
+                                    verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
     m_code = models.CharField(default='', max_length=64, verbose_name='手机唯一标识')
     m_code = models.CharField(default='', max_length=64, verbose_name='手机唯一标识')
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
     addTime = models.IntegerField(verbose_name='添加时间', default=0)
@@ -1397,7 +1398,8 @@ class GatewayPush(models.Model):
     user_id = models.CharField(default='', max_length=32, db_index=True, verbose_name=u'用户id')
     user_id = models.CharField(default='', max_length=32, db_index=True, verbose_name=u'用户id')
     app_bundle_id = models.CharField(default='', max_length=32, verbose_name=u'app包id')
     app_bundle_id = models.CharField(default='', max_length=32, verbose_name=u'app包id')
     app_type = models.IntegerField(default=0, verbose_name=u'app类型')  # 1: ios, 2: 安卓
     app_type = models.IntegerField(default=0, verbose_name=u'app类型')  # 1: ios, 2: 安卓
-    push_type = models.IntegerField(default=0, verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
+    push_type = models.IntegerField(default=0,
+                                    verbose_name=u'推送类型')  # 0: apns, 1: 安卓gcm, 2: 极光, 3:华为, 4:小米, 5:vivo, 6:oppo, 7:魅族
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
     token_val = models.CharField(default='', max_length=500, verbose_name=u'设备验证令牌')
     m_code = models.CharField(default='', max_length=64, db_index=True, verbose_name='手机唯一标识')
     m_code = models.CharField(default='', max_length=64, db_index=True, verbose_name='手机唯一标识')
     lang = models.CharField(default='en', max_length=8, verbose_name='推送语言')
     lang = models.CharField(default='en', max_length=8, verbose_name='推送语言')
@@ -3367,9 +3369,86 @@ class TestSerialRepetition(models.Model):
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     id = models.AutoField(primary_key=True, verbose_name='自增id')
     serial_number = models.CharField(blank=True, unique=True, db_index=True, max_length=20, default='',
     serial_number = models.CharField(blank=True, unique=True, db_index=True, max_length=20, default='',
                                      verbose_name='序列号')
                                      verbose_name='序列号')
+    phone_model = models.CharField(max_length=64, default='', verbose_name='手机型号')
     created_time = models.IntegerField(default=0, verbose_name='创建时间')
     created_time = models.IntegerField(default=0, verbose_name='创建时间')
 
 
     class Meta:
     class Meta:
         db_table = 'test_serial_repetition'
         db_table = 'test_serial_repetition'
         verbose_name = '测试序列号重复问题'
         verbose_name = '测试序列号重复问题'
         verbose_name_plural = verbose_name
         verbose_name_plural = verbose_name
+
+
+class SocketPowerStatistics(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    device_id = models.CharField(max_length=32, default='', verbose_name='设备id')
+    serial_number = models.CharField(db_index=True, max_length=20, default='',
+                                     verbose_name='序列号')
+    electricity = models.DecimalField(default=0, max_digits=10, decimal_places=2, verbose_name='设备当日用电KWh')
+    power = models.DecimalField(default=0, max_digits=10, decimal_places=2, verbose_name='功率w')
+    accumulated_time = models.SmallIntegerField(default=0, verbose_name='当天累计时长(秒)')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 's_socket_power_statistics'
+        verbose_name = '插座电量统计'
+        verbose_name_plural = verbose_name
+
+
+class SocketInfo(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    device_id = models.CharField(max_length=32, default='', verbose_name='设备id')
+    serial_number = models.CharField(db_index=True, max_length=20,
+                                     verbose_name='序列号')
+    online = models.BooleanField(default=False, verbose_name='在线状态False:不在线,True:在线')
+    type_switch = models.SmallIntegerField(default=0,
+                                           verbose_name='开关类型 0:总开关,1:倒计时开关')
+    status = models.BooleanField(default=False, verbose_name='开关状态 0:关闭,1:开启')
+    count_down_time = models.IntegerField(default=0, verbose_name='倒计时时间戳')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 's_socket_info'
+        verbose_name = '插座信息'
+        verbose_name_plural = verbose_name
+
+
+class SocketSchedule(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    device_id = models.CharField(max_length=32, default='', verbose_name='设备id')
+    serial_number = models.CharField(db_index=True, max_length=20, default='',
+                                     verbose_name='序列号')
+    time_type = models.SmallIntegerField(default=0, verbose_name='排查时间类型 0:按时间 1:按时间段划分')
+    switch_status = models.BooleanField(default=False, verbose_name='开关状态 0:关闭,1:开启')
+    task_status = models.BooleanField(default=False, verbose_name='任务状态状态 0:关闭,1:启动')
+    start_time = models.IntegerField(default=0, verbose_name='开始时间')
+    end_time = models.IntegerField(default=0, verbose_name='结束时间')
+    repeat = models.SmallIntegerField(default=0,
+                                      verbose_name='重复周期用数值表示 设备转二进制例127则二进制1111111')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='创建时间')
+
+    class Meta:
+        db_table = 's_socket_schedule'
+        verbose_name = '插座排程'
+        verbose_name_plural = verbose_name
+
+
+class SocketRecordsLog(models.Model):
+    id = models.AutoField(primary_key=True, verbose_name='自增id')
+    user_id = models.CharField(default='', db_index=True, max_length=32, verbose_name=u'用户id')
+    serial_number = models.CharField(db_index=True, max_length=20, default='',
+                                     verbose_name='序列号')
+    records_type = models.SmallIntegerField(default=0,
+                                            verbose_name='记录类型 0:设备开关 1:插座日志')
+    content = models.CharField(max_length=128, blank=True, verbose_name='记录内容')
+    status = models.SmallIntegerField(default=0, verbose_name='0:未读/未操作,1:已读/已操作')
+    created_time = models.IntegerField(default=0, verbose_name='创建时间')
+    updated_time = models.IntegerField(default=0, verbose_name='更新时间')
+
+    class Meta:
+        db_table = 's_socket_records_log'
+        verbose_name = '插座日志记录'
+        verbose_name_plural = verbose_name
+        app_label = "PushModel"