Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Hexiwear BLE access
-
Need some help with access to BLE services & characteristics with the Hexiwear dev platformpje !?
from __future__ import print_function import cb import sound import time import struct import console console.set_color(0, 0, 1) print(""" _ _ _____ _ | || |___ _ _ * | __ | |_ _ ___ | -- | -_| \/ | | __ -| | | | -_| |_||_|___|_/\__|_ _____|_|___|___| """) console.set_color() class HeartRateManager (object): def __init__(self): self.peripheral = None def did_discover_peripheral(self, p): if p.name and 'HEXIWEAR' in p.name and not self.peripheral: self.peripheral = p print('Connecting to Hexiwear...') cb.connect_peripheral(p) def did_connect_peripheral(self, p): print('Connected:', p.name) print('Discovering services...') p.discover_services() def did_discover_services(self, p, error): print('did_discover_services({})'.format(p.name)) cb.get_state() print("Name:", p.name) print("UUID:", p.uuid) try: state = 'Disconnected Connecting Connected'.split()[p.state] except IndexError: state = 'Invalid state ({})'.format(p.state) print("STAT: ", state) time.sleep(0.4) print("AUTH:", cb.CH_PROP_AUTHENTICATED_SIGNED_WRITES) time.sleep(0.4) print("Properties:", cb.CH_PROP_EXTENDED_PROPERTIES) time.sleep(0.4) print("Indicate:", cb.CH_PROP_INDICATE) time.sleep(0.4) print("Encryption:", cb.CH_PROP_NOTIFY_ENCRYPTION_REQUIRED) time.sleep(0.4) print("{} Services:".format(len(p.services))) for s in p.services: print("-" + str(s.uuid)) p.discover_characteristics(s) def did_discover_characteristics(self, s, error): print("Characteristics:") for c in s.characteristics: print("-" + str(c.uuid)) # s.set_notify_value(c, True) s.read_characteristic_value(c) data = s.read_characteristic_value(c) print(c.value, data) def did_write_value(self, c, error): print(self.peripheral.properties) time.sleep(0.5) def did_update_value(self, c, error): time.sleep(0.5) def did_fail_to_connect_peripheral(self, p, error): print('Failed to connect: %s' % (error,)) def did_disconnect_peripheral(self, p, error): print('Disconnected, error: %s' % (error,)) self.peripheral = None mngr = HeartRateManager() cb.set_central_delegate(mngr) print('Scanning for Hexiwear...') cb.scan_for_peripherals() try: while True: pass except KeyboardInterrupt: cb.reset()
Can’t get access to all characteristics need some pointers!?
Thx in advance
-
@robStacks what seems to be the problem?
-
I just can’t get access to the other services
Thx for the help guys...
-
Looks like maybe you are missing an indent - you wAnt to call discover_characteristics for each service. Your code would only be the last.
Should be:
for s in p.services: print("-" + str(s.uuid)) p.discover_characteristics(s)
-
Great thx that’s it thx allot!
-
Well almost now I am getting just the first characteristic of each service but getting closer.
Thx a bunch!
-
is there a service.read_characteristic_value? or is it under peripheral? also, the read command does not return a value, you must implement did_update_value.
Peripheral.read_characteristic_value(characteristic)
Retrieve the value of the given Characteristic. When the value has been read, your central delegate will receive a did_update_value callback, at which point you can access the value with the characteristics’s value attribute. Not all characteristics are guaranteed to have a readable value.If you need synchronous access like this, perhaps, implement a semaphore system -- update_value sets a semaphore that the did_discover_characteristics blocks on ( you do maybe need to make sure did_discover_characteristics uses @in_background)
-
Ok thx for your help I get the full readout now
Listing all services and characteristics
Now I want to get the raw values of all the sensors and print them.
You talked about setting up a semafore system?
I am totally new to this can you explain more in-depth please?The code till now:
import cb import time class HexiwearManager (object): def __init__(self): self.peripheral = None def did_discover_peripheral(self, p): if p.name and 'HEXIWEAR' in p.name and not self.peripheral: self.peripheral = p print('Connecting to Hexiwear...') cb.connect_peripheral(p) def did_connect_peripheral(self, p): print('Connected:', p.name) print('Discovering services...') p.discover_services() def did_discover_services(self, p, error): print('did_discover_services({})'.format(p.name)) cb.get_state() print("Name:", p.name) print("UUID:", p.uuid) try: state = 'Disconnected Connecting Connected'.split()[p.state] except IndexError: state = 'Invalid state ({})'.format(p.state) print("STAT: ", state) time.sleep(0.4) print("AUTH:", cb.CH_PROP_AUTHENTICATED_SIGNED_WRITES) time.sleep(0.4) print("Properties:", cb.CH_PROP_EXTENDED_PROPERTIES) time.sleep(0.4) print("Indicate:", cb.CH_PROP_INDICATE) time.sleep(0.4) print("Encryption:", cb.CH_PROP_NOTIFY_ENCRYPTION_REQUIRED) time.sleep(0.4) print("{} Services:".format(len(p.services))) for s in p.services: print("-" + str(s.uuid)) p.discover_characteristics(s) def did_discover_characteristics(self, s, error): print("{} Characteristics:".format(len(s.characteristics))) for c in s.characteristics: print("-" + str(c.uuid)) def did_fail_to_connect_peripheral(self, p, error): print('Failed to connect: %s' % (error,)) def did_disconnect_peripheral(self, p, error): print('Disconnected, error: %s' % (error,)) self.peripheral = None mngr = HexiwearManager() cb.set_central_delegate(mngr) print('Scanning for Hexiwear...') cb.scan_for_peripherals() try: while True: pass except KeyboardInterrupt: cb.reset() ```
-
something like this, for simple reading.
notice that you call read, but the actual access to c.value is in update_value -- so your code just needs to be asynchronous, responding to value updates there.if you need synchronous access, it becomes harder, since your main code needs to wait until the value has been updated. which can be tricky because i dont think there is a guarantee that when you request a read, that a read actually happens by the device, etc.
CHPROPS={cb.CH_PROP_BROADCAST:'Broadcast', cb.CH_PROP_READ:'Read', cb.CH_PROP_WRITE_WITHOUT_RESPONSE:'WriteWithoutResponse', cb.CH_PROP_WRITE:'Write', cb.CH_PROP_NOTIFY:'Notify', cb.CH_PROP_INDICATE:'Indicate', cb.CH_PROP_AUTHENTICATED_SIGNED_WRITES:'AuthSignedWrites', cb.CH_PROP_EXTENDED_PROPERTIES:'ExtendedProps', cb.CH_PROP_NOTIFY_ENCRYPTION_REQUIRED:'NotifyEncrypReq', cb.CH_PROP_INDICATE_ENCRYPTION_REQUIRED:'IndicateEncrReq'} #...inside your manager... def did_discover_characteristics(self, s, error): # You can now read or write the characteristic's value props=[] for propbit,name in CHPROPS.items(): if c.properties & propbit: props.append(name) print(f'-UUID:{c.uuid} PROPS:{",".join(props)}') if cb.CH_PROP_READ & c.properties: self.peripheral.read_characteristic_value(c) def did_update_value(self, c): '''called when characteristic is read''' print(f'-UUID:{c.uuid} + VALUE:{c.value}')
-
Where do I put in the CHPROPS?
Should I put it in sitepackages and import it in the beginning of the code?
Keep getting “CHPROPS” is not defined no matter where in the code I put it in.Thx again for the help!
-
just in the same file, before you declare the class.
or, i suppose, it would be cleaner to define inside
__init__
, asself.CHPROPS
, then refer to it as such in inside did_discover_characteristics.The purpose of that is to give a more meaningful display of characateristic properties -- but you could always just print c.properties, and figure out the bitmask yourself.