เปิดใช้การดําเนินการตามคําสั่งซื้อในพื้นที่สําหรับการดําเนินการในบ้านอัจฉริยะ

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

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

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

72ffb320986092c.png

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

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

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

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

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

สิ่งที่คุณต้องมี

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

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

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

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

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

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

สร้างโปรเจ็กต์ Actions

  1. ไปที่Actions on Google Developer Console
  2. คลิกโปรเจ็กต์ใหม่ จากนั้นป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์

AWXw5E1m9zVgvVeyeL3uxwCX6DtWOCK6LRSLmOATFzjMbmE5cSWBdSVhJZDFpEFH2azZTK2eMs6OYYdMJYiGb5bKqFEzxaLyRUYuckwC

เลือกแอปสมาร์ทโฮม

ในหน้าจอภาพรวมในคอนโซล Actions ให้เลือกสมาร์ทโฮม

36RsBUWBgbgsa5xZ7MJVMm1sIg07nXbfjv0mWCxXViaC5SlbL2gMigw9hgXsZQhNMHLLFOfiKdZsSTNXONFB1i47gksw3SBNpkVYl492Weryolgx1GDI

เลือกการ์ดประสบการณ์บ้านอัจฉริยะ แล้วระบบจะนำคุณไปยังคอนโซลโปรเจ็กต์

pzgHPsmc2LvLoeUvJfkjKQqD_BvO4v8JOPlcrxsmyptFkkjL4PP6LqrM9r5tNvEIfT9HmK-UKw3GWFPXTjqo4nUrhD2o5shUKHBE31OT8iIA69JZCev7_0_nh-lnL2oJHoxGfqqZ4w

ติดตั้ง Firebase CLI

อินเทอร์เฟซบรรทัดคำสั่งของ Firebase (CLI) จะช่วยให้คุณแสดงเว็บแอปภายในเครื่องและทำให้เว็บแอปใช้งานได้กับโฮสติ้งของ 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. เรียกใช้แอปเริ่มต้น

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

รับซอร์สโค้ด

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

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

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

เกี่ยวกับโครงการ

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

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

Fulfillment ระบบคลาวด์ที่ระบุมีฟังก์ชันต่อไปนี้ใน index.js

  • fakeauth - ปลายทางการให้สิทธิ์สำหรับการลิงก์บัญชี
  • faketoken - ปลายทางโทเค็นสำหรับการลิงก์บัญชี
  • smarthome - ปลายทางสำหรับ Intent ของ Smart Home
  • 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

หากคุณกำลังเริ่มต้นโปรเจ็กต์อีกครั้ง ให้เลือกไม่ เมื่อระบบถามว่าคุณต้องการเริ่มต้นหรือเขียนทับฟังก์ชัน/.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 หลายรายการ

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

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

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

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

กำหนดค่าโปรเจ็กต์คอนโซล Actions

ใต้ภาพรวม > สร้างการดำเนินการ เลือกเพิ่มการดำเนินการ ป้อน URL ของ Cloud Function ที่ดำเนินการตามคำสั่งซื้อสำหรับ Intent ของสมาร์ทโฮม แล้วคลิกบันทึก

https://us-central1-<project-id>.cloudfunctions.net/smarthome

Uso-o00XQXBHvOR9vQq9tmpYDYQJKsFEstsgRFnxPAJf7zJ2FxwhISiodo3dB1Tz49Okd6ivi66fjpo7rarS_GZelglGWCT1r9FzDGUl1r67ddIcIbQrxqN8jG9F9GAKOpk0Ckc-eA

ในหน้า Develop > แท็บการเรียกใช้ ให้เพิ่มชื่อที่แสดงสำหรับการดำเนินการของคุณ แล้วคลิกบันทึก ชื่อนี้จะปรากฏในแอป Google Home

gvC-TvmKDy-D-xjwkeCjNt__9ErA7DL8hZWa1oH1yPJ9SpYOepDYjxx6WnJ56IG-t37fJ65kmHISQdh72Ot2G-0tu6Flxf4gom5kvx_3hlvFeMqYuFgXr_85pfWWn7VLFHtS55p1zw

s4yc1kOW4XtKUQN1EYegiDLU5oTqmxQ2PNbeaujm26OQmYKKpjug7j5FYmutLSAZ1zBd-ZkcZlL7zyTZqw4bge3_oOeWvJTsqJ-A08vfZwImYQrKiquLskLuTpmMqXEZD1xchhCWGQ

ในการเปิดใช้การลิงก์บัญชี ให้เลือกพัฒนา > ตัวเลือกการลิงก์บัญชีในแถบการนำทางด้านซ้าย ใช้การตั้งค่าการลิงก์บัญชีต่อไปนี้

Client-ID

ABC123

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

DEF456

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

https://us-central1-<project-id>.cloudfunctions.net/fakeauth

URL ของโทเค็น

https://us-central1-<project-id>.cloudfunctions.net/faketoken

