SmartSwitchController.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. # -*- coding: utf-8 -*-
  2. """
  3. # @Author : cheng
  4. # @Time : 2023/7/10 11:20
  5. # @File: SmartSwitchController.py
  6. """
  7. import datetime
  8. import json
  9. import os
  10. import threading
  11. import time
  12. from django.views import View
  13. from Model.models import SwitchDimmingSettings, SwitchChronopher, Device_Info, SceneLog, FamilyRoomDevice, \
  14. SwitchOperateLog
  15. from Object.RedisObject import RedisObject
  16. from Service.CommonService import CommonService
  17. from Object.ApschedulerObject import ApschedulerObject
  18. from django.db import transaction
  19. from Ansjer.config import LOGGER
  20. APSCHEDULER_TOPIC_NAME = 'loocam/switch/time_scheduling/{}' # 排程主题
  21. RESET_SWITCH_TOPIC_NAME = 'loocam/smart-switch/{}' # 重置设备
  22. class SmartSwitchView(View):
  23. def get(self, request, *args, **kwargs):
  24. request.encoding = 'utf-8'
  25. operation = kwargs.get('operation')
  26. return self.validation(request.GET, request, operation)
  27. def post(self, request, *args, **kwargs):
  28. request.encoding = 'utf-8'
  29. operation = kwargs.get('operation')
  30. return self.validation(request.POST, request, operation)
  31. def validation(self, request_dict, request, operation):
  32. token_code, user_id, response = CommonService.verify_token_get_user_id(request_dict, request)
  33. if operation == 'switch-chronopher-log': # 设备上报排程日志
  34. return self.create_chronopher_log(request_dict, response)
  35. if operation == 'switch-operate-log': # 设备上报操作日志
  36. return self.create_operate_log(request_dict, response)
  37. elif operation == 'reset': # 设备重置
  38. return self.reset(request_dict, response)
  39. else:
  40. if token_code != 0:
  41. return response.json(token_code)
  42. if operation == 'get-dimming-setting': # 获取智能开关调光设置
  43. return self.get_dimming_setting(request_dict, response)
  44. elif operation == 'get-chronopher-setting': # 获取定时计划
  45. return self.get_chronopher_setting(request_dict, response)
  46. elif operation == 'add-or-edit-chronopher': # 添加/编辑定时计划
  47. return self.add_or_edit_chronopher(request_dict, response)
  48. elif operation == 'delete-chronopher': # 删除定时计划
  49. return self.delete_chronopher(request_dict, response)
  50. elif operation == 'edit-dimming-correction': # 设置调光校正
  51. return self.edit_dimming_correction(request_dict, response)
  52. elif operation == 'edit-dimming-setting': # 修改智能开关调光设置
  53. return self.edit_dimming_setting(request_dict, response)
  54. elif operation == 'get-chronopher-log': # 查询排程日志
  55. return self.get_chronopher_log(request_dict, response)
  56. elif operation == 'get-operate-log': # 查询普通操作日志
  57. return self.get_operate_log(request_dict, response)
  58. else:
  59. return response.json(414)
  60. @staticmethod
  61. def get_dimming_setting(request_dict, response):
  62. """
  63. 获取智能开关调光设置信息
  64. @param request_dict: 请求参数
  65. @request_dict deviceId: 设备id
  66. @param response: 响应对象
  67. @return: response
  68. """
  69. device_id = request_dict.get('deviceId', None)
  70. if not device_id:
  71. return response.json(444)
  72. try:
  73. switch_setting_info_qs = SwitchDimmingSettings.objects.filter(device_id=device_id).values()
  74. if not switch_setting_info_qs.exists():
  75. return response.json(173)
  76. res = {
  77. 'clickTurnOnSpeed': switch_setting_info_qs[0]['click_turn_on_speed'],
  78. 'clickTurnOffSpeed': switch_setting_info_qs[0]['click_turn_off_speed'],
  79. 'doubleClick': switch_setting_info_qs[0]['double_click'],
  80. 'press': switch_setting_info_qs[0]['press'],
  81. 'doublePressClickTurnOnSpeed': switch_setting_info_qs[0]['double_press_click_turn_on_speed'],
  82. 'doublePressClickTurnOffSpeed': switch_setting_info_qs[0]['double_press_click_turn_off_speed'],
  83. 'dimmingCorrection': switch_setting_info_qs[0]['dimming_correction'],
  84. }
  85. return response.json(0, res)
  86. except Exception as e:
  87. print(e)
  88. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  89. @staticmethod
  90. def edit_dimming_correction(request_dict, response):
  91. """
  92. 修改智能开关调光校正
  93. @param request_dict: 请求参数
  94. @request_dict deviceId: 设备id
  95. @request_dict dimmingCorrection: 调光校正
  96. @param response: 响应对象
  97. @return: response
  98. """
  99. device_id = request_dict.get('deviceId', None)
  100. dimming_correction = request_dict.get('dimmingCorrection', None)
  101. if not device_id:
  102. return response.json(444)
  103. try:
  104. SwitchDimmingSettings.objects.filter(device_id=device_id).update(dimming_correction=dimming_correction)
  105. return response.json(0)
  106. except Exception as e:
  107. print(e)
  108. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  109. @staticmethod
  110. def edit_dimming_setting(request_dict, response):
  111. """
  112. 修改智能开关调光设置
  113. @param request_dict: 请求参数
  114. @request_dict deviceId: 设备id
  115. @request_dict clickTurnOnSpeed: 单击开启速度
  116. @request_dict clickTurnOffSpeed: 单击关闭速度
  117. @request_dict doubleClick: 双击
  118. @request_dict press: 长按
  119. @request_dict doublePressClickTurnOnSpeed: 双击/长按开启速度
  120. @request_dict doublePressClickTurnOffSpeed: 双击/长按单击关闭速度
  121. @param response: 响应对象
  122. @return: response
  123. """
  124. device_id = request_dict.get('deviceId', None)
  125. click_turn_on_speed = request_dict.get('clickTurnOnSpeed', None)
  126. click_turn_off_speed = request_dict.get('clickTurnOffSpeed', None)
  127. double_click = request_dict.get('doubleClick', None)
  128. press = request_dict.get('press', None)
  129. double_press_click_turn_on_speed = request_dict.get('doublePressClickTurnOnSpeed', None)
  130. double_press_click_turn_off_speed = request_dict.get('doublePressClickTurnOffSpeed', None)
  131. if not device_id:
  132. return response.json(444)
  133. try:
  134. dimming_setting_data = {
  135. 'device_id': device_id,
  136. 'click_turn_on_speed': click_turn_on_speed,
  137. 'click_turn_off_speed': click_turn_off_speed,
  138. 'double_click': double_click,
  139. 'press': press,
  140. 'double_press_click_turn_on_speed': double_press_click_turn_on_speed,
  141. 'double_press_click_turn_off_speed': double_press_click_turn_off_speed
  142. }
  143. SwitchDimmingSettings.objects.filter(device_id=device_id).update(**dimming_setting_data)
  144. return response.json(0)
  145. except Exception as e:
  146. print(e)
  147. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  148. @staticmethod
  149. def get_chronopher_setting(request_dict, response):
  150. """
  151. 获取定时计划设置
  152. @param request_dict: 请求参数
  153. @request_dict deviceId: 设备id
  154. @param response: 响应对象
  155. @return: response
  156. """
  157. device_id = request_dict.get('deviceId', None)
  158. if not device_id:
  159. return response.json(444)
  160. try:
  161. switch_chronopher_qs = SwitchChronopher.objects.filter(device_id=device_id).values()
  162. if not switch_chronopher_qs.exists():
  163. return response.json(173)
  164. switch_chronopher_list = []
  165. for item in switch_chronopher_qs:
  166. switch_chronopher_list.append({
  167. 'chronopherId': item['id'],
  168. 'timeTypeRadio': item['time_type_radio'],
  169. 'timePoint': item['time_point'],
  170. 'timeQuantumStartTime': item['time_quantum_start_time'],
  171. 'timeQuantumEndTime': item['time_quantum_end_time'],
  172. 'timePointDeviceWillDoing': item['time_point_device_will_doing'],
  173. 'timeQuantumDeviceWillDoing': item['time_quantum_device_will_doing'],
  174. 'slowOpenOrCloseSpeed': item['slow_open_or_close_speed'],
  175. 'repeat': item['repeat'],
  176. })
  177. return response.json(0, {'list': switch_chronopher_list})
  178. except Exception as e:
  179. print(e)
  180. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  181. @staticmethod
  182. def add_or_edit_chronopher(request_dict, response):
  183. """
  184. 添加/编辑定时计划
  185. @param request_dict: 请求参数
  186. @request_dict deviceId: 设备id
  187. @request_dict chronopherId: 定时计划id
  188. @request_dict timeTypeRadio: 切换时间点/时间段
  189. @request_dict timePoint: 时间点
  190. @request_dict timeQuantumStartTime: 时间段开始时间
  191. @request_dict timeQuantumEndTime: 时间段结束时间
  192. @request_dict timePointDeviceWillDoing: 设备将会
  193. @request_dict timeQuantumDeviceWillDoing: 设备将会
  194. @request_dict slowOpenOrCloseSpeed: 缓慢开/关速度
  195. @request_dict repeat: 重复周期
  196. @param response: 响应对象
  197. @return: response
  198. """
  199. is_edit = request_dict.get('isEdit', None)
  200. device_id = request_dict.get('deviceId', None)
  201. chronopher_id = request_dict.get('chronopherId', None)
  202. time_type_radio = int(request_dict.get('timeTypeRadio', 0))
  203. time_point = request_dict.get('timePoint', None)
  204. time_quantum_start_time = request_dict.get('timeQuantumStartTime', None)
  205. time_quantum_end_time = request_dict.get('timeQuantumEndTime', None)
  206. time_point_device_will_doing = request_dict.get('timePointDeviceWillDoing', None)
  207. time_quantum_device_will_doing = request_dict.get('timeQuantumDeviceWillDoing', None)
  208. slow_open_or_close_speed = request_dict.get('slowOpenOrCloseSpeed', None)
  209. repeat = request_dict.get('repeat', None)
  210. if not all([device_id, repeat]):
  211. return response.json(444, {'param': 'deviceId,repeat'})
  212. device_qs = Device_Info.objects.filter(id=device_id).values('serial_number')
  213. if not device_qs.exists():
  214. return response.json(173)
  215. if time_type_radio == 1: # 时间点
  216. if not all([time_point, slow_open_or_close_speed]):
  217. return response.json(444, {'param': 'timePoint,slowOpenOrCloseSpeed'})
  218. chronopher_data = {
  219. 'device_id': device_id,
  220. 'time_type_radio': time_type_radio,
  221. 'time_point': time_point,
  222. 'time_point_device_will_doing': time_point_device_will_doing,
  223. 'slow_open_or_close_speed': slow_open_or_close_speed,
  224. 'repeat': repeat
  225. }
  226. elif time_type_radio == 2: # 时间段
  227. if not all([time_quantum_start_time, time_quantum_end_time]):
  228. return response.json(444, {'param': 'timeQuantumStartTime,timeQuantumEndTime'})
  229. time_quantum_start_time = int(time_quantum_start_time)
  230. time_quantum_end_time = int(time_quantum_end_time)
  231. chronopher_data = {
  232. 'device_id': device_id,
  233. 'time_type_radio': time_type_radio,
  234. 'time_quantum_start_time': time_quantum_start_time,
  235. 'time_quantum_end_time': time_quantum_end_time,
  236. 'time_quantum_device_will_doing': time_quantum_device_will_doing,
  237. 'repeat': repeat
  238. }
  239. else:
  240. return response.json(444, {'param': 'timeTypeRadio'})
  241. try:
  242. with transaction.atomic():
  243. apscheduler_obj = ApschedulerObject()
  244. if is_edit:
  245. if not chronopher_id:
  246. return response.json(444, {'param': 'timeTypeRadio'})
  247. update_flag = SwitchChronopher.objects.filter(device_id=device_id, id=chronopher_id).update(
  248. **chronopher_data)
  249. if not update_flag:
  250. return response.json(173)
  251. apscheduler_obj.del_job('switchchronopher_{}'.format(chronopher_id))
  252. apscheduler_obj.del_job('switchchronopher_{}_1'.format(chronopher_id))
  253. apscheduler_obj.del_job('switchchronopher_{}_2'.format(chronopher_id))
  254. else:
  255. switch_qs = SwitchChronopher.objects.create(**chronopher_data)
  256. chronopher_id = switch_qs.id
  257. # 设置定时任务
  258. serial_number = device_qs[0]['serial_number']
  259. topic_name = APSCHEDULER_TOPIC_NAME.format(serial_number)
  260. if time_type_radio == 1:
  261. task_id = 'switchchronopher_{}'.format(chronopher_id)
  262. if time_point_device_will_doing in ['0', '1']: # 开启或关闭
  263. msg = {
  264. "taskId": chronopher_id,
  265. "deviceSwitch": int(time_point_device_will_doing), # 设备开关-1:反转,0:关,1:开,2:预设亮度
  266. "slowTime": slow_open_or_close_speed
  267. }
  268. else: # 开启且设置亮度
  269. msg = {
  270. "taskId": chronopher_id,
  271. "deviceSwitch": 2,
  272. "pwmControl": int(time_point_device_will_doing),
  273. 'slowTime': slow_open_or_close_speed
  274. }
  275. time_str = datetime.datetime.fromtimestamp(int(time_point))
  276. apscheduler_obj.create_cron_job(SmartSwitchView.send_mqtt, task_id, repeat, time_str.hour,
  277. time_str.minute, [serial_number, topic_name, msg, task_id])
  278. else:
  279. start_hour = int(time_quantum_start_time / 60 // 60)
  280. start_minute = int(time_quantum_start_time / 60 % 60)
  281. end_hour = int(time_quantum_end_time / 60 // 60)
  282. end_minute = int(time_quantum_end_time / 60 % 60)
  283. if time_quantum_device_will_doing in ['0', '1']:
  284. begin_task_id = 'switchchronopher_{}_1'.format(chronopher_id) # 开始任务id
  285. end_task_id = 'switchchronopher_{}_2'.format(chronopher_id) # 结束任务id
  286. msg = {"taskId": chronopher_id,
  287. "deviceSwitch": int(time_quantum_device_will_doing)}
  288. apscheduler_obj.create_cron_job(SmartSwitchView.send_mqtt, begin_task_id, repeat, start_hour,
  289. start_minute, [serial_number, topic_name, msg, begin_task_id])
  290. msg = {"taskId": chronopher_id,
  291. "deviceSwitch": 0 if int(time_quantum_device_will_doing) == 1 else 1}
  292. apscheduler_obj.create_cron_job(SmartSwitchView.send_mqtt, end_task_id, repeat, end_hour,
  293. end_minute, [serial_number, topic_name, msg, end_task_id])
  294. else: # 间隔任务
  295. minute = int(time_quantum_device_will_doing)
  296. task_id = 'switchchronopher_{}'.format(chronopher_id) # 开始任务id
  297. msg = {"taskId": chronopher_id,
  298. "deviceSwitch": -1}
  299. if minute >= 60:
  300. hour = '{}-{}/{}'.format(start_hour, end_hour, minute // 60)
  301. minute = start_minute
  302. else:
  303. hour = '{}-{}'.format(start_hour, end_hour)
  304. minute = '{}/{}'.format(start_minute, minute)
  305. apscheduler_obj.create_cron_job(SmartSwitchView.send_mqtt, task_id, repeat, hour, minute,
  306. [serial_number, topic_name, msg, task_id])
  307. return response.json(0)
  308. except Exception as e:
  309. print(e)
  310. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  311. @staticmethod
  312. def delete_chronopher(request_dict, response):
  313. """
  314. 删除定时计划
  315. @param request_dict: 请求参数
  316. @request_dict deviceId: 设备id
  317. @request_dict chronopherId: 定时计划id
  318. @param response: 响应对象
  319. @return: response
  320. """
  321. device_id = request_dict.get('deviceId', None)
  322. chronopher_id = request_dict.get('chronopherId', None)
  323. if not chronopher_id:
  324. return response.json(444, {'error param': 'deviceId or chronopherId'})
  325. try:
  326. delete_flag = SwitchChronopher.objects.filter(device_id=device_id, id=chronopher_id).delete()
  327. if not delete_flag[0]:
  328. return response.json(173)
  329. apscheduler_obj = ApschedulerObject()
  330. apscheduler_obj.del_job('switchchronopher_{}'.format(chronopher_id)) # 删除定时任务
  331. apscheduler_obj.del_job('switchchronopher_{}_1'.format(chronopher_id))
  332. apscheduler_obj.del_job('switchchronopher_{}_2'.format(chronopher_id))
  333. return response.json(0)
  334. except Exception as e:
  335. print(e)
  336. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  337. @staticmethod
  338. def send_mqtt(serial_number, topic_name, msg, task_id):
  339. """
  340. 定时发送mqtt, (不要随意更改,否则定时任务不执行)
  341. @param serial_number: 设备序列号
  342. @param topic_name: 主题
  343. @param msg: 消息
  344. @param task_id: 任务id
  345. @return: response
  346. """
  347. now_time = int(time.time())
  348. msg['implementTime'] = now_time
  349. redis_obj = RedisObject()
  350. is_lock = redis_obj.CONN.setnx(task_id + 'do_notify', 1)
  351. redis_obj.CONN.expire(task_id + 'do_notify', 60)
  352. if not is_lock:
  353. return
  354. result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg, qos=0)
  355. LOGGER.info('定时发送mqtt结果:{},参数:{},{},{},{},{},线程:{},进程:{}'.format(result, serial_number, topic_name, msg,
  356. now_time, task_id,
  357. threading.get_ident(), os.getpid()))
  358. redis_obj.del_data(key=task_id + 'do_notify')
  359. @staticmethod
  360. def create_chronopher_log(request_dict, response):
  361. """
  362. 生成执行日志
  363. @param request_dict: 请求参数
  364. @request_dict serialNumber: 设备序列号
  365. @request_dict chronopherId: 排程id
  366. @request_dict status: 执行状态
  367. @param response: 响应对象
  368. @return: response
  369. """
  370. serial_number = request_dict.get('serialNumber', None)
  371. chronopher_id = request_dict.get('taskId', None)
  372. operate_status = request_dict.get('status', None)
  373. switch_status = request_dict.get('switchStatus', None)
  374. implement_time = request_dict.get('implementTime', None)
  375. if not all([serial_number, chronopher_id, operate_status, switch_status, implement_time]):
  376. return response.json(444, {'error param': 'deviceId or chronopherId'})
  377. device_qs = Device_Info.objects.filter(serial_number=serial_number).values('id')
  378. if not device_qs.exists():
  379. return response.json(173)
  380. device_id = device_qs[0]['id']
  381. chronopher_qs = SwitchChronopher.objects.filter(device_id=device_id, id=chronopher_id).values(
  382. 'time_type_radio', 'time_point', 'time_quantum_start_time', 'time_quantum_end_time',
  383. 'time_point_device_will_doing', 'time_quantum_device_will_doing', 'slow_open_or_close_speed', 'repeat')
  384. if not chronopher_qs.exists():
  385. return response.json(173)
  386. try:
  387. scene_log = {
  388. 'scene_id': chronopher_id,
  389. 'device_id': device_id,
  390. 'tasks': json.dumps(chronopher_qs[0]),
  391. 'status': operate_status,
  392. 'created_time': implement_time,
  393. }
  394. scene_qs = SceneLog.objects.filter(created_time=implement_time, device_id=device_id,
  395. scene_id=chronopher_id)
  396. if not scene_qs.exists():
  397. SceneLog.objects.create(**scene_log)
  398. operate_log = {
  399. 'device_id': device_id,
  400. 'status': switch_status,
  401. 'operate_type': 2,
  402. 'created_time': implement_time
  403. }
  404. operate_qs = SwitchOperateLog.objects.filter(**operate_log)
  405. if not operate_qs.exists():
  406. SwitchOperateLog.objects.create(**operate_log)
  407. return response.json(0)
  408. except Exception as e:
  409. print(e)
  410. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  411. @staticmethod
  412. def get_chronopher_log(request_dict, response):
  413. """
  414. 查询排程执行日志
  415. @param request_dict: 请求参数
  416. @request_dict deviceId: 设备id
  417. @param response: 响应对象
  418. @return: response
  419. """
  420. device_id = request_dict.get('deviceId', None)
  421. if not device_id:
  422. return response.json(444, {'error param': 'deviceId'})
  423. try:
  424. scene_qs = SceneLog.objects.filter(device_id=device_id).values('tasks', 'status', 'created_time', 'id')
  425. res = []
  426. for item in scene_qs:
  427. res.append({
  428. 'id': item['id'],
  429. 'tasks': json.loads(item['tasks']),
  430. 'status': item['status'],
  431. 'created_time': item['created_time']
  432. })
  433. return response.json(0, res)
  434. except Exception as e:
  435. print(e)
  436. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  437. @staticmethod
  438. def reset(request_dict, response):
  439. """
  440. 查询执行日志
  441. @param request_dict: 请求参数
  442. @request_dict serialNumber: 设备序列号
  443. @param response: 响应对象
  444. @return: response
  445. """
  446. serial_number = request_dict.get('serialNumber', None)
  447. if not serial_number:
  448. return response.json(444, {'error param': 'serialNumber'})
  449. device_qs = Device_Info.objects.filter(serial_number=serial_number).values('id')
  450. if not device_qs.exists():
  451. return response.json(173)
  452. device_id = device_qs[0]['device_id']
  453. try:
  454. # 删除智能开关数据
  455. SwitchDimmingSettings.objects.filter(device_id=device_id).delete()
  456. chronopher_qs = SwitchChronopher.objects.filter(device_id=device_id)
  457. if chronopher_qs.exists():
  458. chronopher_id = chronopher_qs[0].id
  459. apscheduler_obj = ApschedulerObject()
  460. apscheduler_obj.del_job('switchchronopher_{}'.format(chronopher_id)) # 删除定时任务
  461. apscheduler_obj.del_job('switchchronopher_{}_1'.format(chronopher_id))
  462. apscheduler_obj.del_job('switchchronopher_{}_2'.format(chronopher_id))
  463. chronopher_qs.delete()
  464. SceneLog.objects.filter(device_id=device_id).delete()
  465. FamilyRoomDevice.objects.filter(device_id=device_id).delete()
  466. Device_Info.objects.filter(id=device_id).delete()
  467. except Exception as e:
  468. print(e)
  469. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  470. @staticmethod
  471. def del_switch(device_id, serial_number):
  472. """
  473. 删除开关
  474. @param device_id: 设备id
  475. @param serial_number: 设备序列号
  476. @return: response
  477. """
  478. try:
  479. SwitchDimmingSettings.objects.filter(device_id=device_id).delete()
  480. chronopher_qs = SwitchChronopher.objects.filter(device_id=device_id)
  481. if chronopher_qs.exists():
  482. chronopher_id = chronopher_qs[0].id
  483. apscheduler_obj = ApschedulerObject()
  484. apscheduler_obj.del_job('switchchronopher_{}'.format(chronopher_id)) # 删除定时任务
  485. apscheduler_obj.del_job('switchchronopher_{}_1'.format(chronopher_id))
  486. apscheduler_obj.del_job('switchchronopher_{}_2'.format(chronopher_id))
  487. chronopher_qs.delete()
  488. SceneLog.objects.filter(device_id=device_id).delete()
  489. msg = {
  490. "device_reset": 1 # 重置智能开关
  491. }
  492. topic_name = RESET_SWITCH_TOPIC_NAME.format(serial_number)
  493. result = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg)
  494. LOGGER.info('执行重置开关mqtt结果:{}'.format(result))
  495. except Exception as e:
  496. print(e)
  497. LOGGER.info('error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  498. @staticmethod
  499. def create_operate_log(request_dict, response):
  500. """
  501. 设备上报排程日志
  502. @param request_dict: 请求参数
  503. @request_dict serialNumber: 设备序列号
  504. @param response: 响应对象
  505. @return: response
  506. """
  507. serial_number = request_dict.get('serialNumber', None)
  508. status = request_dict.get('switchStatus', None)
  509. implement_time = request_dict.get('implementTime', None)
  510. if not all([serial_number, status, implement_time]):
  511. return response.json(444, {'error param': 'deviceId or chronopherId'})
  512. device_qs = Device_Info.objects.filter(serial_number=serial_number).values('id')
  513. if not device_qs.exists():
  514. return response.json(173)
  515. device_id = device_qs[0]['id']
  516. try:
  517. operate_log = {
  518. 'device_id': device_id,
  519. 'status': status,
  520. 'created_time': implement_time,
  521. }
  522. operate_qs = SwitchOperateLog.objects.filter(**operate_log)
  523. if not operate_qs.exists():
  524. SwitchOperateLog.objects.create(**operate_log)
  525. return response.json(0)
  526. except Exception as e:
  527. print(e)
  528. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))
  529. @staticmethod
  530. def get_operate_log(request_dict, response):
  531. """
  532. 查询普通操作日志
  533. @param request_dict: 请求参数
  534. @request_dict deviceId: 设备id
  535. @param response: 响应对象
  536. @return: response
  537. """
  538. device_id = request_dict.get('deviceId', None)
  539. if not device_id:
  540. return response.json(444, {'error param': 'deviceId'})
  541. try:
  542. scene_qs = SwitchOperateLog.objects.filter(device_id=device_id).values('status', 'created_time', 'id',
  543. 'operate_type')
  544. return response.json(0, list(scene_qs))
  545. except Exception as e:
  546. print(e)
  547. return response.json(500, 'error_line:{}, error_msg:{}'.format(e.__traceback__.tb_lineno, repr(e)))