123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- # -*- encoding: utf-8 -*-
- """
- @File : SmartSocketController.py
- @Time : 2023/3/17 11:52
- @Author : stephen
- @Email : zhangdongming@asj6.wecom.work
- @Software: PyCharm
- """
- import logging
- import time
- from django.db import transaction
- from django.http import QueryDict
- from django.views import View
- from Model.models import SocketInfo, SocketSchedule, Device_Info
- from Object.ResponseObject import ResponseObject
- from Object.TokenObject import TokenObject
- 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):
- token = TokenObject(request.META.get('HTTP_AUTHORIZATION'))
- lang = request_dict.get('lang', 'cn')
- response = ResponseObject(lang)
- if token.code != 0:
- return response.json(token.code)
- if operation == 'addSwitch': # 添加插座开关
- return self.add_switch(request_dict, response)
- elif operation == 'addCountDown': # 添加插座倒计时
- return self.add_count_down(request_dict, response)
- elif operation == 'addSchedule': # 添加插座排程
- return self.save_socket_schedule(request_dict, response)
- return response.json(404)
- @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 add_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 add_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, 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:
- # 添加排程
- 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
|