Web Serial API का इस्तेमाल शुरू करना

1. परिचय

पिछली बार अपडेट किए जाने की तारीख: 19-09-2022

आपको क्या बनाना होगा

इस कोडलैब में, आपको एक ऐसा वेब पेज बनाना होगा जो Web Serial API का इस्तेमाल करके BBC Micro:bit बोर्ड के 5x5 LED मैट्रिक्स पर इमेज दिखाने के लिए उससे इंटरैक्ट करे. आपको Web Serial API के बारे में जानकारी मिलेगी. साथ ही, ब्राउज़र के ज़रिए सीरियल डिवाइसों से कनेक्ट करने के लिए, पढ़ने लायक, लिखने लायक, और स्ट्रीम को बदलने के तरीके के बारे में भी जानकारी मिलेगी.

67543f4caaaca5de.png

आपको इनके बारे में जानकारी मिलेगी

  • वेब सीरियल पोर्ट को खोलने और बंद करने का तरीका
  • इनपुट स्ट्रीम से डेटा मैनेज करने के लिए, रीड लूप का इस्तेमाल करने का तरीका
  • राइट स्ट्रीम से डेटा भेजने का तरीका

आपको इन चीज़ों की ज़रूरत होगी

  • Espruino फ़र्मवेयर 2v04 वाला BBC Micro:bit v1 बोर्ड
  • Chrome का नया वर्शन (80 या इसके बाद का)
  • एचटीएमएल, सीएसएस, JavaScript, और Chrome DevTools के बारे में जानकारी

हमने इस कोडलैब के लिए micro:bit v1 का इस्तेमाल किया है, क्योंकि यह किफ़ायती है. साथ ही, इसमें कुछ इनपुट (बटन) और आउटपुट (5x5 एलईडी डिसप्ले) मिलते हैं. इसके अलावा, इसमें और भी इनपुट और आउटपुट मिल सकते हैं. micro:bit की सुविधाओं के बारे में जानने के लिए, Espruino की साइट पर BBC micro:bit पेज देखें.

2. Web Serial API के बारे में जानकारी

Web Serial API, वेबसाइटों को स्क्रिप्ट की मदद से सीरियल डिवाइस से डेटा पढ़ने और उसमें डेटा लिखने का तरीका उपलब्ध कराता है. यह एपीआई, वेबसाइटों को माइक्रोकंट्रोलर और 3D प्रिंटर जैसे सीरियल डिवाइसों के साथ कम्यूनिकेट करने की अनुमति देकर, वेब और फ़िज़िकल वर्ल्ड को जोड़ता है.

वेब टेक्नोलॉजी का इस्तेमाल करके बनाए जा रहे कंट्रोल सॉफ़्टवेयर के कई उदाहरण हैं. उदाहरण के लिए:

कुछ मामलों में, ये वेबसाइटें किसी नेटिव एजेंट ऐप्लिकेशन के ज़रिए डिवाइस से संपर्क करती हैं. इस ऐप्लिकेशन को उपयोगकर्ता मैन्युअल तरीके से इंस्टॉल करता है. अन्य मामलों में, ऐप्लिकेशन को Electron जैसे फ़्रेमवर्क की मदद से, पैकेज किए गए नेटिव ऐप्लिकेशन के तौर पर डिलीवर किया जाता है. अन्य मामलों में, उपयोगकर्ता को एक और चरण पूरा करना होगा. जैसे, यूएसबी फ़्लैश ड्राइव की मदद से, कंपाइल किए गए ऐप्लिकेशन को डिवाइस पर कॉपी करना.

साइट और उसके ज़रिए कंट्रोल किए जाने वाले डिवाइस के बीच सीधे तौर पर बातचीत करके, उपयोगकर्ता अनुभव को बेहतर बनाया जा सकता है.

3. सेट अप करना

कोड पाना

हमने इस कोडलैब के लिए ज़रूरी सभी चीज़ों को Glitch प्रोजेक्ट में डाल दिया है.

  1. कोई नया ब्राउज़र टैब खोलें और https://web-serial-codelab-start.glitch.me/ पर जाएं.
  2. स्टार्टर प्रोजेक्ट का अपना वर्शन बनाने के लिए, Remix Glitch लिंक पर क्लिक करें.
  3. अपने कोड को काम करते हुए देखने के लिए, दिखाएं बटन पर क्लिक करें और फिर नई विंडो में चुनें.

