JavaScript ब्रिज API
Web Bluetooth
navigator.bluetooth का स्वरूप, जिसका जवाब नेटिव तरीके से दिया जाता है ताकि Chrome के लिए लिखा पेज बिना बदलाव के चले।
wbConnect ब्रिज#
window.WebToApk.wbConnect(requestId: String, deviceId: String)
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
device.gatt.connect() के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (gatt.connect() के ज़रिए) BluetoothRemoteGATTServer का Promise, डिवाइस की सर्विसेज़ खोज लिए जाने के बाद। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
async function connectAndList(device) {
try {
var server = await device.gatt.connect();
var services = await server.getPrimaryServices();
services.forEach(function (s) { console.log('service', s.uuid); });
return server;
} catch (err) {
showStatus('Could not connect: ' + err.message); // NetworkError, NotFoundError
return null;
}
}डिवाइस के कटने पर दोबारा जुड़ें। उसी डिवाइस पर connect() को फिर बुलाना काम करता है:
device.addEventListener('gattserverdisconnected', async function () {
showStatus('Reconnecting...');
try { await connectAndList(device); showStatus('Connected'); } catch (e) {}
});एक ही समय में दो सेंसरों से जुड़ें, जैसे हार्ट-रेट स्ट्रैप और पावर मीटर:
async function connectBoth(hrDevice, powerDevice) {
var servers = await Promise.all([hrDevice.gatt.connect(), powerDevice.gatt.connect()]);
var hr = await servers[0].getPrimaryService('heart_rate');
var power = await servers[1].getPrimaryService('cycling_power');
return {
heartRate: await hr.getCharacteristic('heart_rate_measurement'),
power: await power.getCharacteristic('cycling_power_measurement')
};
}ध्यान दें: रॉ सिग्नेचर wbConnect(requestId, deviceId)। पहले से जुड़े डिवाइस से जुड़ने पर वह तुरंत फिर पूरा हो जाता है। connect() पूरा होने से पहले getPrimaryService(s) NetworkError के साथ रिजेक्ट होता है। कई डिवाइस एक ही समय में जुड़े रह सकते हैं।
wbDisconnect ब्रिज#
window.WebToApk.wbDisconnect(deviceId: String)
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
device.gatt.disconnect() (और device.forget()) के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: कुछ नहीं (disconnect() वेब स्टैंडर्ड की तरह सिंक्रोनस है)। फिर डिवाइस gattserverdisconnected चलाता है। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
var device = null; // from navigator.bluetooth.requestDevice(...)
document.getElementById('stop').addEventListener('click', function () {
if (device && device.gatt.connected) device.gatt.disconnect();
});
// Fires for your own disconnect() and when the device goes away by itself.
function watch(dev) {
dev.addEventListener('gattserverdisconnected', function () {
showStatus('Disconnected from ' + (dev.name || dev.id));
});
}अपने Stop और सेंसर के रेंज से बाहर जाने में फ़र्क करें, और दोबारा सिर्फ़ दूसरी स्थिति में जुड़ें:
var userStopped = false;
function stopSession(device) {
userStopped = true;
if (device.gatt.connected) device.gatt.disconnect();
}
function watchDrops(device) {
device.addEventListener('gattserverdisconnected', function () {
if (userStopped) { userStopped = false; showStatus('Session ended'); return; }
showStatus('Sensor out of range, reconnecting...');
device.gatt.connect()
.then(resubscribe) // your code: get the characteristics, startNotifications()
.catch(function () { showStatus('Could not reconnect'); });
});
}एक "सेंसर हटाएँ" बटन: forget() डिवाइस को डिसकनेक्ट करके हटा देता है, और उसके बाद कोई gattserverdisconnected नहीं आता:
var device = null; // from navigator.bluetooth.requestDevice(...)
document.getElementById('forget').addEventListener('click', async function () {
if (!device) return;
await device.forget();
device = null;
showStatus('Sensor removed. Tap Connect to pick one again.');
});ध्यान दें: रॉ सिग्नेचर wbDisconnect(deviceId)। डिसकनेक्ट के बाद पुराने सर्विस और कैरेक्टरिस्टिक ऑब्जेक्ट नोटिफ़िकेशन पाना बंद कर देते हैं; अगले connect() के बाद उन्हें दोबारा लें और startNotifications() फिर से बुलाएँ। ऐप बंद होते समय हर कनेक्शन छोड़ देता है।
wbGetCharacteristics ब्रिज#
window.WebToApk.wbGetCharacteristics(requestId: String, deviceId: String, service: String)
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
service.getCharacteristic(uuid) और service.getCharacteristics() के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (सर्विस के ज़रिए) एक BluetoothRemoteGATTCharacteristic का, या उनके एक ऐरे का Promise, हर एक में uuid और properties (read, write, writeWithoutResponse, notify, indicate, broadcast, authenticatedSignedWrites) के साथ। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
async function describe(server) {
var service = await server.getPrimaryService('heart_rate');
// One characteristic, by standard name, 16-bit number or full UUID:
var measurement = await service.getCharacteristic('heart_rate_measurement'); // same as 0x2a37
// All of them:
var list = await service.getCharacteristics();
list.forEach(function (c) {
var p = c.properties;
console.log(c.uuid, p.read ? 'read' : '', p.write ? 'write' : '', p.notify ? 'notify' : '');
});
return measurement;
}कस्टम सर्विस की कैरेक्टरिस्टिक्स को उनके UUID हार्ड-कोड करने के बजाय, वे क्या कर सकती हैं उसके आधार पर ढूँढें:
async function findSerialPipes(server) {
var svc = await server.getPrimaryService('0000ffe0-0000-1000-8000-00805f9b34fb');
var list = await svc.getCharacteristics();
var incoming = list.find(function (c) { return c.properties.notify || c.properties.indicate; });
var outgoing = list.find(function (c) { return c.properties.write || c.properties.writeWithoutResponse; });
if (!incoming || !outgoing) throw new Error('This device does not look like a serial adapter');
return { incoming: incoming, outgoing: outgoing };
}एक वैकल्पिक कैरेक्टरिस्टिक पढ़ें और NotFoundError को "इस डिवाइस में यह नहीं है" मानें:
var LOCATIONS = ['Other', 'Chest', 'Wrist', 'Finger', 'Hand', 'Ear lobe', 'Foot'];
async function sensorLocation(server) {
var hr = await server.getPrimaryService('heart_rate');
try {
var chr = await hr.getCharacteristic('body_sensor_location'); // 0x2a38, optional in the spec
var v = await chr.readValue();
return LOCATIONS[v.getUint8(0)] || 'Unknown';
} catch (err) {
if (err.name === 'NotFoundError') return null; // this strap does not report it
throw err;
}
}ध्यान दें: रॉ सिग्नेचर wbGetCharacteristics(requestId, deviceId, service)। जो UUID सर्विस में नहीं है वह NotFoundError के साथ रिजेक्ट होता है; अनजाना नाम TypeError फेंकता है (कस्टम कैरेक्टरिस्टिक के लिए पूरा UUID दें)। सूची हर सर्विस के लिए एक बार ली जाती है और फिर दोबारा इस्तेमाल होती है।
wbIsAvailable ब्रिज#
window.WebToApk.wbIsAvailable(): Boolean
getAvailability(): बताता है कि फ़ोन में Bluetooth है या नहीं (Chrome का जवाब), यह नहीं कि वह चालू है या नहीं। requestDevice() यूज़र से उसे चालू करने को कहता है; सिर्फ़ बंद होने पर false लौटाने से वे पेज जो पहले जाँचते हैं ("if (!await getAvailability())") "Bluetooth सपोर्ट नहीं है" कह देते थे और उस प्रॉम्प्ट तक कभी पहुँचते ही नहीं थे (फ़िटनेस रिपोर्ट 2026-10-03)।
उदाहरण
navigator.bluetooth.getAvailability() के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (getAvailability() के ज़रिए) true का Promise जब बिल्ड में Bluetooth है और फ़ोन का Bluetooth चालू है, वरना false। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
async function updateBluetoothHint() {
var hint = document.getElementById('bt-hint');
if (!navigator.bluetooth) { hint.textContent = 'Bluetooth is not available in this app.'; return; }
var on = await navigator.bluetooth.getAvailability();
hint.textContent = on ? '' : 'Turn on Bluetooth to connect your sensor.';
}
document.addEventListener('visibilitychange', function () {
if (!document.hidden) updateBluetoothHint();
});Connect बटन तभी चालू करें जब Bluetooth चालू हो, और यूज़र के ऐप में लौटने पर हर बार फिर जाँचें:
async function refreshConnectButton() {
var btn = document.getElementById('connect');
if (!navigator.bluetooth) { btn.hidden = true; return; }
btn.disabled = !(await navigator.bluetooth.getAvailability());
}
window.addEventListener('load', refreshConnectButton);
document.addEventListener('visibilitychange', function () {
if (!document.hidden) refreshConnectButton();
});चुनने वाले को खोलने से पहले साफ़ "Bluetooth बंद है" संदेश दें, बाद में NotFoundError दिखाने के बजाय:
document.getElementById('scan').addEventListener('click', async function () {
if (!navigator.bluetooth) { showStatus('Bluetooth is not available in this app.'); return; }
if (!(await navigator.bluetooth.getAvailability())) {
showStatus('Bluetooth is off. Turn it on, then tap Scan again.');
return;
}
try {
var device = await navigator.bluetooth.requestDevice({ acceptAllDevices: true });
showStatus('Picked ' + (device.name || device.id));
} catch (err) {
showStatus(err.name === 'NotFoundError' ? 'No device chosen.' : err.message);
}
});ध्यान दें: रॉ सिग्नेचर wbIsAvailable(): Boolean (सिंक्रोनस)। यह सिर्फ़ अडैप्टर जाँचता है - कोई अनुमति नहीं माँगता। वेब स्टैंडर्ड का availabilitychanged इवेंट नहीं चलता, इसलिए पेज दिखने पर फिर से जाँचें।
wbNotify ब्रिज#
window.WebToApk.wbNotify(
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
characteristic.startNotifications() और stopNotifications() के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (कैरेक्टरिस्टिक के ज़रिए) खुद उसी कैरेक्टरिस्टिक का Promise। हर नई वैल्यू पर उस पर characteristicvaluechanged चलता है, वैल्यू event.target.value (एक DataView) में होती है। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
var cadenceChr = null;
async function startCadence(server) {
var svc = await server.getPrimaryService('running_speed_and_cadence');
cadenceChr = await svc.getCharacteristic('rsc_measurement');
cadenceChr.addEventListener('characteristicvaluechanged', onRsc);
await cadenceChr.startNotifications();
}
function onRsc(e) {
var v = e.target.value;
var kmh = v.getUint16(1, true) / 256 * 3.6;
var spm = v.getUint8(3);
show('run', kmh.toFixed(1) + ' km/h, ' + spm + ' steps/min');
}
async function stopCadence() {
if (!cadenceChr) return;
cadenceChr.removeEventListener('characteristicvaluechanged', onRsc);
try { await cadenceChr.stopNotifications(); } catch (e) {}
}जिस थर्मामीटर का मापन सिर्फ़ इंडिकेशन सपोर्ट करता है, उसे उसी तरह सब्सक्राइब किया जाता है, यहाँ oncharacteristicvaluechanged प्रॉपर्टी के ज़रिए:
async function watchThermometer(server) {
var svc = await server.getPrimaryService('health_thermometer');
var chr = await svc.getCharacteristic('temperature_measurement');
chr.oncharacteristicvaluechanged = function (e) {
var v = e.target.value;
var mantissa = v.getUint32(1, true) & 0x00ffffff; // IEEE-11073 FLOAT
if (mantissa & 0x800000) mantissa -= 0x1000000;
var fahrenheit = v.getUint8(0) & 1;
show('temp', (mantissa * Math.pow(10, v.getInt8(4))).toFixed(1) + (fahrenheit ? ' °F' : ' °C'));
};
await chr.startNotifications();
}सीरियल जैसे डिवाइस से टेक्स्ट लाइनें पाएँ, उन नोटिफ़िकेशन को जोड़ते हुए जो किसी लाइन को बीच में तोड़ देते हैं:
async function listenForLines(server, onLine) {
var uart = await server.getPrimaryService('6e400001-b5a3-f393-e0a9-e50e24dcca9e');
var tx = await uart.getCharacteristic('6e400003-b5a3-f393-e0a9-e50e24dcca9e');
if (!tx.properties.notify && !tx.properties.indicate) throw new Error('This device does not stream data');
var decoder = new TextDecoder(), buffer = '';
tx.addEventListener('characteristicvaluechanged', function (e) {
buffer += decoder.decode(e.target.value, { stream: true });
var lines = buffer.split('\n');
buffer = lines.pop();
lines.forEach(onLine);
});
await tx.startNotifications();
return tx;
}ध्यान दें: रॉ सिग्नेचर wbNotify(requestId, deviceId, service, characteristic, enable)। जो कैरेक्टरिस्टिक सिर्फ़ इंडिकेशन सपोर्ट करती है, उसे अपने आप इंडिकेशन से सब्सक्राइब किया जाता है। जो कैरेक्टरिस्टिक नोटिफ़ाई नहीं कर सकती वह NotSupportedError के साथ रिजेक्ट होती है। oncharacteristicvaluechanged = fn भी काम करता है। डिसकनेक्ट के बाद दोबारा सब्सक्राइब करें।
wbRead ब्रिज#
window.WebToApk.wbRead(requestId: String, deviceId: String, service: String, characteristic: String)
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
characteristic.readValue() के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (readValue() के ज़रिए) एक DataView का Promise; characteristic.value भी अपडेट होता है। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
async function readInfo(server) {
try {
var battery = await server.getPrimaryService('battery_service');
var level = await (await battery.getCharacteristic('battery_level')).readValue();
show('battery', level.getUint8(0) + '%');
var info = await server.getPrimaryService('device_information');
var maker = await (await info.getCharacteristic('manufacturer_name_string')).readValue();
show('maker', new TextDecoder().decode(maker));
} catch (err) {
// NotFoundError: the device has no such service/characteristic
// NotSupportedError: read rejected by the device NetworkError: not connected / read failed
show('info', err.message);
}
}ऐसे सेंसर को पोल करें जिसे सिर्फ़ पढ़ा जा सकता है, यहाँ स्टैंडर्ड Temperature कैरेक्टरिस्टिक (0x2a6e, डिग्री के सौवें हिस्से में):
var pollTimer = null;
async function startTemperaturePolling(server) {
var env = await server.getPrimaryService('environmental_sensing');
var temp = await env.getCharacteristic(0x2a6e);
pollTimer = setInterval(async function () {
try {
var v = await temp.readValue();
show('temp', (v.getInt16(0, true) / 100).toFixed(1) + ' °C');
} catch (err) {
clearInterval(pollTimer); // NetworkError once the sensor is gone
show('temp', err.message);
}
}, 5000);
}एक साथ कई रीड शुरू करके "इस डिवाइस के बारे में" पैनल भरें; वे आपके लिए एक के बाद एक चलते हैं:
async function readDeviceInfo(server) {
var info = await server.getPrimaryService('device_information');
var names = ['model_number_string', 'serial_number_string', 'firmware_revision_string'];
var decoder = new TextDecoder();
var results = await Promise.allSettled(names.map(async function (name) {
var chr = await info.getCharacteristic(name);
return decoder.decode(await chr.readValue());
}));
results.forEach(function (r, i) {
show(names[i], r.status === 'fulfilled' ? r.value : '-'); // missing ones reject with NotFoundError
});
}ध्यान दें: रॉ सिग्नेचर wbRead(requestId, deviceId, service, characteristic)। एक डिवाइस पर पढ़ना, लिखना और नोटिफ़िकेशन बदलना उसी क्रम में एक के बाद एक चलते हैं जिसमें आप उन्हें बुलाते हैं, इसलिए बीच में इंतज़ार किए बिना कई बुला सकते हैं।
wbRequestDevice ब्रिज#
window.WebToApk.wbRequestDevice(requestId: String, optionsJson: String)
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
navigator.bluetooth.requestDevice(options) के पीछे का आंतरिक ट्रांसपोर्ट: यह ऐप का डिवाइस चुनने वाला दिखाता है। पेज navigator.bluetooth.requestDevice इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (requestDevice के ज़रिए) एक BluetoothDevice {id, name, gatt} का Promise। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड navigator.bluetooth का ज़िक्र करता है) और आसपास के डिवाइस की अनुमति, जो पहली बार इस्तेमाल पर माँगी जाती है।
document.getElementById('pick').addEventListener('click', async function () {
if (!navigator.bluetooth) { showStatus('Bluetooth is not available in this app.'); return; }
try {
var device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['cycling_power'] }, { namePrefix: 'KICKR' }],
optionalServices: ['battery_service']
});
showStatus('Picked ' + (device.name || device.id));
} catch (err) {
if (err.name === 'NotFoundError') showStatus('No device chosen.'); // also: Bluetooth off
else showStatus(err.name + ': ' + err.message); // SecurityError = permission
}
});फ़िल्टर करने के बजाय आसपास के हर डिवाइस की सूची बनाने के लिए: requestDevice({ acceptAllDevices: true }).
कस्टम डिवाइस को उसके सटीक नाम या नाम के प्रीफ़िक्स से चुनें, उसकी अपनी 128-बिट सर्विस भी सूची में डालें ताकि जुड़ने के बाद इस्तेमाल हो सके:
async function pickLamp() {
try {
return await navigator.bluetooth.requestDevice({
filters: [{ name: 'Desk Lamp' }, { namePrefix: 'LAMP-' }], // either one matches
optionalServices: ['0000ffe0-0000-1000-8000-00805f9b34fb']
});
} catch (err) {
if (err.name === 'SecurityError') showStatus('Allow Nearby devices to find your lamp.');
else if (err.name !== 'NotFoundError') showStatus(err.message); // NotFoundError = cancelled
return null;
}
}हर सेशन में डिवाइस एक बार माँगें और बाद के टैप पर उसे दोबारा इस्तेमाल करें (getDevices() उपलब्ध नहीं है, इसलिए जो ऑब्जेक्ट मिला उसे संभालकर रखें):
var scale = null;
document.getElementById('weigh').addEventListener('click', async function () {
if (!navigator.bluetooth) { showStatus('Bluetooth is not available in this app.'); return; }
try {
if (!scale) {
scale = await navigator.bluetooth.requestDevice({
filters: [{ services: ['weight_scale'], namePrefix: 'MI' }] // both keys must match
});
}
var server = await scale.gatt.connect();
var svc = await server.getPrimaryService('weight_scale');
var chr = await svc.getCharacteristic('weight_measurement');
chr.addEventListener('characteristicvaluechanged', onWeight);
await chr.startNotifications();
} catch (err) {
showStatus(err.name + ': ' + err.message);
}
});ध्यान दें: रॉ सिग्नेचर wbRequestDevice(requestId, optionsJson); जवाब पेज को नहीं, पॉलीफ़िल को वापस मिलता है। requestDevice को टैप से बुलाएँ। फ़िल्टर services (विज्ञापित होना ज़रूरी), name (सटीक) और namePrefix इस्तेमाल करते हैं; फ़िल्टर तब मैच होता है जब उसकी सारी कुंजियाँ मैच करें, और डिवाइस तब मैच होता है जब कोई भी फ़िल्टर मैच करे। न filters न acceptAllDevices → TypeError। चुनने वाले को रद्द करने पर NotFoundError के साथ रिजेक्ट होता है। चुनने वाला 30 सेकंड स्कैन करता है। device.id डिवाइस का Bluetooth पता है।
wbWrite ब्रिज#
window.WebToApk.wbWrite(
WebBluetoothPolyfill के लिए रॉ ट्रांसपोर्ट। पेज इन्हें कभी सीधे नहीं बुलाता - वह navigator.bluetooth बुलाता है, ठीक वैसे ही जैसे ब्राउज़र में।
इसे अकेले नहीं, बल्कि इसके समूह Web Bluetooth (navigator.bluetooth) में समझाया गया है।
उदाहरण
characteristic.writeValue(), writeValueWithResponse() और writeValueWithoutResponse() के पीछे का आंतरिक ट्रांसपोर्ट। पेज navigator.bluetooth इस्तेमाल करते हैं; इसे सीधे न बुलाएँ।
लौटाता है: (कैरेक्टरिस्टिक के ज़रिए) undefined का Promise। ज़रूरत: Bluetooth (ZIP या HTML बिल्ड में अपने आप चालू हो जाता है जब आपका कोड इसका ज़िक्र करता है navigator.bluetooth).
जवाब के साथ (writeValue भी वही है): डिवाइस के लिखने की पुष्टि करने पर पूरा होता है।
async function setTargetPower(server, watts) {
var ftms = await server.getPrimaryService('fitness_machine');
var cp = await ftms.getCharacteristic('00002ad9-0000-1000-8000-00805f9b34fb'); // FTMS control point
await cp.writeValueWithResponse(new Uint8Array([0x00])); // request control
var cmd = new DataView(new ArrayBuffer(3));
cmd.setUint8(0, 0x05); // set target power
cmd.setInt16(1, watts, true);
await cp.writeValueWithResponse(cmd);
}बिना जवाब के: तेज़, उन स्ट्रीम के लिए जहाँ एक पैकेट खो जाने से फ़र्क नहीं पड़ता।
async function sendText(characteristic, text) {
if (!characteristic.properties.writeWithoutResponse) throw new Error('This characteristic needs writeValue');
await characteristic.writeValueWithoutResponse(new TextEncoder().encode(text));
}लंबी टेक्स्ट कमांड को 20-बाइट के टुकड़ों में भेजें। ऐप डिवाइस से बड़े पैकेट साइज़ की माँग नहीं करता, इसलिए एक बार में 20 बाइट ही समाते हैं:
async function sendLine(rx, text) {
var bytes = new TextEncoder().encode(text + '\n');
for (var i = 0; i < bytes.length; i += 20) {
await rx.writeValueWithoutResponse(bytes.subarray(i, i + 20));
}
}
// sendLine(rxCharacteristic, 'SET COLOR 255 120 0 BRIGHTNESS 80');ध्यान दें: रॉ सिग्नेचर wbWrite(requestId, deviceId, service, characteristic, valueBase64, withResponse)। वैल्यू ArrayBuffer, कोई भी टाइप्ड ऐरे, DataView या बाइट्स का सादा ऐरे हो सकती है; और कुछ भी देने पर TypeError फेंकता है। त्रुटियाँ: NotSupportedError (लिखना रिजेक्ट हुआ), NetworkError (लिखना विफल रहा या जुड़ा नहीं है), NotFoundError.