def encode(self): """Return a packed data string containing the values from this object""" data = pack('II', self.width, self.height) data += pack('ff', *self.northwest) data += pack('ff', *self.northeast) data += pack('ff', *self.southwest) data += self.pixels return data
def __init__(self, header, body): super(Request, self).__init__() self.header = header post_data = "%s%s" % (self.header.pack(), body.pack()) post_data = common.pack("=H", self.header.channelid) + common.xorcode(post_data, __channel__[self.header.channelid]) crc = common.crc32unsigned(post_data) crc = common.crc32unsigned(__channel__[self.header.channelid], crc) self.req_data = "%s%s" % (common.pack("=HI", len(post_data)+6, crc), post_data)
def __init__(self, header, body): super(Request, self).__init__() self.header = header post_data = "%s%s" % (self.header.pack(), body.pack()) post_data = common.pack("=H", self.header.channelid) + common.xorcode( post_data, __channel__[self.header.channelid]) crc = common.crc32unsigned(post_data) crc = common.crc32unsigned(__channel__[self.header.channelid], crc) self.req_data = "%s%s" % (common.pack("=HI", len(post_data) + 6, crc), post_data)
def write_ways(fp, ways): """ Dumps ways to a file. """ fp.write(pack('!L', len(ways))) for letter, way in ways.items(): fp.write(pack('!4s', letter.encode('utf-8'))) for i, part in enumerate(way): if i + 1 < len(way): fp.write(pack('!B', 0x80 | part)) else: fp.write(pack('!B', part))
def sendCommand(self, cls, cmd, payload=b'', waitResp=True): s = common.pack('4B', 0, len(payload), cls, cmd) + payload self.ser.write(s) while True: p = self.recvPacket() if p.typ == 0: return p self.handleEvent(p)
def send_command(self, cls, cmd, payload=b'', wait_resp=True): s = pack('4B', 0, len(payload), cls, cmd) + payload self.ser.write(s) while True: p = self.recv_packet() # no timeout, so p won't be None if p.typ == 0: return p # not a response: must be an event self.handle_event(p)
def encode(self, prev_state={}): """Return the encoded string for a DATA_UPDATE of this object's current state. For OBJECTs, optionally include the previously sent state as OBJECT updates are diffs, not absolute values. This state should be a dict {key: id}""" data = pack('BI', self.value_type, self.id) if self.value_type in self.TYPE_MAP: data += pack(self.TYPE_MAP[self.value_type], self.raw_value) elif self.value_type == ValueType.STRING: data += self.raw_value + '\0' elif self.value_type == ValueType.ARRAY: data += pack('H', len(self.raw_value)) + pack(len(self.raw_value) * 'I', *self.raw_value) elif self.value_type == ValueType.OBJECT: removed = [value_id for key, value_id in prev_state.items() if self.raw_value.get(key) != value_id] added = {key: value_id for key, value_id in self.raw_value.items() if prev_state.get(key) != value_id} data += pack('H', len(added)) for key, value_id in added.items(): data += pack('I', value_id) + key + '\0' data += pack('H', len(removed)) + pack(len(removed) * 'I', *removed) return data
def buttons_pack(self): """""" left = False right = False up = False down = False plus = False minus = False a = False b = False one = False two = False home = False l = [ two, one, b, a, minus, False, False, home, left, right, down, up, plus, False, False, False ] b = common.pack(l) return b
def write(self, fp): """ Recursively writes node into file. """ self.address = fp.tell() fp.write(pack('!L', len(self.children_nodes))) fp.write(pack('!L', len(self.words))) fp.write(pack('!L', 0xDEADBABA)) # Placeholder for word count. ways = [] for way in self.children_nodes: ways.append(way) fp.write(pack('!BL', way, 0xDEADBABA)) # Placeholder for address. for word in self.words: word.write(fp) words_count = len(self.words) for child in self.children_nodes.values(): words_count += child.write(fp) end_position = fp.tell() fp.seek(self.address + 8) fp.write(pack('!L', words_count)) for i, way in enumerate(ways): fp.seek(self.address + 12 + 5 * i + 1) fp.write(pack('!L', self.children_nodes[way].address)) fp.seek(end_position) return words_count
def vibrate(self, length): if length in xrange(1, 4): self.writeAttr(0x19, common.pack('3B', 3, 1, length))
def connect(self): self.bt.endScan() self.bt.disconnect(0) self.bt.disconnect(1) self.bt.disconnect(2) print('scanning MyoArmband') self.bt.discover() while True: p = self.bt.recvPacket() print('scan response MyoArmBand:', p) if p.payload.endswith( b'\x06\x42\x48\x12\x4A\x7F\x2C\x48\x47\xB9\xDE\x04\xA9\x01\x00\x06\xD5' ): addr = list(multiord(p.payload[2:8])) break self.bt.endScan() connPkt = self.bt.connect(addr) self.conn = multiord(connPkt.payload)[-1] self.bt.waitEvent(3, 0) fw = self.readAttr(0x17) _, _, _, _, v0, v1, v2, v3 = common.unpack('BHBBHHHH', fw.payload) print('firmware version MyoArmband: %d.%d.%d.%d' % (v0, v1, v2, v3)) self.old = (v0 == 0) if self.old: self.writeAttr(0x19, b'\x01\x02\x00\x00') self.writeAttr(0x2f, b'\x01\x00') self.writeAttr(0x2c, b'\x01\x00') self.writeAttr(0x32, b'\x01\x00') self.writeAttr(0x35, b'\x01\x00') self.writeAttr(0x28, b'\x01\x00') self.writeAttr(0x1d, b'\x01\x00') C = 1000 emgHz = 50 emgSmooth = 100 imuHz = 50 self.writeAttr( 0x19, common.pack('BBBBHBBBBB', 2, 9, 2, 1, C, emgSmooth, C // emgHz, imuHz, 0, 0)) else: name = self.readAttr(0x03) print('device name MyoArmband: %s' % name.payload) self.writeAttr(0x1d, b'\x01\x00') self.writeAttr(0x24, b'\x02\x00') # self.write_attr(0x19, b'\x01\x03\x00\x01\x01') self.startRaw() def handleData(p): if (p.cls, p.cmd) != (4, 5): return c, attr, typ = common.unpack('BHB', p.payload[:4]) pay = p.payload[5:] if attr == 0x27: vals = common.unpack('8HB', pay) emg = vals[:8] moving = vals[8] self.onEmg(emg, moving) elif attr == 0x1c: vals = common.unpack('10h', pay) quat = vals[:4] acc = vals[4:7] gyro = vals[7:10] self.onImu(quat, acc, gyro) elif attr == 0x23: typ, val, xdir, _, _, _ = common.unpack('6B', pay) if typ == 1: self.onArm(Arm(val), XDirection(xdir)) elif typ == 2: self.onArm(Arm.unknown, XDirection.unknown) elif typ == 3: self.onPose(Pose(val)) else: print('data with unknown attr: %02X %s' % (attr, p)) self.bt.addHandler(handleData)
def pack(self): return "%s%s" % (common.pack("=H", self.version), self.uid)
def writeAttr(self, con, attr, val): self.sendCommand(4, 5, common.pack('BHB', con, attr, len(val)) + val) return self.waitEvent(4, 1)
def readAttr(self, con, attr): self.sendCommand(4, 4, common.pack('BH', con, attr)) return self.waitEvent(4, 5)
def disconnect(self, h): return self.sendCommand(3, 0, common.pack('B', h))
def connect(self): # stop everything from before self.bt.end_scan() self.bt.disconnect(0) self.bt.disconnect(1) self.bt.disconnect(2) # start scanning print('scanning...') self.bt.discover() while True: p = self.bt.recv_packet() print('scan response:', p) if p.payload.endswith(b'\x06\x42\x48\x12\x4A\x7F\x2C\x48\x47\xB9\xDE\x04\xA9\x01\x00\x06\xD5'): addr = list(multiord(p.payload[2:8])) break self.bt.end_scan() # connect and wait for status event conn_pkt = self.bt.connect(addr) self.conn = multiord(conn_pkt.payload)[-1] self.bt.wait_event(3, 0) # get firmware version fw = self.read_attr(0x17) _, _, _, _, v0, v1, v2, v3 = unpack('BHBBHHHH', fw.payload) print('firmware version: %d.%d.%d.%d' % (v0, v1, v2, v3)) self.old = (v0 == 0) if self.old: # don't know what these do # Myo Connect sends them, though we get data # fine without them self.write_attr(0x19, b'\x01\x02\x00\x00') self.write_attr(0x2f, b'\x01\x00') self.write_attr(0x2c, b'\x01\x00') self.write_attr(0x32, b'\x01\x00') self.write_attr(0x35, b'\x01\x00') # enable EMG data self.write_attr(0x28, b'\x01\x00') # enable IMU data self.write_attr(0x1d, b'\x01\x00') # Sampling rate of the underlying EMG sensor, capped to 1000. # If it's less than 1000, emg_hz is correct. If it is greater, # the actual framerate starts dropping inversely. Also, if this # is much less than 1000, EMG data becomes slower to respond to # changes. In conclusion, 1000 is probably a good value. C = 1000 emg_hz = 50 # strength of low-pass filtering of EMG data emg_smooth = 100 imu_hz = 50 # send sensor parameters, or we don't get any data self.write_attr(0x19, pack('BBBBHBBBBB', 2, 9, 2, 1, C, emg_smooth, C // emg_hz, imu_hz, 0, 0)) else: name = self.read_attr(0x03) print('device name: %s' % name.payload) # enable IMU data self.write_attr(0x1d, b'\x01\x00') # enable on/off arm notifications self.write_attr(0x24, b'\x02\x00') self.start_raw() # add data handlers def handle_data(p): if (p.cls, p.cmd) != (4, 5): return c, attr, typ = unpack('BHB', p.payload[:4]) pay = p.payload[5:] if attr == 0x27: vals = unpack('8HB', pay) # not entirely sure what the last byte is, # but it's a bitmask that seems to indicate which # sensors think they're being moved around or something emg = vals[:8] moving = vals[8] self.on_emg(emg, moving) elif attr == 0x1c: vals = unpack('10h', pay) quat = vals[:4] acc = vals[4:7] gyro = vals[7:10] self.on_imu(quat, acc, gyro) elif attr == 0x23: if len(pay) == 6: try: typ, val, xdir, _, _, _ = unpack('6B', pay) except Exception as e: print("Got exception: " + str(e) + "\nContinuing...") return elif len(pay) == 3: try: typ, val, xdir = unpack('3B', pay) except Exception as e: print("Got exception: " + str(e) + "\nContinuing...") return if typ == 1: # on arm self.on_arm(MyoArm(arm=val, xdir=xdir)) elif typ == 2: # removed from arm self.on_arm(MyoArm(MyoArm.UNKNOWN, MyoArm.UNKNOWN)) elif typ == 3: # gesture if val == 255: gesture = MyoGesture(0) else: gesture = MyoGesture(val + 1) self.on_gesture(gesture) else: print('data with unknown attr: %02X %s' % (attr, p)) self.bt.add_handler(handle_data)
def __init__(self, userSetCityid, lastLocateCityid, infotype): super(WeatherBody, self).__init__() self.body = common.pack("=IIH", userSetCityid, lastLocateCityid, infotype)
def write_attr(self, con, attr, val): self.send_command(4, 5, pack('BHB', con, attr, len(val)) + val) return self.wait_event(4, 1)
def read_attr(self, con, attr): self.send_command(4, 4, pack('BH', con, attr)) return self.wait_event(4, 5)
def vibrate(self, length): if length in xrange(1, 4): # first byte tells it to vibrate; purpose of second byte is unknown self.write_attr(0x19, pack('3B', 3, 1, length))
def sendData(self, data): self.write_buffer.write(common.pack(data))
def connect(self, addr): return self.sendCommand( 6, 3, common.pack('6sBHHHH', multichr(addr), 0, 6, 6, 64, 0))
def disconnect(self, h): return self.send_command(3, 0, pack('B', h))
def encode(cls, message_type, payload): """Return encoded bytes for a message of given type with given encoded bytes payload""" return pack('IB', len(payload), message_type) + payload