def handle_registration(self, stream, address): try: # receives the 21-byte registration info and proceeds. # Otherwise yield and keep waiting. message = yield stream.read_bytes(21) # unpacks the received bytes into phone number, IP addr. reg_data = struct.unpack('!I11scIc', message) phone = reg_data[1] logger.info('Registered device(%s)' % phone) # adds this new device into database. device = Device(18, phone, stream) session.add(device) session.commit() self.device_dict[device.portid] = device except Exception as e: logger.exception('Register device(%s) failed' % phone) logger.exception('In handle_registration %s' % e) else: logger.info('[Device list] %s' % self.device_dict.keys()) device.colltype = 'R' self.handle_device(device)
def handle_registration(self, stream, address): try: # receives the 21-byte registration info and proceeds. # Otherwise yield and keep waiting. message = yield stream.read_bytes(21) # 读取设备首次上报的信息(非阻塞化) # unpacks the received bytes into phone number, IP addr. reg_data = struct.unpack('!I11scIc',message) phone = reg_data[1] logger.info('Registered device(%s)' % phone) # adds this new device into database. device = Device(18, phone, stream) # 这3行用sqlalchemy将device信息存入数据库 session.add(device) session.commit() self.device_dict[device.portid] = device # 同时信息保存一份到device_dict except Exception as e: logger.exception('Register device(%s) failed' % phone) # 一旦注册这一步异常,则do nothing next logger.exception('In handle_registration %s' % e) else: logger.info('[Device list] %s' % self.device_dict.keys()) device.colltype = 'R' self.handle_device(device) # 注册成功后的下一步操作
def handle_device(self, device, chktime=None): action = device.colltype or 'R' cmd = None try: # get msg from rabbitmq. # process the msg. if action == 'R': timestamp = now() data = yield self.collect_data(device, 4) # Ensures we only store data in a interval of 1 minute. if not device.chktime or (timestamp.minute != device.chktime.minute): device.chktime = timestamp logger.info("storing data") #devdata = DeviceData(data) #device.devdata.append(devdata) #session.add(device) #session.commit() logger.info('[Parsed data] %s' % data) delay = 60 - timestamp.second if delay > 55: # This is only for keeping the connection alive. # The data returned is not meant to be stored in database. self.io_loop.call_later(55, self.handle_device, device) else: self.io_loop.call_later(delay, self.handle_device, device) elif action == 'C': yield self.send_cmd(device, cmd) self.io_loop.add_callback(self.handle_device, device) elif action == 'H': chktime = chktime yield self.collect_data(device, 4, chktime=chktime) device.chktime = chktime # request history data from device right in the next iteration. #devdata = DeviceData(data) #device.devdata.append(devdata) #session.add(device) #session.commit() chktime += datetime.timedelta(0, 60, 0) self.io_loop.add_callback(self.handle_device, device, chktime) except Exception as e: logger.exception(str(e)) raise e
def handle_device(self, device, chktime=None): action = device.colltype or 'R' cmd = None try: # get msg from rabbitmq. # process the msg. if action == 'R': timestamp = now() data = yield self.collect_data(device, 4) # Ensures we only store data in a interval of 1 minute. if not device.chktime or (timestamp.minute != device.chktime.minute): device.chktime = timestamp logger.info("storing data") #devdata = DeviceData(data) #device.devdata.append(devdata) #session.add(device) #session.commit() logger.info('[Parsed data] %s' % data) delay = 60 - timestamp.second if delay > 55: # This is only for keeping the connection alive. # The data returned is not meant to be stored in database. self.io_loop.call_later(55, self.handle_device, device) else: self.io_loop.call_later(delay, self.handle_device, device) elif action == 'C': yield self.send_cmd(device, cmd) self.io_loop.add_callback(self.handle_device, device) elif action == 'H': chktime = chktime yield self.collect_data(device, 4, chktime=chktime) device.chktime = chktime # request history data from device right in the next iteration. #devdata = DeviceData(data) #device.devdata.append(devdata) #session.add(device) #session.commit() chktime += datetime.timedelta(0,60,0) self.io_loop.add_callback(self.handle_device, device, chktime) except Exception as e: logger.exception(str(e)) raise e # 通过raise唤醒阻塞处,返回值给阻塞调用者,而不是用return
def collect_data(self, device, data_type, interval=1, chktime=None): try: timestamp = now() if data_type == 4 and not chktime else chktime recv_frame = BitArray() request_frame = gen_collect_cmd_frame(device.devaddr, data_type, interval, timestamp) # sends out the inqury command frame. yield device.stream.write(request_frame.bytes) # receives the first 4 leading bytes recv_bytes = yield device.stream.read_bytes(4) leading, head, remain_length = struct.unpack('!HBB', recv_bytes) recv_frame += hex(leading) recv_frame += hex(head) recv_frame += hex(remain_length) # receives the remaining bytes from device. remain_bytes = yield device.stream.read_bytes(remain_length) for byte in remain_bytes: recv_frame += BitArray(uint=ord(byte), length=8) # unpacks the binary data into a Python dict object frame_dict = unpack_frame(remain_bytes, DATA_LENGTHS[data_type]) # parses those data bytes into JSON. data_json = parse_data(frame_dict['data']) logger.info('Received: %s' % recv_frame) except StreamClosedError: logger.exception('Device(%s) lost connection' % device.portid) self.device_dict.pop(device.portid) except Exception as e: logger.error('In collect_data %s' % str(e)) self.device_dict.pop(device.portid) device.stream.close() device.online = False else: raise gen.Return(data_json)
def collect_data(self, device, data_type, interval=1, chktime=None): try: timestamp = now() if data_type==4 and not chktime else chktime recv_frame = BitArray() request_frame = gen_collect_cmd_frame(device.devaddr, data_type, interval, timestamp) # sends out the inqury command frame. yield device.stream.write(request_frame.bytes) # receives the first 4 leading bytes recv_bytes = yield device.stream.read_bytes(4) leading, head, remain_length = struct.unpack('!HBB', recv_bytes) recv_frame += hex(leading) recv_frame += hex(head) recv_frame += hex(remain_length) # receives the remaining bytes from device. remain_bytes = yield device.stream.read_bytes(remain_length) for byte in remain_bytes: recv_frame += BitArray(uint=ord(byte), length=8) # unpacks the binary data into a Python dict object frame_dict = unpack_frame(remain_bytes, DATA_LENGTHS[data_type]) # parses those data bytes into JSON. data_json = parse_data(frame_dict['data']) logger.info('Received: %s' % recv_frame) except StreamClosedError: logger.exception('Device(%s) lost connection' % device.portid) self.device_dict.pop(device.portid) except Exception as e: logger.error('In collect_data %s' % str(e)) self.device_dict.pop(device.portid) device.stream.close() device.online = False else: raise gen.Return(data_json)
def main(): puller = Puller() puller.listen(8777) logger.info('Starting Puller instance......') mainloop=ioloop.IOLoop.instance() mainloop.start()
def handle_stream(self, stream, address): logger.info('New connection from %s' % str(address)) self.handle_registration(stream, address)
def main(): puller = Puller() puller.listen(8777) logger.info('Starting Puller instance......') mainloop = ioloop.IOLoop.instance() mainloop.start()
def handle_stream(self, stream, address): logger.info('New connection from %s' % str(address)) self.handle_registration(stream, address) # 处理设备的首次连接,当注册