เปิดใช้การดำเนินการตามคำสั่งซื้อในร้านสำหรับการผสานรวมระบบคลาวด์กับระบบคลาวด์

1. ก่อนเริ่มต้น

การผสานรวมสมาร์ทโฮมช่วยให้ Google Assistant ควบคุมอุปกรณ์ที่เชื่อมต่อในบ้านของผู้ใช้ได้ หากต้องการสร้างการผสานรวมระบบคลาวด์กับระบบคลาวด์ คุณต้องระบุปลายทาง Webhook ของระบบคลาวด์ที่จัดการIntent ของสมาร์ทโฮมได้ เช่น เมื่อผู้ใช้พูดว่า "Ok Google เปิดไฟ" Assistant จะส่งคําสั่งไปยังการดําเนินการบนระบบคลาวด์เพื่ออัปเดตสถานะของอุปกรณ์

Local Home SDK ช่วยปรับปรุงการผสานรวมสมาร์ทโฮมโดยเพิ่มเส้นทางในเครื่องเพื่อกำหนด Intent ของสมาร์ทโฮมไปยังอุปกรณ์ Google Home โดยตรง ซึ่งจะช่วยเพิ่มความน่าเชื่อถือและลดเวลาในการตอบสนองในการประมวลผลคําสั่งของผู้ใช้ ซึ่งจะช่วยให้คุณเขียนและติดตั้งใช้งานแอปการดำเนินการตามคำสั่งซื้อในพื้นที่เป็น TypeScript หรือ JavaScript ที่ระบุอุปกรณ์และดำเนินการตามคำสั่งในลำโพงอัจฉริยะ Google Home หรือจออัจฉริยะ Google Nest จากนั้นแอปจะสื่อสารกับอุปกรณ์อัจฉริยะที่มีอยู่ของผู้ใช้โดยตรงผ่านเครือข่าย LAN โดยใช้โปรโตคอลมาตรฐานที่มีอยู่เพื่อดำเนินการตามคำสั่ง

72ffb320986092c.png

ข้อกำหนดเบื้องต้น

สิ่งที่คุณจะสร้าง

ในโค้ดแล็บนี้ คุณจะใช้การผสานรวมสมาร์ทโฮมที่สร้างไว้ก่อนหน้านี้กับ Firebase จากนั้นใช้การกำหนดค่าการสแกนใน คอนโซลนักพัฒนาแอป และสร้างแอปในเครื่องโดยใช้ TypeScript เพื่อส่งคำสั่งที่เขียนด้วย Node.js ไปยังอุปกรณ์เครื่องซักผ้าเสมือน

สิ่งที่คุณจะได้เรียนรู้

  • วิธีเปิดใช้และกำหนดค่าการดำเนินการตามคำสั่งซื้อในพื้นที่ในคอนโซลของนักพัฒนาแอป
  • วิธีใช้ Local Home SDK เพื่อเขียนแอปการจำหน่ายสินค้าในร้าน
  • วิธีแก้ไขข้อบกพร่องของแอปการดำเนินการตามคำสั่งซื้อในพื้นที่ที่โหลดไว้ในลำโพง Google Home หรือจออัจฉริยะ Google Nest

สิ่งที่ต้องมี

2. เริ่มต้นใช้งาน

เปิดใช้ส่วนควบคุมกิจกรรม

หากต้องการใช้ Google Assistant คุณต้องแชร์ข้อมูลกิจกรรมบางอย่างกับ Google Google Assistant ต้องใช้ข้อมูลนี้จึงจะทำงานได้อย่างถูกต้อง แต่ข้อกำหนดในการแชร์ข้อมูลไม่ได้เจาะจงสำหรับ SDK เท่านั้น หากต้องการแชร์ข้อมูลนี้ ให้สร้างบัญชี Google หากยังไม่มี คุณใช้บัญชี Google บัญชีใดก็ได้ ไม่จำเป็นต้องเป็นบัญชีนักพัฒนาแอป

เปิดหน้าส่วนควบคุมกิจกรรมของบัญชี Google ที่ต้องการใช้กับ Assistant

ตรวจสอบว่าได้เปิดใช้สวิตช์เปิด/ปิดต่อไปนี้

  • กิจกรรมบนเว็บและแอป - นอกจากนี้ อย่าลืมเลือกช่องทําเครื่องหมายรวมประวัติการเข้าชมใน Chrome และกิจกรรมจากเว็บไซต์ แอป และอุปกรณ์ที่ใช้บริการต่างๆ ของ Google
  • ข้อมูลอุปกรณ์
  • กิจกรรมเสียงพูดและเสียง

สร้างโปรเจ็กต์การผสานรวมระบบคลาวด์กับระบบคลาวด์

  1. ไปที่คอนโซลนักพัฒนาแอป
  2. คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์

ตั้งชื่อโปรเจ็กต์

