|
@@ -7,11 +7,13 @@
|
|
|
import json
|
|
|
import time
|
|
|
|
|
|
+import requests
|
|
|
from django.core.exceptions import ObjectDoesNotExist
|
|
|
from django.db import transaction
|
|
|
from django.db.models import F, Q, Count
|
|
|
from django.views import View
|
|
|
|
|
|
+from Ansjer.config import DETECT_PUSH_DOMAINS
|
|
|
from Ansjer.Config.gatewaySensorConfig import SMART_SCENE_TOPIC, SENSOR_TYPE, EVENT_TYPE, SCENE_EVENT_CREATE, \
|
|
|
SCENE_EVENT_EDIT, SCENE_EVENT_DELETE, SCENE_STATUS_ON, SCENE_STATUS_OFF, SCENE_EVENT_EDIT_STATUS, \
|
|
|
VOICE_AUDITION_TOPIC, SMART_SOCKET_TOPIC, DEVICE_TYPE
|
|
@@ -379,11 +381,12 @@ class SmartSceneView(View):
|
|
|
return response.json(444, {'error param': 'invalid isAllDay'})
|
|
|
|
|
|
msg['time'] = time_dict
|
|
|
- msg['scene_id'] = smart_scene_qs.id
|
|
|
+ scene_id = smart_scene_qs.id
|
|
|
+ msg['scene_id'] = scene_id
|
|
|
|
|
|
# 获取设备任务数据
|
|
|
msg['task'], scene_data = cls.get_task_list_and_scene_data(
|
|
|
- conditions_dict, is_set_time, minutes, repeat, tz, now_time, tasks_list)
|
|
|
+ conditions_dict, is_set_time, minutes, repeat, tz, now_time, tasks_list, scene_id)
|
|
|
|
|
|
smart_scene_qs.device_data = json.dumps(msg)
|
|
|
smart_scene_qs.scene_data = scene_data
|
|
@@ -725,7 +728,8 @@ class SmartSceneView(View):
|
|
|
|
|
|
# 获取设备任务数据
|
|
|
msg['task'], scene_data = cls.get_task_list_and_scene_data(
|
|
|
- conditions_dict, is_set_time, minutes, repeat, tz, now_time, tasks_list, scene_data_dict)
|
|
|
+ conditions_dict, is_set_time, minutes, repeat, tz, now_time, tasks_list, smart_scene_id, scene_data_dict
|
|
|
+ )
|
|
|
|
|
|
with transaction.atomic():
|
|
|
smart_scene_qs.update(scene_name=scene_name, conditions=conditions, tasks=tasks, scene_data=scene_data,
|
|
@@ -1073,8 +1077,9 @@ class SmartSceneView(View):
|
|
|
return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
|
|
|
|
|
|
@classmethod
|
|
|
- def get_task_list_and_scene_data(cls, conditions_dict, is_set_time, minutes, repeat, tz, now_time, tasks_list,
|
|
|
- scene_data_dict=None):
|
|
|
+ def get_task_list_and_scene_data(
|
|
|
+ cls, conditions_dict, is_set_time, minutes, repeat, tz, now_time, tasks_list, scene_id,
|
|
|
+ scene_data_dict=None):
|
|
|
"""
|
|
|
获取设备任务数据和场景数据
|
|
|
@param tasks_list: app任务列表
|
|
@@ -1084,6 +1089,7 @@ class SmartSceneView(View):
|
|
|
@param repeat: 重复星期周期的十进制
|
|
|
@param tz: 时区
|
|
|
@param now_time: 当前时间
|
|
|
+ @param scene_id: 场景id
|
|
|
@param scene_data_dict: 场景数据
|
|
|
@return: task_list, scene_data
|
|
|
"""
|
|
@@ -1092,16 +1098,24 @@ class SmartSceneView(View):
|
|
|
task_list = []
|
|
|
scene_task_list = []
|
|
|
total_delay_time = 0
|
|
|
+ no_device_task = False
|
|
|
+ is_last_task = False
|
|
|
+ tasks_len = len(tasks_list)
|
|
|
|
|
|
# 组织条件数据
|
|
|
condition = cls.get_condition(conditions_dict, is_set_time, minutes, repeat, now_time, tz)
|
|
|
|
|
|
- for task in tasks_list:
|
|
|
+ for index, task in enumerate(tasks_list):
|
|
|
+ # 判断是否为列表的最后一个元素
|
|
|
+ if index == tasks_len - 1:
|
|
|
+ is_last_task = True
|
|
|
+
|
|
|
sensor_type = int(task['device_type'])
|
|
|
total_delay_time += task['delay_time']
|
|
|
# 处理插座数据
|
|
|
# 不用添加到设备的任务列表,添加到mqtt任务列表
|
|
|
if sensor_type == DEVICE_TYPE['socket']:
|
|
|
+ no_device_task = True
|
|
|
serial_number = task['serial_number']
|
|
|
event_type = int(task['event_type'])
|
|
|
delay_time = task['delay_time']
|
|
@@ -1114,8 +1128,12 @@ class SmartSceneView(View):
|
|
|
|
|
|
# 如果条件为设置时间,创建定时任务
|
|
|
if is_set_time:
|
|
|
+ smart_scene_id = 0
|
|
|
+ if no_device_task and is_last_task:
|
|
|
+ smart_scene_id = scene_id
|
|
|
task_temp['task_id'] = cls.create_aps_job(
|
|
|
- condition, minutes, total_delay_time, tz, repeat, sensor_type, event_type, serial_number)
|
|
|
+ condition, minutes, total_delay_time, tz, repeat, sensor_type, event_type, serial_number,
|
|
|
+ smart_scene_id)
|
|
|
scene_task_list.append(task_temp)
|
|
|
else:
|
|
|
task_temp = {
|
|
@@ -1265,7 +1283,8 @@ class SmartSceneView(View):
|
|
|
return False
|
|
|
|
|
|
@classmethod
|
|
|
- def create_aps_job(cls, condition, minutes, total_delay_time, tz, repeat, device_type, event_type, serial_number):
|
|
|
+ def create_aps_job(
|
|
|
+ cls, condition, minutes, total_delay_time, tz, repeat, device_type, event_type, serial_number, scene_id):
|
|
|
"""
|
|
|
创建定时任务
|
|
|
返回任务id和时间
|
|
@@ -1277,6 +1296,7 @@ class SmartSceneView(View):
|
|
|
@param device_type: 设备类型
|
|
|
@param event_type: 事件类型
|
|
|
@param serial_number: 序列号
|
|
|
+ @param scene_id: 场景id
|
|
|
@return: task_id
|
|
|
"""
|
|
|
task_id = serial_number + '_'
|
|
@@ -1286,7 +1306,7 @@ class SmartSceneView(View):
|
|
|
time_stamp = condition['time_dict']['time_stamp'] + total_delay_time
|
|
|
task_id += str(time_stamp)
|
|
|
apscheduler_obj.create_date_job(func=cls.pub_mqtt, task_id=task_id, time_stamp=time_stamp,
|
|
|
- args=(device_type, event_type, serial_number))
|
|
|
+ args=(device_type, event_type, serial_number, scene_id))
|
|
|
# 周期任务
|
|
|
else:
|
|
|
hour, minute, second, is_next_day = cls.handle_delay_time(minutes, total_delay_time)
|
|
@@ -1296,7 +1316,7 @@ class SmartSceneView(View):
|
|
|
task_id += time_str
|
|
|
apscheduler_obj.create_cron_job(func=cls.pub_mqtt, task_id=task_id, day_of_week=weeks,
|
|
|
hour=hour, minute=minute,
|
|
|
- args=(device_type, event_type, serial_number))
|
|
|
+ args=(device_type, event_type, serial_number, scene_id))
|
|
|
return task_id
|
|
|
|
|
|
@staticmethod
|
|
@@ -1344,12 +1364,13 @@ class SmartSceneView(View):
|
|
|
return weeks[:-1]
|
|
|
|
|
|
@staticmethod
|
|
|
- def pub_mqtt(device_type, event_type, serial_number):
|
|
|
+ def pub_mqtt(device_type, event_type, serial_number, scene_id=0):
|
|
|
"""
|
|
|
发布mqtt消息
|
|
|
@param device_type: 设备类型
|
|
|
@param event_type: 事件类型
|
|
|
@param serial_number: 序列号
|
|
|
+ @param scene_id: 场景id
|
|
|
@return:
|
|
|
"""
|
|
|
if device_type == DEVICE_TYPE['socket']:
|
|
@@ -1361,6 +1382,15 @@ class SmartSceneView(View):
|
|
|
}
|
|
|
CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
|
|
|
|
|
|
+ # 没有设备任务时,最后一个任务上报场景日志
|
|
|
+ if scene_id:
|
|
|
+ data = {
|
|
|
+ 'sceneId': scene_id,
|
|
|
+ 'status': 1
|
|
|
+ }
|
|
|
+ url = DETECT_PUSH_DOMAINS + 'gatewayService/sceneLogPush'
|
|
|
+ req = requests.post(url=url, data=data, timeout=8)
|
|
|
+
|
|
|
@staticmethod
|
|
|
def del_aps_job(scene_data_dict):
|
|
|
"""
|