1. ก่อนเริ่มต้น
การผสานรวมระบบคลาวด์กับระบบคลาวด์ใช้ประเภทอุปกรณ์เพื่อให้ Google Assistant ทราบว่าควรใช้ไวยากรณ์ใดกับอุปกรณ์ ลักษณะของอุปกรณ์จะกำหนดความสามารถของประเภทอุปกรณ์ อุปกรณ์จะรับค่าสถานะของลักษณะของอุปกรณ์แต่ละรายการที่เพิ่มลงในการผสานรวม
คุณสามารถเชื่อมต่อลักษณะที่รองรับกับประเภทอุปกรณ์ที่เลือกเพื่อปรับแต่งฟังก์ชันการทำงานของอุปกรณ์ของผู้ใช้ หากต้องการใช้ลักษณะที่กำหนดเองในการดำเนินการซึ่งปัจจุบันไม่มีในสคีมาอุปกรณ์ คุณสามารถใช้ลักษณะโหมดและปุ่มเปิด/ปิดเพื่อควบคุมการตั้งค่าที่เฉพาะเจาะจงด้วยชื่อที่กำหนดเอง
นอกจากความสามารถในการควบคุมพื้นฐานที่ประเภทและลักษณะการทํางานมอบให้แล้ว Smart Home API ยังมีฟีเจอร์เพิ่มเติมเพื่อปรับปรุงประสบการณ์ของผู้ใช้ การตอบกลับข้อผิดพลาดจะให้ความคิดเห็นโดยละเอียดแก่ผู้ใช้เมื่อความตั้งใจไม่สำเร็จ การยืนยันผู้ใช้รองจะขยายคำตอบเหล่านั้นและเพิ่มความปลอดภัยให้กับลักษณะของอุปกรณ์ที่คุณเลือก การส่งคำตอบข้อผิดพลาดที่เฉพาะเจาะจงไปยังบล็อกการตรวจสอบที่ออกโดย Assistant อาจทำให้การผสานรวมระบบคลาวด์ต่อคลาวด์ของคุณต้องได้รับสิทธิ์เพิ่มเติมจึงจะดำเนินการตามคำสั่งได้
ข้อกำหนดเบื้องต้น
- คำแนะนำสำหรับนักพัฒนาซอฟต์แวร์เกี่ยวกับการผสานรวมระบบคลาวด์กับระบบคลาวด์
- Codelab เครื่องซักผ้าสมาร์ทโฮม
- คำแนะนำสำหรับนักพัฒนาแอปเกี่ยวกับประเภทและลักษณะของอุปกรณ์
สิ่งที่คุณจะสร้าง
ในโค้ดแล็บนี้ คุณจะใช้การผสานรวมสมาร์ทโฮมที่สร้างไว้ล่วงหน้ากับ Firebase จากนั้นดูวิธีเพิ่มลักษณะที่ไม่เป็นไปตามมาตรฐานลงในเครื่องซักผ้าสมาร์ทโฮมสำหรับขนาดการซักและโหมดเทอร์โบ นอกจากนี้ คุณยังใช้การรายงานข้อผิดพลาดและการยกเว้น รวมถึงเรียนรู้วิธีบังคับใช้การยอมรับด้วยวาจาเพื่อเปิดเครื่องซักผ้าโดยใช้วิธีการยืนยันผู้ใช้สำรอง
สิ่งที่คุณจะได้เรียนรู้
- วิธีเพิ่มลักษณะการทำงาน "โหมด" และ "เปิด/ปิด" ในการผสานรวม
- วิธีรายงานข้อผิดพลาดและข้อยกเว้น
- วิธีใช้การยืนยันผู้ใช้รอง
สิ่งที่คุณต้องมี
- เว็บเบราว์เซอร์ เช่น Google Chrome
- อุปกรณ์ iOS หรือ Android ที่มีแอป Google Home ติดตั้งไว้
- Node.js เวอร์ชัน 10.16 ขึ้นไป
- บัญชี Google
- บัญชีสำหรับการเรียกเก็บเงินของ Google Cloud
2. เริ่มต้นใช้งาน
เปิดใช้ส่วนควบคุมกิจกรรม
หากต้องการใช้ Google Assistant คุณต้องแชร์ข้อมูลกิจกรรมบางอย่างกับ Google Google Assistant ต้องใช้ข้อมูลนี้จึงจะทำงานได้อย่างถูกต้อง แต่ข้อกำหนดในการแชร์ข้อมูลไม่ได้เจาะจงสำหรับ SDK เท่านั้น หากต้องการแชร์ข้อมูลนี้ ให้สร้างบัญชี Google หากยังไม่มี คุณใช้บัญชี Google บัญชีใดก็ได้ ไม่จำเป็นต้องเป็นบัญชีนักพัฒนาแอป
เปิดหน้าส่วนควบคุมกิจกรรมของบัญชี Google ที่ต้องการใช้กับ Assistant
ตรวจสอบว่าได้เปิดใช้สวิตช์เปิด/ปิดต่อไปนี้
- กิจกรรมบนเว็บและแอป - นอกจากนี้ อย่าลืมเลือกช่องทําเครื่องหมายรวมประวัติการเข้าชมใน Chrome และกิจกรรมจากเว็บไซต์ แอป และอุปกรณ์ที่ใช้บริการต่างๆ ของ Google
- ข้อมูลอุปกรณ์
- กิจกรรมเสียงพูดและเสียง
สร้างโปรเจ็กต์การผสานรวมระบบคลาวด์กับระบบคลาวด์
- ไปที่คอนโซลนักพัฒนาแอป
- คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์
เลือกการผสานรวมระบบคลาวด์กับระบบคลาวด์
ในหน้าแรกของโปรเจ็กต์ในคอนโซลของนักพัฒนาซอฟต์แวร์ ให้เลือกเพิ่มการผสานรวมระบบคลาวด์กับระบบคลาวด์ในส่วนระบบคลาวด์กับระบบคลาวด์
ติดตั้ง Firebase CLI
อินเทอร์เฟซบรรทัดคำสั่ง (CLI) ของ Firebase จะช่วยให้คุณแสดงเว็บแอปในเครื่องและทำให้เว็บแอปใช้งานได้ในโฮสติ้งของ Firebase
หากต้องการติดตั้ง CLI ให้เรียกใช้คำสั่ง npm ต่อไปนี้จากเทอร์มินัล
npm install -g firebase-tools
หากต้องการยืนยันว่าติดตั้ง CLI อย่างถูกต้องแล้ว ให้เรียกใช้คำสั่งต่อไปนี้
firebase --version
ให้สิทธิ์ Firebase CLI ด้วยบัญชี Google โดยเรียกใช้คำสั่งต่อไปนี้
firebase login
สร้างโปรเจ็กต์ Firebase
- ไปที่ Firebase
- คลิกสร้างโปรเจ็กต์ แล้วป้อนชื่อโปรเจ็กต์
- เลือกช่องทำเครื่องหมายข้อตกลง แล้วคลิกต่อไป หากไม่มีช่องทำเครื่องหมายข้อตกลง คุณข้ามขั้นตอนนี้ได้
- เมื่อสร้างโปรเจ็กต์ Firebase แล้ว ให้ค้นหารหัสโปรเจ็กต์ ไปที่ภาพรวมโปรเจ็กต์ แล้วคลิกไอคอนการตั้งค่า > การตั้งค่าโปรเจ็กต์
- โปรเจ็กต์จะแสดงอยู่ในแท็บทั่วไป
เปิดใช้ HomeGraph API
HomeGraph API ช่วยให้สามารถจัดเก็บและค้นหาอุปกรณ์และสถานะของอุปกรณ์ภายใน Home Graph ของผู้ใช้ หากต้องการใช้ API นี้ คุณต้องเปิดคอนโซล Google Cloud ก่อนแล้วเปิดใช้ HomeGraph API
ในคอนโซล Google Cloud ให้เลือกโปรเจ็กต์ที่ตรงกับการดำเนินการของคุณ <firebase-project-id>.
จากนั้นคลิกเปิดใช้ในหน้าจอคลัง API สำหรับ HomeGraph API
3. เรียกใช้แอปเริ่มต้น
เมื่อตั้งค่าสภาพแวดล้อมการพัฒนาซอฟต์แวร์แล้ว คุณสามารถทําให้การเริ่มใช้งานโปรเจ็กต์เพื่อยืนยันว่าทุกอย่างได้รับการกําหนดค่าอย่างถูกต้อง
ดูซอร์สโค้ด
คลิกลิงก์ต่อไปนี้เพื่อดาวน์โหลดตัวอย่างสําหรับโค้ดแล็บนี้ในเครื่องพัฒนาซอฟต์แวร์
...หรือจะโคลนที่เก็บ GitHub จากบรรทัดคำสั่งก็ได้ โดยทำดังนี้
git clone https://github.com/google-home/smarthome-traits.git
แตกไฟล์ ZIP ที่ดาวน์โหลด
เกี่ยวกับโปรเจ็กต์
โปรเจ็กต์เริ่มต้นมีไดเรกทอรีย่อยต่อไปนี้
public:
UI ด้านหน้าสำหรับควบคุมและตรวจสอบสถานะของเครื่องซักผ้าอัจฉริยะได้อย่างง่ายดายfunctions:
บริการระบบคลาวด์ที่ติดตั้งใช้งานอย่างเต็มรูปแบบซึ่งจัดการเครื่องซักผ้าอัจฉริยะด้วย Cloud Functions for Firebase และ Firebase Realtime Database
การดำเนินการตามคำสั่งซื้อจากระบบคลาวด์ที่ระบุมีฟังก์ชันต่อไปนี้ใน index.js
fakeauth
: ปลายทางการให้สิทธิ์สำหรับการลิงก์บัญชีfaketoken
: ปลายทางโทเค็นสำหรับการลิงก์บัญชีsmarthome
: ปลายทางการดำเนินการตามความตั้งใจสมาร์ทโฮมreportstate
: เรียกใช้ Home Graph API เมื่อสถานะอุปกรณ์มีการเปลี่ยนแปลงrequestsync
: เปิดใช้การอัปเดตอุปกรณ์ของผู้ใช้โดยไม่ต้องลิงก์บัญชีอีกครั้ง
เชื่อมต่อกับ Firebase
ไปที่ไดเรกทอรี washer-start
แล้วตั้งค่า Firebase CLI กับโปรเจ็กต์การผสานรวมโดยทำดังนี้
cd washer-start firebase use <firebase-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 วิธีดังนี้
- ใช้ GUI ไปที่โฟลเดอร์
../functions
ใต้โปรเจ็กต์ เลือกไฟล์.eslintrc.js
ที่ซ่อนอยู่ แล้วลบออก อย่าสับสนกับ.eslintrc.json
ที่มีชื่อคล้ายกัน - การใช้บรรทัดคำสั่ง
cd functions rm .eslintrc.js
ทำให้ใช้งานได้กับ Firebase
เมื่อติดตั้งไลบรารีที่ต้องพึ่งพาและกำหนดค่าโปรเจ็กต์แล้ว คุณก็พร้อมเรียกใช้แอปเป็นครั้งแรก
firebase deploy
คุณควรเห็นเอาต์พุตคอนโซลดังต่อไปนี้
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<firebase-project-id>/overview Hosting URL: https://<firebase-project-id>.web.app
คำสั่งนี้จะทําให้เว็บแอปพร้อมใช้งานพร้อมกับ Cloud Functions for Firebase หลายรายการ
เปิด Hosting URL ในเบราว์เซอร์ (https://<firebase-project-id>.web.app
) เพื่อดูเว็บแอป คุณจะเห็นอินเทอร์เฟซต่อไปนี้
เว็บ UI นี้แสดงแพลตฟอร์มของบุคคลที่สามเพื่อดูหรือแก้ไขสถานะของอุปกรณ์ หากต้องการเริ่มป้อนข้อมูลอุปกรณ์ลงในฐานข้อมูล ให้คลิกอัปเดต คุณจะไม่เห็นว่าหน้าเว็บมีการเปลี่ยนแปลงใดๆ แต่ระบบจะจัดเก็บสถานะปัจจุบันของเครื่องซักผ้าไว้ในฐานข้อมูล
ตอนนี้ถึงเวลาเชื่อมต่อบริการระบบคลาวด์ที่คุณติดตั้งใช้งานกับ Google Assistant โดยใช้ Developer Console
กำหนดค่าโปรเจ็กต์ใน Developer Console
ในแท็บพัฒนา ให้เพิ่มชื่อที่แสดงสำหรับการโต้ตอบ ชื่อนี้จะปรากฏในแอป Google Home
ในส่วนการสร้างแบรนด์แอป ให้อัปโหลดไฟล์ png
สำหรับไอคอนแอปขนาด 144 x 144 พิกเซล และตั้งชื่อว่า
หากต้องการเปิดใช้การลิงก์บัญชี ให้ใช้การตั้งค่าการลิงก์บัญชีต่อไปนี้
รหัสลูกค้า |
|
รหัสลับไคลเอ็นต์ |
|
URL สำหรับการอนุญาต |
|
URL โทเค็น |
|
ในส่วน Cloud fulfillment URL ให้ป้อน URL ของ Cloud Functions ที่ดำเนินการตามคำสั่งสำหรับสมาร์ทโฮม
https://us-central1-
คลิกบันทึกเพื่อบันทึกการกําหนดค่าโปรเจ็กต์ แล้วคลิกถัดไป: ทดสอบเพื่อเปิดใช้การทดสอบในโปรเจ็กต์
ตอนนี้คุณจะเริ่มใช้ Webhooks ที่จําเป็นต่อการเชื่อมต่อสถานะของอุปกรณ์กับ Assistant ได้แล้ว
ลิงก์กับ Google Assistant
หากต้องการทดสอบการผสานรวมระบบคลาวด์กับระบบคลาวด์ คุณต้องลิงก์โปรเจ็กต์กับบัญชี Google ซึ่งจะช่วยให้ทดสอบผ่านแพลตฟอร์มต่างๆ ของ Google Assistant และแอป Google Home ที่ลงชื่อเข้าใช้บัญชีเดียวกันได้
- เปิดการตั้งค่า Google Assistant ในโทรศัพท์ โปรดทราบว่าคุณควรลงชื่อเข้าใช้ด้วยบัญชีเดียวกับในคอนโซล
- ไปที่ Google Assistant > การตั้งค่า > การควบคุมอุปกรณ์สมาร์ทโฮม (ในส่วน Assistant)
- คลิกไอคอนค้นหาที่ด้านขวาบน
- ค้นหาแอปทดสอบโดยใช้คำนำหน้า [test] เพื่อค้นหาแอปทดสอบที่ต้องการ
- เลือกรายการนั้น จากนั้น Google Assistant จะตรวจสอบสิทธิ์กับบริการของคุณและส่งคําขอ
SYNC
โดยขอให้บริการของคุณระบุรายการอุปกรณ์สําหรับผู้ใช้
เปิดแอป Google Home และตรวจสอบว่าคุณเห็นอุปกรณ์เครื่องซักผ้า
ยืนยันว่าคุณสามารถควบคุมเครื่องซักผ้าโดยใช้คำสั่งเสียงในแอป Google Home นอกจากนี้ คุณควรเห็นสถานะอุปกรณ์เปลี่ยนแปลงใน UI เว็บส่วนหน้าของการดำเนินการตามคำสั่งซื้อจากระบบคลาวด์ด้วย
เมื่อติดตั้งเครื่องซักผ้าพื้นฐานแล้ว คุณจะปรับแต่งโหมดที่ใช้ได้บนอุปกรณ์ได้
4. เพิ่มโหมด
ลักษณะ action.devices.traits.Modes
ช่วยให้อุปกรณ์มีการตั้งค่าสำหรับโหมดหนึ่งๆ ได้ไม่จำกัดจำนวน แต่ตั้งค่าได้ครั้งละ 1 รายการเท่านั้น คุณจะเพิ่มโหมดลงในเครื่องซักผ้าเพื่อกำหนดขนาดของผ้าที่จะซักได้ ซึ่งได้แก่ เล็ก กลาง หรือใหญ่
อัปเดตการตอบสนองการซิงค์
คุณต้องเพิ่มข้อมูลเกี่ยวกับลักษณะใหม่ลงในSYNC
คําตอบในfunctions/index.js
ข้อมูลนี้จะปรากฏในอาร์เรย์ traits
และออบเจ็กต์ attributes
ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
index.js
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: USER_ID,
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
// Add Modes trait
'action.devices.traits.Modes',
],
name: { ... },
deviceInfo: { ... },
attributes: {
pausable: true,
//Add availableModes
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en',
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en',
}]
}, {
setting_name: 'medium',
setting_values: [{
setting_synonym: ['medium'],
lang: 'en',
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en',
}]
}],
ordered: true,
}],
},
}],
},
};
});
เพิ่มคำสั่ง EXECUTE Intent ใหม่
ใน Intent EXECUTE
ให้เพิ่มคําสั่ง action.devices.commands.SetModes
ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
index.js
const updateDevice = async (execution,deviceId) => {
const {params,command} = execution;
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
case 'action.devices.commands.StartStop':
state = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
Break;
// Add SetModes command
case 'action.devices.commands.SetModes':
state = {load: params.updateModeSettings.load};
ref = firebaseRef.child(deviceId).child('Modes');
break;
}
อัปเดตคำตอบ QUERY
จากนั้นอัปเดตคําตอบ QUERY
เพื่อรายงานสถานะปัจจุบันของเครื่องซัก
เพิ่มการเปลี่ยนแปลงที่อัปเดตแล้วลงในฟังก์ชัน queryFirebase
และ queryDevice
เพื่อรับสถานะที่จัดเก็บไว้ใน Realtime Database
index.js
const queryFirebase = async (deviceId) => {
const snapshot = await firebaseRef.child(deviceId).once('value');
const snapshotVal = snapshot.val();
return {
on: snapshotVal.OnOff.on,
isPaused: snapshotVal.StartStop.isPaused,
isRunning: snapshotVal.StartStop.isRunning,
// Add Modes snapshot
load: snapshotVal.Modes.load,
};
}
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{ ... }],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
// Add currentModeSettings
currentModeSettings: {
load: data.load,
},
};
};
อัปเดตสถานะรายงาน
สุดท้าย ให้อัปเดตฟังก์ชัน reportstate
เพื่อรายงานการตั้งค่าน้ำหนักปัจจุบันของเครื่องซักผ้าไปยังกราฟในบ้าน
index.js
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of your washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
// Add currentModeSettings
currentModeSettings: {
load: snapshot.Modes.load,
},
},
},
},
},
};
ทำให้ใช้งานได้กับ Firebase
เรียกใช้คําสั่งต่อไปนี้เพื่อทําให้การผสานรวมที่อัปเดตแล้วใช้งานได้
firebase deploy --only functions
หลังจากการทําให้ใช้งานได้เสร็จสมบูรณ์แล้ว ให้ไปที่ UI ของเว็บ แล้วคลิกปุ่มรีเฟรช ในแถบเครื่องมือ ซึ่งจะทริกเกอร์การซิงค์คำขอเพื่อให้ Assistant ได้รับข้อมูลคำตอบ
SYNC
ที่อัปเดตแล้ว
ตอนนี้คุณออกคำสั่งเพื่อตั้งค่าโหมดของเครื่องซักผ้าได้แล้ว เช่น
"Ok Google ตั้งค่าน้ำหนักซักผ้าเป็น "มาก""
นอกจากนี้ คุณยังถามคำถามเกี่ยวกับเครื่องซักผ้าได้ เช่น
"Ok Google ปริมาณผ้าในเครื่องซักผ้าคือเท่าไหร่"
5. เพิ่มปุ่มเปิด/ปิด
แอตทริบิวต์ action.devices.traits.Toggles
แสดงถึงแง่มุมที่มีชื่อของอุปกรณ์ซึ่งมีสถานะเป็นจริงหรือเท็จ เช่น เครื่องซักผ้าอยู่ในโหมดเทอร์โบหรือไม่
อัปเดตการตอบสนองการซิงค์
ในการตอบกลับSYNC
คุณต้องเพิ่มข้อมูลเกี่ยวกับลักษณะของอุปกรณ์ใหม่ ซึ่งจะปรากฏในอาร์เรย์ traits
และออบเจ็กต์ attributes
ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
index.js
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: USER_ID,
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
'action.devices.traits.Modes',
// Add Toggles trait
'action.devices.traits.Toggles',
],
name: { ... },
deviceInfo: { ... },
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{ ... }],
ordered: true,
}],
//Add availableToggles
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en',
}],
}],
},
}],
},
};
});
เพิ่มคําสั่ง EXECUTE Intent ใหม่
ใน Intent EXECUTE
ให้เพิ่มคําสั่ง action.devices.commands.SetToggles
ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
index.js
const updateDevice = async (execution,deviceId) => {
const {params,command} = execution;
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
case 'action.devices.commands.StartStop':
state = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.SetModes':
state = {load: params.updateModeSettings.load};
ref = firebaseRef.child(deviceId).child('Modes');
break;
// Add SetToggles command
case 'action.devices.commands.SetToggles':
state = {Turbo: params.updateToggleSettings.Turbo};
ref = firebaseRef.child(deviceId).child('Toggles');
break;
}
อัปเดตคำตอบ QUERY
สุดท้าย คุณต้องอัปเดตคําตอบ QUERY
เพื่อรายงานโหมดเทอร์โบของเครื่องซัก เพิ่มการเปลี่ยนแปลงที่อัปเดตแล้วลงในฟังก์ชัน queryFirebase
และ queryDevice
เพื่อรับสถานะเปิด/ปิดตามที่จัดเก็บไว้ใน Realtime Database
index.js
const queryFirebase = async (deviceId) => {
const snapshot = await firebaseRef.child(deviceId).once('value');
const snapshotVal = snapshot.val();
return {
on: snapshotVal.OnOff.on,
isPaused: snapshotVal.StartStop.isPaused,
isRunning: snapshotVal.StartStop.isRunning,
load: snapshotVal.Modes.load,
// Add Toggles snapshot
Turbo: snapshotVal.Toggles.Turbo,
};
}
const queryDevice = async (deviceId) => {
const data = queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{ ... }],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
currentModeSettings: {
load: data.load,
},
// Add currentToggleSettings
currentToggleSettings: {
Turbo: data.Turbo,
},
};
};
อัปเดตสถานะรายงาน
สุดท้าย ให้อัปเดตฟังก์ชัน reportstate
เพื่อรายงานไปยังกราฟในบ้านว่าตั้งค่าเครื่องซักผ้าเป็นโหมดเทอร์โบหรือไม่
index.js
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of your washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
currentModeSettings: {
load: snapshot.Modes.load,
},
// Add currentToggleSettings
currentToggleSettings: {
Turbo: snapshot.Toggles.Turbo,
},
},
},
},
},
};
ทำให้ใช้งานได้กับ Firebase
เรียกใช้คําสั่งต่อไปนี้เพื่อทําให้ฟังก์ชันที่อัปเดตแล้วใช้งานได้
firebase deploy --only functions
คลิกปุ่มรีเฟรช ใน UI ของเว็บเพื่อเรียกให้ซิงค์คําขอหลังจากการทําให้ใช้งานได้เสร็จสมบูรณ์
ตอนนี้คุณออกคำสั่งให้ตั้งค่าเครื่องซักผ้าเป็นโหมดเทอร์โบได้โดยพูดว่า
"Ok Google เปิดโหมดเทอร์โบสำหรับเครื่องซักผ้า"
นอกจากนี้ คุณยังตรวจสอบได้ว่าเครื่องซักผ้าอยู่ในโหมดเทอร์โบอยู่แล้วหรือไม่โดยทำดังนี้
"Ok Google เครื่องซักผ้าอยู่ในโหมดเทอร์โบไหม"
6. การรายงานข้อผิดพลาดและข้อยกเว้น
การจัดการข้อผิดพลาดในการผสานรวมระบบคลาวด์กับระบบคลาวด์ช่วยให้คุณรายงานให้ผู้ใช้ทราบได้เมื่อปัญหาทําให้การตอบกลับ EXECUTE
และ QUERY
ไม่สําเร็จ การแจ้งเตือนจะสร้างประสบการณ์การใช้งานในเชิงบวกมากขึ้นให้แก่ผู้ใช้เมื่อโต้ตอบกับอุปกรณ์อัจฉริยะและการผสานรวม
เมื่อคำขอ EXECUTE
หรือ QUERY
ไม่สำเร็จ การผสานรวมควรแสดงรหัสข้อผิดพลาด เช่น หากต้องการแสดงข้อผิดพลาดเมื่อผู้ใช้พยายามเปิดเครื่องซักผ้าโดยที่ฝาเปิดอยู่ การตอบกลับ EXECUTE
จะมีลักษณะดังนี้
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [
{
"ids": [
"456"
],
"status": "ERROR",
"errorCode": "deviceLidOpen"
}
]
}
}
ตอนนี้เมื่อผู้ใช้ขอให้เริ่มเครื่องซักผ้า Assistant จะตอบกลับด้วยข้อความว่า
"ฝาเครื่องซักผ้าเปิดอยู่ โปรดปิดแล้วลองอีกครั้ง"
ข้อยกเว้นคล้ายกับข้อผิดพลาด แต่ระบุเมื่อการแจ้งเตือนเชื่อมโยงกับคําสั่ง ซึ่งอาจบล็อกการดําเนินการให้สําเร็จหรือไม่ก็ได้ ข้อยกเว้นสามารถให้ข้อมูลที่เกี่ยวข้องได้โดยใช้ลักษณะ StatusReport
เช่น ระดับแบตเตอรี่หรือการเปลี่ยนแปลงสถานะล่าสุด ระบบจะแสดงรหัสข้อยกเว้นที่ไม่บล็อกพร้อมกับสถานะ SUCCESS
ส่วนรหัสข้อยกเว้นที่บล็อกจะแสดงพร้อมกับสถานะ EXCEPTIONS
ตัวอย่างคำตอบที่มีข้อยกเว้นอยู่ในข้อมูลโค้ดต่อไปนี้
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [{
"ids": ["123"],
"status": "SUCCESS",
"states": {
"online": true,
"isPaused": false,
"isRunning": false,
"exceptionCode": "runCycleFinished"
}
}]
}
}
Assistant จะตอบกลับโดยพูดว่า
"เครื่องซักผ้าทำงานเสร็จแล้ว"
หากต้องการเพิ่มการรายงานข้อผิดพลาดสำหรับเครื่องซักผ้า ให้เปิด functions/index.js
แล้วเพิ่มคําจํากัดความของคลาสข้อผิดพลาดตามที่แสดงในข้อมูลโค้ดต่อไปนี้
index.js
app.onQuery(async (body) => {...});
// Add SmartHome error handling
class SmartHomeError extends Error {
constructor(errorCode, message) {
super(message);
this.name = this.constructor.name;
this.errorCode = errorCode;
}
}
อัปเดตการตอบกลับการดำเนินการเพื่อแสดงรหัสข้อผิดพลาดและสถานะข้อผิดพลาด
index.js
const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
for (const device of command.devices) {
for (const execution of command.execution) {
executePromises.push(
updateDevice(execution, device.id)
.then((data) => {
...
})
//Add error response handling
.catch((error) => {
functions.logger.error('EXECUTE', device.id, error);
result.ids.push(device.id);
if (error instanceof SmartHomeError) {
result.status = 'ERROR';
result.errorCode = error.errorCode;
}
})
);
}
}
}
ตอนนี้ Assistant สามารถแจ้งผู้ใช้เกี่ยวกับรหัสข้อผิดพลาดที่คุณรายงานได้แล้ว คุณจะเห็นตัวอย่างที่เฉพาะเจาะจงในส่วนถัดไป
7. เพิ่มการยืนยันผู้ใช้รอง
คุณควรใช้การยืนยันผู้ใช้รองในการผสานรวมหากอุปกรณ์มีโหมดที่ต้องรักษาความปลอดภัยหรือควรจำกัดไว้สำหรับผู้ใช้ที่ได้รับอนุญาตบางกลุ่มเท่านั้น เช่น การอัปเดตซอฟต์แวร์หรือการปลดล็อก
คุณสามารถใช้การยืนยันผู้ใช้รองในอุปกรณ์ทุกประเภทและลักษณะทั้งหมด โดยปรับแต่งได้ว่าจะให้แสดงภารกิจด้านความปลอดภัยทุกครั้งหรือต้องมีคุณสมบัติตรงตามเกณฑ์ที่เฉพาะเจาะจง
คำถามยืนยันที่รองรับมี 3 ประเภท ได้แก่
No
challenge
- คำขอและการตอบกลับที่ไม่ได้ใช้คำขอตรวจสอบสิทธิ์ (นี่คือลักษณะการทำงานเริ่มต้น)ackNeeded
- วิธีการยืนยันผู้ใช้สำรองที่ต้องมีการรับทราบอย่างชัดแจ้ง (ใช่หรือไม่)pinNeeded
- การยืนยันผู้ใช้รองที่ต้องใช้หมายเลขประจำตัวส่วนบุคคล (PIN)
สําหรับโค้ดแล็บนี้ ให้เพิ่มภารกิจ ackNeeded
ลงในคําสั่งสําหรับการเปิดเครื่องซักผ้าและฟังก์ชันการคืนค่าข้อผิดพลาดหากภารกิจยืนยันรองไม่สําเร็จ
เปิด functions/index.js
แล้วเพิ่มคําจํากัดความของคลาสข้อผิดพลาดที่แสดงรหัสข้อผิดพลาดและประเภทการยืนยันตามที่แสดงในข้อมูลโค้ดต่อไปนี้
index.js
class SmartHomeError extends Error { ... }
// Add secondary user verification error handling
class ChallengeNeededError extends SmartHomeError {
/**
* Create a new ChallengeNeededError
* @param {string} suvType secondary user verification challenge type
*/
constructor(suvType) {
super('challengeNeeded', suvType);
this.suvType = suvType;
}
}
นอกจากนี้ คุณยังต้องอัปเดตการตอบกลับการเรียกใช้เพื่อแสดงข้อผิดพลาด challengeNeeded
ดังนี้
index.js
const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
for (const device of command.devices) {
for (const execution of command.execution) {
executePromises.push(
updateDevice(execution, device.id)
.then((data) => {
...
})
.catch((error) => {
functions.logger.error('EXECUTE', device.id, error);
result.ids.push(device.id);
if (error instanceof SmartHomeError) {
result.status = 'ERROR';
result.errorCode = error.errorCode;
//Add error response handling
if (error instanceof ChallengeNeededError) {
result.challengeNeeded = {
type: error.suvType
};
}
}
})
);
}
}
}
สุดท้าย ให้แก้ไข updateDevice
เพื่อกำหนดให้ต้องมีการรับทราบอย่างชัดเจนเพื่อเปิดหรือปิดเครื่องซักผ้า
index.js
const updateDevice = async (execution,deviceId) => {
const {challenge,params,command} = execution; //Add secondary user challenge
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
//Add secondary user verification challenge
if (!challenge || !challenge.ack) {
throw new ChallengeNeededError('ackNeeded');
}
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
...
}
return ref.update(state)
.then(() => state);
};
ทำให้ใช้งานได้กับ Firebase
เรียกใช้คําสั่งต่อไปนี้เพื่อทําให้ฟังก์ชันที่อัปเดตแล้วใช้งานได้
firebase deploy --only functions
หลังจากติดตั้งใช้งานโค้ดที่อัปเดตแล้ว คุณต้องยอมรับการดำเนินการด้วยวาจาเมื่อขอให้ Assistant เปิดหรือปิดเครื่องซักผ้า ดังนี้
คุณ: "Ok Google เปิดเครื่องซักผ้า"
Assistant: "คุณแน่ใจไหมว่าต้องการเปิดเครื่องซักผ้า"
คุณ: "ใช่"
นอกจากนี้ คุณยังดูการตอบกลับโดยละเอียดสำหรับแต่ละขั้นตอนของขั้นตอนการยืนยันผู้ใช้รองได้โดยเปิดบันทึก Firebase
8. ขอแสดงความยินดี
ยินดีด้วย คุณได้ขยายฟีเจอร์ของการผสานรวมระบบคลาวด์กับระบบคลาวด์ผ่านลักษณะ Modes
และ Toggles
และทำให้การดำเนินการปลอดภัยผ่านการยืนยันผู้ใช้รอง
ดูข้อมูลเพิ่มเติม
ต่อไปนี้คือแนวคิดบางส่วนที่คุณนำไปใช้เพื่อเจาะลึกได้
- เพิ่มความสามารถการดำเนินการในเครื่องลงในอุปกรณ์
- ใช้ประเภทภารกิจยืนยันผู้ใช้รองแบบอื่นเพื่อแก้ไขสถานะอุปกรณ์
- อัปเดตการตอบกลับ QUERY ของลักษณะ
RunCycle
เพื่ออัปเดตแบบไดนามิก - ดูตัวอย่างใน GitHub นี้