1. در مورد چیست؟
در این آزمایشگاه کد روشن، شما یاد خواهید گرفت که چگونه یک شمع بدون شعله LED PLAYBULB را با چیزی جز جاوا اسکریپت به لطف Web Bluetooth API کنترل کنید. در طول مسیر، شما همچنین با ویژگیهای جاوا اسکریپت ES2015 مانند کلاسها ، عملکردهای پیکان ، نقشه و وعدهها بازی خواهید کرد.
چیزی که یاد خواهید گرفت
- نحوه تعامل با دستگاه بلوتوث نزدیک در جاوا اسکریپت
- نحوه استفاده از کلاس های ES2015، توابع پیکان، نقشه و وعده ها
آنچه شما نیاز دارید
- درک اولیه از توسعه وب
- دانش اولیه بلوتوث کم انرژی (BLE) و مشخصات ویژگی عمومی (GATT)
- یک ویرایشگر متن به انتخاب شما
- یک مک، یک Chromebook، یا یک دستگاه Android M با برنامه مرورگر Chrome و یک کابل USB micro به USB.
2. ابتدا بازی کنید
ممکن است بخواهید نسخه نهایی برنامه ای را که می خواهید ایجاد کنید در https://googlecodelabs.github.io/candle-bluetooth بررسی کنید و قبل از اینکه واقعاً وارد این دستگاه شوید با دستگاه بلوتوث PLAYBULB Candle که در اختیار دارید بازی کنید. نرم افزار کد.
همچنین می توانید تغییر رنگ من را در https://www.youtube.com/watch?v=fBCPA9gIxlU تماشا کنید
3. راه اندازی شوید
نمونه کد را دانلود کنید
می توانید کد نمونه این کد را با دانلود فایل فشرده از اینجا دریافت کنید:
یا با شبیه سازی این مخزن git:
git clone https://github.com/googlecodelabs/candle-bluetooth.git
اگر منبع را به صورت فشرده دانلود کرده اید، باز کردن آن باید یک پوشه root candle-bluetooth-master
به شما بدهد.
وب سرور را نصب و تأیید کنید
در حالی که شما آزاد هستید که از وب سرور خود استفاده کنید، این کد لبه برای کار با وب سرور کروم طراحی شده است. اگر هنوز آن برنامه را نصب نکردهاید، میتوانید آن را از فروشگاه وب Chrome نصب کنید.
پس از نصب وب سرور برای برنامه کروم، روی میانبر Apps در نوار نشانک ها کلیک کنید:
در پنجره بعدی، روی نماد وب سرور کلیک کنید:
در ادامه این گفتگو را خواهید دید که به شما امکان می دهد وب سرور محلی خود را پیکربندی کنید:
روی دکمه انتخاب پوشه کلیک کنید و ریشه مخزن کلون شده (یا بایگانی نشده) را انتخاب کنید. این به شما امکان میدهد تا کارهای در حال انجام خود را از طریق URL مشخص شده در گفتگوی وب سرور (در بخش URL(های) وب سرور ) ارائه دهید.
در زیر گزینهها، کادر کنار « نمایش خودکار index.html » را علامت بزنید، همانطور که در زیر نشان داده شده است:
اکنون از سایت خود در مرورگر وب خود بازدید کنید (با کلیک بر روی URL وب سرور برجسته شده) و باید صفحه ای را مشاهده کنید که به شکل زیر است:
اگر میخواهید ببینید این برنامه در تلفن اندرویدی شما چگونه به نظر میرسد، باید Remote debugging را در Android فعال کنید و Port Forwarding را تنظیم کنید (شماره پورت به طور پیشفرض 8887 است). پس از آن، به سادگی می توانید یک تب جدید کروم را به آدرس http://localhost:8887 در تلفن اندرویدی خود باز کنید.
بعدی
در این مرحله این برنامه وب کار زیادی انجام نمی دهد. بیایید شروع به اضافه کردن پشتیبانی بلوتوث کنیم!
4. شمع را کشف کنید
ما با نوشتن کتابخانه ای شروع می کنیم که از کلاس JavaScript ES2015 برای دستگاه بلوتوث PLAYBULB Candle استفاده می کند.
آرامش خود را حفظ کنید. سینتکس کلاس یک مدل ارثی شی گرا جدید را به جاوا اسکریپت معرفی نمی کند. همانطور که در زیر می توانید بخوانید، به سادگی یک نحو بسیار واضح برای ایجاد اشیاء و مقابله با وراثت ارائه می دهد.
ابتدا، بیایید یک کلاس PlaybulbCandle
در playbulbCandle.js
تعریف کنیم و یک نمونه playbulbCandle
ایجاد کنیم که بعداً در فایل app.js
در دسترس خواهد بود.
playbulbCandle.js
(function() {
'use strict';
class PlaybulbCandle {
constructor() {
this.device = null;
}
}
window.playbulbCandle = new PlaybulbCandle();
})();
برای درخواست دسترسی به یک دستگاه بلوتوث نزدیک، باید با navigator.bluetooth.requestDevice
تماس بگیرید. از آنجایی که دستگاه PLAYBULB Candle به طور مداوم (اگر قبلاً جفت نشده است) یک UUID سرویس GATT Bluetooth ثابت که به شکل کوتاه آن به عنوان 0xFF02
شناخته می شود، تبلیغ می کند، می توانیم به سادگی یک ثابت تعریف کرده و آن را به پارامتر خدمات فیلترها در روش connect
عمومی جدید PlaybulbCandle
اضافه کنیم. کلاس
ما همچنین شیء BluetoothDevice
را به صورت داخلی پیگیری خواهیم کرد تا در صورت نیاز بتوانیم بعداً به آن دسترسی داشته باشیم. از آنجایی که navigator.bluetooth.requestDevice
یک JavaScript ES2015 Promise را برمی گرداند، ما این کار را در روش then
انجام خواهیم داد.
playbulbCandle.js
(function() {
'use strict';
const CANDLE_SERVICE_UUID = 0xFF02;
class PlaybulbCandle {
constructor() {
this.device = null;
}
connect() {
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
return navigator.bluetooth.requestDevice(options)
.then(function(device) {
this.device = device;
}.bind(this));
}
}
window.playbulbCandle = new PlaybulbCandle();
})();
به عنوان یک ویژگی امنیتی، کشف دستگاههای بلوتوث نزدیک با navigator.bluetooth.requestDevice
باید از طریق یک حرکت کاربر مانند لمس یا کلیک ماوس فراخوانی شود. به همین دلیل است که وقتی کاربر روی دکمه «اتصال» در فایل app.js
کلیک میکند، روش connect
فراخوانی میکنیم:
app.js
document.querySelector('#connect').addEventListener('click', function(event) {
document.querySelector('#state').classList.add('connecting');
playbulbCandle.connect()
.then(function() {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
})
.catch(function(error) {
console.error('Argh!', error);
});
});
برنامه را اجرا کنید
در این مرحله، از سایت خود در مرورگر وب خود بازدید کنید (با کلیک بر روی URL سرور وب مشخص شده در برنامه وب سرور) یا به سادگی صفحه موجود را بازخوانی کنید. روی دکمه سبز "Connect" کلیک کنید، دستگاه را در انتخابگر انتخاب کنید و کنسول Dev Tools مورد علاقه خود را با میانبر صفحه کلید Ctrl + Shift + J باز کنید و متوجه شوید که شئ BluetoothDevice
ثبت شده است.
اگر بلوتوث خاموش باشد و/یا دستگاه بلوتوث PLAYBULB Candle خاموش باشد، ممکن است با خطا مواجه شوید. در این صورت، آن را روشن کرده و دوباره ادامه دهید.
پاداش اجباری
من در مورد شما نمی دانم اما من قبلاً تعداد زیادی function() {}
در این کد می بینم. اجازه دهید به جای () => {}
جاوا اسکریپت ES2015 توابع پیکان. آنها نجات دهندگان مطلق زندگی هستند: تمام زیبایی های عملکردهای ناشناس، هیچ یک از غم و اندوه الزام آور.
playbulbCandle.js
(function() {
'use strict';
const CANDLE_SERVICE_UUID = 0xFF02;
class PlaybulbCandle {
constructor() {
this.device = null;
}
connect() {
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
return navigator.bluetooth.requestDevice(options)
.then(device => {
this.device = device;
});
}
}
window.playbulbCandle = new PlaybulbCandle();
})();
app.js
document.querySelector('#connect').addEventListener('click', event => {
playbulbCandle.connect()
.then(() => {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
})
.catch(error => {
console.error('Argh!', error);
});
});
بعدی
- باشه... میتونم با این شمع حرف بزنم یا چی؟
- حتما... برو به مرحله بعد
سوالات متداول
5. چیزی بخوانید
پس اکنون که یک BluetoothDevice
از وعده navigator.bluetooth.requestDevice
بازگشته است، چه می کنید؟ بیایید با فراخوانی device.gatt.connect()
به سرور گات راه دور بلوتوث متصل شویم که سرویس بلوتوث و تعاریف مشخصه را در خود نگه می دارد:
playbulbCandle.js
class PlaybulbCandle {
constructor() {
this.device = null;
}
connect() {
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}]};
return navigator.bluetooth.requestDevice(options)
.then(device => {
this.device = device;
return device.gatt.connect();
});
}
}
نام دستگاه را بخوانید
در اینجا ما به سرور GATT دستگاه بلوتوث PLAYBULB Candle متصل هستیم. اکنون میخواهیم سرویس اولیه گات را دریافت کنیم (که قبلاً با عنوان 0xFF02
تبلیغ میشد) و مشخصه نام دستگاه ( 0xFFFF
) را که متعلق به این سرویس است، بخوانیم. با افزودن متد جدید getDeviceName
به کلاس PlaybulbCandle
و استفاده از device.gatt.getPrimaryService
و service.getCharacteristic
به راحتی می توان به این امر دست یافت. متد characteristic.readValue
در واقع یک DataView
برمی گرداند که به سادگی با TextDecoder
رمزگشایی می کنیم.
playbulbCandle.js
const CANDLE_DEVICE_NAME_UUID = 0xFFFF;
...
getDeviceName() {
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_DEVICE_NAME_UUID))
.then(characteristic => characteristic.readValue())
.then(data => {
let decoder = new TextDecoder('utf-8');
return decoder.decode(data);
});
}
بیایید با فراخوانی playbulbCandle.getDeviceName
پس از اتصال و نمایش نام دستگاه، این را به app.js
اضافه کنیم.
app.js
document.querySelector('#connect').addEventListener('click', event => {
playbulbCandle.connect()
.then(() => {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
return playbulbCandle.getDeviceName().then(handleDeviceName);
})
.catch(error => {
console.error('Argh!', error);
});
});
function handleDeviceName(deviceName) {
document.querySelector('#deviceName').value = deviceName;
}
در این مرحله، از سایت خود در مرورگر وب خود بازدید کنید (با کلیک بر روی URL سرور وب مشخص شده در برنامه وب سرور) یا به سادگی صفحه موجود را بازخوانی کنید. مطمئن شوید که PLAYBULB Candle روشن است، سپس روی دکمه "اتصال" در صفحه کلیک کنید و نام دستگاه را در زیر انتخابگر رنگ ببینید.
سطح باتری را بخوانید
همچنین یک مشخصه استاندارد بلوتوث سطح باتری در دستگاه بلوتوث PLAYBULB Candle موجود است که حاوی سطح باتری دستگاه است. این بدان معناست که میتوانیم از نامهای استاندارد مانند battery_service
برای UUID سرویس بلوتوث گات و battery_level
برای ویژگی UUID GATT بلوتوث استفاده کنیم.
بیایید یک متد getBatteryLevel
جدید به کلاس PlaybulbCandle
اضافه کنیم و سطح باتری را به درصد بخوانیم.
playbulbCandle.js
getBatteryLevel() {
return this.device.gatt.getPrimaryService('battery_service')
.then(service => service.getCharacteristic('battery_level'))
.then(characteristic => characteristic.readValue())
.then(data => data.getUint8(0));
}
همچنین باید شی جاوا اسکریپت options
بهروزرسانی کنیم تا سرویس باتری به کلید optionalServices
اضافه شود، زیرا توسط دستگاه بلوتوث PLAYBULB Candle تبلیغ نمیشود، اما دسترسی به آن همچنان اجباری است.
playbulbCandle.js
let options = {filters:[{services:[ CANDLE_SERVICE_UUID ]}],
optionalServices: ['battery_service']};
return navigator.bluetooth.requestDevice(options)
مانند قبل، بیایید با فراخوانی playbulbCandle.getBatteryLevel
این را به app.js
وصل کنیم که نام دستگاه را داشته باشیم و سطح باتری را نمایش دهیم.
app.js
document.querySelector('#connect').addEventListener('click', event => {
playbulbCandle.connect()
.then(() => {
console.log(playbulbCandle.device);
document.querySelector('#state').classList.remove('connecting');
document.querySelector('#state').classList.add('connected');
return playbulbCandle.getDeviceName().then(handleDeviceName)
.then(() => playbulbCandle.getBatteryLevel().then(handleBatteryLevel));
})
.catch(error => {
console.error('Argh!', error);
});
});
function handleDeviceName(deviceName) {
document.querySelector('#deviceName').value = deviceName;
}
function handleBatteryLevel(batteryLevel) {
document.querySelector('#batteryLevel').textContent = batteryLevel + '%';
}
در این مرحله، از سایت خود در مرورگر وب خود بازدید کنید (با کلیک بر روی URL سرور وب مشخص شده در برنامه وب سرور) یا به سادگی صفحه موجود را بازخوانی کنید. روی دکمه "اتصال" در صفحه کلیک کنید و نام دستگاه و سطح باتری
بعدی
- چگونه می توانم رنگ این لامپ را تغییر دهم؟ برای همین اینجا هستم!
-تو خیلی نزدیکی قول میدم...
سوالات متداول
6. رنگ را تغییر دهید
تغییر رنگ به آسانی نوشتن مجموعه ای خاص از دستورات بر روی یک مشخصه بلوتوث ( 0xFFFC
) در سرویس اولیه گات که به عنوان 0xFF02
تبلیغ می شود، است. برای مثال، تبدیل کردن PLAYBULB Candle به قرمز، نوشتن آرایه ای از اعداد صحیح بدون علامت 8 بیتی برابر با [0x00, 255, 0, 0]
که در آن 0x00
اشباع سفید و 255, 0, 0
به ترتیب قرمز هستند. مقادیر سبز و آبی
ما از characteristic.writeValue
استفاده می کنیم تا در واقع برخی از داده ها را در مشخصه بلوتوث در متد جدید setColor
عمومی کلاس PlaybulbCandle
بنویسیم. و همچنین مقادیر واقعی قرمز، سبز و آبی را در صورت تحقق وعده برمی گردانیم تا بتوانیم بعداً از آنها در app.js
استفاده کنیم:
playbulbCandle.js
const CANDLE_COLOR_UUID = 0xFFFC;
...
setColor(r, g, b) {
let data = new Uint8Array([0x00, r, g, b]);
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_COLOR_UUID))
.then(characteristic => characteristic.writeValue(data))
.then(() => [r,g,b]);
}
بیایید تابع changeColor
را در app.js
به روز کنیم تا playbulbCandle.setColor
را با علامت زدن دکمه رادیویی "بدون اثر" فراخوانی کنیم. زمانی که کاربر روی بوم انتخابگر رنگ کلیک میکند، متغیرهای رنگی r, g, b
جهانی از قبل تنظیم شدهاند.
app.js
function changeColor() {
var effect = document.querySelector('[name="effectSwitch"]:checked').id;
if (effect === 'noEffect') {
playbulbCandle.setColor(r, g, b).then(onColorChanged);
}
}
در این مرحله، از سایت خود در مرورگر وب خود بازدید کنید (با کلیک بر روی URL سرور وب مشخص شده در برنامه وب سرور) یا به سادگی صفحه موجود را بازخوانی کنید. روی دکمه "اتصال" در صفحه کلیک کنید و بر روی انتخابگر رنگ کلیک کنید تا هر چند بار که می خواهید رنگ PLAYBULB Candle خود را تغییر دهید.
جلوه های شمع Moar
اگر قبلاً یک شمع روشن کرده اید، می دانید که نور ثابت نیست. خوشبختانه برای ما، مشخصه بلوتوث دیگری ( 0xFFFB
) در سرویس اولیه گات وجود دارد که به عنوان 0xFF02
تبلیغ میشود که به کاربر امکان میدهد جلوههای شمعی را تنظیم کند.
برای مثال میتوان با نوشتن [0x00, r, g, b, 0x04, 0x00, 0x01, 0x00]
به تنظیم یک «افکت شمع» دست یافت. و همچنین می توانید "اثر چشمک زن" را با [0x00, r, g, b, 0x00, 0x00, 0x1F, 0x00]
تنظیم کنید.
بیایید متدهای setCandleEffectColor
و setFlashingColor
را به کلاس PlaybulbCandle
اضافه کنیم.
playbulbCandle.js
const CANDLE_EFFECT_UUID = 0xFFFB;
...
setCandleEffectColor(r, g, b) {
let data = new Uint8Array([0x00, r, g, b, 0x04, 0x00, 0x01, 0x00]);
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_EFFECT_UUID))
.then(characteristic => characteristic.writeValue(data))
.then(() => [r,g,b]);
}
setFlashingColor(r, g, b) {
let data = new Uint8Array([0x00, r, g, b, 0x00, 0x00, 0x1F, 0x00]);
return this.device.gatt.getPrimaryService(CANDLE_SERVICE_UUID)
.then(service => service.getCharacteristic(CANDLE_EFFECT_UUID))
.then(characteristic => characteristic.writeValue(data))
.then(() => [r,g,b]);
}
و اجازه دهید تابع changeColor
در app.js
به روز کنیم تا playbulbCandle.setCandleEffectColor
را زمانی که دکمه رادیویی "Candle Effect" علامت زده می شود و playbulbCandle.setFlashingColor
را هنگامی که دکمه رادیویی "Flashing" علامت زده می شود، فراخوانی کنیم. این بار، اگر برای شما مشکلی ندارد، switch
استفاده می کنیم.
app.js
function changeColor() {
var effect = document.querySelector('[name="effectSwitch"]:checked').id;
switch(effect) {
case 'noEffect':
playbulbCandle.setColor(r, g, b).then(onColorChanged);
break;
case 'candleEffect':
playbulbCandle.setCandleEffectColor(r, g, b).then(onColorChanged);
break;
case 'flashing':
playbulbCandle.setFlashingColor(r, g, b).then(onColorChanged);
break;
}
}
در این مرحله، از سایت خود در مرورگر وب خود بازدید کنید (با کلیک بر روی URL سرور وب مشخص شده در برنامه وب سرور) یا به سادگی صفحه موجود را بازخوانی کنید. روی دکمه "اتصال" در صفحه کلیک کنید و با Candle و Flashing Effects بازی کنید.
بعدی
- همین؟ 3 جلوه ضعیف شمع؟ برای همین اینجا هستم؟
- تعداد بیشتری وجود دارد، اما این بار تنها خواهید بود.
7. مایل اضافی را طی کنید
پس ما اینجا هستیم! ممکن است فکر کنید تقریباً به پایان رسیده است، اما برنامه هنوز تمام نشده است. بیایید ببینیم آیا واقعاً متوجه شدهاید که در طول این کد لبه چه چیزی را کپی پیست کردهاید یا خیر. در اینجا کاری است که میخواهید به تنهایی انجام دهید تا این برنامه بدرخشد.
افکت های از دست رفته را اضافه کنید
در اینجا داده های مربوط به اثرات از دست رفته است:
- پالس:
[0x00, r, g, b, 0x01, 0x00, 0x09, 0x00]
(شاید بخواهید مقادیرr, g, b
را در آنجا تنظیم کنید) - رنگین کمان:
[0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00]
(افراد صرعی ممکن است بخواهند از این مورد اجتناب کنند) - محو شدن رنگین کمان:
[0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x26, 0x00]
این اساساً به معنای افزودن متدهای جدید setPulseColor
، setRainbow
و setRainbowFade
به کلاس PlaybulbCandle
و فراخوانی آنها در changeColor
است.
رفع "بدون اثر"
همانطور که ممکن است متوجه شده باشید، گزینه "بدون اثر" هیچ اثری را در حال انجام بازنشانی نمی کند، این جزئی است اما همچنان. بیایید این را درست کنیم. در متد setColor
، ابتدا باید بررسی کنید که آیا یک افکت از طریق متغیر کلاس جدید _isEffectSet
در حال انجام است یا خیر و اگر true
، قبل از تنظیم رنگ جدید با این داده ها، افکت را خاموش کنید: [0x00, r, g, b, 0x05, 0x00, 0x01, 0x00]
.
نام دستگاه را بنویسید
این یکی آسان است! نوشتن نام دستگاه سفارشی به سادگی نوشتن بر روی مشخصه نام دستگاه بلوتوث قبلی است. من توصیه می کنم از روش encode
TextEncoder
برای دریافت Uint8Array
حاوی نام دستگاه استفاده کنید.
سپس، یک eventListener
"ورودی" را به document.querySelector('#deviceName')
اضافه می کنم و playbulbCandle.setDeviceName
را فراخوانی می کنم تا ساده بماند.
من شخصا اسمم را PLAY💡 CANDLE گذاشتم!
8. همین!
چیزی که یاد گرفتی
- نحوه تعامل با دستگاه بلوتوث نزدیک در جاوا اسکریپت
- نحوه استفاده از کلاس های ES2015، توابع پیکان، نقشه و وعده ها
مراحل بعدی
- درباره Web Bluetooth API بیشتر بیاموزید
- نمونهها و دموهای رسمی بلوتوث وب را مرور کنید
- گربه عبوس در حال پرواز را ببینید