เลือกการผสานรวมระบบคลาวด์กับระบบคลาวด์

ในหน้าแรกของโปรเจ็กต์ในคอนโซลของนักพัฒนาซอฟต์แวร์ ให้เลือกเพิ่มการผสานรวมระบบคลาวด์กับระบบคลาวด์ในส่วนระบบคลาวด์กับระบบคลาวด์

เพิ่มการผสานรวมระบบคลาวด์สู่ระบบคลาวด์

ติดตั้ง Firebase CLI

อินเทอร์เฟซบรรทัดคำสั่ง (CLI) ของ Firebase จะช่วยให้คุณแสดงเว็บแอปในเครื่องและทำให้เว็บแอปใช้งานได้ในโฮสติ้งของ Firebase

หากต้องการติดตั้ง CLI ให้เรียกใช้คำสั่ง npm ต่อไปนี้จากเทอร์มินัล

npm install -g firebase-tools

หากต้องการยืนยันว่าติดตั้ง CLI อย่างถูกต้องแล้ว ให้เรียกใช้คำสั่งต่อไปนี้

firebase --version

ให้สิทธิ์ Firebase CLI ด้วยบัญชี Google โดยเรียกใช้คำสั่งต่อไปนี้

firebase login

เปิดใช้ HomeGraph API

HomeGraph API ช่วยให้สามารถจัดเก็บและค้นหาอุปกรณ์และสถานะของอุปกรณ์ภายใน Home Graph ของผู้ใช้ หากต้องการใช้ API นี้ คุณต้องเปิดคอนโซล Google Cloud ก่อนแล้วเปิดใช้ HomeGraph API

ในคอนโซล Google Cloud ให้เลือกโปรเจ็กต์ที่ตรงกับ <project-id>. ของการผสานรวม จากนั้นคลิกเปิดใช้ในหน้าจอไลบรารี API สำหรับ HomeGraph API

5SVCzM8IZLi_9DV8M0nEklv16NXkpvM0bIzQK2hSyKyvnFHBxPOz90rbr72ayxzmxd5aNROOqC_Cp4outbdlwJdObDs0DIE_8vYzw6dovoVrP9IZWlWsZxDS7UHOi1jiRbDMG8MqUA

3. เรียกใช้แอปเริ่มต้น

เมื่อตั้งค่าสภาพแวดล้อมการพัฒนาซอฟต์แวร์แล้ว คุณสามารถทําให้การเริ่มใช้งานโปรเจ็กต์เพื่อยืนยันว่าทุกอย่างได้รับการกําหนดค่าอย่างถูกต้อง

ดูซอร์สโค้ด

คลิกลิงก์ต่อไปนี้เพื่อดาวน์โหลดตัวอย่างสําหรับโค้ดแล็บนี้ในเครื่องพัฒนาซอฟต์แวร์

...หรือจะโคลนที่เก็บ GitHub จากบรรทัดคำสั่งก็ได้ โดยทำดังนี้

git clone https://github.com/google-home/smarthome-local.git

เกี่ยวกับโปรเจ็กต์

โปรเจ็กต์เริ่มต้นมีไดเรกทอรีย่อยต่อไปนี้

  • public - UI บนเว็บส่วนหน้าสำหรับควบคุมและตรวจสอบเครื่องซักผ้าอัจฉริยะ
  • functions - ฟังก์ชันในระบบคลาวด์ที่ใช้การจำหน่ายสินค้าผ่านระบบคลาวด์สำหรับการผสานรวมระบบคลาวด์สู่ระบบคลาวด์
  • local - โปรเจ็กต์แอปการดำเนินการตามคำสั่งซื้อในพื้นที่แบบโครงร่างที่มี Handler ของ Intent วางไว้ชั่วคราวใน index.ts

การดำเนินการตามคำสั่งซื้อจากระบบคลาวด์ที่ระบุมีฟังก์ชันต่อไปนี้ใน index.js

  • fakeauth - ปลายทางการให้สิทธิ์สําหรับการลิงก์บัญชี
  • faketoken - ปลายทางโทเค็นสำหรับการลิงก์บัญชี
  • smarthome - ปลายทางสำหรับการตอบสนองต่อ Intent สมาร์ทโฮม
  • reportstate - เรียกใช้ HomeGraph API เมื่อสถานะอุปกรณ์มีการเปลี่ยนแปลง
  • updateDevice - ปลายทางที่อุปกรณ์เสมือนใช้เพื่อทริกเกอร์สถานะการรายงาน

เชื่อมต่อกับ Firebase

ไปที่ไดเรกทอรี app-start จากนั้นตั้งค่า Firebase CLI ด้วยโปรเจ็กต์การผสานรวมแบบระบบคลาวด์ต่อระบบคลาวด์ โดยทำดังนี้

cd app-start
firebase use <project-id>

