Bladeren bron

添加插座ChangeReport接口

locky 1 jaar geleden
bovenliggende
commit
e2609d5acd
1 gewijzigde bestanden met toevoegingen van 105 en 1 verwijderingen
  1. 105 1
      controller/deviceStatus.py

+ 105 - 1
controller/deviceStatus.py

@@ -3,7 +3,9 @@
 """
 """
 import json
-import time, datetime
+import time
+import datetime
+from datetime import timezone
 import requests
 import uuid
 import logging
@@ -52,6 +54,8 @@ class deviceStatus(TemplateView):
             return self.delete(request_dict)
         elif operation == 'stateReport':
             return self.StateReport(request_dict)
+        elif operation == 'changeReportSwitch':
+            return self.changeReportSwitch(request_dict)
         elif operation == 'deleteSwitch':
             return self.deleteSwitch(request_dict)
 
@@ -509,6 +513,106 @@ class deviceStatus(TemplateView):
             logger.info('--------删除设备异常--------:error_line:{}, error_msg:{}'.
                         format(e.__traceback__.tb_lineno, repr(e)))
 
+    def changeReportSwitch(self, request_dict):
+        # 通过app或设备打开/关闭插座电源时主动报告状态
+        serial_number = request_dict.get('serial_number')
+        value = request_dict.get('value')
+        cause_type = request_dict.get('cause_type')
+        logger = logging.getLogger('django')
+        logger.info('插座ChangeReport,serial_number:{}, value:{}, cause_type:{}'.format(serial_number, value, cause_type))
+        if not all([serial_number, value, cause_type]):
+            return JsonResponse({'code': 111, 'msg': '参数异常'})
+        skill_name = 'loocam'
+        try:
+            switch_qs = SwitchModel.objects.filter(serial_number=serial_number)
+            if not switch_qs.exists():
+                return JsonResponse({'code': 103, 'msg': '不存在socket数据'})
+            userID = switch_qs[0].userID
+            alexAuth = AlexaAuthModel.objects.filter(userID=userID, skill_name=skill_name). \
+                values('expiresTime', 'refresh_token', 'access_token', 'alexa_region')
+            if not alexAuth.exists():
+                logger.info('序列号为 {} 的用户不存在'.format(serial_number))
+                return JsonResponse({'code': 102, 'msg': 'not found user'})
+
+            expiresTime = alexAuth[0]['expiresTime']
+            refresh_token = alexAuth[0]['refresh_token']
+            access_token = alexAuth[0]['access_token']
+            alexa_region = alexAuth[0]['alexa_region']
+            if alexa_region not in ALEXA_EVENT_API.keys():
+                logger.info('alexa区域信息错误,alexa_region: {}'.format(alexa_region))
+                return JsonResponse({'code': 102, 'msg': 'alexa_region error'})
+
+            now_time = int(time.time())
+            if now_time > expiresTime:
+                res = self.getRefreshToken(refresh_token, skill_name)
+                if 'error' not in res:
+                    alexAuth.update(
+                        access_token=res['access_token'],
+                        refresh_token=res['refresh_token'],
+                        expiresTime=now_time + 300,
+                        updTime=now_time,
+                    )
+                    access_token = res['access_token']
+                else:
+                    return JsonResponse({'code': 102, 'msg': 'get refresh_token fail'})
+
+            endpoints = []
+            for switch in switch_qs:
+                endpointId = {"endpointId": switch.serial_number}
+                endpoints.append(endpointId)
+            switch_qs.delete()
+            headers = {
+                "Authorization": "Bearer " + access_token,
+                "Content-Type": "application/json;charset=UTF-8",
+                "Cache-Control": "no-cache"
+            }
+
+            # 转换时间格式
+            iso_string = datetime.datetime.now(timezone.utc).isoformat()
+            time_of_sample = iso_string.split('.')[0] + 'Z'
+            payload = {
+                "event": {
+                    "header": {
+                        "namespace": "Alexa",
+                        "name": "ChangeReport",
+                        "messageId": str(uuid.uuid4()),
+                        "payloadVersion": "3"
+                    },
+                    "endpoint": {
+                        "scope": {
+                            "type": "BearerToken",
+                            "token": access_token
+                        },
+                        "endpoints": endpoints
+                    },
+                    "payload": {
+                        "change": {
+                            "cause": {
+                                "type": cause_type
+                            },
+                            "properties": [
+                                {
+                                    "namespace": "Alexa.PowerController",
+                                    "name": "powerState",
+                                    "value": value,
+                                    "timeOfSample": time_of_sample,
+                                    "uncertaintyInMilliseconds": 0
+                                }
+                            ]
+                        }
+                    }
+                }
+            }
+
+            api_uri = ALEXA_EVENT_API[alexa_region]
+            response = requests.post(api_uri, json=payload, headers=headers)
+            logger.info('--------Alexa ChangeReport响应: {}--------'.format(response))
+            return JsonResponse({'res': 'success'})
+        except Exception as e:
+            logger.info('--------插座ChangeReport异常--------:error_line:{}, error_msg:{}'.
+                        format(e.__traceback__.tb_lineno, repr(e)))
+            return JsonResponse({'res': 'error'})
+
     # 向alexa事件网关发送删除插座操作
     def deleteSwitch(self, request_dict):
         serial_number = request_dict.get("serial_number", '')