หากต้องการรองรับการดําเนินการตามคําสั่งซื้อในพื้นที่ คุณต้องสร้างแอปเพื่อจัดการ Intent ของสมาร์ทโฮมเหล่านี้
IDENTIFY
: รองรับการค้นพบอุปกรณ์อัจฉริยะที่ควบคุมได้ในพื้นที่ เครื่องจัดการ Intent จะดึงข้อมูลที่อุปกรณ์อัจฉริยะกลับมาระหว่างที่ค้นพบและส่งข้อมูลนี้ตามการตอบกลับ GoogleEXECUTE
: รองรับการเรียกใช้คําสั่งQUERY
: รองรับการค้นหาสถานะอุปกรณ์REACHABLE_DEVICES
: (ไม่บังคับ) รองรับการค้นพบอุปกรณ์ปลายทางที่ควบคุมในเครื่องได้หลังฮับ (หรือบริดจ์)
แอปนี้ทํางานในอุปกรณ์ Google Home หรือ Google Nest ของผู้ใช้และเชื่อมต่ออุปกรณ์อัจฉริยะกับ Assistant คุณสร้างแอปได้โดยใช้ TypeScript (แนะนํา) หรือ JavaScript
ขอแนะนําให้ใช้ TypeScript เนื่องจากคุณใช้ประโยชน์จากการเชื่อมโยงเพื่อให้ข้อมูลที่แอปแสดงเป็นไปตามประเภทที่แพลตฟอร์มคาดหวัง
ดูรายละเอียดเพิ่มเติมเกี่ยวกับ API ดังกล่าวได้ในข้อมูลอ้างอิง API ของ Home Home
ข้อมูลโค้ดต่อไปนี้แสดงวิธีเริ่มต้นแอปสําหรับการดําเนินการตามคําสั่งซื้อในพื้นที่และแนบเครื่องจัดการ
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
import App = smarthome.App; const localHomeApp: App = new App("1.0.0"); localHomeApp .onIdentify(identifyHandler) .onReachableDevices(reachableDevicesHandler) .onExecute(executeHandler) .listen() .then(() => { console.log("Ready"); });
สร้างโปรเจ็กต์
หากต้องการทําให้แอปดําเนินการตามคําสั่งซื้อในเครื่องใช้งานได้ คุณจะต้องสร้างแพ็กเกจ JavaScript สําหรับโค้ดและทรัพยากร Dependency ทั้งหมด
ใช้ project initializer ของแอปการดําเนินการตามคําสั่งซื้อในพื้นที่เพื่อเริ่มโครงสร้างโครงสร้างโปรเจ็กต์ที่เหมาะสมด้วยการกําหนดค่า Bundler ที่คุณต้องการ
เทมเพลตโปรเจ็กต์
หากต้องการเลือกการกําหนดค่า Bundler ให้เรียกใช้คําสั่ง npm init
ดังที่แสดงในตัวอย่างต่อไปนี้
TypeScript ที่ไม่มีการกําหนดค่า Bundler
npm init @google/local-home-app project-directory/ --bundler none
โครงสร้างโปรเจ็กต์
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
แทนที่ project-directory ด้วยไดเรกทอรีใหม่ที่มีโปรเจ็กต์แอปสําหรับการดําเนินการตามคําสั่งซื้อในพื้นที่
TypeScript ที่มีการกําหนดค่า webpack ของ Bundler
npm init @google/local-home-app project-directory/ --bundler webpack
โครงสร้างโปรเจ็กต์
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── webpack.config.web.js ├── webpack.config.node.js └── serve.js
แทนที่ project-directory ด้วยไดเรกทอรีใหม่ที่มีโปรเจ็กต์แอปสําหรับการดําเนินการตามคําสั่งซื้อในพื้นที่
TypeScript ที่มีการกําหนดค่า Bundle Rollup:
npm init @google/local-home-app project-directory/ --bundler rollup
โครงสร้างโปรเจ็กต์
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── rollup.config.js └── serve.js
แทนที่ project-directory ด้วยไดเรกทอรีใหม่ที่มีโปรเจ็กต์แอปสําหรับการดําเนินการตามคําสั่งซื้อในพื้นที่
TypeScript ที่มีการกําหนดค่า Bundler Parcel
npm init @google/local-home-app project-directory/ --bundler parcel
โครงสร้างโปรเจ็กต์
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
แทนที่ project-directory ด้วยไดเรกทอรีใหม่ที่มีโปรเจ็กต์แอปสําหรับการดําเนินการตามคําสั่งซื้อในพื้นที่
ทํางานทั่วไประดับโปรเจ็กต์
โปรเจ็กต์ที่สร้างขึ้นรองรับสคริปต์ npm ต่อไปนี้
cd project-directory/ npm run build
สคริปต์นี้จะรวบรวมแหล่งที่มาของ TypeScript และรวมแอปของคุณกับทรัพยากร Dependency สําหรับสภาพแวดล้อมรันไทม์ของ Chrome ในไดเรกทอรีย่อย dist/web
และสภาพแวดล้อมรันไทม์ของ Node.js ในไดเรกทอรีย่อย dist/node
cd project-directory/ npm run lint npm run compile npm test
สคริปต์นี้จะยืนยันไวยากรณ์ของโค้ด TypeScript คอมไพล์โดยไม่ต้องสร้างเอาต์พุตในไดเรกทอรีย่อยของ dist/
และเรียกใช้การทดสอบอัตโนมัติจาก test.ts
cd project-directory/ npm run start
ในระหว่างการพัฒนา สคริปต์นี้จะให้บริการ App Bundle สําหรับสภาพแวดล้อมรันไทม์ของ Chrome และ Node.js ในเครื่อง
ติดตั้งใช้งานเครื่องจัดการ IDENTIFY
ระบบจะทริกเกอร์เครื่องจัดการ IDENTIFY
เมื่ออุปกรณ์ Google Home หรือ Google Nest รีบูตและเห็นอุปกรณ์ในเครือข่ายที่ไม่ได้รับการยืนยัน (รวมถึงอุปกรณ์ปลายทางที่เชื่อมต่อกับฮับ) แพลตฟอร์ม Home จะสแกนหาอุปกรณ์ในเครื่องโดยใช้ข้อมูลการกําหนดค่าการสแกนที่คุณระบุไว้ก่อนหน้านี้ และเรียกเครื่องจัดการ IDENTIFY
ด้วยผลการสแกน
IdentifyRequest
จากแพลตฟอร์ม Home Home มีข้อมูลการสแกนอินสแตนซ์ LocalIdentifiedDevice
ระบบป้อนข้อมูลอินสแตนซ์ device
เพียง 1 รายการเท่านั้น โดยอิงตามการกําหนดค่าการสแกนที่ค้นพบอุปกรณ์
หากผลการสแกนตรงกับอุปกรณ์ของคุณ เครื่องจัดการ IDENTIFY
ควรแสดงผลออบเจ็กต์ IdentifyResponsePayload
ซึ่งประกอบด้วยออบเจ็กต์ device
ที่มีข้อมูลเมตาของบ้านอัจฉริยะ (เช่น ประเภท ลักษณะเฉพาะ และสถานะรายงาน)
Google จะตั้งการเชื่อมโยงอุปกรณ์หาก verificationId
จากการตอบกลับ IDENTIFY
ตรงกับค่า otherDeviceIds
ค่าใดค่าหนึ่งซึ่งตอบกลับโดย SYNC
ตัวอย่าง
ข้อมูลโค้ดต่อไปนี้แสดงวิธีการสร้างเครื่องจัดการ IDENTIFY
สําหรับการผสานรวมอุปกรณ์แบบสแตนด์อโลนและฮับ
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const verificationId = "local-device-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: device.id || "", verificationId, // Must match otherDeviceIds in SYNC response }, }, }; return response; };
const identifyHandler = (request: IntentFlow.IdentifyRequest): IntentFlow.IdentifyResponse => { // Obtain scan data from protocol defined in your scan config const device = request.inputs[0].payload.device; if (device.udpScanData === undefined) { throw Error("Missing discovery response"); } const scanData = device.udpScanData.data; // Decode scan data to obtain metadata about local device const proxyDeviceId = "local-hub-id"; // Return a response const response: IntentFlow.IdentifyResponse = { intent: Intents.IDENTIFY, requestId: request.requestId, payload: { device: { id: proxyDeviceId, isProxy: true, // Device can control other local devices isLocalOnly: true, // Device not present in `SYNC` response }, }, }; return response; };
ระบุอุปกรณ์ที่อยู่ภายใต้ฮับ
หาก Google ระบุอุปกรณ์ฮับ ระบบจะคิดว่าฮับเป็นเหมือนอุปกรณ์ปลายทางที่เชื่อมต่อของฮับและพยายามยืนยันอุปกรณ์ปลายทางเหล่านั้น
หากต้องการให้ Google ยืนยันว่ามีอุปกรณ์ฮับอยู่ ให้ทําตามวิธีการต่อไปนี้สําหรับเครื่องจัดการ IDENTIFY
ของคุณ
- หากการตอบกลับของ
SYNC
รายงานรหัสของอุปกรณ์ปลายทางในพื้นที่ที่เชื่อมต่อกับฮับ ให้ตั้งค่าisProxy
เป็นtrue
ในIdentifyResponsePayload
- หากการตอบกลับ
SYNC
ไม่รายงานอุปกรณ์ฮับ ให้ตั้งค่าisLocalOnly
เป็นtrue
ในIdentifyResponsePayload
- ช่อง
device.id
มีรหัสอุปกรณ์ในเครื่องสําหรับอุปกรณ์ฮับ
ใช้ตัวแฮนเดิล REACHABLE_DEVICES (การผสานรวมฮับเท่านั้น)
Google จะส่ง Intent ของ REACHABLE_DEVICES
เพื่อยืนยันว่าอุปกรณ์ปลายทางใดที่ควบคุมในเครื่องได้ จะมีการทริกเกอร์ Intent นี้ทุกครั้งที่ Google สแกนการสแกน (ประมาณทุก 1 นาที) ตราบใดที่มีการตรวจพบฮับออนไลน์
คุณใช้เครื่องจัดการ REACHABLE_DEVICES
คล้ายกับเครื่องจัดการ IDENTIFY
เว้นแต่ว่าเครื่องจัดการจะต้องรวบรวมรหัสอุปกรณ์เพิ่มเติมที่เข้าถึงได้โดยพร็อกซีพร็อกซีในเครื่อง (ซึ่งก็คือฮับ) ช่อง device.verificationId
มีรหัสอุปกรณ์ในเครื่องสําหรับอุปกรณ์ปลายทางที่เชื่อมต่อกับฮับ
ReachableDevicesRequest
จากแพลตฟอร์ม Home จะมีอินสแตนซ์ของ LocalIdentifiedDevice
ผ่านอินสแตนซ์นี้ คุณจะได้รับรหัสอุปกรณ์พร็อกซีและข้อมูลจากผลการสแกน
เครื่องจัดการ REACHABLE_DEVICES
ควรแสดงผลออบเจ็กต์ ReachableDevicesPayload
ที่มีออบเจ็กต์ devices
ที่มีอาร์เรย์ของค่า verificationId
ที่แสดงถึงอุปกรณ์ปลายทางที่ฮับควบคุม ค่า verificationId
ต้องตรงกับ otherDeviceIds
ค่าใดค่าหนึ่งในการตอบกลับ SYNC
ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีสร้างแฮนเดิล REACHABLE_DEVICES
const reachableDevicesHandler = (request: IntentFlow.ReachableDevicesRequest): IntentFlow.ReachableDevicesResponse => { // Reference to the local proxy device const proxyDeviceId = request.inputs[0].payload.device.id; // Gather additional device ids reachable by local proxy device // ... const reachableDevices = [ // Each verificationId must match one of the otherDeviceIds // in the SYNC response { verificationId: "local-device-id-1" }, { verificationId: "local-device-id-2" }, ]; // Return a response const response: IntentFlow.ReachableDevicesResponse = { intent: Intents.REACHABLE_DEVICES, requestId: request.requestId, payload: { devices: reachableDevices, }, }; return response; };
ติดตั้งใช้งานเครื่องจัดการ EXECUTE
เครื่องจัดการ EXECUTE
ในแอปจะประมวลผลคําสั่งของผู้ใช้และใช้ Local Home SDK เพื่อเข้าถึงอุปกรณ์อัจฉริยะผ่านโปรโตคอลที่มีอยู่
แพลตฟอร์ม Home Home ส่งเพย์โหลดอินพุตเดียวกันไปยังฟังก์ชันตัวแฮนเดิล EXECUTE
สําหรับ Intent ของ EXECUTE
สําหรับการดําเนินการตามระบบคลาวด์ ในทํานองเดียวกัน เครื่องจัดการ EXECUTE
จะแสดงผลข้อมูลเอาต์พุตในรูปแบบเดียวกับการประมวลผล Intent ของ EXECUTE
คุณสามารถใช้คลาส Execute.Response.Builder
ที่ Local Home SDK มีให้เพื่อลดความซับซ้อนของการสร้างการตอบกลับ
แอปของคุณไม่มีสิทธิ์เข้าถึงที่อยู่ IP ของอุปกรณ์โดยตรง แต่ให้ใช้อินเทอร์เฟซ CommandRequest
แทนเพื่อสร้างคําสั่งตามโปรโตคอลใดโปรโตคอลหนึ่งต่อไปนี้ ได้แก่ UDP, TCP หรือ HTTP จากนั้นเรียกใช้ฟังก์ชัน deviceManager.send()
เพื่อส่งคําสั่ง
เมื่อกําหนดเป้าหมายคําสั่งไปยังอุปกรณ์ ให้ใช้รหัสอุปกรณ์ (และพารามิเตอร์จากช่อง customData
หากรวมอยู่ใน) จากการตอบกลับ SYNC
เพื่อสื่อสารกับอุปกรณ์
ตัวอย่าง
ข้อมูลโค้ดต่อไปนี้แสดงวิธีสร้างแฮนเดิล EXECUTE
const executeHandler = (request: IntentFlow.ExecuteRequest): Promise<IntentFlow.ExecuteResponse> => { // Extract command(s) and device target(s) from request const command = request.inputs[0].payload.commands[0]; const execution = command.execution[0]; const response = new Execute.Response.Builder() .setRequestId(request.requestId); const result = command.devices.map((device) => { // Target id of the device provided in the SYNC response const deviceId = device.id; // Metadata for the device provided in the SYNC response // Use customData to provide additional required execution parameters const customData: any = device.customData; // Convert execution command into payload for local device let devicePayload: string; // ... // Construct a local device command over TCP const deviceCommand = new DataFlow.TcpRequestData(); deviceCommand.requestId = request.requestId; deviceCommand.deviceId = deviceId; deviceCommand.data = devicePayload; deviceCommand.port = customData.port; deviceCommand.operation = Constants.TcpOperation.WRITE; // Send command to the local device return localHomeApp.getDeviceManager() .send(deviceCommand) .then((result) => { response.setSuccessState(result.deviceId, state); }) .catch((err: IntentFlow.HandlerError) => { err.errorCode = err.errorCode || IntentFlow.ErrorCode.INVALID_REQUEST; response.setErrorState(device.id, err.errorCode); }); }); // Respond once all commands complete return Promise.all(result) .then(() => response.build()); };
ใช้เครื่องจัดการ QUERY
เครื่องจัดการ QUERY
ในแอปจะประมวลผลคําขอผู้ใช้และใช้ SDK ในเครื่องเพื่อรายงานสถานะอุปกรณ์อัจฉริยะ
แพลตฟอร์ม Local Home จะส่งเพย์โหลดคําขอเดียวกันไปยังฟังก์ชันเครื่องจัดการ "QUERY" สําหรับ Intent ของ QUERY
สําหรับการดําเนินการตามระบบคลาวด์ ในทํานองเดียวกัน เครื่องจัดการ QUERY
จะแสดงผลข้อมูลในรูปแบบเดียวกับการประมวลผล Intent ของ QUERY
การส่งคําสั่งไปยังอุปกรณ์หลังฮับ
หากต้องการควบคุมอุปกรณ์ปลายทางหลังฮับ คุณอาจต้องให้ข้อมูลเพิ่มเติมในเพย์โหลดคําสั่งเฉพาะโปรโตคอลที่ส่งไปยังฮับเพื่อให้ฮับระบุว่าอุปกรณ์มีเป้าหมายเป็นคําสั่งใด ในบางกรณี ระบบอาจอนุมานจากค่า device.id
โดยตรง แต่เมื่อไม่ใช่กรณีดังกล่าว คุณควรใส่ข้อมูลเพิ่มเติมนี้ในช่อง customData
หากคุณสร้างแอปโดยใช้ TypeScript อย่าลืมรวบรวมแอปเป็น JavaScript คุณสามารถใช้ระบบโมดูลที่ต้องการเพื่อเขียนโค้ดได้ ตรวจสอบว่าเบราว์เซอร์ Chrome รองรับเป้าหมาย