กําหนดค่าโปรเจ็กต์ Firebase

เริ่มต้นโปรเจ็กต์ Firebase

firebase init

เลือกฟีเจอร์ CLI, ฐานข้อมูลเรียลไทม์, ฟังก์ชัน และฟีเจอร์โฮสติ้งที่มีโฮสติ้งของ Firebase

? Which Firebase CLI features do you want to set up for this directory? Press Space to select features, then
 Enter to confirm your choices.
❯◉ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance
 ◯ Firestore: Configure security rules and indexes files for Firestore
 ◉ Functions: Configure a Cloud Functions directory and its files
 ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys
 ◯ Hosting: Set up GitHub Action deploys
 ◯ Storage: Configure a security rules file for Cloud Storage
 ◯ Emulators: Set up local emulators for Firebase products
 ◯ Remote Config: Configure a template file for Remote Config
 ◯ Extensions: Set up an empty Extensions manifest

ซึ่งจะเริ่มต้น API และฟีเจอร์ที่จําเป็นสําหรับโปรเจ็กต์

เริ่มต้น Realtime Database เมื่อได้รับข้อความแจ้ง คุณใช้ตำแหน่งเริ่มต้นสำหรับอินสแตนซ์ฐานข้อมูลได้

? It seems like you haven't initialized Realtime Database in your project yet. Do you want to set it up?
Yes

? Please choose the location for your default Realtime Database instance:
us-central1

เนื่องจากคุณใช้โค้ดโปรเจ็กต์เริ่มต้น ให้เลือกไฟล์เริ่มต้นสำหรับกฎการรักษาความปลอดภัย และตรวจสอบว่าคุณไม่ได้เขียนทับไฟล์กฎฐานข้อมูลที่มีอยู่

? File database.rules.json already exists. Do you want to overwrite it with the Realtime Database Security Rules for <project-ID>-default-rtdb from the Firebase Console?
No

หากจะเริ่มต้นโปรเจ็กต์ใหม่ ให้เลือกเขียนทับเมื่อระบบถามว่าคุณต้องการเริ่มต้นหรือเขียนทับโค้ดเบส

? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

เมื่อกําหนดค่าฟังก์ชัน คุณควรใช้ไฟล์เริ่มต้น และตรวจสอบว่าคุณไม่ได้เขียนทับไฟล์ index.js และ package.json ที่มีอยู่เดิมในตัวอย่างโปรเจ็กต์

? What language would you like to use to write Cloud Functions?
JavaScript

? Do you want to use ESLint to catch probable bugs and enforce style?
No

? File functions/package.json already exists. Overwrite?
No

? File functions/index.js already exists. Overwrite?
No

หากจะเริ่มต้นโปรเจ็กต์ใหม่ ให้เลือกไม่เมื่อระบบถามว่าคุณต้องการเริ่มต้นหรือเขียนทับ functions/.gitignore

? File functions/.gitignore already exists. Overwrite?
No
? Do you want to install dependencies with npm now?
Yes

สุดท้าย ให้กําหนดค่าการตั้งค่าโฮสติ้งให้ใช้ไดเรกทอรี public ในโค้ดโปรเจ็กต์ และใช้ไฟล์ index.html ที่มีอยู่ เลือกไม่เมื่อระบบขอให้ใช้ ESLint

? What do you want to use as your public directory?
public

? Configure as a single-page app (rewrite all urls to /index.html)?
Yes

? Set up automatic builds and deploys with GitHub?
No

? File public/index.html already exists. Overwrite?
 No

หากเปิดใช้ ESLint โดยไม่ได้ตั้งใจ คุณปิดใช้ได้ 2 วิธีดังนี้

  1. ใช้ GUI ไปที่โฟลเดอร์ ../functions ใต้โปรเจ็กต์ เลือกไฟล์ .eslintrc.js ที่ซ่อนอยู่ แล้วลบออก อย่าสับสนกับ .eslintrc.json ที่มีชื่อคล้ายกัน
  2. การใช้บรรทัดคำสั่ง
    cd functions
    rm .eslintrc.js
    

คัดลอกไฟล์ firebase.json จากไดเรกทอรี washer-done ไปยังไดเรกทอรี washer-start โดยเขียนทับไฟล์ใน washer-start เพื่อให้แน่ใจว่าคุณมีการกำหนดค่า Firebase ที่ถูกต้องและสมบูรณ์

ในไดเรกทอรี washer-start ให้ทำดังนี้

cp -vp ../washer-done/firebase.json .

ทำให้ใช้งานได้กับ Firebase

เมื่อติดตั้ง Dependency และกำหนดค่าโปรเจ็กต์แล้ว คุณก็พร้อมเรียกใช้แอปเป็นครั้งแรก

firebase deploy

คุณควรเห็นเอาต์พุตคอนโซลดังต่อไปนี้

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

