我正在构建一个使用pyobjus连接到TI SensorTag的Kivy应用。我在扫描过程中成功获取应用程序以找到传感器,但我无法连接它。我找到了一些代码here,但它适用于不同的传感器。我得到的错误是来自pyobjus的Exception AssertionError: AssertionError() in 'pyobjus.protocol_forwardInvocation' ignored
,但我无法弄清楚如何跟踪错误,因为它被忽略了。
修改
这是代码,似乎问题在于connect()函数
class Ble(object):
def check_le(self, central):
state = central.state
if state == CBCentralManagerStateUnknown:
print 'CentralManager: Unknown state'
elif state == CBCentralManagerStatePoweredOn:
print 'CentralManager: Ready to go!'
return True
elif state == CBCentralManagerStatePoweredOff:
print 'CentralManager: Bluetooth is powered off'
elif state == CBCentralManagerStateUnauthorized:
print 'CentralManager: The application is not authorized to use BLE' # noqa
elif state == CBCentralManagerStateUnsupported:
print 'CentralManager: This hardware doesnt support BLE'
def connect(self, peripheral):
print "connecting"
self.stop_scan()
self.central.cancelPeripheralConnection_(peripheral)
self.central.connectPeripheral_options_(peripheral, None, None)
def disconnecte(self, peripheral):
# XXX !
print "Disconnect Not Implemented!"
def create(self):
self.callback = None
self.peripherals = {}
load_framework(INCLUDE.IOBluetooth)
CBCentralManager = autoclass('CBCentralManager')
self.central = CBCentralManager.alloc().initWithDelegate_queue_(
self, None)
def start_scan(self):
print 'Scanning started on Mac OSX MJR'
self.asked_services = []
self.central.scanForPeripheralsWithServices_options_(None, None)
Clock.schedule_interval(self.pop_queue, 0.04)
def stop_scan(self):
print "stopping scan"
self.central.stopScan()
def pop_queue(self, dt):
if self.queue:
self.callback(*self.queue.pop(0))
@protocol('CBCentralManagerDelegate')
def centralManagerDidUpdateState_(self, central):
print 'central state', central.state
self.check_le(central)
self.start_scan()
@protocol('CBCentralManagerDelegate')
def centralManager_didDiscoverPeripheral_advertisementData_RSSI_(
self, central, peripheral, data, rssi):
# print('centralManager:didDiscoverPeripheral:advertisementData:RSSI:')
# uuid = peripheral.identifier.UUIDString().cString()
# if peripheral.name:
# print('-> name=', peripheral.name.cString())
# print 'uuid:', uuid
keys = data.allKeys()
count = keys.count()
if count < 2:
return
name = peripheral.name.cString()
# name = data.objectForKey_(keys.objectAtIndex_(count - 2)).cString()
values = data.objectForKey_(keys.objectAtIndex_(count - 1))
sensor = c.get_from_ptr(values.bytes().arg_ref, 'c', values.length())
uuid = peripheral.description().cString()
if self.callback:
self.callback(rssi.intValue(), name, sensor)
else:
print uuid, name, sensor, rssi
if uuid not in self.peripherals:
pass
#self.connect(peripheral)
self.peripherals[name] = (peripheral, rssi)
@protocol('CBCentralManagerDelegate')
def centralManager_didConnectPeripheral_(self, central, peripheral):
if not peripheral.name.UTF8String():
return
peripheral.delegate = self
CBUUID = autoclass('CBUUID')
service = CBUUID.UUIDWithString_('1901')
peripheral.discoverServices_([service])
@protocol('CBPeripheralDelegate')
def peripheral_didDiscoverServices_(self, peripheral, error):
for i in range(peripheral.services.count()):
service = peripheral.services.objectAtIndex_(i)
if service.UUID.UUIDString.cString() == '1901':
break
else:
assert(0)
peripheral.discoverCharacteristics_forService_([], service)
@protocol('CBPeripheralDelegate')
def peripheral_didDiscoverCharacteristicsForService_error_(self, peripheral, service, error):
print "discovered characteristic: ", service, service.characteristics
for i in range(service.characteristics.count()):
ch = service.characteristics.objectAtIndex_(i)
if ch.UUID.UUIDString.cString() == '2B01':
peripheral.setNotifyValue_forCharacteristic_(True, ch)
print "set notify for chr {}".format(i)
@protocol('CBPeripheralDelegate')
def peripheral_didUpdateNotificationStateForCharacteristic_error_(
self, peripheral, characteristic, error):
# probably needs to decode like for advertising
# sensor = c.get_from_ptr(values.bytes().arg_ref, 'c', values.length())
print "characteristic: {} notifying: {}".format(characteristic.UUID.UUIDString.cString(), characteristic.isNotifying)
pass
@protocol('CBPeripheralDelegate')
def peripheral_didUpdateValueForCharacteristic_error_(self, peripheral, characteristic, error):
# probably needs to decode like for advertising
# sensor = c.get_from_ptr(values.bytes().arg_ref, 'c', values.length())
data = c.get_from_ptr(characteristic.value.bytes().arg_ref, 'c', characteristic.value.length())
name = peripheral.name.cString()
peripheral.readRSSI()
rssi = peripheral.RSSI and peripheral.RSSI.intValue() or 0
if self.callback:
if self.queue is not None:
self.queue.append((rssi, name, data))
else:
self.callback(rssi, name, data)
else:
print name, rsii, data
答案 0 :(得分:1)
这意味着您的某个协议方法中存在某个错误,例如centralManager_didDiscoverPeripheral_advertisementData_RSSI_()
。但是你没有提供任何代码。
我现在也更新了我的plyer BLE代码 - 它支持连接和基本读/写特性。这是一项正在进行的工作,代码非常混乱,因为它是我的BLE测试和学习环境。您可以在此处查看:https://github.com/kivy/plyer/pull/185
如果您尝试为此编写自己的代码,请记住一些事项。首先,确保在连接时保留对CBPeripheral
对象的引用 - 否则将取消分配对象,并且您的连接将无声地失败。其次,请务必通过CBPeripheralDelegate
而不是peripheral.setDelegate_(self)
设置peripheral.delegate = self
- 后者将不起作用,并且不会调用您的协议方法。最后,pyobjus中存在一个错误,它将字节传递给void*
参数 - 这将阻止您创建二进制NSData
对象来读取/写入特征值。我虽然有{({3}})的公关。