# -*- encoding: utf-8 -*- """ @File : GatewayDeviceController.py @Time : 2022/6/6 13:50 @Author : stephen @Email : zhangdongming@asj6.wecom.work @Software: PyCharm """ import time from django.db import transaction from django.db.models import Q from django.views.generic.base import View from Ansjer.Config.gatewaySensorConfig import SMART_SCENE_TOPIC from Controller.SensorGateway.EquipmentFamilyController import EquipmentFamilyView from Model.models import FamilyRoomDevice, FamilyRoom, GatewaySubDevice, Device_Info, UserFamily, FamilyMember, \ UidSetModel, iotdeviceInfoModel, SmartScene, SceneLog, SocketInfo, SocketPowerStatistics from Object.ResponseObject import ResponseObject from Object.TokenObject import TokenObject from Service.CommonService import CommonService class GatewayDeviceView(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 = TokenObject(request.META.get('HTTP_AUTHORIZATION')) lang = request_dict.get('lang', None) response = ResponseObject(lang) if lang else ResponseObject(token.lang) if token.code != 0: return response.json(token.code) user_id = token.userID # 网关设备 if operation == 'list': return self.gateway_device_list(request_dict, response) elif operation == 'del': return self.gateway_device_del(user_id, request_dict, response) elif operation == 'update': return self.gateway_device_update(user_id, request_dict, response) elif operation == 'my/family/list': return self.my_family_list(user_id, response) elif operation == 'location-setting': return self.device_location_setting(user_id, request_dict, response) @classmethod def device_location_setting(cls, user_id, request_dict, response): """ 网关位置迁移 @param user_id: 用户id @param request_dict: 请求参数字典 @param response: 响应对象 @return: [] """ device_id = request_dict.get('deviceId', None) family_id = request_dict.get('familyId', None) room_id = request_dict.get('roomId', None) if not all([device_id, family_id]): return response.json(444) family_id = int(family_id) permission = EquipmentFamilyView.get_member_permission_details(user_id, family_id) if not permission or permission == '003': return response.json(404) try: with transaction.atomic(): family_room_device_qs = FamilyRoomDevice.objects.filter(device_id=device_id, family_id=family_id) if family_room_device_qs.exists(): family_room_device_qs = family_room_device_qs.filter(sub_device=0) if family_room_device_qs.exists() and room_id: family_room_device_qs.update(room_id=int(room_id)) else: user_family_qs = UserFamily.objects.filter(id=family_id) if not user_family_qs: return response.json(173) family_room_device_qs = FamilyRoomDevice.objects.filter(device_id=device_id) if family_room_device_qs.exists(): param_data = {'family_id': family_id, 'room_id': 0} if room_id: param_data['room_id'] = room_id family_room_device_qs.update(**param_data) return response.json(0) except Exception as e: print(e) return response.json(177, repr(e)) @classmethod def gateway_device_update(cls, user_id, request_dict, response): """ 网关设备修改名称 @param user_id: @param request_dict: @param response: @return: """ device_name = request_dict.get('deviceName') device_id = request_dict.get('deviceId') if not all([device_name, device_id]): return response.json(444) device_info_qs = Device_Info.objects.filter(userID_id=user_id, id=device_id) if device_info_qs.exists(): device_info_qs.update(NickName=device_name) uid_set_qs = UidSetModel.objects.filter(uid=device_info_qs[0].UID) if uid_set_qs.exists(): uid_set_qs.update(nickname=device_name) return response.json(0) @classmethod def my_family_list(cls, user_id, response): """ 我的家庭列表 @param user_id: @param response: @return: """ user_family_qs = UserFamily.objects.filter(user_id=user_id).values() family_list = [] if user_family_qs.exists(): family_member_qs = FamilyMember.objects.filter(user_id=user_id, identity=1) \ .order_by('sort').values('identity', 'family_id', 'family__name', 'permission_id', 'permission__no', 'family__location', 'user__username', 'user__userIconUrl') items = EquipmentFamilyView.family_info_list(family_member_qs) return response.json(0, items) return response.json(0, family_list) @classmethod def gateway_device_del(cls, user_id, request_dict, response): """ 网关设备删除或删除子设备 @param user_id: @param request_dict: @param response: @return: """ device_id = request_dict.get('deviceId') family_id = request_dict.get('familyId') # 1 删除网关 否则删除子设备 sub_ids = request_dict.get('subIds') if not family_id: return response.json(444) permission = EquipmentFamilyView.get_member_permission_details(user_id, family_id) if not permission or permission == '003': return response.json(404) try: with transaction.atomic(): if device_id: device_qs = Device_Info.objects.filter(id=device_id) if device_qs.exists(): family_device_qs = FamilyRoomDevice.objects.filter(device_id=device_id) if family_device_qs.exists(): family_device_qs.delete() uid_set_qs = UidSetModel.objects.filter(uid=device_qs.first().UID) if uid_set_qs.exists(): uid_set_qs.delete() # 如果有子设备,删除子设备和关联的场景数据 gateway_qs = GatewaySubDevice.objects.filter(device_id=device_id) if gateway_qs.exists(): sub_id_list = gateway_qs.values_list('id', flat=True) smart_scene_qs = SmartScene.objects.filter( Q(device_id=device_id) | Q(sub_device_id__in=sub_id_list)) else: smart_scene_qs = SmartScene.objects.filter(device_id=device_id) if smart_scene_qs.exists(): # 通知设备删除场景id smart_scene_info = smart_scene_qs.values('id') serial_number = device_qs.first().serial_number topic_name = SMART_SCENE_TOPIC.format(serial_number) for smart_scene in smart_scene_info: msg = { 'smart_scene_delete': int(smart_scene['id']) } success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg) try: assert success except AssertionError: return response.json(10044) time.sleep(0.3) smart_scene_qs.delete() gateway_qs.delete() # 删除子设备 scene_log_qs = SceneLog.objects.filter(device_id=device_id) if scene_log_qs.exists(): scene_log_qs.delete() device_qs.delete() elif sub_ids: sub_ids = sub_ids.split(',') ids = [] for item in sub_ids: sub_id = int(item) ids.append(sub_id) sub_device_qs = GatewaySubDevice.objects.filter(id=sub_id).values('device_type', 'src_addr', 'device__serial_number') serial_number = sub_device_qs[0]['device__serial_number'] topic_name = SMART_SCENE_TOPIC.format(serial_number) device_type = sub_device_qs[0]['device_type'] if device_type == 216: # 删除智能按钮通知设备 msg = { 'sos_delete': int(sub_device_qs[0]['src_addr'], 16) } success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg) try: assert success except AssertionError: return response.json(10044) time.sleep(0.3) family_device_qs = FamilyRoomDevice.objects.filter(sub_device__in=ids) if family_device_qs.exists(): family_device_qs.delete() gateway_sub_qs = GatewaySubDevice.objects.filter(id__in=ids) if gateway_sub_qs.exists(): gateway_sub_qs.delete() smart_scene_qs = SmartScene.objects.filter(sub_device_id__in=ids) if smart_scene_qs.exists(): smart_scene_info = smart_scene_qs.values('id') for smart_scene in smart_scene_info: # 通知设备删除场景id msg = { 'smart_scene_delete': int(smart_scene['id']) } success = CommonService.req_publish_mqtt_msg(serial_number, topic_name, msg) try: assert success except AssertionError: return response.json(10044) time.sleep(0.3) smart_scene_qs.delete() scene_log_qs = SceneLog.objects.filter(sub_device_id__in=ids) if scene_log_qs.exists(): scene_log_qs.delete() return response.json(0) except Exception as e: print(e) return response.json(177, repr(e)) @classmethod def gateway_device_list(cls, request_dict, response): """ 网关设备列表 @param request_dict: @param response: @return: """ device_id = request_dict.get('deviceId', None) if not device_id: return response.json(444) device_qs = FamilyRoomDevice.objects.filter(device_id=device_id, sub_device=0) if not device_qs.exists(): return response.json(173) try: device_qs = device_qs.values('family_id', 'device_id', 'room_id', 'device__Type', 'device__NickName', 'device__UID', 'device__serial_number') device_qs = device_qs.first() room_id = device_qs['room_id'] family_id = device_qs['family_id'] gateway_room_name = '' if room_id: room_qs = FamilyRoom.objects.filter(id=room_id) gateway_room_name = room_qs.first().name if room_qs.exists() else '' iot_device_info_qs = iotdeviceInfoModel.objects.filter( serial_number=device_qs['device__serial_number'][0:6]) iot_data = {} if iot_device_info_qs.exists(): iot_device_Info = iot_device_info_qs.values('endpoint', 'token_iot_number') iot_data = { 'endpoint': iot_device_Info[0]['endpoint'], 'token_iot_number': iot_device_Info[0]['token_iot_number'] } gateway = { 'deviceId': device_qs['device_id'], 'deviceType': device_qs['device__Type'], 'deviceNickName': device_qs['device__NickName'], 'UID': device_qs['device__UID'], 'serialNumber': device_qs['device__serial_number'], 'roomName': gateway_room_name, 'iot': iot_data, 'roomId': room_id, 'familyId': family_id, 'power': 0, 'electricity': 0, 'countDownTime': 0, 'socketStatus': False, 'online': False, 'accumulatedTime': 0, 'start': False, } if device_qs['device__Type'] == 201: socket_info_qs = SocketInfo.objects.filter(device_id=device_id) if not socket_info_qs.exists(): return response.json(173) socket_data = cls.smart_socket(device_id) gateway['power'] = socket_data['power'] gateway['electricity'] = socket_data['electricity'] gateway['countDownTime'] = socket_data['countDownTime'] gateway['accumulatedTime'] = socket_data['accumulatedTime'] gateway['socketStatus'] = socket_data['socketStatus'] gateway['online'] = socket_data['online'] gateway['start'] = socket_data['start'] family_device_qs = FamilyRoomDevice.objects.filter(device_id=device_id) family_device_qs = family_device_qs.filter(~Q(sub_device=0)).order_by('-created_time') sub_device = [] sub_id_list = [] if family_device_qs.exists(): family_device_qs = family_device_qs.values() for item in family_device_qs: sub_id = item['sub_device'] sub_id_list.append(sub_id) gateway_sub_qs = GatewaySubDevice.objects.filter(device_id=device_id, id=sub_id).values( 'id', 'device_type', 'nickname', 'src_addr', 'status', 'created_time', 'ieee_addr') if not gateway_sub_qs.exists(): continue room_id = item['room_id'] room_qs = FamilyRoom.objects.filter(id=room_id) gateway_room_name = room_qs.first().name if room_qs.exists() else '' gateway_sub_qs = gateway_sub_qs.first() sub_device.append({ 'gatewaySubId': gateway_sub_qs['id'], 'nickName': gateway_sub_qs['nickname'], 'deviceType': gateway_sub_qs['device_type'], 'srcAddr': gateway_sub_qs['src_addr'], 'status': gateway_sub_qs['status'], 'createdTime': gateway_sub_qs['created_time'], 'roomName': gateway_room_name, 'roomId': room_qs.first().id if room_qs.exists() else 0, 'ieeeAddr': gateway_sub_qs['ieee_addr'], 'familyId': family_id, }) scene_count = SmartScene.objects.filter(Q(device_id=device_id) | Q(sub_device_id__in=sub_id_list)).count() res = {'gateway': gateway, 'sub_device': sub_device, 'sub_device_count': len(sub_device), 'scene_count': scene_count} return response.json(0, res) except Exception as e: print(e.args) return response.json(500) @classmethod def smart_socket(cls, device_id): """ 查詢插座信息 """ data = { 'power': 0, 'electricity': 0, 'countDownTime': 0, 'accumulatedTime': 0, 'socketStatus': False, 'online': False, 'start': False, } # 插座信息 socket_info_qs = SocketInfo.objects.filter(device_id=device_id).values('online', 'type_switch', 'status', 'count_down_time', 'start') # 插座信息 data['socketStatus'] = socket_info_qs[0]['status'] if socket_info_qs[0]['status'] else False data['start'] = socket_info_qs[0]['start'] if socket_info_qs[0]['status'] else False data['online'] = socket_info_qs[0]['online'] if socket_info_qs[0]['online'] else False data['countDownTime'] = socket_info_qs[0]['count_down_time'] if socket_info_qs[0][ 'count_down_time'] else 0 # 查詢插座電量 socket_power_qs = SocketPowerStatistics.objects.filter(device_id=device_id).values('accumulated_time', 'power', 'electricity') if not socket_power_qs.exists(): return data data['power'] = socket_power_qs[0]['power'] data['electricity'] = socket_power_qs[0]['electricity'] data['accumulatedTime'] = socket_power_qs[0]['accumulated_time'] return data # # ___====-_ _-====___ # _--^^^#####// \\#####^^^--_ # _-^##########// ( ) \\##########^-_ # -############// |\^^/| \\############- # _/############// (@::@) \\############\_ # /#############(( \\// ))#############\ # -###############\\ (oo) //###############- # -#################\\ / VV \ //#################- # -###################\\/ \//###################- # _#/|##########/\######( /\ )######/\##########|\#_ # |/ |#/\#/\#/\/ \#/\##\ | | /##/\#/ \/\#/\#/\#| \| # ` |/ V V ` V \#\| | | |/#/ V ' V V \| ' # ` ` ` ` / | | | | \ ' ' ' ' # ( | | | | ) # __\ | | | | /__ # (vvv(VVV)(VVV)vvv) # 神兽保佑 # 代码无BUG! #