4. सीरियल कनेक्शन खोलना

यह देखना कि Web Serial API काम करता है या नहीं

सबसे पहले, यह देखें कि आपके मौजूदा ब्राउज़र पर Web Serial API काम करता है या नहीं. इसके लिए, देखें कि serial, navigator में है या नहीं.

DOMContentLoaded इवेंट में, अपने प्रोजेक्ट में यह कोड जोड़ें:

script.js - DOMContentLoaded

// CODELAB: Add feature detection here.
const notSupported = document.getElementById('notSupported');
notSupported.classList.toggle('hidden', 'serial' in navigator);

इससे यह पता चलता है कि वेब सीरियल की सुविधा काम करती है या नहीं. अगर ऐसा है, तो यह कोड उस बैनर को छिपा देता है जिसमें लिखा होता है कि वेब सीरियल काम नहीं करता.

इसे आज़माएँ

  1. पेज लोड करें.
  2. पुष्टि करें कि पेज पर लाल रंग का कोई बैनर न दिख रहा हो, जिसमें यह जानकारी दी गई हो कि वेब सीरियल काम नहीं करता.

सीरियल पोर्ट खोलें

इसके बाद, हमें सीरियल पोर्ट खोलना होगा. अन्य मॉडर्न एपीआई की तरह, Web Serial API भी एसिंक्रोनस है. यह इनपुट के इंतज़ार में, यूज़र इंटरफ़ेस (यूआई) को ब्लॉक होने से रोकता है. हालांकि, यह इसलिए भी ज़रूरी है, क्योंकि वेब पेज को किसी भी समय सीरियल डेटा मिल सकता है. साथ ही, हमें इसे सुनने का एक तरीका चाहिए.

किसी कंप्यूटर में एक से ज़्यादा सीरियल डिवाइस हो सकते हैं. ऐसे में, जब ब्राउज़र पोर्ट का अनुरोध करने की कोशिश करता है, तो उपयोगकर्ता को यह प्रॉम्प्ट दिखता है कि उसे किस डिवाइस से कनेक्ट करना है.

अपने प्रोजेक्ट में यह कोड जोड़ें:

script.js - connect()

// CODELAB: Add code to request & open port here.
// - Request a port and open a connection.
port = await navigator.serial.requestPort();
// - Wait for the port to open.
await port.open({ baudRate: 9600 });

requestPort कॉल, उपयोगकर्ता को उस डिवाइस से कनेक्ट करने का प्रॉम्प्ट देता है जिससे वह कनेक्ट करना चाहता है. port.open को कॉल करने से पोर्ट खुल जाता है. हमें सीरियल डिवाइस से बातचीत करने की रफ़्तार भी बतानी होगी. BBC micro:bit, यूएसबी-टू-सिरियल चिप और मुख्य प्रोसेसर के बीच 9600 बाउड कनेक्शन का इस्तेमाल करता है.

कनेक्ट बटन को भी जोड़ें और उपयोगकर्ता के क्लिक करने पर, उसे connect() पर कॉल करने दें.

अपने प्रोजेक्ट में यह कोड जोड़ें:

script.js - clickConnect()

// CODELAB: Add connect code here.
await connect();

इसे आज़माएँ

हमारे प्रोजेक्ट में अब शुरुआत करने के लिए ज़रूरी चीज़ें मौजूद हैं. कनेक्ट करें बटन पर क्लिक करने से, उपयोगकर्ता को कनेक्ट करने के लिए सीरियल डिवाइस चुनने के लिए कहा जाता है. इसके बाद, वह micro:bit से कनेक्ट हो जाता है.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने के डायलॉग बॉक्स में, BBC माइक्रो:बिट डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. टैब पर, आपको यह बताने वाला एक आइकॉन दिखेगा कि आपने सीरियल डिवाइस से कनेक्ट किया है:

e695daf2277cd3a2.png

सीरियल पोर्ट से डेटा सुनने के लिए, इनपुट स्ट्रीम सेट अप करना

कनेक्ट हो जाने के बाद, हमें डिवाइस का डेटा पढ़ने के लिए इनपुट स्ट्रीम और एक रीडर सेट अप करना होगा. सबसे पहले, हम port.readable को कॉल करके पोर्ट से पढ़ी जा सकने वाली स्ट्रीम पाएंगे. हमें पता है कि हमें डिवाइस से टेक्स्ट मिलेगा, इसलिए हम उसे टेक्स्ट डिकोडर के ज़रिए भेजेंगे. इसके बाद, हम एक रीडर पाएंगे और रीड लूप शुरू करेंगे.

