8 from dbus.mainloop.glib import DBusGMainLoop
13 BLUEZ_SERVICE_NAME = 'org.bluez'
14 DBUS_OM_IFACE = 'org.freedesktop.DBus.ObjectManager'
15 DBUS_PROP_IFACE = 'org.freedesktop.DBus.Properties'
17 GATT_SERVICE_IFACE = 'org.bluez.GattService1'
18 GATT_CHRC_IFACE = 'org.bluez.GattCharacteristic1'
20 HR_SVC_UUID = '0000180d-0000-1000-8000-00805f9b34fb'
21 HR_MSRMT_UUID = '00002a37-0000-1000-8000-00805f9b34fb'
22 BODY_SNSR_LOC_UUID = '00002a38-0000-1000-8000-00805f9b34fb'
23 HR_CTRL_PT_UUID = '00002a39-0000-1000-8000-00805f9b34fb'
25 # The objects that we interact with.
28 body_snsr_loc_chrc = None
29 hr_ctrl_pt_chrc = None
32 def generic_error_cb(error):
33 print('D-Bus call failed: ' + str(error))
37 def body_sensor_val_to_str(val):
53 return 'Reserved value'
56 def sensor_contact_val_to_str(val):
57 if val == 0 or val == 1:
58 return 'not supported'
60 return 'no contact detected'
62 return 'contact detected'
64 return 'invalid value'
67 def body_sensor_val_cb(value):
69 print('Invalid body sensor location value: ' + repr(value))
72 print('Body sensor location value: ' + body_sensor_val_to_str(value[0]))
75 def hr_msrmt_start_notify_cb():
76 print('HR Measurement notifications enabled')
79 def hr_msrmt_changed_cb(iface, changed_props, invalidated_props):
80 if iface != GATT_CHRC_IFACE:
83 if not len(changed_props):
86 value = changed_props.get('Value', None)
90 print('New HR Measurement')
93 value_format = flags & 0x01
94 sc_status = (flags >> 1) & 0x03
95 ee_status = flags & 0x08
97 if value_format == 0x00:
101 hr_msrmt = value[1] | (value[2] << 8)
104 print('\tHR: ' + str(int(hr_msrmt)))
105 print('\tSensor Contact status: ' +
106 sensor_contact_val_to_str(sc_status))
109 print('\tEnergy Expended: ' + str(int(value[next_ind])))
113 # Read the Body Sensor Location value and print it asynchronously.
114 body_snsr_loc_chrc[0].ReadValue(reply_handler=body_sensor_val_cb,
115 error_handler=generic_error_cb,
116 dbus_interface=GATT_CHRC_IFACE)
118 # Listen to PropertiesChanged signals from the Heart Measurement
120 hr_msrmt_prop_iface = dbus.Interface(hr_msrmt_chrc[0], DBUS_PROP_IFACE)
121 hr_msrmt_prop_iface.connect_to_signal("PropertiesChanged",
124 # Subscribe to Heart Rate Measurement notifications.
125 hr_msrmt_chrc[0].StartNotify(reply_handler=hr_msrmt_start_notify_cb,
126 error_handler=generic_error_cb,
127 dbus_interface=GATT_CHRC_IFACE)
130 def process_chrc(chrc_path):
131 chrc = bus.get_object(BLUEZ_SERVICE_NAME, chrc_path)
132 chrc_props = chrc.GetAll(GATT_CHRC_IFACE,
133 dbus_interface=DBUS_PROP_IFACE)
135 uuid = chrc_props['UUID']
137 if uuid == HR_MSRMT_UUID:
139 hr_msrmt_chrc = (chrc, chrc_props)
140 elif uuid == BODY_SNSR_LOC_UUID:
141 global body_snsr_loc_chrc
142 body_snsr_loc_chrc = (chrc, chrc_props)
143 elif uuid == HR_CTRL_PT_UUID:
144 global hr_ctrl_pt_chrc
145 hr_ctrl_pt_chrc = (chrc, chrc_props)
147 print('Unrecognized characteristic: ' + uuid)
152 def process_hr_service(service_path):
153 service = bus.get_object(BLUEZ_SERVICE_NAME, service_path)
154 service_props = service.GetAll(GATT_SERVICE_IFACE,
155 dbus_interface=DBUS_PROP_IFACE)
157 uuid = service_props['UUID']
159 if uuid != HR_SVC_UUID:
160 print('Service is not a Heart Rate Service: ' + uuid)
163 # Process the characteristics.
164 chrc_paths = service_props['Characteristics']
165 for chrc_path in chrc_paths:
166 process_chrc(chrc_path)
169 hr_service = (service, service_props, service_path)
174 def interfaces_removed_cb(object_path, interfaces):
178 if object_path == hr_service[2]:
179 print('Service was removed')
184 # Prase the service path from the arguments.
185 parser = argparse.ArgumentParser(
186 description='D-Bus Heart Rate Service client example')
187 parser.add_argument('service_path', metavar='<service-path>',
188 type=dbus.ObjectPath, nargs=1,
189 help='GATT service object path')
190 args = parser.parse_args()
191 service_path = args.service_path[0]
193 # Set up the main loop.
194 DBusGMainLoop(set_as_default=True)
196 bus = dbus.SystemBus()
198 mainloop = gobject.MainLoop()
200 om = dbus.Interface(bus.get_object(BLUEZ_SERVICE_NAME, '/'), DBUS_OM_IFACE)
201 om.connect_to_signal('InterfacesRemoved', interfaces_removed_cb)
204 if not process_hr_service(service_path):
206 except dbus.DBusException as e:
210 print 'Heart Rate Service ready'
217 if __name__ == '__main__':