1. ก่อนเริ่มต้น
การผสานรวมแบบคลาวด์ต่อคลาวด์ใช้ประเภทอุปกรณ์เพื่อให้ Google Assistant ทราบว่าควรใช้ไวยากรณ์ใดกับอุปกรณ์ ลักษณะของอุปกรณ์จะกำหนดความสามารถของประเภทอุปกรณ์ อุปกรณ์จะรับช่วงสถานะของลักษณะอุปกรณ์แต่ละอย่างที่เพิ่มลงในการผสานรวม
คุณเชื่อมต่อลักษณะที่รองรับกับอุปกรณ์ประเภทที่เลือกเพื่อปรับแต่งฟังก์ชันการทำงานของอุปกรณ์ของผู้ใช้ได้ หากต้องการใช้ลักษณะที่กำหนดเองใน Actions ที่ยังไม่มีในสคีมาอุปกรณ์ ลักษณะโหมดและสวิตช์จะช่วยให้ควบคุมการตั้งค่าที่เฉพาะเจาะจงได้ด้วยชื่อที่กำหนดเองซึ่งคุณกำหนด
นอกเหนือจากความสามารถในการควบคุมพื้นฐานที่ประเภทและลักษณะระบุไว้แล้ว Smart Home API ยังมีฟีเจอร์เพิ่มเติมเพื่อปรับปรุงประสบการณ์ของผู้ใช้ การตอบกลับข้อผิดพลาดจะให้ความคิดเห็นโดยละเอียดของผู้ใช้เมื่อ Intent ไม่สำเร็จ การยืนยันผู้ใช้รองจะขยายการตอบสนองเหล่านั้นและเพิ่มความปลอดภัยให้กับลักษณะอุปกรณ์ที่คุณเลือก การผสานรวมแบบคลาวด์ต่อคลาวด์สามารถกำหนดให้มีการให้สิทธิ์เพิ่มเติมเพื่อดำเนินการคำสั่งให้เสร็จสมบูรณ์ได้โดยการส่งการตอบกลับข้อผิดพลาดที่เฉพาะเจาะจงไปยังบล็อกการท้าทายที่ออกโดย 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
- ข้อมูลอุปกรณ์
- กิจกรรมเสียงพูดและเสียง
สร้างโปรเจ็กต์การผสานรวมแบบคลาวด์ต่อคลาวด์
- ไปที่แผงควบคุมสำหรับนักพัฒนาแอป
- คลิกสร้างโปรเจ็กต์ ป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์
เลือกการผสานรวมแบบคลาวด์ต่อคลาวด์
ในหน้าแรกของโปรเจ็กต์ใน Developer Console ให้เลือกเพิ่มการผสานรวมแบบคลาวด์ต่อคลาวด์ในส่วนคลาวด์ต่อคลาวด์
ติดตั้ง Firebase CLI
อินเทอร์เฟซบรรทัดคำสั่ง (CLI) ของ Firebase จะช่วยให้คุณแสดงเว็บแอปในเครื่องและทําให้เว็บแอปใช้งานได้ในโฮสติ้งของ Firebase
หากต้องการติดตั้ง CLI ให้เรียกใช้คำสั่ง npm ต่อไปนี้จากเทอร์มินัล
npm install -g firebase-tools
หากต้องการยืนยันว่าได้ติดตั้ง CLI อย่างถูกต้องแล้ว ให้เรียกใช้คำสั่งต่อไปนี้
firebase --version
ให้สิทธิ์ Firebase CLI ด้วยบัญชี Google โดยการเรียกใช้คำสั่งต่อไปนี้
firebase login
เพิ่ม Firebase ลงในโปรเจ็กต์ Google Home Developer Console
วิธีที่ 1: ผ่านคอนโซล Firebase
- ไปที่ Firebase
- คลิกสร้างโปรเจ็กต์ Firebase
- ในหน้าจอสร้างโปรเจ็กต์ ให้คลิกเพิ่ม Firebase ไปยังโปรเจ็กต์ Google Cloud
- ในหน้าจอเริ่มต้นใช้งาน ให้เลือกโปรเจ็กต์ Google Cloud ที่คุณเพิ่งสร้างใน Google Home Developer Console แล้วคลิกต่อไป
วิธีที่ 2: ผ่าน Firebase CLI
firebase projects:addfirebase
เลือกโปรเจ็กต์ Google Home Developer Console ที่คุณเพิ่งสร้างเพื่อเพิ่ม Firebase
เมื่อเพิ่ม Firebase ลงในโปรเจ็กต์ Google Home Developer Console แล้ว Firebase จะปรากฏในคอนโซล Firebase รหัสโปรเจ็กต์ของโปรเจ็กต์ Firebase จะสอดคล้องกับรหัสโปรเจ็กต์ Google Home Developer Console
เปิดใช้ HomeGraph API
HomeGraph API ช่วยให้จัดเก็บและค้นหาอุปกรณ์และสถานะของอุปกรณ์ภายใน Home Graph ของผู้ใช้ได้ หากต้องการใช้ API นี้ คุณต้องเปิด Google Cloud Console และเปิดใช้ HomeGraph API ก่อน
ในคอนโซล Google Cloud ให้เลือกโปรเจ็กต์ที่ตรงกับ Actions <firebase-project-id>.
จากนั้นในหน้าจอคลัง API สำหรับ HomeGraph API ให้คลิกเปิดใช้
3. เรียกใช้แอปเริ่มต้น
ตอนนี้คุณได้ตั้งค่าสภาพแวดล้อมในการพัฒนาแล้ว คุณสามารถติดตั้งใช้งานโปรเจ็กต์เริ่มต้นเพื่อยืนยันว่าทุกอย่างได้รับการกำหนดค่าอย่างถูกต้อง
รับซอร์สโค้ด
คลิกลิงก์ต่อไปนี้เพื่อดาวน์โหลดตัวอย่างสำหรับ Codelab นี้ในเครื่องพัฒนาของคุณ
...หรือจะโคลนที่เก็บ GitHub จากบรรทัดคำสั่งก็ได้
git clone https://github.com/google-home/smarthome-traits.git
คลายไฟล์ ZIP ที่ดาวน์โหลด
เกี่ยวกับโครงการนี้
โปรเจ็กต์เริ่มต้นมีไดเรกทอรีย่อยต่อไปนี้
public:
UI ส่วนหน้าเพื่อควบคุมและตรวจสอบสถานะของเครื่องซักผ้าอัจฉริยะได้อย่างง่ายดายfunctions:
บริการระบบคลาวด์ที่ใช้งานอย่างเต็มรูปแบบซึ่งจัดการเครื่องซักผ้าอัจฉริยะด้วย Cloud Functions for Firebase และฐานข้อมูลเรียลไทม์ของ Firebase
การจัดการคำสั่งซื้อในระบบคลาวด์ที่ระบุมีฟังก์ชันต่อไปนี้ใน index.js
fakeauth
: ปลายทางการให้สิทธิ์สำหรับการลิงก์บัญชีfaketoken
: ปลายทางโทเค็นสำหรับการลิงก์บัญชีsmarthome
: ปลายทางการดำเนินการตามความตั้งใจของสมาร์ทโฮมreportstate
: เรียกใช้ Home Graph API เมื่อมีการเปลี่ยนแปลงสถานะอุปกรณ์requestsync
: ช่วยให้ผู้ใช้สามารถอัปเดตอุปกรณ์ได้โดยไม่ต้องลิงก์บัญชีอีกครั้ง
เชื่อมต่อกับ Firebase
ไปที่ไดเรกทอรี washer-start
แล้วตั้งค่า Firebase CLI ด้วยโปรเจ็กต์การผสานรวม
cd washer-start firebase use <project-id>
กำหนดค่าโปรเจ็กต์ Firebase
เริ่มต้นโปรเจ็กต์ Firebase
firebase init
เลือกฟีเจอร์ CLI, Realtime Database และฟีเจอร์ Functions
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed) >( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore ( ) Genkit: Setup a new Genkit project with Firebase (*) Functions: Configure a Cloud Functions directory and its files ( ) App Hosting: Configure an apphosting.yaml file for App Hosting ( ) Hosting: Configure files for Firebase Hosting and (optionally) 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 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance ( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore
ซึ่งจะเริ่มต้น 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
หากเปิดใช้ 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/<project-id>/overview Hosting URL: https://<project-id>.web.app
คำสั่งนี้จะทําการติดตั้งใช้งานเว็บแอปพร้อมกับ Cloud Functions for Firebase หลายรายการ
เปิด URL การโฮสต์ในเบราว์เซอร์ (https://<firebase-project-id>.web.app
) เพื่อดูเว็บแอป คุณจะเห็นอินเทอร์เฟซต่อไปนี้
UI บนเว็บนี้แสดงแพลตฟอร์มของบุคคลที่สามสำหรับดูหรือแก้ไขสถานะอุปกรณ์ หากต้องการเริ่มป้อนข้อมูลอุปกรณ์ลงในฐานข้อมูล ให้คลิกอัปเดต คุณจะไม่เห็นการเปลี่ยนแปลงใดๆ ในหน้า แต่ระบบจะจัดเก็บสถานะปัจจุบันของเครื่องซักผ้าไว้ในฐานข้อมูล
ตอนนี้ได้เวลาเชื่อมต่อบริการระบบคลาวด์ที่คุณติดตั้งใช้งานกับ Google Assistant โดยใช้ Developer Console แล้ว
กำหนดค่าโปรเจ็กต์ใน Developer Console
ในแท็บพัฒนา ให้เพิ่มชื่อที่แสดงสำหรับการโต้ตอบ ชื่อนี้จะปรากฏในแอป Google Home
ในส่วนการสร้างแบรนด์แอป ให้อัปโหลดไฟล์ png
สำหรับไอคอนแอปขนาด 144 x 144 พิกเซล และตั้งชื่อว่า
หากต้องการเปิดใช้การลิงก์บัญชี ให้ใช้การตั้งค่าการลิงก์บัญชีต่อไปนี้
รหัสลูกค้า |
|
รหัสลับไคลเอ็นต์ |
|
URL สำหรับการอนุญาต |
|
URL โทเค็น |
|
ในส่วน URL การดำเนินการตามคำสั่งในระบบคลาวด์ ให้ป้อน URL สำหรับ Cloud Functions ที่ให้การดำเนินการตามคำสั่งสำหรับ Intent ของสมาร์ทโฮม
https://us-central1-<project-id>.cloudfunctions.net/smarthome
คลิกบันทึกเพื่อบันทึกการกำหนดค่าโปรเจ็กต์ จากนั้นคลิกถัดไป: ทดสอบเพื่อเปิดใช้การทดสอบในโปรเจ็กต์
ตอนนี้คุณเริ่มใช้ Webhook ที่จำเป็นเพื่อเชื่อมต่อสถานะอุปกรณ์กับ Assistant ได้แล้ว
ลิงก์กับ Google Assistant
หากต้องการทดสอบการผสานรวมแบบคลาวด์ต่อคลาวด์ คุณต้องลิงก์โปรเจ็กต์กับบัญชี Google ซึ่งจะช่วยให้ทดสอบผ่านแพลตฟอร์ม Google Assistant และแอป Google Home ที่ลงชื่อเข้าใช้บัญชีเดียวกันได้
- เปิดการตั้งค่า Google Assistant ในโทรศัพท์ โปรดทราบว่าคุณควรลงชื่อเข้าใช้บัญชีเดียวกับที่ใช้ในคอนโซล
- ไปที่ Google Assistant > การตั้งค่า > การควบคุมบ้าน (ในส่วน Assistant)
- คลิกไอคอนค้นหาที่ด้านขวาบน
- ค้นหาแอปทดสอบโดยใช้คำนำหน้า [ทดสอบ] เพื่อค้นหาแอปทดสอบที่ต้องการ
- เลือกรายการนั้น จากนั้น 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,
}],
},
}],
},
};
});
เพิ่มคำสั่ง Intent EXECUTE ใหม่
ในความตั้งใจ 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
เพื่อรายงานการตั้งค่าการโหลดปัจจุบันของเครื่องซักผ้าไปยัง Home Graph
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',
}],
}],
},
}],
},
};
});
เพิ่มคำสั่ง Intent EXECUTE ใหม่
ในความตั้งใจ 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
เพื่อรายงานไปยัง Home Graph ว่าตั้งค่าเครื่องซักผ้าเป็นโหมดเทอร์โบหรือไม่
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
รวมถึงรักษาความปลอดภัยในการดำเนินการผ่านการยืนยันผู้ใช้รอง
ดูข้อมูลเพิ่มเติม
ต่อไปนี้คือไอเดียบางส่วนที่คุณนำไปใช้เพื่อเจาะลึกได้
- เพิ่มความสามารถในการดำเนินการในเครื่องลงในอุปกรณ์
- ใช้การยืนยันผู้ใช้รองประเภทอื่นเพื่อแก้ไขสถานะอุปกรณ์
- อัปเดตการตอบกลับของ
RunCycle
ลักษณะ QUERY เพื่ออัปเดตแบบไดนามิก - ดูตัวอย่าง GitHub นี้