class bit_file: def __init__(self, f, bits_per_op, mode='read', keep_open=False, read_size=MAX_ENCODING, read_count=1): if mode not in ['read', 'write']: raise Exception('bad bit_file mode. Try "read" or "write"') self.mode = mode if isinstance(f, str): fmode = 'wb' if mode == 'write' else 'rb' self.f = open(f, fmode) self.keep_open = False else: self.f = f self.keep_open = keep_open # determines whether __exit__ is a flush()+close(), or just a flush() self.bits_per_op = bits_per_op self.stream = BitStream() self.read_size = read_size self.read_count = read_count def __enter__(self): return self def __exit__(self, type, value, traceback): if self.mode == 'write' and not self.f.closed: self.save() if not self.keep_open and not self.f.closed: with self.f: # close file pass def write(self, bits): if isinstance(bits, bit_write_buffer): bits = bits.stream if not isinstance(bits, Bits): bits = Bits(uint=bits, length=self.bits_per_op) self.stream.append(bits) def read(self): if self.read_count and self.stream.bitpos == self.stream.length: self.stream.clear() self.stream.append(Bits(bytes=self.f.read(self.read_size))) self.read_count -= 1 try: bits = self.stream.read(f'uint:{self.bits_per_op}') except bitstring.ReadError: try: bits = self.stream.read('uint') except bitstring.InterpretError: bits = 0 return bits def save(self): self.f.write(self.stream.tobytes())
if( usbEndpoint == INCOMING_ENDPOINT and usbHeader[0] != 'ABC' ): print 'Unexpected USB Header. Expected "0x414243", got "0x%s".' % ( usbHeader[0].encode( 'hex' ) ) raise Exception messageBuffer.append( usbBuffer.read( usbHeader[1] * 8 ) ) # Clear the messageBuffer if we have a full message # TODO - we need to be able to figure out if all 60 bytes are conusumed, but it's the end of the message if( usbHeader[1] < USB_PACKET_SIZE ): print >> sys.stderr, 'Message %s' % ( 'OUT' if usbEndpoint == OUTGOING_ENDPOINT else 'IN' ) print >> sys.stderr, 'Hex: %s' % ( messageBuffer.hex ) # TODO - make a bayerMessage to also handle standard command sequences and ASTM messages if( messageBuffer.bytes[0:2] != 'Q\x03' ): print >> sys.stderr, 'String: %s\n' % ( messageBuffer.bytes ) else: msg = BayerBinaryMessage.MessageFactory( messageBuffer, BayerBinaryMessage.OUT if usbEndpoint == OUTGOING_ENDPOINT else BayerBinaryMessage.IN, pumpSession ) if( msg is not None ): if( isinstance( msg, MtGetAttachedPumpMessage ) ): pumpSession.pumpSerial = msg.pumpSerial pumpSession.stickSerial = msg.stickSerial elif( isinstance( msg, MtFindPump ) ): pumpSession.radioChannel = msg.radioChannel print msg print messageBuffer.clear() i+=1 print "Processed %d messages" % ( i )
messageBuffer.append(usbBuffer.read(usbHeader[1] * 8)) # Clear the messageBuffer if we have a full message # TODO - we need to be able to figure out if all 60 bytes are conusumed, but it's the end of the message if (usbHeader[1] < USB_PACKET_SIZE): print >> sys.stderr, 'Message %s' % ( 'OUT' if usbEndpoint == OUTGOING_ENDPOINT else 'IN') print >> sys.stderr, 'Hex: %s' % (messageBuffer.hex) # TODO - make a bayerMessage to also handle standard command sequences and ASTM messages if (messageBuffer.bytes[0:2] != 'Q\x03'): print >> sys.stderr, 'String: %s\n' % (messageBuffer.bytes) else: msg = BayerBinaryMessage.MessageFactory( messageBuffer, BayerBinaryMessage.OUT if usbEndpoint == OUTGOING_ENDPOINT else BayerBinaryMessage.IN, pumpSession) if (msg is not None): if (isinstance(msg, ReadInfoResponse)): pumpSession.pumpSerial = msg.pumpSerial pumpSession.stickSerial = msg.stickSerial elif (isinstance(msg, NegotiateChannel)): pumpSession.radioChannel = msg.radioChannel print msg print messageBuffer.clear() i += 1 print "Processed %d messages" % (i)
class PacketDecoder(object): HEADER = "0x59" FOOTER = "0x5254464d" LENGTH = 56 * 8 PATTERN = "2BH9I8B2I" packet_store = [] def __init__(self, listener_func): self.listener_func = listener_func self.stream = BitStream() def push(self, byte_array): self.stream.append(byte_array) def handle(self): while True: if len(self.stream) < self.LENGTH: break # Look for a header header_pos = self.stream.find(self.HEADER) if header_pos: header_pos = header_pos[0] else: self.stream.clear() break end_pos = header_pos + self.LENGTH if len(self.stream) < end_pos: # Not Enough Data break # Extract potential packet potential_packet = self.stream[header_pos:end_pos].bytes valid_packet = self.analyze_packet(potential_packet) if valid_packet: self.stream = self.stream[end_pos:] else: self.stream = self.stream[header_pos + 1 :] self.save_packets() self.packet_store = [] def analyze_packet(self, byte_string): if len(byte_string) != 56: return data = struct.unpack(self.PATTERN, byte_string) header = data[0] footer = data[21] if hex(header) == self.HEADER and hex(footer) == self.FOOTER: if self.validate_checksums(data): packet = self.create_packet(data) self.packet_store.append(packet) return True return False def validate_checksums(self, packet_data): # voltage_checksum = packet_data[12] # current_checksum = packet_data[13] # period_checksum = packet_data[14] # active_checksum = packet_data[15] # reactive_checksum = packet_data[16] # apparent_power = packet_data[17] # phase_angle_checksum = packet_data[18] # power_factor_checksum = packet_data[19] # checksum = packet_data[20] return True def create_packet(self, packet_data): flags = packet_data[2] epoch = packet_data[3] voltage = packet_data[4] * (2.37748 * 10 ** -4) + -0.14427 current = packet_data[5] * (113240.82786) + 953.97194 period = packet_data[6] active_power = packet_data[7] reactive_power = packet_data[8] apparent_power = packet_data[9] phase_angle = packet_data[10] power_factor = packet_data[11] return Packet( flags=flags, epoch=epoch, voltage=voltage, current=current, period=period, active_power=active_power, reactive_power=reactive_power, apparent_power=apparent_power, phase_angle=phase_angle, power_factor=power_factor, ) def save_packets(self): # submit packets to lib if self.packet_store: self.listener_func(self.packet_store)
class PacketDecoder(object): HEADER = '0x59' FOOTER = '0x5254464d' LENGTH = 56 * 8 PATTERN = "2BH9I8B2I" packet_store = [] def __init__(self, listener_func): self.listener_func = listener_func self.stream = BitStream() def push(self, byte_array): self.stream.append(byte_array) def handle(self): while True: if len(self.stream) < self.LENGTH: break #Look for a header header_pos = self.stream.find(self.HEADER) if header_pos: header_pos = header_pos[0] else: self.stream.clear() break end_pos = header_pos + self.LENGTH if len(self.stream) < end_pos: # Not Enough Data break # Extract potential packet potential_packet = self.stream[header_pos:end_pos].bytes valid_packet = self.analyze_packet(potential_packet) if valid_packet: self.stream = self.stream[end_pos:] else: self.stream = self.stream[header_pos + 1:] self.save_packets() self.packet_store = [] def analyze_packet(self, byte_string): if len(byte_string) != 56: return data = struct.unpack(self.PATTERN, byte_string) header = data[0] footer = data[21] if hex(header) == self.HEADER and hex(footer) == self.FOOTER: if self.validate_checksums(data): packet = self.create_packet(data) self.packet_store.append(packet) return True return False def validate_checksums(self, packet_data): #voltage_checksum = packet_data[12] #current_checksum = packet_data[13] #period_checksum = packet_data[14] #active_checksum = packet_data[15] #reactive_checksum = packet_data[16] #apparent_power = packet_data[17] #phase_angle_checksum = packet_data[18] #power_factor_checksum = packet_data[19] #checksum = packet_data[20] return True def create_packet(self, packet_data): flags = packet_data[2] epoch = packet_data[3] voltage = packet_data[4] * (2.37748 * 10**-4) + -0.14427 current = packet_data[5] * (113240.82786) + 953.97194 period = packet_data[6] active_power = packet_data[7] reactive_power = packet_data[8] apparent_power = packet_data[9] phase_angle = packet_data[10] power_factor = packet_data[11] return Packet( flags=flags, epoch=epoch, voltage=voltage, current=current, period=period, active_power=active_power, reactive_power=reactive_power, apparent_power=apparent_power, phase_angle=phase_angle, power_factor=power_factor, ) def save_packets(self): # submit packets to lib if self.packet_store: self.listener_func(self.packet_store)
def dataCollect(self, args): """ init of _pf for further data analysis and presentation """ p_process_start= re.compile(r'Event log entries: [[]newest entry first[]]') p_process_found = False skip_lines = 4 self._dataDict = collections.OrderedDict() self._time = 0 self._dataDict['timestampHex'] = [] self._dataDict['timestamp'] = [] self._dataDict['timeLast'] = [] self._dataDict['timeLastInUs'] = [] self._dataDict['processId'] = [] self._dataDict['processName'] = [] self._dataDict['bfn'] = [] self._dataDict['ssn'] = [] self._dataDict['eventId'] = [] self._dataDict['eventIdHex'] = [] self._dataDict['eventName'] = [] self._dataDict['extraInfo'] = [] self._dataDict['extraInfo_parse'] = [] self._dataDict['note'] = [] self._dataDict['origin'] = [] entryList = [] entryIndex = 0 complete_block = False p_close = re.compile(r"^\n") p_data = re.compile(r'\w+\s+(.*)') currentLine = 0 endLine = 0 startLine = 0 if args.maxNumEventEntries > 0: assert(args.endEntry <= args.maxNumEventEntries) bufferEnd = None call("ag --numbers 'Max file size reached, dump aborted:' {} > temp".format(args.logFile), shell=True) if os.path.getsize("./temp") != 0: bufferEnd = check_output("ag --numbers 'Max file size reached, dump aborted:' {}".format(args.logFile), shell=True) os.remove("./temp") if bufferEnd: print('"Max file size reached, dump aborted" found') bufferEnd = bufferEnd.decode('utf-8') endLine = int(bufferEnd.split(":")[0]) - 2 # skip non-data lines directly if args.maxNumEventEntries == 0 and args.endEntry == 0: args.maxNumEventEntries = 30000 print("warning: Max file size reached in ecda dump {}, and dump aborted, filter out latest 30000 entries".format(args.logFile)) elif args.maxNumEventEntries and args.endEntry == 0: print("warning: Max file size reached in ecda dump {}, and dump aborted, filter out latest {} entries".format(args.logFile, args.maxNumEventEntries)) elif args.maxNumEventEntries == 0 and args.endEntry : print("warning: Max file size reached in ecda dump {}, and dump aborted, filter out entries from {} to {}".format(args.logFile, args.startEntry, args.endEntry)) elif args.maxNumEventEntries and args.endEntry : print("warning: Max file size reached in ecda dump {}, and dump aborted, filter out entries from {} to {}".format(args.logFile, args.startEntry, max(args.endEntry, args.startEntry+args.maxNumEventEntries))) bufferStart= None call("ag --numbers 'newest entry first' {} > temp".format(args.logFile), shell=True) if os.path.getsize("./temp") != 0: bufferStart= check_output("ag --numbers 'newest entry first' {}".format("temp"), shell=True) os.remove("./temp") if bufferStart: bufferStart= bufferStart.decode('utf-8') allLines = bufferStart.split("\n") startLine = int(allLines[1].split(":")[1]) + 5 #skip non-data ,include current line else: print("warning: no event log entry found in {}, return without parsing".format(args.logFile)) return if endLine == 0: bufferEnd= check_output("ag --numbers 'End of dump' {}".format(args.logFile), shell=True) assert(bufferEnd) #shall never be None print('"End of dump" found') bufferEnd = bufferEnd.decode('utf-8') endLine = int(bufferEnd.split(":")[0]) - 2 # skip non-data lines directly if args.startEntry < args.endEntry or args.maxNumEventEntries: print("info expect endEntry {}, maxNumEventEntries {} real entriesTotal {}".format(args.endEntry, args.maxNumEventEntries, (endLine-startLine)*2 )) endTemp = max(startLine + (args.endEntry>>1), startLine + (args.maxNumEventEntries>>1)) endLine = min(endTemp, endLine) startLine += (args.startEntry>>1) # skip non-data lines directly print("info: parse event entries from {} to {}".format(args.startEntry, (endLine-startLine)*2+args.startEntry)) eventLogEntryBitStream = BitStream() with open(args.logFile) as f: for line in f: #if p_process_start.search(line) and complete_block is False: # # skip part event log block # complete_block = True # continue ##if p_process_found is False and p_process_start.search(line): ## p_process_found = True ## continue ##if p_process_found and skip_lines > 0: ## skip_lines -= 1 ## continue ##if p_process_found and p_close.search(line): ## p_process_found = False ## break ##if args.maxNumEventEntries : ## if maxNumLines > 0: ## maxNumLines -= 1 ## else: ## break currentLine += 1 #ag counter from 1 if currentLine >= startLine and currentLine < endLine: #[startline,endline) if (currentLine - startLine)%1000 == 0: print("{} entries collected".format((currentLine - startLine)*2)) ##if p_process_found and skip_lines == 0: #m = p_data.search(line) ##print(line) #data = m.group(1).split(" ") #if len(data) == 4: # eventLogEntryBitStream.append('0x'+data[0]) # eventLogEntryBitStream.append('0x'+data[1]) # eventLogEntryBitStream.append('0x'+data[2]) # eventLogEntryBitStream.append('0x'+data[3]) # self.dataEntryAppend(eventLogEntryBitStream) # eventLogEntryBitStream.clear() # entryList.append(entryIndex) # entryIndex += 1 #else: # # two event entries of 64 bits for each # eventLogEntryBitStream.append('0x'+data[0]) # eventLogEntryBitStream.append('0x'+data[1]) # eventLogEntryBitStream.append('0x'+data[2]) # eventLogEntryBitStream.append('0x'+data[3]) # self.dataEntryAppend(eventLogEntryBitStream) # eventLogEntryBitStream.clear() # entryList.append(entryIndex) # entryIndex += 1 # eventLogEntryBitStream.append('0x'+data[4]) # eventLogEntryBitStream.append('0x'+data[5]) # eventLogEntryBitStream.append('0x'+data[6]) # eventLogEntryBitStream.append('0x'+data[7]) # self.dataEntryAppend(eventLogEntryBitStream) # eventLogEntryBitStream.clear() # entryList.append(entryIndex) # entryIndex += 1 data = line.strip().split(" ") # offset '' entries if len(data) == 6: eventLogEntryBitStream.append('0x'+data[2]) eventLogEntryBitStream.append('0x'+data[3]) eventLogEntryBitStream.append('0x'+data[4]) eventLogEntryBitStream.append('0x'+data[5]) self.dataEntryAppend(eventLogEntryBitStream) eventLogEntryBitStream.clear() entryList.append(entryIndex) entryIndex += 1 else: # two event entries of 64 bits for each eventLogEntryBitStream.append('0x'+data[2]) eventLogEntryBitStream.append('0x'+data[3]) eventLogEntryBitStream.append('0x'+data[4]) eventLogEntryBitStream.append('0x'+data[5]) self.dataEntryAppend(eventLogEntryBitStream) eventLogEntryBitStream.clear() entryList.append(entryIndex) entryIndex += 1 eventLogEntryBitStream.append('0x'+data[6]) eventLogEntryBitStream.append('0x'+data[7]) eventLogEntryBitStream.append('0x'+data[8]) eventLogEntryBitStream.append('0x'+data[9]) self.dataEntryAppend(eventLogEntryBitStream) eventLogEntryBitStream.clear() entryList.append(entryIndex) entryIndex += 1 print("--finish 64 bit eventlog entry collection") pass