คำสั่งนี้จะทําให้เว็บแอปพร้อมใช้งานพร้อมกับ Cloud Functions for Firebase หลายรายการ

เปิด Hosting URL ในเบราว์เซอร์ (https://<project-id>.web.app) เพื่อดูเว็บแอป คุณจะเห็นอินเทอร์เฟซต่อไปนี้

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

เว็บ UI นี้แสดงแพลตฟอร์มของบุคคลที่สามเพื่อดูหรือแก้ไขสถานะของอุปกรณ์ หากต้องการเริ่มป้อนข้อมูลอุปกรณ์ลงในฐานข้อมูล ให้คลิกอัปเดต คุณจะไม่เห็นว่าหน้าเว็บมีการเปลี่ยนแปลงใดๆ แต่ระบบจะจัดเก็บสถานะปัจจุบันของเครื่องซักผ้าไว้ในฐานข้อมูล

ตอนนี้ถึงเวลาเชื่อมต่อบริการระบบคลาวด์ที่คุณติดตั้งใช้งานกับ Google Assistant โดยใช้ Developer Console

กำหนดค่าโปรเจ็กต์ใน Developer Console

ในแท็บพัฒนา ให้เพิ่มชื่อที่แสดงสำหรับการโต้ตอบ ชื่อนี้จะปรากฏในแอป Google Home

เพิ่มชื่อที่แสดง

ในส่วนการสร้างแบรนด์แอป ให้อัปโหลดไฟล์ png สำหรับไอคอนแอปขนาด 144 x 144 พิกเซล และตั้งชื่อว่า .png

เพิ่มไอคอนแอป

หากต้องการเปิดใช้การลิงก์บัญชี ให้ใช้การตั้งค่าการลิงก์บัญชีต่อไปนี้

รหัสลูกค้า

ABC123

รหัสลับไคลเอ็นต์

DEF456

URL สำหรับการอนุญาต

https://us-central1-
.cloudfunctions.net/fakeauth

URL ของโทเค็น

https://us-central1-
.cloudfunctions.net/faketoken

อัปเดต URL การลิงก์บัญชี

ในส่วน URL การดําเนินการบนระบบคลาวด์ ให้ป้อน URL ของฟังก์ชันบนระบบคลาวด์ที่ดําเนินการตาม Intent สมาร์ทโฮม

https://us-central1--cloudfunctions.net/smarthome

เพิ่ม URL ของ Cloud Function

คลิกบันทึกเพื่อบันทึกการกําหนดค่าโปรเจ็กต์ แล้วคลิกถัดไป: ทดสอบเพื่อเปิดใช้การทดสอบในโปรเจ็กต์

ทดสอบการผสานรวมระบบคลาวด์กับระบบคลาวด์

ตอนนี้คุณจะเริ่มใช้ Webhooks ที่จําเป็นต่อการเชื่อมต่อสถานะของอุปกรณ์กับ Assistant ได้แล้ว

หากต้องการทดสอบการผสานรวมระบบคลาวด์กับระบบคลาวด์ คุณต้องลิงก์โปรเจ็กต์กับบัญชี Google ซึ่งจะช่วยให้ทดสอบผ่านแพลตฟอร์มต่างๆ ของ Google Assistant และแอป Google Home ที่ลงชื่อเข้าใช้บัญชีเดียวกันได้

  1. เปิดการตั้งค่า Google Assistant ในโทรศัพท์ โปรดทราบว่าคุณควรลงชื่อเข้าใช้ด้วยบัญชีเดียวกับในคอนโซล
  2. ไปที่ Google Assistant > การตั้งค่า > การควบคุมอุปกรณ์สมาร์ทโฮม (ในส่วน Assistant)
  3. คลิกไอคอนค้นหาที่ด้านขวาบน
  4. ค้นหาแอปทดสอบโดยใช้คำนำหน้า [test] เพื่อค้นหาแอปทดสอบที่ต้องการ
  5. เลือกรายการนั้น จากนั้น Google Assistant จะตรวจสอบสิทธิ์กับบริการของคุณและส่งคําขอ SYNC โดยขอให้บริการของคุณระบุรายการอุปกรณ์สําหรับผู้ใช้

เปิดแอป Google Home และตรวจสอบว่าคุณเห็นอุปกรณ์เครื่องซักผ้า

XcWmBVamBZtPfOFqtsr5I38stPWTqDcMfQwbBjetBgxt0FCjEs285pa9K3QXSASptw0KYN2G8yfkT0-xg664V4PjqMreDDs-HPegHjOc4EVtReYPu-WKZyygq9Xmkf8X8z9177nBjQ

ยืนยันว่าคุณสามารถควบคุมเครื่องซักผ้าโดยใช้คำสั่งเสียงในแอป Google Home นอกจากนี้ คุณควรเห็นสถานะอุปกรณ์เปลี่ยนแปลงใน UI เว็บส่วนหน้าของการดำเนินการตามคำสั่งซื้อจากระบบคลาวด์ด้วย

ตอนนี้คุณเริ่มเพิ่มการดำเนินการตามคำสั่งซื้อในพื้นที่ในการผสานรวมได้แล้ว

4. อัปเดตการจำหน่ายสินค้าในระบบคลาวด์

หากต้องการรองรับการดำเนินการตามคำสั่งซื้อในพื้นที่ คุณต้องเพิ่มช่องใหม่ต่ออุปกรณ์ชื่อ otherDeviceIds ในการตอบกลับ SYNC ของคลาวด์ซึ่งมีตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์ ช่องนี้ยังระบุความสามารถในการควบคุมอุปกรณ์ดังกล่าวในเครื่องด้วย

เพิ่มช่อง otherDeviceIds ลงในคําตอบ SYNC ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

functions/index.js

app.onSync((body) => {
  return {
    requestId: body.requestId,
    payload: {
      agentUserId: '123',
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [ ... ],
        name: { ... },
        deviceInfo: { ... },
        willReportState: true,
        attributes: {
          pausable: true,
        },
        otherDeviceIds: [{
          deviceId: 'deviceid123',
        }],
      }],
    },
  };
});

