def parse(cls, address, data): '''Used to parse data received from Mijia. Currently supports versions 3 and 5 of the protocol. Arguments: address (str): MAC address of Mijia. data (bytes): received data in bytes. ''' b = BitArray(bytes=bytearray.fromhex(data)) if len(b) == 160: uuid, flag, id, index, mac, datatype, length, temperature, humidity = b.unpack( 'uintle:16, uintle:16, uintle:16, uintle:8, uintle:48, uintle:16, uintle:8, intle:16, intle:16' ) temperature /= 10.0 humidity /= 10.0 return cls( address, temperature=float(temperature), humidity=float(humidity), ) if len(b) == 136: uuid, flag, id, index, mac, datatype, length, battery_level = b.unpack( 'uintle:16, uintle:16, uintle:16, uintle:8, uintle:48, uintle:16, uintle:8, uintle:8' ) return cls( address, battery_level=float(battery_level), )
def getFieldVal(self, fName, vInd): """ get field value as string fName is field as (as is in Metedata) vInd is field value index (zero bases) raises IndexError in case vInd is larger then field value number raises KeyEror in case fName is not a valid field name """ # get field object for f in self.fields: if f["FieldName"] == fName: fld = f break else: raise KeyError if f["NoOfSymbols"] == "0": # this effectively means None... return self.NoneValueStr # check value index range if vInd >= int(f["NoOfSymbols"]): raise IndexError # read data sequentially os.lseek(self.fp, self.stPos + int(f["Offset"]), os.SEEK_SET) # seek to symbol table beginning for i in range(vInd + 1): # read field type byte b = ord(os.read(self.fp, 1)) # read value if b in [4, 5, 6]: # string containing types if b in [5, 6]: # skip numeric value skipSize = 4 if b == 5 else 8 # byte size to skip smth = os.lseek(self.fp, skipSize, os.SEEK_CUR) val = b'' while True: # have to read bytewise - very ineffective bt = os.read(self.fp, 1) if bt == b'\0': break val += bt val = val.decode("utf-8") # string is always UTF-8 elif b in [1, 2]: # numeric types a = BitArray(os.read(self.fp, b * 4)) if b == 1: val = a.unpack("intle:32")[0] else: val = a.unpack("floatle:64")[0] else: print("UNHANDLED YET TYPE: ", b) # never happened to me... return val
def kalyna_encrypt(pt, key): key = BitArray(key.to_bytes(16, sys.byteorder)) key_ = np.uint64(np.array(key.unpack('uintle:64, uintle:64'))) pt = BitArray(bytearray(pt, encoding='utf-8')) fm = ", ".join(['uintle:64'] * (pt.len // 64)) pt_ = np.uint64(np.array(pt.unpack(fm))) cipher = [] for i in range(0, len(pt_), 2): k = Kalyna() k.kalyna_key_expand(key_) if i == len(pt_) - 1: pt_s = np.uint64(np.array([pt_[i], 0x0])) else: pt_s = np.uint64(np.array([pt_[i], pt_[i + 1]])) cipher.extend(k.kalyna_encipher(pt_s)) return cipher
def Order_Replace(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!QQII", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 array[7] = array[7] / 10000 return (array)
def System_Event_Message(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!c", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 array[-1] = chr(ord(array[-1])) return (array)
def Excueted_Price_Order(message): array1 = [message[0]] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!QIQcI", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 array[8] = array[8] / 10000 return(array)
def Add_Order(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!QcI8sI", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 array[8] = array[8] / 10000 return (array)
class mpt1327_state: def __init__(self): self.data = BitArray(uint=0, length=64) self.cnt = 0 self.codeword = 0 self.prev = 0 self.base_freq = 170.8 self.step_freq = 0.0125 def crc(self): data, checksum = self.data.unpack('uint:48, uint:15') return CRC.calcWord(data, 48) == checksum and self.data.count(1) % 2 == 0 # Even parity
def kalyna_decrypt(ct_, key): key = BitArray(key.to_bytes(16, sys.byteorder)) key_ = np.uint64(np.array(key.unpack('uintle:64, uintle:64'))) plain = [] for i in range(0, len(ct_), 2): k = Kalyna() k.kalyna_key_expand(key_) if i == len(ct_) - 1: ct_s = np.uint64(np.array([ct_[i], 0x0])) else: ct_s = np.uint64(np.array([ct_[i], ct_[i + 1]])) plain.extend(k.kalyna_decipher(ct_s)) result = bytes(np.uint64(np.array(plain))).decode('utf-8') return result.split(' ')[:4]
def rx_stream(self, count=None, secs=None): self.set_rx_mode() start = time.time() while count is None or count > 0: buffer = self.device.read(0x82, 64) if count is not None: count -= 1 if secs is not None: if time.time() >= start + secs: break pkt = BitArray(bytes=buffer) metadata = pkt.unpack('uint:8, uint:8, uint:8, uint:8, uint:32,' 'int:8, int:8, int:8, uint:8') metanames = ('pkt_type', 'status', 'channel', 'clkn_high', 'clk100ns', 'rssi_max', 'rssi_min', 'rss_avg', 'rssi_count') yield dict(zip(metanames, metadata)), pkt[112:]
def rx_stream(self, count=None, secs=None): self.set_rx_mode() start = time.time() while count is None or count > 0: buffer = self.device.read(0x82, 64) if count is not None: count -= 1 if secs is not None: if time.time() >= start+secs: break pkt = BitArray(bytes=buffer) metadata = pkt.unpack('uint:8, uint:8, uint:8, uint:8, uint:32,' 'int:8, int:8, int:8, uint:8') metanames = ('pkt_type', 'status', 'channel', 'clkn_high', 'clk100ns', 'rssi_max', 'rssi_min', 'rss_avg', 'rssi_count') yield dict(zip(metanames, metadata)), pkt[112:]
def getRow(self, rInd): """ returns row as dictionary values are always strings, index is 0 based Bytes in the file are in reversed order, keep this in mind when processing raises IndexError in case rInd is larger then row number """ # check row index range if rInd >= int(self.attribs["NoOfRecords"]): raise IndexError # seek to the rows table beginning os.lseek( self.fp, self.stPos + int(self.attribs["Offset"]) + int(self.attribs["RecordByteSize"]) * rInd, os.SEEK_SET) bts = bytearray(os.read(self.fp, int(self.attribs["RecordByteSize"]))) bts.reverse() # bytes are reversed in file ba = BitArray(bts) # very slow operation btw indList = ba.unpack(self.createMask()) # make list # create resulting dictionary res = {} # add fields with more than one value for fInd, f in enumerate(self.fieldsInRow()): symInd = indList[fInd] + int( f["Bias"]) # always add bias - it is 0 or -2 val = self.NoneValueStr if symInd < 0 else self.getFieldVal( f["FieldName"], symInd) # NULL correction res[f["FieldName"]] = val # add fields with one value for cf in [ f for f in self.fields if f["BitWidth"] == "0" ]: # we use BitWidth, will elaborate later (there are cases...) res[cf["FieldName"]] = self.getFieldVal(cf["FieldName"], 0) return res
def _get_value(self, ncom_byte): b = BitArray(bytes=ncom_byte) self._data = b.unpack(('uintle:8, uintle:16,' # Sync, Time 'intle:24, intle:24, intle:24,' # AccX, AccY, AccZ 'intle:24, intle:24, intle:24,' # AngX, AngY, AngZ 'uintle:8, uintle:64, uintle:64, uintle:32,' # NavStat, Lat, Long, Alti 'uintle:24, uintle:24, uintle:24,' # Vel North, Vel East, Vel Down 'uintle:24, uintle:24, uintle:24' # Heading, Pitch, Roll )) self.d = OrderedDict(zip(self._names, self._data)) assert self.d['Sync'] == 231, print("Sync byte not matched:0x{:x}".format(self.d['Sync'])) # Always 0xE7 self.d['AccX'] *= ACC_FACTOR self.d['AccY'] *= ACC_FACTOR self.d['AccZ'] *= ACC_FACTOR self.d['AngX'] *= ANG_FACTOR self.d['AngY'] *= ANG_FACTOR self.d['AngZ'] *= ANG_FACTOR self.d['Vel_North'] *= VEL_FACTOR self.d['Vel_East'] *= VEL_FACTOR self.d['Vel_Down'] *= VEL_FACTOR self.d['Heading'] *= IMU_FACTOR self.d['Pitch'] *= IMU_FACTOR self.d['Roll'] *= IMU_FACTOR self.d['NavStat'] = self._navstat.get(self.d['NavStat'], 'Reserved')
def IPOUpdate(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!8sIcI", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return (array)
def parse(cls, address, data): '''Used to parse data received from RuuviTag. Currently supports versions 3 and 5 of the protocol. Arguments: address (str): MAC address of RuuviTag. data (bytes): received data in bytes. ''' b = BitArray(bytes=data) # Try to find protocol version 3 # https://github.com/ruuvi/ruuvi-sensor-protocols#data-format-3-protocol-specification if b.find('0xFF990403'): # If it's found, parse data b = list(b.split('0xFF990403', count=2))[-1] _, humidity, temperature_sign, temperature, temperature_fraction, pressure, \ accel_x, accel_y, accel_z, battery_voltage = b.unpack( # Ignore the packet type and manufacturer specs, # as they've been handled before 'uint:32,' + # Parse the actual payload 'uint:8, int:1, uint:7, uint:8, uint:16,' + 'int:16, int:16, int:16, uint:16') temperature_sign = -1 if temperature_sign == -1 else 1 # ... and return an instance of the calling class return cls(address, 3, temperature=temperature_sign * (float(temperature) + temperature_fraction / 100.0), humidity=humidity / 2.0, pressure=(pressure + 50000) / 100.0, acceleration_x=accel_x / 1000.0, acceleration_y=accel_y / 1000.0, acceleration_z=accel_z / 1000.0, battery_voltage=battery_voltage / 1000.0) # Try to find protocol version 5 # https://github.com/ruuvi/ruuvi-sensor-protocols#data-format-5-protocol-specification if b.find('0xFF990405'): # If it's found, parse data b = list(b.split('0xFF990405', count=2))[-1] _, temperature, humidity, pressure, \ accel_x, accel_y, accel_z, \ battery_voltage, tx_power, \ movement_counter, measurement_sequence, mac = b.unpack( # Ignore the packet type and manufacturer specs, # as they've been handled before 'uint:32,' + # Parse the actual payload 'int:16, uint:16, uint:16,' + 'int:16, int:16, int:16,' + 'uint:11, uint:5,' + 'uint:8, uint:16, uint:48') # Not sure what to do with MAC at the moment? # Maybe compare it to the one received by btle and # raise an exception if doesn't match? mac = '%x' % mac mac = ':'.join(mac[i:i + 2] for i in range(0, 12, 2)) # ... and return an instance of the calling class return cls(address, 5, temperature=float(temperature) * 0.005, humidity=humidity * 0.0025, pressure=(pressure + 50000) / 100.0, acceleration_x=accel_x / 1000.0, acceleration_y=accel_y / 1000.0, acceleration_z=accel_z / 1000.0, battery_voltage=(battery_voltage + 1600) / 1000.0, tx_power=-40 + tx_power, movement_counter=movement_counter, measurement_sequence=measurement_sequence)
def Market_Participant_Position(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!4s8sccc", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return (array)
def MWCB_Status(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!c", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return (array)
def Stock_Directory(message): array1 = [message[0]] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!8sccIcc2scccccIc", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return(array)
def Stock_Trading(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!8scc4s", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return (array)
def Reg_SHO(message): array1 = [message[0]] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!8sc", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return(array)
def Cross_Trade(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!Q8sIQc", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return (array)
def MWCB_Decline(message): array1 = [message[0]] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!QQQ", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return(array)
def Order_Cancel(message): array1 = [chr(message[0])] + list(struct.unpack("!HH", message[1:5])) b = BitArray(bytes=message[5:11]) array2 = list(struct.unpack("!QI", message[11:len(message)])) array = array1 + b.unpack('uintbe:48') + array2 return (array)
def unpack_bits(byte_array, fmt, **kwargs): ba = BitArray(bytes=byte_array) result = ba.unpack(fmt, **kwargs) return result
s = serial.Serial("COM1",19200,bytesize=serial.SEVENBITS,stopbits=serial.STOPBITS_ONE) buffer = [] count = 0 alldata = np.zeros([8,10]) while True: index = count%10 count += 1 print "index = ", index try: data = s.read() if data == "\x7f": bits = BitArray(bytes=buffer) # test length: if bits.length == 8*40: time.sleep(0.1) a, b, c, d, c4, c5, c6, c7 = bits.unpack('uintle:40,uintle:40,uintle:40,uintle:40,uintle:40,uintle:40,uintle:40,uintle:40') #print a, b, c, d, c4, c5, c6, c7 newdata = np.array((a, b, c, d, c4, c5, c6, c7)) alldata[:,index] = newdata if index == 0: print alldata # update plot every 10 shots for rect, h in zip(rects, alldata.mean(axis=1)): rect.set_height(h) axes.relim() axes.autoscale_view(True,True,True) plt.pause(0.001) plt.draw() else: print "short packet"
assert(logDict['ucTag2'] == ord('G')) if __name__ == '__main__': test_bitStruct(bitStruct) for _ in range(1): fefefe = splitBitStructIn32bits(bitStruct) logDict = OrderedDict() logEntry = map(str, getLogEntryFromDevice()) assert(len(logEntry) == 112) for logE in logEntry: rawBits = BitArray('int:32=' + logE) ent = next(fefefe) b = rawBits.unpack(entryToFmtString(ent)) for (k, v) in zip(ent, b): logDict[k[1]] = v test_ValidLogDict(logDict) # print logDict print 'ucChksum: ', hex(logDict['ucChksum']) print 'ucVer: ', logDict['ucVer'] print 'uiTimestamp: ', logDict['uiTimestamp'] print 'global.accWatisar: ', logDict['global.accWatisar'] print 'ChLogEntry_ChA.ucThermHR: ', logDict['ChLogEntry_ChA.ucThermHR'] print 'ChLogEntry_ChA.usMinLoadZ0: ', logDict['ChLogEntry_ChA.usMinLoadZ0'] print 'ChLogEntry_ChA.usMaxLoadZ0: ', logDict['ChLogEntry_ChA.usMaxLoadZ0'] print 'ChLogEntry_ChA.usMinLoadZ1: ', logDict['ChLogEntry_ChA.usMinLoadZ1'] print 'ChLogEntry_ChA.usMaxLoadZ1: ', logDict['ChLogEntry_ChA.usMaxLoadZ1'] print ''
def writeB(scene, b_name): #Sanitization checks #if no image size, error if scene.n_films == 0: print "Error: Scene needs a film." return #if no camera, error: if scene.n_cameras == 0: print "Error: Scene needs a camera." return #if no bounding box, error if scene.n_boundboxes == 0: print "Error: Scene needs a bounding box." return #Create bitstring s = BitArray() #Film film = scene.films[0] t = BitArray() t = bitstring.pack("3*int:32", 0, film['width'], film['height']) print t.unpack("3*int:32") s = s + t #Camera camera = scene.cameras[0] t = BitArray() t = bitstring.pack("int:32, 12*float:32", 1, camera['point'][0], camera['point'][1], camera['point'][2], camera['fieldOfView'], camera['toPoint'][0], camera['toPoint'][1], camera['toPoint'][2], camera['up'][0], camera['up'][1], camera['up'][2], camera['lensRadius'], camera['focalDepth']) print t.unpack("int:32, 12*float:32") s = s + t #Lights for i in range(scene.n_lights): light = scene.lights[i] t = BitArray() t = bitstring.pack("2*int:32, 6*float:32", 2, light['type'], light['point'][0], light['point'][1], light['point'][2], light['color'][0], light['color'][1], light['color'][2]) print t.unpack("2*int:32, 6*float:32") s = s + t #Materials for i in range(scene.n_materials): mat = scene.materials[i] t = BitArray() t = bitstring.pack("int:32, 3*float:32, 2*int:32, 4*float:32", 3, mat['color'][0], mat['color'][1], mat['color'][2], mat['type'], mat['metal'], mat['specular'], mat['lambert'], mat['ambient'], mat['exponent']) print t.unpack("int:32, 3*float:32, 2*int:32, 4*float:32") s = s + t #Spheres for i in range(scene.n_spheres): sphere = scene.spheres[i] t = BitArray() t = bitstring.pack("int:32, 4*float:32, int:32", 4, sphere['point'][0], sphere['point'][1], sphere['point'][2], sphere['radius'], sphere['materialIndex']) print t.unpack("int:32, 4*float:32, int:32") s = s + t #Triangles for i in range(scene.n_triangles): tri = scene.triangles[i] t = BitArray() t = bitstring.pack("int:32, 9*float:32, int:32", 5, tri['point1'][0], tri['point1'][1], tri['point1'][2], tri['point2'][0], tri['point2'][1], tri['point2'][2], tri['point3'][0], tri['point3'][1], tri['point3'][2], tri['materialIndex']) print t.unpack("int:32, 9*float:32, int:32") s = s + t #Bounding Box box = scene.boundboxes[0] t = BitArray() t = bitstring.pack("int:32, 6*float:32", 6, box['min'][0], box['min'][1], box['min'][2], box['max'][0], box['max'][1], box['max'][2]) print t.unpack("int:32, 6*float:32") s = s + t #Send end code t = BitArray() t = bitstring.pack("int:32", 7) s = s + t #Write to file with open(b_name, "wb") as f: s.tofile(f)
s = serial.Serial("/dev/ttyUSB2", 19200, bytesize=serial.SEVENBITS, stopbits=serial.STOPBITS_ONE) buffer = [] while True: try: data = s.read() if data == "\x7f": bits = BitArray(bytes=buffer) # test length: if bits.length == 8 * 40: time.sleep(0.1) a, b, c, d, c4, c5, c6, c7 = bits.unpack( 'uintle:40,uintle:40,uintle:40,uintle:40,uintle:40,uintle:40,uintle:40,uintle:40' ) print a, b, c, d, c4, c5, c6, c7 plt.scatter((a, b, c, d, c4, c5, c6, c7), (0, 1, 2, 3, 4, 5, 6, 7)) plt.draw() else: print "short packet" buffer = [] else: buffer.append(data) except KeyboardInterrupt: print "W: interrupt received, ending data collection" break s.close()