rRyZTiBSTuPk3YtJtXjDK1pPftUxsaEhs9jzpvFtbHTD6bEwYxM8jV4MWxiljKA1bKVZrIRoO9O3jtBefLKf_OyMpukPjwIj8zGvyU3UwASzMrnRskl-hVAfAmQVi4sC_zAwgYwRXw

คลิกบันทึกเพื่อบันทึกการกำหนดค่าการลิงก์บัญชี จากนั้นคลิกทดสอบเพื่อเปิดใช้การทดสอบในโปรเจ็กต์

OgUvpQfXioygkRwPcaJpzjyNQDZy6enidUC8YMPaCOrZi0YeWCFsCJV9Gqg-_UfsqTnn4KEg--uE3Ymr0QuamDonF4RyYHtRKcULXABDuaEnj2hq8i20LYj1SrGP_1lQ_UsUB90pGw

ระบบจะเปลี่ยนเส้นทางคุณไปยังเครื่องมือจำลอง ตรวจสอบว่าได้เปิดใช้การทดสอบสำหรับโปรเจ็กต์แล้วโดยวางเมาส์เหนือไอคอน "การทดสอบในอุปกรณ์" (soCeBB1CkSIEqsBmDc8Cth6EjgcXUnrOHeOpLNlvMiiXM73Rmh8iBK1ZFLFd47kycYqIMq3Fm49ryAGUt79BXVPDyEB1IU3W0fgiL49iqTAVrpRszL10mmxzq_AQTJZVrXor-vne2w)

2zbfeYpG-wEd2SFP07Wc4mJzHakLX7YvrNw3IV0_0Kd-TonfsKIvvjKWlwvrmTm5jLj3XPWqCtcDd5J2z6gwn9fnchpYVraw1j_mE4M0LVppAl5WY5cK7g0uZyhZ3VFFS25yPmyksg

คุณต้องลิงก์โปรเจ็กต์กับบัญชี 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 เว็บฟรอนท์เอนด์ของ Fulfillment ระบบคลาวด์

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

4. อัปเดต Fulfillment ระบบคลาวด์

หากต้องการรองรับการดําเนินการตามคําสั่งซื้อในพื้นที่ คุณต้องเพิ่มช่องต่ออุปกรณ์ใหม่ที่ชื่อ 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 จะเข้าถึงและดาวน์โหลดได้

ในคอนโซลการดำเนินการ ให้เลือกพัฒนา > การดำเนินการ แล้วหาส่วนกำหนดค่า SDK ของบ้านในเครื่อง ป้อน URL ต่อไปนี้ลงในช่อง URL ทดสอบ แทรกรหัสโปรเจ็กต์ แล้วคลิกบันทึก

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

7d59b31f8d2a988.png

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

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

ฟิลด์

คำอธิบาย

ค่าที่แนะนำ

ที่อยู่ในการออกอากาศ

ที่อยู่ในการออกอากาศ UDP

255.255.255.255

พอร์ตประกาศ

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

3311

พอร์ตสำหรับฟัง

พอร์ตที่ Google Home คอยฟังคำตอบ

3312

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

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

48656c6c6f4c6f63616c486f6d6553444b

4777bf63c53b6858.png

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

6. ใช้การจำหน่ายในพื้นที่

คุณจะพัฒนาแอปการดำเนินการตามคำสั่งซื้อในพื้นที่ใน TypeScript โดยใช้แพ็กเกจการพิมพ์ของ 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));

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

เพิ่มเครื่องจัดการ IDENTIFY

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

ในขณะเดียวกัน แพลตฟอร์มจะเรียกใช้ 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 ที่ส่งไปยัง Cloud Fulfillment ของคุณ ดังนั้นตรรกะสำหรับการประมวลผล Intent ในเครื่องจะคล้ายกับวิธีที่คุณจัดการกับ Intent ในระบบคลาวด์

แอปสามารถใช้ซ็อกเก็ต TCP/UDP หรือคำขอ HTTP(S) เพื่อสื่อสารกับอุปกรณ์ในเครือข่ายเดียวกัน ใน Codelab นี้ 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 ที่คอมไพล์แล้ว ซึ่งมีแอปภายในเครื่องและทรัพยากร Dependency
  • index.html - หน้าโฮสติ้งในเครื่องที่ใช้เพื่อแสดงแอปสำหรับการทดสอบในอุปกรณ์

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

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

firebase deploy --only hosting

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

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

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

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

พารามิเตอร์

ค่าที่แนะนำ

รหัสอุปกรณ์

deviceid123

discoveryPortOut

3311

discoveryPacket

HelloLocalHomeSDK

รหัสโปรเจ็กต์

รหัสโปรเจ็กต์ Actions

เปิดเครื่อง

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

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

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

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

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

567f97789a7d8846.png

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

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

6b67ded470a4c8be.png

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

ทดสอบ Fulfillment ในพื้นที่

ส่งคำสั่งไปยังอุปกรณ์โดยใช้การควบคุมด้วยการสัมผัสในแอป 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 หรือจอแสดงผลเพื่อแสดงภาพสถานะปัจจุบันของ