ติดตั้งใช้งานโปรเจ็กต์ที่อัปเดตแล้วใน Firebase โดยทำดังนี้

firebase deploy --only functions

หลังจากการทําให้ใช้งานได้เสร็จสมบูรณ์แล้ว ให้ไปที่ UI ของเว็บ แล้วคลิกปุ่มรีเฟรช ae8d3b25777a5e30.png ในแถบเครื่องมือ ซึ่งจะทริกเกอร์การดำเนินการ "ซิงค์คำขอ" เพื่อให้ Assistant ได้รับข้อมูลการตอบกลับ SYNC ที่อัปเดตแล้ว

bf4f6a866160a982.png

5. กำหนดค่าการดำเนินการตามคำสั่งซื้อในพื้นที่

ในส่วนนี้ คุณจะเพิ่มตัวเลือกการกำหนดค่าที่จำเป็นสำหรับการนำส่งในพื้นที่ในการผสานรวมระบบคลาวด์ต่อคลาวด์ ในระหว่างการพัฒนา คุณจะเผยแพร่แอปการดำเนินการตามคำสั่งซื้อในพื้นที่ไปยังโฮสติ้ง Firebase ซึ่งอุปกรณ์ Google Home สามารถเข้าถึงและดาวน์โหลดแอปได้

ใน Google Home Developer Console ให้ไปที่ Project > Cloud-to-cloud ทางด้านซ้ายของหน้าจอ แล้วเลือกแก้ไขสำหรับการผสานรวม ในหน้าการตั้งค่าและการกําหนดค่า ให้เลื่อนไปที่การจำหน่ายสินค้าในร้าน แล้วเปิดการตั้งค่า ป้อน URL ต่อไปนี้ในช่อง URL ทดสอบแต่ละช่อง แทรกรหัสโปรเจ็กต์ แล้วคลิกบันทึก

https://<project-id>.web.app/local-home/index.html

local-fulfillment.png

ถัดไป เราต้องกำหนดวิธีที่อุปกรณ์ Google Home ควรค้นพบอุปกรณ์อัจฉริยะภายใน แพลตฟอร์มบ้านในพื้นที่รองรับโปรโตคอลหลายรายการสำหรับการค้นหาอุปกรณ์ ซึ่งรวมถึง mDNS, UPnP และการออกอากาศ UDP คุณจะใช้การออกอากาศ UDP เพื่อค้นหาเครื่องซักผ้าอัจฉริยะ

คลิก + เพิ่มการกำหนดค่าการสแกนในส่วนการตรวจหาอุปกรณ์เพื่อเพิ่มการกำหนดค่าการสแกนใหม่ เลือก UDP เป็นโปรโตคอล แล้วกรอกแอตทริบิวต์ต่อไปนี้

ฟิลด์

คำอธิบาย

ค่าที่แนะนำ

ที่อยู่สำหรับ Discovery

ที่อยู่การค้นพบ UDP

255.255.255.255

พอร์ตการออกอากาศ

พอร์ตที่ Google Home ส่งการออกอากาศ UDP

3311

พอร์ตการฟัง

พอร์ตที่ Google Home รอการตอบกลับ

3312

แพ็กเก็ตการค้นพบ

ข้อมูลเพย์โหลดการออกอากาศ UDP

48656c6c6f4c6f63616c486f6d6553444b

device-discovery.png

สุดท้าย ให้คลิกบันทึกที่ด้านล่างของหน้าต่างเพื่อเผยแพร่การเปลี่ยนแปลง

6. ใช้การดำเนินการตามคำสั่งซื้อในพื้นที่

