ปรับปรุงและรักษาความปลอดภัยให้กับการดําเนินการในบ้านอัจฉริยะ

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

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

dc8dce0dea87cd5c.png

คุณสามารถเชื่อมต่อลักษณะทั้งหมดที่รองรับกับประเภทอุปกรณ์ที่เลือกเพื่อปรับแต่งฟังก์ชันการทำงานของผู้ใช้ อุปกรณ์ หากต้องการใช้ลักษณะที่กําหนดเองในการดําเนินการที่ยังไม่มีในสคีมาอุปกรณ์ ลักษณะ Modes และ Toggles จะอนุญาตการตั้งค่าที่เฉพาะเจาะจง ด้วยชื่อที่กำหนดเองซึ่งคุณกำหนด

นอกเหนือจากความสามารถในการควบคุมพื้นฐานตามประเภทและลักษณะแล้ว Smart Home API ยังมีฟีเจอร์เพิ่มเติมเพื่อปรับปรุงประสบการณ์ของผู้ใช้อีกด้วย การตอบกลับข้อผิดพลาดจะแสดงความคิดเห็นโดยละเอียดของผู้ใช้เมื่อ Intent นั้นดำเนินการไม่สำเร็จ การยืนยันผู้ใช้รองจะขยายคำตอบเหล่านั้นและเพิ่มการรักษาความปลอดภัยเพิ่มเติมให้กับลักษณะของอุปกรณ์ที่คุณต้องการ การส่งคำตอบข้อผิดพลาดที่เจาะจงไปยังบล็อกคำท้าที่ออกโดย Assistant จะทำให้การดำเนินการในสมาร์ทโฮมของคุณจำเป็นต้องได้รับการให้สิทธิ์เพิ่มเติมเพื่อทำงานตามคำสั่งได้

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

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

ใน Codelab นี้ คุณจะได้ติดตั้งใช้งานการผสานรวมสมาร์ทโฮมที่สร้างไว้ล่วงหน้ากับ Firebase จากนั้นศึกษาวิธีเพิ่มลักษณะที่ไม่เป็นไปตามมาตรฐานลงในเครื่องซักผ้าในบ้านสำหรับโหลดขนาดและโหมดเทอร์โบ นอกจากนี้ คุณยังจะใช้การรายงานข้อผิดพลาดและข้อยกเว้น ตลอดจนเรียนรู้ที่จะบังคับใช้การตอบรับด้วยวาจาเพื่อเปิดเครื่องซักผ้าโดยใช้การยืนยันผู้ใช้รอง

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

  • วิธีเพิ่มโหมดและสลับลักษณะต่างๆ ลงในการดำเนินการ
  • วิธีรายงานข้อผิดพลาดและข้อยกเว้น
  • วิธีใช้การยืนยันผู้ใช้รอง

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

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

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

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

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

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

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

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

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

3d6b68ca79afd54c.png

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

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

2fa4988f44f8914b.png

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

ติดตั้ง 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

ee198858a6eac112.png

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 วิธี ดังนี้

  1. ใช้ GUI ไปที่โฟลเดอร์ ../functions ภายใต้โปรเจ็กต์ แล้วเลือกไฟล์ที่ซ่อนอยู่ .eslintrc.js แล้วลบออก อย่าเข้าใจผิดว่าเป็นชื่อที่คล้ายกัน .eslintrc.json
  2. ใช้บรรทัดคำสั่งดังนี้
    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) เพื่อดูเว็บแอป คุณจะเห็นอินเทอร์เฟซต่อไปนี้

5845443e94705557.png

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

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

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

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

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

9d7b223427f587ca.png

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

774d0c40c351c7da.png

a8c4673eb11d76ee.png

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

Client-ID

ABC123

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

DEF456

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

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

URL ของโทเค็น

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

9730d20b90bcc038.png

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

ee0547f05b5efd98.png

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

d0495810dbadf059.png

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

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

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

ae252220753726f6.png

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

bf4f6a866160a982.png

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

"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

คลิกปุ่มรีเฟรช ae8d3b25777a5e30.png ใน 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

289dbe48f4bb8106.png

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

674c4f4392e98c1.png

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

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

ตัวอย่างแนวคิดที่สามารถนำไปใช้เพื่อเจาะลึกรายละเอียดมีดังนี้

  • เพิ่มความสามารถในการดำเนินการในเครื่องให้กับอุปกรณ์
  • ใช้คำถามประเภทรองในการยืนยันผู้ใช้ประเภทอื่นเพื่อแก้ไขสถานะอุปกรณ์
  • อัปเดตการตอบกลับ QUERY ของลักษณะ RunCycle เพื่ออัปเดตแบบไดนามิก
  • สำรวจตัวอย่าง GitHub นี้