अपने प्रोजेक्ट में यह कोड जोड़ें:

script.js - connect()

// CODELAB: Add code to read the stream here.
let decoder = new TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable;

reader = inputStream.getReader();
readLoop();

रीड लूप एक असाइनोक्रोनस फ़ंक्शन है, जो लूप में चलता है और मुख्य थ्रेड को ब्लॉक किए बिना कॉन्टेंट का इंतज़ार करता है. नया डेटा आने पर, रीडर दो प्रॉपर्टी दिखाता है: value और done बूलियन. अगर done सही है, तो इसका मतलब है कि पोर्ट बंद हो गया है या अब कोई डेटा नहीं आ रहा है.

अपने प्रोजेक्ट में यह कोड जोड़ें:

script.js - readLoop()

// CODELAB: Add read loop here.
while (true) {
  const { value, done } = await reader.read();
  if (value) {
    log.textContent += value + '\n';
  }
  if (done) {
    console.log('[readLoop] DONE', done);
    reader.releaseLock();
    break;
  }
}

इसे आज़माएँ

हमारा प्रोजेक्ट अब डिवाइस से कनेक्ट हो सकता है और डिवाइस से मिले किसी भी डेटा को लॉग एलिमेंट में जोड़ देगा.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने के डायलॉग बॉक्स में, BBC माइक्रो:बिट डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको Espruino का लोगो दिखना चाहिए:

dd52b5c37fc4b393.png

सीरियल पोर्ट पर डेटा भेजने के लिए, आउटपुट स्ट्रीम सेट अप करना

आम तौर पर, सीरियल कम्यूनिकेशन दो-तरफ़ा होता है. हमें सीरियल पोर्ट से डेटा पाने के साथ-साथ, उसमें डेटा भी भेजना है. इनपुट स्ट्रीम की तरह ही, हम आउटपुट स्ट्रीम पर सिर्फ़ टेक्स्ट भेजेंगे.

सबसे पहले, एक टेक्स्ट एन्कोडर स्ट्रीम बनाएं और स्ट्रीम को port.writeable से कनेक्ट करें.

script.js - connect()

// CODELAB: Add code setup the output stream here.
const encoder = new TextEncoderStream();
outputDone = encoder.readable.pipeTo(port.writable);
outputStream = encoder.writable;

इसे Espruino फ़र्मवेयर के साथ सीरियल के ज़रिए कनेक्ट किए जाने पर, BBC Micro:bit बोर्ड, JavaScript read-eval-print लूप (REPL) की तरह काम करता है. यह Node.js शेल की तरह ही काम करता है. इसके बाद, हमें स्ट्रीम में डेटा भेजने का एक तरीका बताना होगा. नीचे दिए गए कोड को आउटपुट स्ट्रीम से राइटर मिलता है और इसके बाद हर लाइन को भेजने के लिए write का इस्तेमाल किया जाता है. भेजी गई हर लाइन में एक नई लाइन वर्ण (\n) शामिल होता है, ताकि micro:bit को भेजे गए निर्देश का आकलन करने के लिए कहा जा सके.

script.js - writeToStream()

// CODELAB: Write to output stream
const writer = outputStream.getWriter();
lines.forEach((line) => {
  console.log('[SEND]', line);
  writer.write(line + '\n');
});
writer.releaseLock();

सिस्टम को किसी खास स्थिति में लाने और उसे भेजे गए वर्णों को दोहराने से रोकने के लिए, हमें CTRL-C भेजना होगा और गड़बड़ी की जानकारी देने वाली सुविधा बंद करनी होगी.

script.js - connect()

// CODELAB: Send CTRL-C and turn off echo on REPL
writeToStream('\x03', 'echo(false);');

इसे आज़माएँ

हमारा प्रोजेक्ट अब माइक्रो:बिट से डेटा भेज और प्राप्त कर सकता है. आइए, देखते हैं कि हम सही तरीके से निर्देश भेज सकते हैं या नहीं:

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने के डायलॉग बॉक्स में, BBC माइक्रो:बिट डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. Chrome DevTools में कंसोल टैब खोलें और writeToStream('console.log("yes")'); टाइप करें

आपको पेज पर कुछ ऐसा दिखेगा:

15e2df0064b5de28.png

5. एलईडी मैट्रिक्स को कंट्रोल करें

मैट्रिक्स ग्रिड स्ट्रिंग बनाना

micro:bit पर एलईडी मैट्रिक्स को कंट्रोल करने के लिए, हमें show() को कॉल करना होगा. इस तरीके से, डिवाइस में पहले से मौजूद 5x5 एलईडी स्क्रीन पर ग्राफ़िक दिखाए जाते हैं. इसके लिए एक बाइनरी संख्या या स्ट्रिंग डालें.

हम चेकबॉक्स पर बार-बार जाकर, 1 और 0 का एक कलेक्शन जनरेट करेंगे. इससे यह पता चलेगा कि किस चेकबॉक्स पर सही का निशान लगा है और किस पर नहीं. इसके बाद, हमें ऐरे को उलटना होगा, क्योंकि हमारे चेकबॉक्स का क्रम, मैट्रिक में एलईडी के क्रम से उलट है. इसके बाद, हम ऐरे को स्ट्रिंग में बदलते हैं और micro:bit को भेजने के लिए कमांड बनाते हैं.

script.js - sendGrid()

// CODELAB: Generate the grid
const arr = [];
ledCBs.forEach((cb) => {
  arr.push(cb.checked === true ? 1 : 0);
});
writeToStream(`show(0b${arr.reverse().join('')})`);

मैट्रिक को अपडेट करने के लिए, चेकबॉक्स को जोड़ना