คุณจะพัฒนาแอปการจำหน่ายสินค้าในร้านเป็น TypeScript โดยใช้ แพ็กเกจ typings ของ Local Home SDK ดูโครงร่างที่ให้ไว้ในโปรเจ็กต์เริ่มต้น

local/index.ts

/// <reference types="@google/local-home-sdk" />

import App = smarthome.App;
import Constants = smarthome.Constants;
import DataFlow = smarthome.DataFlow;
import Execute = smarthome.Execute;
import Intents = smarthome.Intents;
import IntentFlow = smarthome.IntentFlow;

...

class LocalExecutionApp {

  constructor(private readonly app: App) { }

  identifyHandler(request: IntentFlow.IdentifyRequest):
      Promise<IntentFlow.IdentifyResponse> {
    // TODO: Implement device identification
  }

  executeHandler(request: IntentFlow.ExecuteRequest):
      Promise<IntentFlow.ExecuteResponse> {
    // TODO: Implement local fulfillment
  }

  ...
}

const localHomeSdk = new App('1.0.0');
const localApp = new LocalExecutionApp(localHomeSdk);
localHomeSdk
  .onIdentify(localApp.identifyHandler.bind(localApp))
  .onExecute(localApp.executeHandler.bind(localApp))
  .listen()
  .then(() => console.log('Ready'))
  .catch((e: Error) => console.error(e));

องค์ประกอบหลักของการดำเนินการตามคำสั่งซื้อในพื้นที่คือคลาส smarthome.App โปรเจ็กต์เริ่มต้นจะแนบตัวแฮนเดิลสำหรับ Intent IDENTIFY และ EXECUTE จากนั้นเรียกใช้เมธอด listen() เพื่อแจ้งให้ Local Home SDK ทราบว่าแอปพร้อมใช้งาน

เพิ่มตัวแฮนเดิล IDENTIFY

Local Home SDK จะทริกเกอร์ตัวแฮนเดิล IDENTIFY เมื่ออุปกรณ์ Google Home พบอุปกรณ์ที่ยังไม่ได้ยืนยันในเครือข่ายภายในตามการกำหนดค่าการสแกนที่ระบุไว้ในคอนโซลของนักพัฒนาซอฟต์แวร์

ในระหว่างนี้ แพลตฟอร์มจะเรียกใช้ identifyHandler ด้วยข้อมูลการสแกนที่ได้เมื่อ Google พบอุปกรณ์ที่ตรงกัน ในแอปของคุณ การสแกนจะดำเนินการโดยใช้การออกอากาศ UDP และข้อมูลการสแกนที่ส่งไปยังตัวแฮนเดิล IDENTIFY จะมีเพย์โหลดการตอบกลับที่อุปกรณ์ในเครื่องส่ง

แฮนเดิลจะแสดงผลอินสแตนซ์ IdentifyResponse ที่มีตัวระบุที่ไม่ซ้ำกันสำหรับอุปกรณ์ในเครื่อง เพิ่มโค้ดต่อไปนี้ลงในเมธอด identifyHandler เพื่อประมวลผลการตอบกลับ UDP ที่มาจากอุปกรณ์ในเครื่องและระบุรหัสอุปกรณ์ในเครื่องที่เหมาะสม

local/index .ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device ID.
  const localDeviceId = Buffer.from(scanData.data, 'hex');

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

โปรดทราบว่าช่อง verificationId ต้องตรงกับค่า otherDeviceIds ค่าใดค่าหนึ่งในคำตอบ SYNC ซึ่งจะแจ้งว่าอุปกรณ์พร้อมจำหน่ายในพื้นที่ใน Home Graph ของผู้ใช้ หลังจาก Google พบรายการที่ตรงกัน ระบบจะถือว่าอุปกรณ์ดังกล่าวได้รับการยืนยันและพร้อมสำหรับการจำหน่ายสินค้าในพื้นที่

เพิ่มตัวแฮนเดิล EXECUTE

Local Home SDK จะทริกเกอร์ตัวแฮนเดิล EXECUTE เมื่ออุปกรณ์ที่รองรับการตอบสนองในเครื่องได้รับคําสั่ง เนื้อหาของ Intent ในเครื่องจะเทียบเท่ากับ Intent EXECUTE ที่ส่งไปยังการดําเนินการบนระบบคลาวด์ ดังนั้นตรรกะในการประมวลผล Intent ในเครื่องจะคล้ายกับวิธีจัดการ Intent ในระบบคลาวด์

แอปสามารถใช้ซ็อกเก็ต TCP/UDP หรือคำขอ HTTP(S) เพื่อสื่อสารกับอุปกรณ์ภายในได้ ในโค้ดแล็บนี้ HTTP จะทำหน้าที่เป็นโปรโตคอลที่ใช้ควบคุมอุปกรณ์เสมือน หมายเลขพอร์ตจะกำหนดไว้ใน index.ts เป็นตัวแปร SERVER_PORT

