คุณต้องสร้างแอปเพื่อรองรับ Intent ของสมาร์ทโฮมเหล่านี้เพื่อรองรับการดําเนินการตามในท้องถิ่น
IDENTIFY
: รองรับการค้นพบอุปกรณ์อัจฉริยะที่ควบคุมได้ในพื้นที่ เครื่องจัดการ Intent จะแยกข้อมูลที่อุปกรณ์อัจฉริยะแสดงผลระหว่างการสํารวจและส่งข้อมูลนั้นไปยัง GoogleEXECUTE
: รองรับการเรียกใช้คําสั่งQUERY
: รองรับการค้นหาสถานะอุปกรณ์REACHABLE_DEVICES
: (ไม่บังคับ) รองรับการสํารวจอุปกรณ์ปลายทางที่ควบคุมได้ในพื้นที่ซึ่งอยู่หลังอุปกรณ์ฮับ (หรือบริดจ์)
แอปนี้ทํางานในอุปกรณ์ Google Home หรือ Google Nest ของผู้ใช้ และเชื่อมต่ออุปกรณ์อัจฉริยะกับ Assistant คุณสามารถสร้างแอปโดยใช้ TypeScript (ที่ต้องการ) หรือ JavaScript
เราขอแนะนําให้ใช้ TypeScript เพราะคุณสามารถใช้ประโยชน์จากการเชื่อมโยงอย่างคงที่ เพื่อให้แน่ใจว่าข้อมูลที่แสดงในแอปของคุณจะตรงกับประเภทของแพลตฟอร์มที่คาด
สําหรับรายละเอียดเพิ่มเติมเกี่ยวกับ API โปรดดูข้อมูลอ้างอิง API ของ Home Home SDK
ข้อมูลโค้ดต่อไปนี้แสดงวิธีที่คุณสามารถเริ่มแอปสําหรับการดําเนินการตามคําสั่งซื้อในพื้นที่และแนบเครื่องจัดการ
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 สําหรับโค้ดและการอ้างอิงทั้งหมด
ใช้ Project Initializer ของแอปดําเนินการตามคําสั่งซื้อในเครื่องเพื่อเปิดโครงสร้างโปรเจ็กต์ที่เหมาะสมด้วยการกําหนดค่า Bundler ที่คุณต้องการ
เทมเพลตโปรเจ็กต์
ในการเลือกการตั้งค่า Bundle ให้เรียกใช้คําสั่ง 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 ที่มีการกําหนดค่า Rollup ของ Bundle:
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 ที่มีการกําหนดค่า Bundle 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
เพียงอินสแตนซ์เดียว โดยอิงตามการกําหนดค่าการสแกนที่ค้นพบอุปกรณ์
หากผลการสแกนตรงกับอุปกรณ์ของคุณ เครื่องจัดการ 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 ระบุอุปกรณ์ Hub จะถือว่าอุปกรณ์นั้นๆ เป็นท่อต่ออุปกรณ์ปิดท้ายที่เชื่อมต่อของฮับและพยายามยืนยันอุปกรณ์ปลายทางเหล่านั้น
หากต้องการให้ Google ยืนยันได้ว่ามีอุปกรณ์ Hub อยู่ ให้ทําตามวิธีการต่อไปนี้สําหรับเครื่องจัดการ IDENTIFY
ของคุณ
- หากการตอบกลับ
SYNC
รายงานรหัสของอุปกรณ์ปลายทางในเครือข่ายที่เชื่อมต่อกับฮับ ให้ตั้งค่าisProxy
เป็นtrue
ในIdentifyResponsePayload
- หากการตอบกลับ
SYNC
ไม่รายงานอุปกรณ์ Hub ให้ตั้งค่าisLocalOnly
เป็นtrue
ในIdentifyResponsePayload
- ช่อง
device.id
มีรหัสอุปกรณ์ในเครื่องของอุปกรณ์ตัวเครื่องเอง
ใช้เครื่องจัดการ REACHABLE_DEVICES (การผสานรวมฮับเท่านั้น)
Google จะส่ง Intent ของ REACHABLE_DEVICES
ไปยังอุปกรณ์ปลายทางที่ควบคุมได้จากเครื่อง จะมีการทริกเกอร์ Intent นี้ทุกครั้งที่ Google เรียกใช้การสแกนการค้นพบ (ทุกๆ 1 นาทีโดยประมาณ) ตราบใดที่ระบบตรวจพบว่าฮับออนไลน์
คุณติดตั้งเครื่องจัดการ REACHABLE_DEVICES
ที่คล้ายกับเครื่องจัดการ IDENTIFY
เว้นแต่ว่าเครื่องจัดการจะต้องรวบรวมรหัสอุปกรณ์เพิ่มเติมที่เข้าถึงได้โดยพร็อกซีภายในเครื่อง (ซึ่งก็คือฮับ) ช่อง device.verificationId
มีรหัสอุปกรณ์ภายในสําหรับผู้ใช้ปลายทางที่เชื่อมต่อกับฮับ
ReachableDevicesRequest
จากแพลตฟอร์ม Home 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 เพื่อเข้าถึงอุปกรณ์อัจฉริยะผ่านโปรโตคอลที่มีอยู่
แพลตฟอร์มในเครื่องของบ้านจะส่งเพย์โหลดอินพุตไปยังฟังก์ชันของ EXECUTE
แบบเดียวกับ Intent ของ EXECUTE
ที่จะทําให้ Cloud Fulfillment เสร็จสมบูรณ์ ในทํานองเดียวกัน เครื่องจัดการ 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
ในแอปจะประมวลผลคําขอผู้ใช้และใช้ Local Home SDK เพื่อรายงานสถานะอุปกรณ์อัจฉริยะ
แพลตฟอร์ม Home ส่งผ่านเปย์โหลดคําขอไปยังฟังก์ชัน "QUERY" ของคําขอเดียวกับ Intent ของ QUERY
ที่ดําเนินการตามคําขอระบบคลาวด์ ในทํานองเดียวกัน เครื่องจัดการของ QUERY
จะ
แสดงข้อมูลในรูปแบบเดียวกับที่ประมวลผล Intent ของ QUERY
การส่งคําสั่งไปยังอุปกรณ์ที่อยู่ด้านหลังฮับ
หากต้องการควบคุมอุปกรณ์ปลายทางที่อยู่เบื้องหลังฮับ คุณอาจต้องให้ข้อมูลเพิ่มเติมในเพย์โหลดคําสั่งเฉพาะโปรโตคอลที่ส่งไปยังฮับเพื่อให้ฮับระบุอุปกรณ์ที่กําหนดให้คําสั่งนี้ ในบางกรณี ค่านี้สามารถอนุมานจากค่า device.id
ได้โดยตรง แต่เมื่อไม่ใช่กรณีนี้ คุณควรใส่ข้อมูลเพิ่มเติมนี้เป็นส่วนหนึ่งของช่อง customData
หากคุณสร้างแอปโดยใช้ TypeScript อย่าลืมคอมไพล์แอปเป็น JavaScript คุณสามารถใช้ระบบโมดูลที่คุณเลือกเพื่อเขียนโค้ด ตรวจสอบว่าเบราว์เซอร์ Chrome รองรับเป้าหมายของคุณ