इसके बाद, हमें चेकबॉक्स में होने वाले बदलावों को सुनना होगा. अगर वे बदलते हैं, तो उस जानकारी को micro:bit पर भेजना होगा. सुविधा का पता लगाने वाले कोड (// CODELAB: Add feature detection here.) में, यह लाइन जोड़ें:

script.js - DOMContentLoaded

initCheckboxes();

माइक्रो:बिट के पहली बार कनेक्ट होने पर, ग्रिड को रीसेट करते हैं, ताकि यह खुश चेहरा दिखाए. drawGrid() फ़ंक्शन पहले से मौजूद है. यह फ़ंक्शन sendGrid() की तरह ही काम करता है. यह 1 और 0 के अरे को लेता है और चेकबॉक्स को सही तरीके से चुनता है.

script.js - clickConnect()

// CODELAB: Reset the grid on connect here.
drawGrid(GRID_HAPPY);
sendGrid();

इसे आज़माएँ

अब, जब पेज micro:bit से कनेक्ट होगा, तो वह खुश चेहरे वाला इमोजी भेजेगा. चेकबॉक्स पर क्लिक करने से, एलईडी मैट्रिक्स पर डिसप्ले अपडेट हो जाएगा.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने वाले डायलॉग में, BBC micro:bit डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको माइक्रो:बिट LED मैट्रिक्स पर एक मुस्कान दिखाई देगी.
  5. चेकबॉक्स को बदलकर, एलईडी मैट्रिक्स पर कोई दूसरा पैटर्न बनाएं.

6. माइक्रो:बिट बटन जोड़ें

micro:bit के बटन पर वॉच इवेंट जोड़ना

micro:bit पर दो बटन होते हैं. ये बटन, एलईडी मैट्रिक्स के दोनों ओर होते हैं. Espruino में setWatch फ़ंक्शन होता है, जो बटन दबाने पर इवेंट/कॉलबैक भेजता है. क्योंकि हम दोनों बटन को सुनना चाहते हैं, इसलिए हम अपने फ़ंक्शन को जेनरिक बनाएंगे और उससे इवेंट के विवरण प्रिंट करेंगे.

script.js - watchButton()

// CODELAB: Hook up the micro:bit buttons to print a string.
const cmd = `
  setWatch(function(e) {
    print('{"button": "${btnId}", "pressed": ' + e.state + '}');
  }, ${btnId}, {repeat:true, debounce:20, edge:"both"});
`;
writeToStream(cmd);

इसके बाद, हर बार सीरियल पोर्ट को डिवाइस से कनेक्ट करने पर, हमें दोनों बटन (माइक्रो:बिट बोर्ड पर BTN1 और BTN2 के नाम) को जोड़ने की ज़रूरत होगी.

script.js - clickConnect()

// CODELAB: Initialize micro:bit buttons.
watchButton('BTN1');
watchButton('BTN2');

इसे आज़माएँ

कनेक्ट होने पर खुश चेहरा दिखाने के अलावा, माइक्रो:बिट पर किसी भी बटन को दबाने से, पेज पर टेक्स्ट जुड़ जाएगा, जिससे पता चलेगा कि कौनसा बटन दबाया गया था. ज़्यादातर मामलों में, हर वर्ण अपनी लाइन में होगा.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने के डायलॉग बॉक्स में, BBC माइक्रो:बिट डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको माइक्रो:बिट्स LED मैट्रिक्स पर एक मुस्कान दिखाई देगी.
  5. माइक्रो:बिट पर बटन दबाएं और पुष्टि करें कि यह दबाए गए बटन के विवरण के साथ पेज पर नया टेक्स्ट जोड़ता है.

7. आने वाले डेटा को पार्स करने के लिए, ट्रांसफ़ॉर्म स्ट्रीम का इस्तेमाल करना

स्ट्रीम को मैनेज करने का बुनियादी तरीका

micro:bit के किसी बटन को दबाने पर, वह स्ट्रीम के ज़रिए सीरियल पोर्ट को डेटा भेजता है. स्ट्रीम बहुत उपयोगी होती हैं, लेकिन वे आपके लिए चुनौती की तरह भी हो सकती हैं, क्योंकि यह ज़रूरी नहीं है कि आपको सभी डेटा एक साथ मिल जाएं और वे मनचाहे तरीके से बंटे हुए हो सकते हैं.

ऐप्लिकेशन फ़िलहाल, इनकमिंग स्ट्रीम के आने पर उसे प्रिंट करता है (readLoop में). ज़्यादातर मामलों में, हर वर्ण अपनी लाइन में होता है, लेकिन यह ज़्यादा मददगार नहीं होता. आम तौर पर, स्ट्रीम को अलग-अलग लाइन में पार्स किया जाना चाहिए. साथ ही, हर मैसेज को उसकी लाइन के तौर पर दिखाया जाना चाहिए.

TransformStream की मदद से स्ट्रीम में बदलाव किया जा रहा है

ऐसा करने के लिए, हम स्ट्रीम ट्रांसफ़ॉर्म ( TransformStream) का इस्तेमाल कर सकते हैं. इससे इनकमिंग स्ट्रीम को पार्स करने और पार्स किया गया डेटा लौटाने में मदद मिलती है. एक ट्रांसफ़ॉर्म स्ट्रीम, स्ट्रीम सोर्स (इस मामले में, माइक्रो:बिट) और स्ट्रीम का इस्तेमाल करने वाली किसी भी चीज़ (इस मामले में readLoop) के बीच हो सकती है. इसके खत्म होने से पहले, उसमें आर्बिट्रेरी ट्रांसफ़ॉर्मेशन लागू किया जा सकता है. इसे किसी असेंबली लाइन की तरह समझें: जैसे ही विजेट लाइन पर आता है, लाइन का हर चरण विजेट में बदलाव करता है. इससे, जब तक यह आखिरी जगह पर आता है, तब तक वह पूरी तरह से काम करने वाला विजेट हो.

ज़्यादा जानकारी के लिए, MDN के Streams API के कॉन्सेप्ट देखें.

LineBreakTransformer की मदद से स्ट्रीम में बदलाव करना

आइए, एक LineBreakTransformer क्लास बनाएं, जो स्ट्रीम को लाइन ब्रेक (\r\n) के आधार पर अलग-अलग हिस्सों में बांटेगी. इस क्लास में दो तरीके transform और flush होने चाहिए. स्ट्रीम में नया डेटा मिलने पर, transform तरीके को हर बार कॉल किया जाता है. डेटा को सूची में जोड़ा जा सकता है या उसे बाद के लिए सेव किया जा सकता है. flush तरीके को तब कॉल किया जाता है, जब स्ट्रीम बंद हो जाती है. यह उस डेटा को मैनेज करता है जिसे अब तक प्रोसेस नहीं किया गया है.

अपने transform वाले तरीके में, हम container में नया डेटा जोड़ेंगे. इसके बाद, यह जांच करेंगे कि container में कोई लाइन ब्रेक है या नहीं. अगर कोई है, तो उसे ऐरे में बांटें. इसके बाद, पार्स की गई लाइनों को भेजने के लिए controller.enqueue() को कॉल करते हुए, लाइनों को दोहराएं.

script.js - LineBreakTransformer.transform()

// CODELAB: Handle incoming chunk
this.container += chunk;
const lines = this.container.split('\r\n');
this.container = lines.pop();
lines.forEach(line => controller.enqueue(line));

स्ट्रीम बंद होने पर, हम enqueue का इस्तेमाल करके कंटेनर में बचे हुए डेटा को फ़्लश कर देंगे.

script.js - LineBreakTransformer.flush()

// CODELAB: Flush the stream.
controller.enqueue(this.container);

आखिर में, हमें इनकमिंग स्ट्रीम को नए LineBreakTransformer के ज़रिए पाइप करना होगा. हमारी मूल इनपुट स्ट्रीम को सिर्फ़ TextDecoderStream से तक प्रोसेस किया गया था. इसलिए, हमें अपने नए LineBreakTransformer से जोड़ने के लिए, एक और pipeThrough जोड़ना होगा.

script.js - connect()

// CODELAB: Add code to read the stream here.
let decoder = new TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable
  .pipeThrough(new TransformStream(new LineBreakTransformer()));

इसे आज़माएँ

अब, micro:bit के किसी बटन को दबाने पर, प्रिंट किया गया डेटा एक लाइन में दिखेगा.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने वाले डायलॉग में, BBC micro:bit डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको माइक्रो:बिट LED मैट्रिक्स पर एक मुस्कान दिखाई देगी.
  5. micro:bit पर बटन दबाएं और पुष्टि करें कि आपको कुछ ऐसा दिख रहा है:

eead3553d29ee581.png

JSONTransformer की मदद से स्ट्रीम में बदलाव करना

हम readLoop में, स्ट्रिंग को JSON में पार्स करने की कोशिश कर सकते हैं. हालांकि, आइए एक बहुत ही आसान JSON ट्रांसफ़ॉर्मर बनाते हैं, जो डेटा को JSON ऑब्जेक्ट में बदल देगा. अगर डेटा, मान्य JSON नहीं है, तो जो भी मिला है उसे वापस करें.

script.js - JSONTransformer.transform

// CODELAB: Attempt to parse JSON content
try {
  controller.enqueue(JSON.parse(chunk));
} catch (e) {
  controller.enqueue(chunk);
}

इसके बाद, LineBreakTransformer से गुज़रने के बाद स्ट्रीम को JSONTransformer से पाइपलाइन करें. इससे हमें अपने JSONTransformer को आसान रखने में मदद मिलती है, क्योंकि हम जानते हैं कि JSON को कभी भी एक लाइन में ही भेजा जाएगा.

script.js - connect

// CODELAB: Add code to read the stream here.
let decoder = new TextDecoderStream();
inputDone = port.readable.pipeTo(decoder.writable);
inputStream = decoder.readable
  .pipeThrough(new TransformStream(new LineBreakTransformer()))
  .pipeThrough(new TransformStream(new JSONTransformer()));

इसे आज़माएँ

अब, जब आप माइक्रो:बिट बटन में से कोई एक बटन दबाते हैं, तो आपको पेज पर प्रिंट किया हुआ [object Object] दिखाई देगा.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने वाले डायलॉग में, BBC micro:bit डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको micro:bit के एलईडी मैट्रिक्स पर मुस्कुराता हुआ चेहरा दिखेगा.
  5. micro:bit पर मौजूद बटन दबाएं और पुष्टि करें कि आपको कुछ ऐसा दिख रहा है:

बटन दबाने पर जवाब देना

माइक्रो:बिट बटन दबाए जाने का जवाब देने के लिए, readLoop को अपडेट करें, ताकि यह पता लगाया जा सके कि उसे मिला डेटा, button प्रॉपर्टी वाला object है या नहीं. इसके बाद, बटन को दबाने पर होने वाली कार्रवाई को मैनेज करने के लिए, buttonPushed को कॉल करें.

script.js - readLoop()

const { value, done } = await reader.read();
if (value && value.button) {
  buttonPushed(value);
} else {
  log.textContent += value + '\n';
}

जब माइक्रो:बिट बटन पुश किया जाता है, तो LED मैट्रिक्स पर डिस्प्ले बदल जाना चाहिए. मैट्रिक्स को सेट करने के लिए, नीचे दिए गए कोड का इस्तेमाल करें:

script.js - buttonPushed()

// CODELAB: micro:bit button press handler
if (butEvt.button === 'BTN1') {
  divLeftBut.classList.toggle('pressed', butEvt.pressed);
  if (butEvt.pressed) {
    drawGrid(GRID_HAPPY);
    sendGrid();
  }
  return;
}
if (butEvt.button === 'BTN2') {
  divRightBut.classList.toggle('pressed', butEvt.pressed);
  if (butEvt.pressed) {
    drawGrid(GRID_SAD);
    sendGrid();
  }
}

इसे आज़माएँ

अब, micro:bit के किसी बटन को दबाने पर, एलईडी मैट्रिक्स, खुश या उदास चेहरे में बदल जाएगी.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने के डायलॉग बॉक्स में, BBC माइक्रो:बिट डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको माइक्रो:बिट्स LED मैट्रिक्स पर एक मुस्कान दिखाई देगी.
  5. micro:bit पर बटन दबाएं और पुष्टि करें कि एलईडी मैट्रिक बदल गई है.

8. सीरियल पोर्ट को बंद करना

आखिरी चरण में, पोर्ट को डिसकनेक्ट करने की सुविधा को कनेक्ट करना होता है, ताकि उपयोगकर्ता के काम पूरी करने के बाद पोर्ट को बंद कर दिया जा सके.

जब उपयोगकर्ता 'कनेक्ट करें/डिसकनेक्ट करें' बटन पर क्लिक करे, तब पोर्ट को बंद कर दें

जब उपयोगकर्ता कनेक्ट करें/डिसकनेक्ट करें बटन पर क्लिक करता है, तो हमें कनेक्शन बंद करना होगा. अगर पोर्ट पहले से खुला है, तो disconnect() को कॉल करें. इसके बाद, यूज़र इंटरफ़ेस (यूआई) को अपडेट करके बताएं कि पेज अब सीरियल डिवाइस से कनेक्ट नहीं है.

script.js - clickConnect()

// CODELAB: Add disconnect code here.
if (port) {
  await disconnect();
  toggleUIConnected(false);
  return;
}

स्ट्रीम और पोर्ट बंद करना

disconnect फ़ंक्शन में, हमें इनपुट स्ट्रीम बंद करनी होगी, आउटपुट स्ट्रीम बंद करनी होगी, और पोर्ट को बंद करना होगा. इनपुट स्ट्रीम बंद करने के लिए, reader.cancel() को कॉल करें. cancel को कॉल करने की प्रोसेस, सिंक नहीं होती. इसलिए, इसके पूरा होने का इंतज़ार करने के लिए, हमें await का इस्तेमाल करना होगा:

script.js - disconnect()

// CODELAB: Close the input stream (reader).
if (reader) {
  await reader.cancel();
  await inputDone.catch(() => {});
  reader = null;
  inputDone = null;
}

आउटपुट स्ट्रीम बंद करने के लिए, writer पाएं, close() को कॉल करें, और outputDone ऑब्जेक्ट के बंद होने का इंतज़ार करें:

script.js - disconnect()

// CODELAB: Close the output stream.
if (outputStream) {
  await outputStream.getWriter().close();
  await outputDone;
  outputStream = null;
  outputDone = null;
}

आखिर में, सीरियल पोर्ट को बंद करें और इसके बंद होने का इंतज़ार करें:

script.js - disconnect()

// CODELAB: Close the port.
await port.close();
port = null;

इसे आज़माएँ

अब अपनी मर्ज़ी से सीरियल पोर्ट को खोला और बंद किया जा सकता है.

  1. पेज को फिर से लोड करें.
  2. कनेक्ट करें बटन पर क्लिक करें.
  3. सीरियल पोर्ट चुनने वाले डायलॉग में, BBC micro:bit डिवाइस चुनें और कनेक्ट करें पर क्लिक करें.
  4. आपको माइक्रो:बिट LED मैट्रिक्स पर एक मुस्कान दिखेगी
  5. डिसकनेक्ट करें बटन दबाएं और पुष्टि करें कि एलईडी मैट्रिक बंद हो गई है और कंसोल में कोई गड़बड़ी नहीं है.

9. बधाई हो

बधाई हो! आपने Web Serial API का इस्तेमाल करने वाला अपना पहला वेब ऐप्लिकेशन बना लिया है.

वेब सीरियल एपीआई और वेब से जुड़ी उन सभी नई शानदार सुविधाओं के बारे में जानने के लिए https://goo.gle/fugu-api-tracker पर नज़र रखें जिन पर Chrome टीम काम कर रही है.