เพิ่มโค้ดต่อไปนี้ลงในเมธอด executeHandler เพื่อประมวลผลคําสั่งขาเข้าและส่งไปยังอุปกรณ์ภายในผ่าน HTTP

local/index.ts

executeHandler(request: IntentFlow.ExecuteRequest):
    Promise<IntentFlow.ExecuteResponse> {
  console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));

  const command = request.inputs[0].payload.commands[0];
  const execution = command.execution[0];
  const response = new Execute.Response.Builder()
    .setRequestId(request.requestId);

  const promises: Array<Promise<void>> = command.devices.map((device) => {
    console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));

    // Convert execution params to a string for the local device
    const params = execution.params as IWasherParams;
    const payload = this.getDataForCommand(execution.command, params);

    // Create a command to send over the local network
    const radioCommand = new DataFlow.HttpRequestData();
    radioCommand.requestId = request.requestId;
    radioCommand.deviceId = device.id;
    radioCommand.data = JSON.stringify(payload);
    radioCommand.dataType = 'application/json';
    radioCommand.port = SERVER_PORT;
    radioCommand.method = Constants.HttpOperation.POST;
    radioCommand.isSecure = false;

    console.log("Sending request to the smart home device:", payload);

    return this.app.getDeviceManager()
      .send(radioCommand)
      .then(() => {
        const state = {online: true};
        response.setSuccessState(device.id, Object.assign(state, params));
        console.log(`Command successfully sent to ${device.id}`);
      })
      .catch((e: IntentFlow.HandlerError) => {
        e.errorCode = e.errorCode || 'invalid_request';
        response.setErrorState(device.id, e.errorCode);
        console.error('An error occurred sending the command', e.errorCode);
      });
  });

  return Promise.all(promises)
    .then(() => {
      return response.build();
    })
    .catch((e) => {
      const err = new IntentFlow.HandlerError(request.requestId,
          'invalid_request', e.message);
      return Promise.reject(err);
    });
}

คอมไพล์ แอป TypeScript

ไปที่ไดเรกทอรี local/ แล้วเรียกใช้คําสั่งต่อไปนี้เพื่อดาวน์โหลดคอมไพเลอร์ TypeScript และคอมไพล์แอป

cd local
npm install
npm run build

ซึ่งจะคอมไพล์แหล่งที่มา index.ts (TypeScript) และวางเนื้อหาต่อไปนี้ไว้ในไดเรกทอรี public/local-home/

  • bundle.js - เอาต์พุต JavaScript ที่คอมไพล์แล้วซึ่งมีแอปในเครื่องและไลบรารีที่ใช้ร่วมกัน
  • index.html - หน้าการโฮสต์ในเครื่องที่ใช้แสดงแอปสำหรับการทดสอบในอุปกรณ์

ทำให้โปรเจ็กต์ทดสอบใช้งานได้

ติดตั้งใช้งานไฟล์โปรเจ็กต์ที่อัปเดตแล้วในโฮสติ้งของ Firebase เพื่อให้เข้าถึงไฟล์เหล่านั้นได้จากอุปกรณ์ Google Home

firebase deploy --only hosting

7. เริ่มเครื่องซักผ้าอัจฉริยะ

ตอนนี้ถึงเวลาทดสอบการสื่อสารระหว่างแอปการดำเนินการตามคำสั่งซื้อในพื้นที่กับเครื่องซักผ้าอัจฉริยะแล้ว โปรเจ็กต์เริ่มต้นของโค้ดแล็บมีเครื่องซักผ้าอัจฉริยะแบบเสมือนจริงที่เขียนด้วย Node.js ซึ่งจำลองเครื่องซักผ้าอัจฉริยะที่ผู้ใช้ควบคุมได้แบบภายใน

กำหนดค่าอุปกรณ์

คุณต้องกำหนดค่าอุปกรณ์เสมือนให้ใช้พารามิเตอร์ UDP เดียวกันกับที่ใช้กับการกำหนดค่าการสแกนเพื่อค้นหาอุปกรณ์ในคอนโซลของนักพัฒนาซอฟต์แวร์ นอกจากนี้ คุณจะต้องบอกอุปกรณ์เสมือนว่าให้รายงานรหัสอุปกรณ์ในเครื่องใดและรหัสโปรเจ็กต์ของการผสานรวมระบบคลาวด์ต่อคลาวด์ที่จะใช้สำหรับเหตุการณ์รายงานสถานะเมื่อสถานะอุปกรณ์เปลี่ยนแปลง

พารามิเตอร์

ค่าที่แนะนำ

deviceId

deviceid123

discoveryPortOut

3311

discoveryPacket

HelloLocalHomeSDK

projectId

