Web Bluetooth / Notifications (Async Await) Sample
Available in Chrome 55+ |
View on GitHub |
Browse Samples
The Web Bluetooth
API lets websites discover and communicate with devices over the
Bluetooth 4 wireless standard using the Generic Attribute Profile (GATT). It is
currently partially implemented in Android M, Chrome OS, Mac, and Windows 10.
This sample illustrates the use of the Web Bluetooth API to start and stop
characteristic notifications from a nearby Bluetooth Low Energy Device. You may
want to try this demo with the BLE Peripheral Simulator App
from the Google
Play Store and check out the Notifications (Promises)
sample.
alert_notification
automation_io
battery_service
blood_pressure
body_composition
bond_management
continuous_glucose_monitoring
current_time
cycling_power
cycling_speed_and_cadence
device_information
environmental_sensing
generic_access
generic_attribute
glucose
health_thermometer
heart_rate
human_interface_device (blocklisted)
immediate_alert
indoor_positioning
internet_protocol_support
link_loss
location_and_navigation
next_dst_change
phone_alert_status
pulse_oximeter
reference_time_update
running_speed_and_cadence
scan_parameters
tx_power
user_data
weight_scale
aerobic_heart_rate_lower_limit
aerobic_heart_rate_upper_limit
aerobic_threshold
age
aggregate
alert_category_id
alert_category_id_bit_mask
alert_level
alert_notification_control_point
alert_status
altitude
anaerobic_heart_rate_lower_limit
anaerobic_heart_rate_upper_limit
anaerobic_threshold
analog
apparent_wind_direction
apparent_wind_speed
gap.appearance
barometric_pressure_trend
battery_level
blood_pressure_feature
blood_pressure_measurement
body_composition_feature
body_composition_measurement
body_sensor_location
bond_management_control_point
bond_management_feature
boot_keyboard_input_report
boot_keyboard_output_report
boot_mouse_input_report
gap.central_address_resolution_support
cgm_feature
cgm_measurement
cgm_session_run_time
cgm_session_start_time
cgm_specific_ops_control_point
cgm_status
csc_feature
csc_measurement
current_time
cycling_power_control_point
cycling_power_feature
cycling_power_measurement
cycling_power_vector
database_change_increment
date_of_birth
date_of_threshold_assessment
date_time
day_date_time
day_of_week
descriptor_value_changed
gap.device_name
dew_point
digital
dst_offset
elevation
email_address
exact_time_256
fat_burn_heart_rate_lower_limit
fat_burn_heart_rate_upper_limit
firmware_revision_string
first_name
five_zone_heart_rate_limits
floor_number
gender
glucose_feature
glucose_measurement
glucose_measurement_context
gust_factor
hardware_revision_string
heart_rate_control_point
heart_rate_max
heart_rate_measurement
heat_index
height
hid_control_point
hid_information
hip_circumference
humidity
indoor_positioning_configuration
intermediate_blood_pressure
intermediate_temperature
irradiance
language
last_name
latitude
ln_control_point
ln_feature
local_east_coordinate.xml
local_north_coordinate
local_time_information
location_and_speed
location_name
longitude
magnetic_declination
magnetic_flux_density_2D
magnetic_flux_density_3D
manufacturer_name_string
maximum_recommended_heart_rate
measurement_interval
model_number_string
navigation
new_alert
gap.peripheral_preferred_connection_parameters
gap.peripheral_privacy_flag (blocklisted - write)
plx_continuous_measurement
plx_features
plx_spot_check_measurement
pnp_id
pollen_concentration
position_quality
pressure
protocol_mode
rainfall
gap.reconnection_address (blocklisted)
record_access_control_point
reference_time_information
report
report_map
resting_heart_rate
ringer_control_point
ringer_setting
rsc_feature
rsc_measurement
sc_control_point
scan_interval_window
scan_refresh
sensor_location
serial_number_string (blocklisted)
gatt.service_changed
software_revision_string
sport_type_for_aerobic_and_anaerobic_thresholds
supported_new_alert_category
supported_unread_alert_category
system_id
temperature
temperature_measurement
temperature_type
three_zone_heart_rate_limits
time_accuracy
time_source
time_update_control_point
time_update_state
time_with_dst
time_zone
true_wind_direction
true_wind_speed
two_zone_heart_rate_limit
tx_power_level
uncertainty
unread_alert_status
user_control_point
user_index
uv_index
vo2_max
waist_circumference
weight
weight_measurement
weight_scale_feature
wind_chill
Live Output
JavaScript Snippet
var myCharacteristic ;
async function onStartButtonClick () {
let serviceUuid = document . querySelector ( ' #service ' ). value ;
if ( serviceUuid . startsWith ( ' 0x ' )) {
serviceUuid = parseInt ( serviceUuid );
}
let characteristicUuid = document . querySelector ( ' #characteristic ' ). value ;
if ( characteristicUuid . startsWith ( ' 0x ' )) {
characteristicUuid = parseInt ( characteristicUuid );
}
try {
log ( ' Requesting Bluetooth Device... ' );
const device = await navigator . bluetooth . requestDevice ({
filters : [{ services : [ serviceUuid ]}]});
log ( ' Connecting to GATT Server... ' );
const server = await device . gatt . connect ();
log ( ' Getting Service... ' );
const service = await server . getPrimaryService ( serviceUuid );
log ( ' Getting Characteristic... ' );
myCharacteristic = await service . getCharacteristic ( characteristicUuid );
await myCharacteristic . startNotifications ();
log ( ' > Notifications started ' );
myCharacteristic . addEventListener ( ' characteristicvaluechanged ' ,
handleNotifications );
} catch ( error ) {
log ( ' Argh! ' + error );
}
}
async function onStopButtonClick () {
if ( myCharacteristic ) {
try {
await myCharacteristic . stopNotifications ();
log ( ' > Notifications stopped ' );
myCharacteristic . removeEventListener ( ' characteristicvaluechanged ' ,
handleNotifications );
} catch ( error ) {
log ( ' Argh! ' + error );
}
}
}
function handleNotifications ( event ) {
let value = event . target . value ;
let a = [];
// Convert raw data bytes to hex values just for the sake of showing something.
// In the "real" world, you'd use data.getUint8, data.getUint16 or even
// TextDecoder to process raw data bytes.
for ( let i = 0 ; i < value . byteLength ; i ++ ) {
a . push ( ' 0x ' + ( ' 00 ' + value . getUint8 ( i ). toString ( 16 )). slice ( - 2 ));
}
log ( ' > ' + a . join ( ' ' ));
}