1. ก่อนเริ่มต้น
การดำเนินการสำหรับสมาร์ทโฮมใช้ประเภทอุปกรณ์เพื่อให้ Google Assistant ทราบว่าควรใช้ไวยากรณ์ใดกับอุปกรณ์ ลักษณะของอุปกรณ์จะกำหนดความสามารถของอุปกรณ์แต่ละประเภท อุปกรณ์จะรับค่าสถานะของลักษณะอุปกรณ์แต่ละรายการที่เพิ่มลงในการดำเนินการ
คุณสามารถเชื่อมต่อลักษณะทั้งหมดที่รองรับกับประเภทอุปกรณ์ที่เลือกเพื่อปรับแต่งฟังก์ชันการทำงานของผู้ใช้ อุปกรณ์ หากต้องการใช้ลักษณะที่กําหนดเองในการดําเนินการที่ยังไม่มีในสคีมาอุปกรณ์ ลักษณะ Modes และ Toggles จะอนุญาตการตั้งค่าที่เฉพาะเจาะจง ด้วยชื่อที่กำหนดเองซึ่งคุณกำหนด
นอกเหนือจากความสามารถในการควบคุมพื้นฐานตามประเภทและลักษณะแล้ว Smart Home API ยังมีฟีเจอร์เพิ่มเติมเพื่อปรับปรุงประสบการณ์ของผู้ใช้อีกด้วย การตอบกลับข้อผิดพลาดจะแสดงความคิดเห็นโดยละเอียดของผู้ใช้เมื่อ Intent นั้นดำเนินการไม่สำเร็จ การยืนยันผู้ใช้รองจะขยายคำตอบเหล่านั้นและเพิ่มการรักษาความปลอดภัยเพิ่มเติมให้กับลักษณะของอุปกรณ์ที่คุณต้องการ การส่งคำตอบข้อผิดพลาดที่เจาะจงไปยังบล็อกคำท้าที่ออกโดย Assistant จะทำให้การดำเนินการในสมาร์ทโฮมของคุณจำเป็นต้องได้รับการให้สิทธิ์เพิ่มเติมเพื่อทำงานตามคำสั่งได้
ข้อกำหนดเบื้องต้น
- สร้างคู่มือการดำเนินการสมาร์ทโฮมสำหรับนักพัฒนาซอฟต์แวร์
- Codelab เกี่ยวกับเครื่องซักผ้าสมาร์ทโฮม
- คู่มือนักพัฒนาซอฟต์แวร์ประเภทอุปกรณ์และลักษณะ
สิ่งที่คุณจะสร้าง
ใน Codelab นี้ คุณจะได้ติดตั้งใช้งานการผสานรวมสมาร์ทโฮมที่สร้างไว้ล่วงหน้ากับ Firebase จากนั้นศึกษาวิธีเพิ่มลักษณะที่ไม่เป็นไปตามมาตรฐานลงในเครื่องซักผ้าในบ้านสำหรับโหลดขนาดและโหมดเทอร์โบ นอกจากนี้ คุณยังจะใช้การรายงานข้อผิดพลาดและข้อยกเว้น ตลอดจนเรียนรู้ที่จะบังคับใช้การตอบรับด้วยวาจาเพื่อเปิดเครื่องซักผ้าโดยใช้การยืนยันผู้ใช้รอง
สิ่งที่คุณจะได้เรียนรู้
- วิธีเพิ่มโหมดและสลับลักษณะต่างๆ ลงในการดำเนินการ
- วิธีรายงานข้อผิดพลาดและข้อยกเว้น
- วิธีใช้การยืนยันผู้ใช้รอง
สิ่งที่ต้องมี
- เว็บเบราว์เซอร์ เช่น Google Chrome
- อุปกรณ์ iOS หรือ Android ที่ติดตั้งแอป Google Home
- Node.js เวอร์ชัน 10.16 ขึ้นไป
- บัญชี Google
- บัญชีสำหรับการเรียกเก็บเงินของ Google Cloud
2. เริ่มต้นใช้งาน
เปิดใช้ส่วนควบคุมกิจกรรม
คุณต้องแชร์ข้อมูลกิจกรรมบางอย่างกับ Google จึงจะใช้ Google Assistant ได้ Google Assistant ต้องใช้ข้อมูลนี้เพื่อให้ทำงานได้อย่างถูกต้อง แต่ข้อกำหนดในการแชร์ข้อมูลไม่ได้มีไว้เฉพาะสำหรับ SDK นี้ หากต้องการแชร์ข้อมูลนี้ ให้สร้างบัญชี Google หากคุณยังไม่มีบัญชี คุณจะใช้บัญชี Google ใดก็ได้ โดยไม่จำเป็นต้องเป็นบัญชีนักพัฒนาแอปของคุณ
เปิดหน้าส่วนควบคุมกิจกรรมของบัญชี Google ที่คุณต้องการใช้กับ Assistant
ตรวจสอบว่าสวิตช์เปิด/ปิดต่อไปนี้เปิดอยู่
- เว็บและ กิจกรรมบนแอป - นอกจากนี้ โปรดตรวจสอบว่าได้เลือกช่องทําเครื่องหมายรวมประวัติการเข้าชมใน Chrome และกิจกรรมจากเว็บไซต์ แอป และอุปกรณ์ที่ใช้บริการต่างๆ ของ Google
- ข้อมูลอุปกรณ์
- เสียงและ กิจกรรมเสียง
สร้างโปรเจ็กต์ Actions
- ไปที่Actions on Google Developer Console
- คลิกโปรเจ็กต์ใหม่ จากนั้นป้อนชื่อโปรเจ็กต์ แล้วคลิกสร้างโปรเจ็กต์
เลือกแอปสมาร์ทโฮม
ในหน้าจอภาพรวมในคอนโซล Actions ให้เลือกสมาร์ทโฮม
เลือกการ์ดประสบการณ์สมาร์ทโฮม แล้วคลิกเริ่มสร้าง จากนั้นระบบจะนําคุณไปยังคอนโซลโปรเจ็กต์
ติดตั้ง 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
3. เรียกใช้แอปเริ่มต้น
เมื่อตั้งค่าสภาพแวดล้อมในการพัฒนาซอฟต์แวร์แล้ว ก็ทำให้โปรเจ็กต์เริ่มต้นใช้งานได้เพื่อยืนยันว่ามีการกำหนดค่าทุกอย่างอย่างถูกต้อง
รับซอร์สโค้ด
คลิกลิงก์ต่อไปนี้เพื่อดาวน์โหลดตัวอย่างสำหรับ Codelab นี้ในเครื่องพัฒนา
...หรือโคลนที่เก็บ GitHub จากบรรทัดคำสั่งก็ได้
git clone https://github.com/google-home/smarthome-traits.git
แตกไฟล์ ZIP ที่ดาวน์โหลด
เกี่ยวกับโครงการ
โปรเจ็กต์เริ่มต้นมีไดเรกทอรีย่อยต่อไปนี้
public:
UI ฟรอนท์เอนด์ที่ช่วยให้ควบคุมและตรวจสอบสถานะของเครื่องซักผ้าอัจฉริยะได้อย่างง่ายดายfunctions:
บริการระบบคลาวด์ที่ใช้งานอย่างเต็มรูปแบบเพื่อจัดการเครื่องซักผ้าอัจฉริยะด้วย Cloud Functions สำหรับ Firebase และฐานข้อมูลเรียลไทม์ของ Firebase
Fulfillment ระบบคลาวด์ที่ระบุมีฟังก์ชันต่อไปนี้ใน index.js
fakeauth
: ปลายทางการให้สิทธิ์สำหรับการลิงก์บัญชีfaketoken
: ปลายทางของโทเค็นสำหรับการลิงก์บัญชีsmarthome
: ปลายทางการดำเนินการตาม Intent ของสมาร์ทโฮมreportstate
: เรียกใช้ Home Graph API เมื่อสถานะของอุปกรณ์เปลี่ยนแปลงrequestsync
: เปิดใช้การอัปเดตอุปกรณ์ของผู้ใช้ได้โดยไม่ต้องลิงก์บัญชีอีกครั้ง
เชื่อมต่อกับ Firebase
ไปที่ไดเรกทอรี washer-start
แล้วตั้งค่า Firebase CLI ด้วยโปรเจ็กต์การดำเนินการของคุณ ดังนี้
cd washer-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 วิธี ดังนี้
- ใช้ GUI ไปที่โฟลเดอร์
../functions
ภายใต้โปรเจ็กต์ แล้วเลือกไฟล์ที่ซ่อนอยู่.eslintrc.js
แล้วลบออก อย่าเข้าใจผิดว่าเป็นชื่อที่คล้ายกัน.eslintrc.json
- ใช้บรรทัดคำสั่งดังนี้
cd functions rm .eslintrc.js
ทำให้ใช้งานได้ใน 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
) เพื่อดูเว็บแอป คุณจะเห็นอินเทอร์เฟซต่อไปนี้
UI เว็บนี้แสดงแพลตฟอร์มของบุคคลที่สามเพื่อดูหรือแก้ไขสถานะอุปกรณ์ คลิกอัปเดตเพื่อเริ่มเพิ่มฐานข้อมูลด้วยข้อมูลอุปกรณ์ คุณจะไม่เห็นการเปลี่ยนแปลงใดๆ ในหน้าดังกล่าว แต่สถานะปัจจุบันของเครื่องซักผ้าจะจัดเก็บไว้ในฐานข้อมูล
ถึงเวลาเชื่อมต่อบริการระบบคลาวด์ที่คุณทำให้ใช้งานได้กับ Google Assistant โดยใช้คอนโซล Actions
กำหนดค่าโปรเจ็กต์คอนโซล Actions
ใต้ภาพรวม > สร้างการดำเนินการ เลือกเพิ่มการดำเนินการ ป้อน URL ของ Cloud Function ที่ดำเนินการตามคำสั่งซื้อสำหรับ Intent ของสมาร์ทโฮม แล้วคลิกบันทึก
https://us-central1-<project-id>.cloudfunctions.net/smarthome
ในหน้า Develop > แท็บการเรียกใช้ ให้เพิ่มชื่อที่แสดงสำหรับการดำเนินการของคุณ แล้วคลิกบันทึก ชื่อนี้จะปรากฏในแอป Google Home
ในการเปิดใช้การลิงก์บัญชี ให้เลือกพัฒนา > ตัวเลือกการลิงก์บัญชีในแถบการนำทางด้านซ้าย ใช้การตั้งค่าการลิงก์บัญชีต่อไปนี้
Client-ID |
|
รหัสลับไคลเอ็นต์ |
|
URL สำหรับการอนุญาต |
|
URL ของโทเค็น |
|
คลิกบันทึกเพื่อบันทึกการกำหนดค่าการลิงก์บัญชี จากนั้นคลิกทดสอบเพื่อเปิดใช้การทดสอบในโปรเจ็กต์
ระบบจะเปลี่ยนเส้นทางคุณไปยังเครื่องมือจำลอง หากคุณไม่เห็น "เปิดใช้การทดสอบแล้ว" ให้คลิกรีเซ็ตการทดสอบเพื่อยืนยันว่าเปิดใช้การทดสอบอยู่
ลิงก์กับ Google Assistant
คุณต้องลิงก์โปรเจ็กต์กับบัญชี Google เพื่อทดสอบการดำเนินการสมาร์ทโฮม วิธีนี้ช่วยให้ทำการทดสอบผ่านแพลตฟอร์ม Google Assistant และแอป Google Home ที่ลงชื่อเข้าใช้บัญชีเดียวกัน
- เปิดการตั้งค่า Google Assistant ในโทรศัพท์ โปรดทราบว่าคุณควรลงชื่อเข้าสู่ระบบด้วยบัญชีเดียวกับในคอนโซล
- ไปที่ Google Assistant > การตั้งค่า > ระบบควบคุมอุปกรณ์ในบ้าน (ในส่วน Assistant)
- คลิกไอคอนค้นหาที่ด้านขวาบน
- ค้นหาแอปทดสอบโดยใช้คำนำหน้า [test] เพื่อค้นหาแอปทดสอบที่ต้องการ
- เลือกรายการที่ต้องการ จากนั้น Google Assistant จะตรวจสอบสิทธิ์กับบริการของคุณและส่งคำขอ
SYNC
เพื่อขอให้บริการระบุรายการอุปกรณ์ให้กับผู้ใช้
เปิดแอป Google Home แล้วตรวจสอบว่าคุณเห็นอุปกรณ์เครื่องซักผ้า
ยืนยันว่าคุณควบคุมเครื่องซักผ้าโดยใช้คำสั่งเสียงในแอป Google Home ได้ นอกจากนี้ คุณจะเห็นการเปลี่ยนแปลงสถานะอุปกรณ์ใน UI เว็บฟรอนท์เอนด์ของ Fulfillment ระบบคลาวด์
หลังจากติดตั้งใช้งานเครื่องซักผ้าพื้นฐานแล้ว คุณจะปรับแต่งโหมดที่ใช้ได้ในอุปกรณ์ได้
4. เพิ่มโหมด
ลักษณะ action.devices.traits.Modes
ช่วยให้อุปกรณ์มีการตั้งค่าโหมดใดก็ได้ตามจำนวนที่กำหนด ซึ่งจะตั้งค่าได้ครั้งละ 1 โหมดเท่านั้น คุณจะเพิ่มโหมดให้กับเครื่องซักผ้าเพื่อกำหนดขนาดของผ้าที่ใช้ใส่เสื้อผ้า ได้แก่ เล็ก กลาง หรือใหญ่
อัปเดตการตอบสนองของ SYNC
คุณต้องเพิ่มข้อมูลเกี่ยวกับลักษณะเฉพาะใหม่ในคำตอบของ 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 ใหม่
ใน 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
เพื่อรายงานการตั้งค่าภาระงานปัจจุบันของเครื่องซักผ้าไปยัง 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
ในการตอบกลับ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 ใหม่
ใน 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
เพื่อรายงานไปยัง 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( ... )
//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)
สำหรับ Codelab นี้ ให้เพิ่มคำถาม ackNeeded
ลงในคำสั่งสำหรับการเปิดเครื่องซักผ้า และฟังก์ชันเพื่อแสดงข้อผิดพลาดหากการยืนยันครั้งที่ 2 ล้มเหลว
เปิด 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( ... )
.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 นี้