รหัสโปรเจ็กต์ของการผสานรวมระบบคลาวด์กับระบบคลาวด์

เริ่มอุปกรณ์

ไปที่ไดเรกทอรี virtual-device/ แล้วเรียกใช้สคริปต์อุปกรณ์โดยส่งพารามิเตอร์การกําหนดค่าเป็นอาร์กิวเมนต์

cd virtual-device
npm install
npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

ตรวจสอบว่าสคริปต์อุปกรณ์ทํางานด้วยพารามิเตอร์ที่คาดไว้ ดังนี้

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

8. แก้ไขข้อบกพร่องของแอป TypeScript

ในส่วนต่อไปนี้ คุณจะยืนยันว่าอุปกรณ์ Google Home สามารถสแกน ระบุ และส่งคำสั่งไปยังเครื่องซักผ้าอัจฉริยะเสมือนจริงผ่านเครือข่ายภายในได้อย่างถูกต้อง คุณสามารถใช้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Google Chrome เพื่อเชื่อมต่อกับอุปกรณ์ Google Home, ดูบันทึกคอนโซล และแก้ไขข้อบกพร่องของแอป TypeScript

เชื่อมต่อเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ Chrome

หากต้องการเชื่อมต่อโปรแกรมแก้ไขข้อบกพร่องกับแอปการดำเนินการตามคำสั่งซื้อในเครื่อง ให้ทำตามขั้นตอนต่อไปนี้

  1. ตรวจสอบว่าคุณได้ลิงก์อุปกรณ์ Google Home กับผู้ใช้ที่มีสิทธิ์เข้าถึงโปรเจ็กต์ Developer Console แล้ว
  2. รีบูตอุปกรณ์ Google Home ซึ่งจะช่วยให้อุปกรณ์รับ URL ของ HTML รวมถึงการกำหนดค่าการสแกนที่คุณใส่ไว้ในคอนโซลของนักพัฒนาซอฟต์แวร์ได้
  3. เปิด Chrome บนเครื่องสำหรับพัฒนาซอฟต์แวร์
  4. เปิดแท็บ Chrome ใหม่ แล้วป้อน chrome://inspect ในช่องที่อยู่เพื่อเปิดเครื่องมือตรวจสอบ

คุณควรเห็นรายการอุปกรณ์ในหน้านี้ และ URL ของแอปควรปรากฏใต้ชื่ออุปกรณ์ Google Home

567f97789a7d8846.png

เปิดเครื่องมือตรวจสอบ

คลิกตรวจสอบใต้ URL ของแอปเพื่อเปิดเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์ของ Chrome เลือกแท็บ Console และตรวจสอบว่าคุณเห็นเนื้อหาของ Intent IDENTIFY ที่พิมพ์โดยแอป TypeScript

6b67ded470a4c8be.png

เอาต์พุตนี้หมายความว่าแอปการดำเนินการตามคำสั่งซื้อในพื้นที่ของคุณค้นพบและระบุอุปกรณ์เสมือนได้สําเร็จ

ทดสอบการดำเนินการตามคำสั่งซื้อในพื้นที่

ส่งคำสั่งไปยังอุปกรณ์โดยใช้การควบคุมด้วยการสัมผัสในแอป Google Home หรือผ่านคำสั่งเสียงไปยังอุปกรณ์ Google Home เช่น

"Ok Google เปิดเครื่องซักผ้า"

"Ok Google เริ่มเครื่องซักผ้า"

"Ok Google หยุดเครื่องซักผ้า"

ซึ่งควรทริกเกอร์ให้แพลตฟอร์มส่ง Intent EXECUTE ไปยังแอป TypeScript

bc030517dacc3ac9.png

ยืนยันว่าคุณเห็นสถานะของเครื่องซักผ้าอัจฉริยะในพื้นที่เปลี่ยนแปลงตามแต่ละคำสั่ง

...
***** The washer is RUNNING *****
...
***** The washer is STOPPED *****

9. ขอแสดงความยินดี

764dbc83b95782a.png

ยินดีด้วย คุณใช้ Local Home SDK เพื่อผสานรวมการตอบสนองในเครื่องเข้ากับการผสานรวมแบบระบบคลาวด์ต่อระบบคลาวด์

ดูข้อมูลเพิ่มเติม

คุณสามารถลองทำสิ่งต่อไปนี้

  • เปลี่ยนการกําหนดค่าการสแกนและทําให้ใช้งานได้ เช่น ลองใช้พอร์ต UDP หรือแพ็กเก็ตการค้นพบอื่น
  • แก้ไขโค้ดเบสของอุปกรณ์อัจฉริยะเสมือนให้ทำงานบนอุปกรณ์แบบฝัง เช่น Raspberry Pi และใช้ LED หรือจอแสดงผลเพื่อแสดงสถานะปัจจุบันเป็นภาพ