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