def handle_on_connect(self): topic = '/aaiot/mqttService/receive/controlbus/system/heartbeat' self.connectObject.subscribe(topic, qos=QOS_LOCAL) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format(topic, QOS_LOCAL)) topic = '/aaiot/+/receive/controlbus/event/websocket/city_weather/0' self.connectObject.subscribe(topic, qos=QOS_LOCAL) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format(topic, QOS_LOCAL))
def updataSelfStatus(self,status): if self.type == 'button' or self.type == 'channel': if status == 'on' or status == 'off': self.channel_value = status elif self.type == 'level': try: self.level_value = float(status) except: pass elif self.type == 'string': self.string_value = status elif self.type == 'macro': if status == 'on' or status == 'off': self.channel_value = status else: yield logClient.tornadoInfoLog('聚集通道狀態反饋錯誤:{}'.format(status)) elif self.type == 'matrix': if isinstance(status,dict): self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog('矩阵通道:{}更新状态为:{}'.format(self.name, self.matrix_value)) else: try: status = json.loads(status) self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog('矩阵通道:{}更新状态为:{}'.format(self.name,self.matrix_value)) except: yield logClient.tornadoErrorLog(status) elif self.type == 'none': if self.feedback == 'button' or self.feedback == 'channel': if status == 'on' or status == 'off': self.channel_value = status elif self.feedback == 'level': try: self.level_value = float(status) except: pass elif self.feedback == 'string': self.string_value = status elif self.feedback == 'matrix': if isinstance(status, dict): self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog('矩阵通道:{}更新状态为:{}'.format(self.name, self.matrix_value)) else: try: status = json.loads(status) self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog('矩阵通道:{}更新状态为:{}'.format(self.name, self.matrix_value)) except: yield logClient.tornadoErrorLog(status) else: yield logClient.tornadoErrorLog('未知通道:{}'.format(self.guid)) return else: yield logClient.tornadoErrorLog('未知通道:{}'.format(self.guid)) return for callback in self.updateCallback: yield callback(self.guid,self.getSelfStatus())
def handle_message(self): try: while self.mosquittoReceiveBuffer: try: msg = self.mosquittoReceiveBuffer.pop(0) except: return topic = msg.get('topic') topic_list = msg.get('topic_list') control_event = msg.get('data') data = { 'type': 'control', 'topic': topic, 'topic_list': topic_list, 'control_event': control_event } meeting_room_guid = topic_list[1] type_ = topic_list[5] if type_ == 'command': channel = topic_list[7] if channel == 'macro': #计算macro信息 try: macro_info = json.loads(control_event) except: macro_info = [] yield self.updateMeetingRoomMacro( meeting_room_guid, macro_info) data = { 'type': 'sync_device', 'meeting_room_guid': meeting_room_guid } yield logClient.tornadoDebugLog(json_dumps(data)) for websocketObject in self.websocketObject.clientObjectSet: if meeting_room_guid in websocketObject.meeting_room_list: websocketObject.sendToClientService( json_dumps(data)) else: yield logClient.tornadoDebugLog(json_dumps(data)) if topic_list[5] == 'macro': yield self.macroControlHandle(meeting_room_guid, topic, topic_list, control_event) else: yield self.transmitControlComand( meeting_room_guid, data) except Exception as e: yield logClient.tornadoErrorLog(str(e)) self.handle_message_task = None
def handle_on_connect(self): topic = '/aaiot/mqttService/receive/controlbus/system/heartbeat' self.connectObject.subscribe(topic, qos=QOS_LOCAL) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/websocket/#' self.connectObject.subscribe(topic, qos=QOS_LOCAL) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/device/update_authorization/#' self.connectObject.subscribe(topic, qos=QOS_LOCAL) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL))
def minuteTask(self): # todo: time事件 yield logClient.tornadoDebugLog('一分钟事件触发') self.ioloop.add_timeout(self.ioloop.time() // 60 * 60 + 60, self.minuteTask) now_ = datetime.datetime.now() compare_hour = now_.hour compare_minute = now_.minute # compare_second = now_.second # compare_year = now_.year # compare_month = now_.month # compare_day = now_.day topic = '/aaiot/0/send/controlbus/event/time/{}/{}'.format( compare_hour, compare_minute) if compare_hour == 0 and compare_minute == 0: update_schedule_flag = 1 else: update_schedule_flag = 0 yield self.myPublish(topic, '', qos=QOSLOCAL) for meeting_room_guid, meeting_room_object in self.meetingRoomDict.items( ): yield meeting_room_object.handleSelfSchedule( update_schedule=update_schedule_flag)
def on_message(self, client, userdata, message): # 1 获取主题,数据 topic = message.topic topic_list = self.TopicToList(topic) logClient.tornadoDebugLog(topic + ' ' + message.payload.decode()) if len(topic_list) < 6: return data = { 'topic': topic, 'data': message.payload.decode(), 'topic_list': topic_list } self.mosquittoReceiveBuffer.append(data) if self.handle_message_task == None: self.handle_message_task = 1 asyncio.ensure_future(self.handle_message(), loop=self.aioloop).add_done_callback( self.handleMessageCallback)
def updateLabelInfo(self,name,company_db,delayFlag=None,callback=None): now_time = time.time() brush_info = yield self.getSelfInfo() if callback == None: if brush_info == self.lastBrushInfo: yield logClient.tornadoInfoLog('会议室:{},两次推送内容相同,取消推送'.format(name)) return if now_time - self.lastBrushTime < 60: yield logClient.tornadoInfoLog('会议室:{},两次推送间隔太短,启动延时推送'.format(name)) if self.waitBrushTask != None: #有任务 yield logClient.tornadoDebugLog('会议室:{},存在相同任务,删除任务'.format(name)) self.ioloop.remove_timeout(self.waitBrushTask) else: yield logClient.tornadoDebugLog('会议室:{},无相同任务,添加任务'.format(name)) if callback == None: self.waitBrushTask = self.ioloop.add_timeout(self.ioloop.time() + 60-int((now_time - self.lastBrushTime)), self.updateLabelInfo, name,company_db, delayFlag) else: self.waitBrushTask = self.ioloop.add_timeout(self.ioloop.time() + 60-int((now_time - self.lastBrushTime)), self.updateLabelInfo, name,company_db, delayFlag, callback) return None self.lastBrushTime = now_time self.waitBrushTask = None yield self.checkSelfLabelTemplate(name) fault_count = 0 while True: result = yield self.brushSelfInfo(brush_info) if result == True: yield logClient.tornadoInfoLog('会议室:{},{}推送商品成功'.format(name,'延时' if delayFlag else '')) yield self.keepNowBrushInfo(brush_info) yield self.storageSelf(company_db) yield self.printNowBrushInfo(brush_info) break elif result == 501: yield logClient.tornadoErrorLog('会议室:{},推送商品token失效'.format(name)) yield self.eslCloudClient.tokenError() else: yield logClient.tornadoErrorLog('会议室:{},{}推送商品失败'.format(name,'延时' if delayFlag else '')) yield gen.sleep(10) fault_count += 1 if fault_count >= 10: break
def initMeetingRoom(self): for DATABASE in DATABASES: db = DATABASE['name'] # 获取公司名称 if db == 'aura': db_name = 'default' else: db_name = db data = { 'database': 'aura', 'fields': ['name'], 'eq': { 'database_name': db_name } } msg = yield mysqlClient.tornadoSelectOnly('d_company', data) if msg['ret'] == '0' and msg['lenght'] == 1: company_name = msg['msg'][0]['name'] else: yield logClient.tornadoErrorLog('数据库:{},查询错误:({})'.format( db, 'd_company')) continue data = { 'database': db, 'fields': [ 'guid', 'room_name', 'sin_minute', 'status_group_guid_id as schedule_status', ], 'eq': { 'is_delete': False, # 'guid':'ec5eadb8-9744-11e9-922b-5254002d0365', }, } msg = yield mysqlClient.tornadoSelectAll('d_meeting_room', data) if msg['ret'] == '0': room_list = msg['msg'] else: yield logClient.tornadoErrorLog('获取数据库:排程信息失败') continue for room_info in room_list: room_info['company_db'] = db room_info['company_name'] = company_name room_info['publish_function'] = self.myPublish meeting_room_object = MeetingRoom(**room_info) self.meetingRoomDict[ meeting_room_object.guid] = meeting_room_object else: yield logClient.tornadoDebugLog('会议室更新完成,开始分钟事件') self.ioloop.add_timeout(self.ioloop.time(), self.minuteTask)
def reportDeviceInfo(self, meeting_room_guid, device_list, macro_list): topic = '/aaiot/{}/receive/controlbus/event/command/0/device'.format( meeting_room_guid) data = { "type": "device", "devices_list": device_list, "marco_list": macro_list, "ts": time.time(), "status": "ok", "processTime": 0 } self.my_publish(topic, json_dumps(data)) yield logClient.tornadoDebugLog('同步设备,macro 信息给后台')
def handleOnMessage(self,mReceiveMessageObject): yield logClient.tornadoDebugLog(mReceiveMessageObject.topic) if mReceiveMessageObject.topicList[6] == 'city_weather': data = mReceiveMessageObject.data try: data = json.loads(data) except: return city_guid = data.get('city_guid') connection_token = data.get('connection_token') city = self.cityDict.get(city_guid) if city == None: return yield city.askSelfInfo(connection_token)
def wsClientLoopRun(self): '''接收websocket服务器的信息''' try: msg = yield self.serviceObject.read_message() except: msg = None # return if msg is None: yield logClient.tornadoInfoLog("connection closed") yield self.closeAllClient() else: msg = json.loads(msg) yield logClient.tornadoDebugLog('2---服务端信息:({})'.format(msg)) yield self.forwardInformation(json_dumps(msg)) self.ioloop.add_timeout(self.ioloop.time(), self.wsClientLoopRun)
def websocketSync(self, data): try: data = json.loads(data) except: return msg_type = data.get('type') if msg_type == None: return yield logClient.tornadoDebugLog('同步信息:类型为{}'.format(data.get('type'))) for clientObject in self.clientSet: for connection_token, user_info in clientObject.login_info.items(): func = self.typeToFunction.get(msg_type) if func == None: return yield func(clientObject, connection_token, user_info, data)
def storageSelf(self, company_db): goods_info = yield self.getSelfInfo() data = { 'database': company_db, 'msg': { 'update_time': datetime.datetime.now(), 'is_delete': False, }, 'eq': { 'barcode': goods_info.get('barcode') } } data['msg'] = {**goods_info, **data['msg']} msg = yield mysqlClient.tornadoUpdateMany('d_shop_goods', data) if msg['ret'] != '0': yield logClient.tornadoDebugLog('更新数据库:商品:{}信息失败'.format(goods_info.get('barcode'))) return
def on_message(self, data): ''' 1>接受前端的信息,2>发送给websocketService,3>接受websocketService的消息,4>分发给前端 ''' try: msg = json.loads(data) except JSONDecodeError as e: try: msg = eval(data) except: return if not isinstance(msg, dict): return yield logClient.tornadoDebugLog('1---中控客户端信息:{}'.format(msg)) msg_type = msg.get('type') if msg_type == 'login': self.meeting_room_list = msg.get('meeting_room_list') if self.login == None: self.login = True data = {'type': 'update_device', 'meeting_room_guid': None} self.sendToClientService(json_dumps(data)) if not self.login: return if msg_type == 'heartbeat': # self.lastHeartbeat = time.time() self.lastHeartbeat = msg.get('time') if msg_type == 'channel_status': #收到中控的通道反馈信息,通过网关同步回去 topic = msg.get('topic') data = msg.get('data') topic_list = self.TopicToList(topic) self.mosquittoClient.handleChannelSync(topic, topic_list, data) elif msg_type == 'update_device': yield logClient.tornadoInfoLog('从中控中获取设备更新信息') self.mosquittoClient.updateMeetingRoomDevice( msg.get('meeting_room_device_list')) elif msg_type == 'sync_device': yield logClient.tornadoInfoLog('从中控中获取设备同步信息') self.mosquittoClient.syncMeetingRoomDevice( msg.get('meeting_room_device_list'))
def wsClientLoopRun(self): '''接收websocket服务器的信息''' try: msg = yield self.connectionObject.read_message() except: msg = None # return if msg is None: yield logClient.tornadoInfoLog("connection closed") self.connectionObject = None self.ioloop.add_timeout(self.ioloop.time()+1, self.wsClientConnect) else: self.ioloop.add_timeout(self.ioloop.time(), self.wsClientLoopRun) try: msg = json.loads(msg) except: return yield logClient.tornadoDebugLog('2---收到服务端信息:({})'.format(msg)) type = msg.get('type') if type == 'control': topic = msg.get('topic') topic_list = msg.get('topic_list') control_event = msg.get('control_event') meeting_room_guid = topic_list[1] try: port = topic_list[6] port = int(port) except: return meeting_room_object = self.meeting_room_dict.get(meeting_room_guid) if meeting_room_object == None: return for device_guid, device_object in meeting_room_object.items(): if port == device_object.port or port == str(device_object.port): yield device_object.controlSelf(msg) elif type == 'update_device' or type == 'sync_device': meeting_room_guid = msg.get('meeting_room_guid') yield self.reportSelfDevice(type_info = type,meeting_room_guid=meeting_room_guid)
def get_meeting_room_info(self, msg): ''' msg = { 'ret':0, 'type': request_type, 'use_room_list':use_room_list, 'connection_token':connection_token, } ''' yield logClient.tornadoDebugLog('获取会议室info') connection_token = msg.get('connection_token') control_info = msg.get('control_info') room_list_info = [] # 获取房间信息 use_room_list = msg.get('use_room_list', []) if not isinstance(use_room_list, list): return for meeting_room_guid in use_room_list: if meeting_room_guid == None: continue #实体会议室 meeting_room_object = self.GuidToMeetingRoom.get(meeting_room_guid) if meeting_room_object: channel_info = yield self.getMeetingRoomChannelInfo( meeting_room_object) room_list_info.append(channel_info) for separate_group_info in self.separate_meeting_room_list: real_meeting_room_guid = separate_group_info.get( 'real_meeting_room_guid') if real_meeting_room_guid == meeting_room_guid: if control_info: separate_group_info['separate_mode'] = 0 msg = { 'ret': 0, 'type': 'separate_change', 'mode': separate_group_info.get('separate_mode'), 'meeting_room_info': { 'real_meeting_room_guid': real_meeting_room_guid, 'separate_meeting_room_guid_list': [ x['guid'] for x in separate_group_info.get( 'meeting_room_info') ] } } topic = '/aaiot/0/send/controlbus/event/websocket/0/separete_change' yield self.myPublish(topic, json_dumps(msg), QOS_LOCAL) elif separate_group_info['separate_mode'] == 1: # control_info = 1 msg = { 'ret': 0, 'type': 'separate_change', 'mode': separate_group_info.get('separate_mode'), 'meeting_room_info': { 'real_meeting_room_guid': real_meeting_room_guid, 'separate_meeting_room_guid_list': [ x['guid'] for x in separate_group_info.get( 'meeting_room_info') ] } } topic = '/aaiot/0/send/controlbus/event/websocket/0/separete_change' yield self.myPublish(topic, json_dumps(msg), QOS_LOCAL) else: #虚拟会议室 virtual_meeting_room_object = self.GuidToVirtualMeetingRoom.get( meeting_room_guid) if virtual_meeting_room_object != None: real_meeting_room_guid_list = virtual_meeting_room_object.get( 'real_meeting_room_guid_list') for real_meeting_room_guid in real_meeting_room_guid_list: if real_meeting_room_guid in use_room_list: continue real_meeting_room_object = self.GuidToMeetingRoom.get( real_meeting_room_guid) if real_meeting_room_object == None: continue channel_info = yield self.getMeetingRoomChannelInfo( real_meeting_room_object) room_list_info.append(channel_info) else: #分房会议室 for separate_group_info in self.separate_meeting_room_list: real_meeting_room_guid = separate_group_info.get( 'real_meeting_room_guid') for meeting_room_info in separate_group_info.get( 'meeting_room_info'): guid = meeting_room_info.get('guid') if meeting_room_guid == guid: if control_info: separate_group_info['separate_mode'] = 1 # 进入分房模式 msg = { 'ret': 0, 'type': 'separate_change', 'mode': separate_group_info.get( 'separate_mode'), 'meeting_room_info': { 'real_meeting_room_guid': real_meeting_room_guid, 'separate_meeting_room_guid_list': [ x['guid'] for x in separate_group_info. get('meeting_room_info') ] } } topic = '/aaiot/0/send/controlbus/event/websocket/0/separete_change' yield self.myPublish( topic, json_dumps(msg), QOS_LOCAL) elif separate_group_info['separate_mode'] == 0: # 进入分房模式 # control_info = 1 msg = { 'ret': 0, 'type': 'separate_change', 'mode': separate_group_info.get( 'separate_mode'), 'meeting_room_info': { 'real_meeting_room_guid': real_meeting_room_guid, 'separate_meeting_room_guid_list': [ x['guid'] for x in separate_group_info. get('meeting_room_info') ] } } topic = '/aaiot/0/send/controlbus/event/websocket/0/separete_change' yield self.myPublish( topic, json_dumps(msg), QOS_LOCAL) real_meeting_room_object = self.GuidToMeetingRoom.get( real_meeting_room_guid) if real_meeting_room_object == None: break channel_info = yield self.getMeetingRoomChannelInfo( real_meeting_room_object) #更改會議室名稱,和guid channel_info[ 'room_name'] = meeting_room_info.get( 'room_name') channel_info[ 'room_guid'] = meeting_room_info.get( 'guid') room_list_info.append(channel_info) break else: continue break if not control_info: msg = { 'ret': 0, 'type': 'info', 'room_info_list': room_list_info, 'connection_token': connection_token } topic = '/aaiot/0/send/controlbus/event/websocket/0/info' yield self.myPublish(topic, json_dumps(msg), QOS_LOCAL)
def handle_on_connect(self): topic = '/aaiot/mqttService/receive/controlbus/system/heartbeat' self.connectObject.subscribe(topic, qos=QOS_LOCAL) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/0/receive/controlbus/event/websocket/#' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的websocket事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/receive/controlbus/system/#' # 使用模式2订阅所有网关发送给会议室的心跳数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/button/#' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/channel/#' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/level/#' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/string/#' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/matrix/#' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/command/#' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) topic = '/aaiot/+/receive/controlbus/event/matrix/0/0' # 使用模式2订阅所有网关发送给会议室的button数据 self.connectObject.subscribe(topic, qos=QOS) yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS)) # # 监控作用 # topic = '/aaiot/+/send/controlbus/event/#' # self.mosquittoClient.subscribe(topic, qos=QOS) # 使用模式0订阅,自己发送给网关的控制数据 # topic = '/aaiot/+/send/controlbus/system/#' # self.mosquittoClient.subscribe(topic, qos=QOS) # 使用模式0订阅,自己发送给网关的心跳数据 # eventService的事件 topic = '/aaiot/+/send/controlbus/event/schedule/schedule_info/0' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的排程事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/schedule/remaining_time/#' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的排程事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/schedule/schedule_time/#' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的排程事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/recognition/0/0' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的识别事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/schedule/add' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的排程事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/schedule/remove' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的排程事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/schedule/change' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的排程事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/update/0/0' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地同步事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/time/#' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的时间事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/macro/add_change' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的时间事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL)) topic = '/aaiot/+/send/controlbus/event/macro/remove' self.connectObject.subscribe(topic, qos=QOS_LOCAL) # 使用模式0订阅,本地服务的时间事件 yield logClient.tornadoDebugLog('订阅主题:({}),qos=({})'.format( topic, QOS_LOCAL))
def on_message(self, data): ''' 1>接受前端的信息,2>发送给websocketService,3>接受websocketService的消息,4>分发给前端 ''' try: msg = json.loads(data) except JSONDecodeError as e: try: msg = eval(data) except: return if not isinstance(msg, dict): return yield logClient.tornadoDebugLog('1---客户端信息:{}'.format(msg)) # 获取操作类型 request_type = msg.get('type') # 1:获取连接token,直接生产一个token返回给前端 if request_type == 'login': if self.logined == 1: self.last_connection_token.append(self.connection_token) self.connection_token = uuid.uuid1().urn.split(':')[2] msg['connection_token'] = self.connection_token if self.host == None: # self.close() # return self.host = '127.0.0.1' msg['host'] = self.host self.server.sendToService(json_dumps(msg)) return # 2:接收心跳 elif request_type == 'heartbeat': self.lastHeartbeat = time.time() return # 3:否则转发websocketService else: connection_token = msg.get('connection_token', ) # 2.1:connection_token验证 if connection_token != self.connection_token: msg = { 'ret': 1, 'type': request_type, 'errmsg': 'connection_token error' } self.sendToWebsocketClient(json_dumps(msg)) return # 2.2:记录控制任务 if request_type == 'control': guid = msg.get('guid') meeting_room_guid = msg.get('meeting_room_guid') event_type = msg.get('event_type') if event_type == 'click' or event_type == 'on' or event_type == 'off' or event_type == 'pulse' or event_type == 'toggle': #查阅guid是否在上次控制缓存中 if guid in self.last_control_dict.keys(): if event_type == 'click': if msg['status'] == 'on': msg['status'] = 'off' elif msg['status'] == 'off': msg['status'] = 'on' yield self.sendToWebsocketClient(json_dumps(msg)) return else: self.last_control_dict[guid] = time.time() self.ioloop.add_timeout(self.ioloop.time() + 0.6, self.deleteControlRecord, guid) delay_time = self.sync_delay_dict.get(guid, 3) new_later_task = self.ioloop.add_timeout( self.ioloop.time() + delay_time, self.query_status, guid, meeting_room_guid) # 尝试获取相同guid已有查询任务 last_later_task = self.query_task_dict.get(guid) if last_later_task != None: self.ioloop.remove_timeout(last_later_task) self.query_task_dict[guid] = new_later_task self.server.sendToService(data) return
def forwardInformation(self, msg): ''' 功能: 将收到的信息,找到connection_token 相同的连接客户端,同步给他 1> channel_feedback类型(物联服务器主动推送消息) 需要判断是否有查询任务在等待,有查询任务则不推送 2> control类型(控制返回的假状态),需要处理聚集同步的事务 3> query类型(本服务查询,物联服务器返回的真实状态),直接同步 ''' try: msg = json.loads(msg) except: return msg_connection_token = msg.get('connection_token') msg_used = False for clientObject in self.clientObjectSet: # 遍历所有前端websocket连接用户 # connection_token 过滤 if clientObject.connection_token != msg_connection_token or msg_connection_token == None: continue msg_used = True #分类型处理 type_ = msg['type'] # channel_feedback类消息 -- 推送给connection_token相同的前端,如果有查询任务在等待,则不推送 if type_ == 'channel_feedback': channel_guid = msg.get('guid') # 获取同步信息guid信息 if channel_guid == None: continue # 如果通道guid不在查询字典中,说明可以推送给前端 if channel_guid not in clientObject.query_task_dict.keys(): # yield logClient.tornadoDebugLog('没有等待查询任务...推送信息:{}'.format(channel_guid)) yield clientObject.sendToWebsocketClient(msg) else: yield logClient.tornadoDebugLog( '查询任务等待中...不推送:{}'.format(channel_guid)) elif type_ == 'login': #获取登录结果 ret = msg.get('ret', 1) if ret == 0: #已登录状态,退出上一次登录 if clientObject.logined == 1: for last_connection_token in clientObject.last_connection_token: logont_msg = { 'type': 'logout', 'connection_token': last_connection_token } yield self.sendToService(json_dumps(logont_msg)) yield logClient.tornadoWarningLog( '删除上次登录token:{}'.format(last_connection_token)) else: clientObject.last_connection_token = [] #未登录状态 标注:已经登录 else: clientObject.logined = 1 yield clientObject.sendToWebsocketClient(msg) # 其他类型,直接推送 else: if type_ == 'device_switch': print(msg) yield clientObject.sendToWebsocketClient(msg) #判断是否是聚集通道,如果是聚集通道有同步的需要做同步 #只有控制聚集通道时,才同步 if type_ == 'control': channel_guid = msg.get('guid') # 获取同步信息guid信息 if channel_guid == None: continue # 获取聚集通达状态 channel_status = msg.get('status') # 获取聚集通道的状态 #1: 尝试判断是否为聚集通道 sync_info = self.sync_channel_dict.get(channel_guid) if sync_info != None: # 聚集通道 # 尝试获取状态相同的同步通道类别 sync_channel_list = sync_info.get(channel_status) if sync_channel_list == None: continue # 遍历所有通道同步的通道,发送假反馈给前端 for sync_channel_info in sync_channel_list: guid = sync_channel_info.get('sync_channel_guid') meeting_room_guid = sync_channel_info.get( 'meeting_room_guid') status = sync_channel_info.get('sync_channel_status') try: status = int(status) except: pass info = { 'ret': 0, 'type': 'control', 'guid': guid, 'meeting_room_guid': meeting_room_guid, 'status': status, 'connection_token': msg_connection_token } yield clientObject.sendToWebsocketClient(info) # 添加查询任务 delay_time = self.sync_delay_dict.get(guid, 3) new_later_task = clientObject.ioloop.add_timeout( self.ioloop.time() + delay_time, clientObject.query_status, guid, meeting_room_guid) last_later_task = clientObject.query_task_dict.get( guid) if last_later_task != None: clientObject.ioloop.remove_timeout(last_later_task) clientObject.query_task_dict[guid] = new_later_task #2: 尝试获取互斥 for mutex_group in self.mutex_group_list: channel_guid_list = mutex_group.get( 'channel_guid_list', []) if channel_guid in channel_guid_list: mutex_channel_info_dict = mutex_group.get( 'mutex_channel_info', []) master_info = mutex_channel_info_dict.get(channel_guid) if master_info == None: continue master_now_status = None for key, value in master_info.items(): if value == channel_status: master_now_status = key break if master_now_status != None: if master_now_status == 'negative_value': #其他通道取负值 other_channel_status = 'positive_value' elif master_now_status == 'positive_value': #其他通道取正值 other_channel_status = 'negative_value' else: continue for guid, mutex_channel_info in mutex_channel_info_dict.items( ): if guid != channel_guid: status = mutex_channel_info.get( other_channel_status) meeting_room_guid = mutex_channel_info.get( 'meeting_room_guid') try: status = int(status) except: pass info = { 'ret': 0, 'type': 'control', 'guid': guid, 'meeting_room_guid': meeting_room_guid, 'status': status, 'connection_token': msg_connection_token } yield clientObject.sendToWebsocketClient( info) # 添加查询任务 delay_time = self.sync_delay_dict.get( guid, 3) new_later_task = clientObject.ioloop.add_timeout( self.ioloop.time() + delay_time, clientObject.query_status, guid, meeting_room_guid) last_later_task = clientObject.query_task_dict.get( guid) if last_later_task != None: clientObject.ioloop.remove_timeout( last_later_task) clientObject.query_task_dict[ guid] = new_later_task else: continue else: if msg_used == False: logont_msg = { 'type': 'logout', 'connection_token': msg_connection_token } yield self.sendToService(json_dumps(logont_msg)) yield logClient.tornadoWarningLog( '删除上次登录token:{}'.format(msg_connection_token))
def updateSelfStatus(self, status): old_status = self.getSelfStatus() if old_status == status: return else: if self.type != 'matrix': msg = { 'type': 'channel_status', 'topic': self.receiveTopic, 'data': status } self.ioloop.add_timeout(self.ioloop.time(), self.websocketWrite, msg) if self.type == 'button' or self.type == 'channel': if status == 'on' or status == 'off': self.channel_value = status elif self.type == 'level': try: self.level_value = float(status) except: pass elif self.type == 'string': self.string_value = status elif self.type == 'macro': self.channel_value = status elif self.type == 'matrix': if isinstance(status, dict): self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog('矩阵通道:{}更新状态为:{}'.format( self.name, self.matrix_value)) else: try: status = json.loads(status) status = status.get('channel_guid') if old_status != status: self.matrix_value = status yield logClient.tornadoDebugLog( '矩阵通道:{}更新状态为:{}'.format(self.name, self.matrix_value)) msg = { 'type': 'channel_status', 'topic': self.receiveTopic, 'data': status } self.ioloop.add_timeout(self.ioloop.time(), self.websocketWrite, msg) # yield self.publish_function(self.receiveTopic, value, qos=2) except: yield logClient.tornadoErrorLog(status) elif self.type == 'none': if self.feedback == 'button' or self.feedback == 'channel': if status == 'on' or status == 'off': self.channel_value = status elif self.feedback == 'level': try: self.level_value = float(status) except: pass elif self.feedback == 'string': self.string_value = status elif self.feedback == 'matrix': if isinstance(status, dict): self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog('矩阵通道:{}更新状态为:{}'.format( self.name, self.matrix_value)) else: try: status = json.loads(status) self.matrix_value = status.get('channel_guid') yield logClient.tornadoDebugLog( '矩阵通道:{}更新状态为:{}'.format(self.name, self.matrix_value)) except: yield logClient.tornadoErrorLog(status) else: yield logClient.tornadoErrorLog('未知通道:{}'.format(self.guid)) return else: yield logClient.tornadoErrorLog('未知通道:{}'.format(self.guid)) return for callback in self.updateCallback: yield callback(self.guid, self.getSelfStatus())
def getMacroInfo(self, meeting_room_guid): topic = '/aaiot/{}/receive/controlbus/event/command/0/macro'.format( meeting_room_guid) data = '' self.my_publish(topic, data) yield logClient.tornadoDebugLog('获取macro信息')
def open(self, *args: str, **kwargs: str): self.meeting_room_guid = None if self not in self.clientSet: self.clientSet.add(self) yield logClient.tornadoDebugLog('websocket连接接入,当前登录用户数量{}'.format(len(self.clientSet)))
def on_close(self) -> None: # 从server的websocket对象集合中移除自己 self.clientSet.discard(self) yield logClient.tornadoDebugLog('websocket断开连接,当前登录用户数量{}'.format(len(self.clientSet))) del self
def open(self): self.server.clientObjectSet.add(self) yield logClient.tornadoDebugLog('websocket连接接入,当前连接数量:{}'.format( len(self.server.clientObjectSet)))