Để hỗ trợ phương thức thực hiện cục bộ, bạn cần xây dựng một ứng dụng để xử lý ý định nhà thông minh:
IDENTIFY
: Hỗ trợ tính năng khám phá các thiết bị thông minh có thể điều khiển cục bộ. Chiến lược phát hành đĩa đơn trình xử lý ý định trích xuất dữ liệu mà thiết bị thông minh của bạn trả về trong quá trình khám phá rồi gửi phản hồi cho Google.EXECUTE
: Hỗ trợ thực thi lệnh.QUERY
: Hỗ trợ truy vấn trạng thái thiết bị.REACHABLE_DEVICES
: (Không bắt buộc) Hỗ trợ chức năng khám phá các nội dung có thể kiểm soát cục bộ thiết bị cuối phía sau một thiết bị trung tâm (hoặc cầu nối).
Ứng dụng này chạy trên thiết bị Google Home hoặc Google Nest của người dùng và kết nối thiết bị thông minh của bạn với Trợ lý Google. Bạn có thể tạo ứng dụng bằng cách sử dụng TypeScript (ưu tiên) hoặc JavaScript.
Bạn nên dùng TypeScript vì bạn có thể tận dụng liên kết để đảm bảo tĩnh rằng dữ liệu mà ứng dụng của bạn trả về khớp với các loại mà nền tảng mong đợi.
Để biết thêm thông tin chi tiết về API này, hãy xem Tài liệu tham khảo về Local Home SDK API.
Các đoạn mã sau đây cho thấy cách bạn có thể khởi chạy ứng dụng thực hiện cục bộ và đính kèm trình xử lý của bạn.
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"); });
Tạo dự án
Để triển khai ứng dụng thực hiện cục bộ, bạn cần tạo một gói JavaScript cho mã của bạn cũng như tất cả các phần phụ thuộc của nó.
Dùng dự án ứng dụng thực hiện cục bộ trình khởi tạo để tự khởi động cấu trúc dự án thích hợp bằng trình gói ưu tiên của bạn .
Mẫu dự án
Để chọn cấu hình trình gói, hãy chạy lệnh npm init
như minh hoạ trong
các ví dụ sau:
TypeScript không có cấu hình gói:
npm init @google/local-home-app project-directory/ --bundler none
Cấu trúc dự án:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
Thay thế project-directory bằng một thư mục mới chứa dự án ứng dụng thực hiện cục bộ.
TypeScript với trình gói webpack cấu hình:
npm init @google/local-home-app project-directory/ --bundler webpack
Cấu trúc dự án:
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
Thay thế project-directory bằng một thư mục mới chứa dự án ứng dụng thực hiện cục bộ.
TypeScript với Rollup cấu hình gói:
npm init @google/local-home-app project-directory/ --bundler rollup
Cấu trúc dự án:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json ├── rollup.config.js └── serve.js
Thay thế project-directory bằng một thư mục mới chứa dự án ứng dụng thực hiện cục bộ.
TypeScript với Parcel cấu hình gói:
npm init @google/local-home-app project-directory/ --bundler parcel
Cấu trúc dự án:
project-directory/ ├── node_modules/ ├── package.json ├── .gitignore ├── index.ts ├── test.ts ├── tsconfig.json ├── tslint.json └── serve.js
Thay thế project-directory bằng một thư mục mới chứa dự án ứng dụng thực hiện cục bộ.
Thực hiện các tác vụ phổ biến ở cấp dự án
Dự án đã tạo hỗ trợ các npm sau tập lệnh:
cd project-directory/ npm run build
Tập lệnh này biên dịch nguồn TypeScript và gói ứng dụng của bạn cùng với các phần phụ thuộc của nó cho môi trường thời gian chạy Chrome trong thư mục con dist/web
và môi trường thời gian chạy Node.js trong thư mục con dist/node
.
cd project-directory/ npm run lint npm run compile npm test
Tập lệnh này xác minh cú pháp của mã TypeScript, biên dịch mã mà không tạo ra bất kỳ kết quả nào trong thư mục con dist/
và chạy kiểm thử tự động từ test.ts
.
cd project-directory/ npm run start
Trong quá trình phát triển, tập lệnh này sẽ phân phát gói ứng dụng của bạn cho môi trường thời gian chạy Chrome và Node.js một cách cục bộ.
Triển khai trình xử lý IDENTIFY
Trình xử lý IDENTIFY
sẽ được kích hoạt khi thiết bị Google Home hoặc Google Nest khởi động lại và
thấy các thiết bị cục bộ chưa được xác minh (bao gồm cả thiết bị cuối được kết nối với một thiết bị trung tâm). Chiến lược phát hành đĩa đơn
Nền tảng Local Home sẽ quét tìm các thiết bị trong nhà bằng thông tin cấu hình quét
mà bạn chỉ định trước đó và gọi trình xử lý IDENTIFY
kèm theo kết quả quét.
Chiến lược phát hành đĩa đơn
IdentifyRequest
trên nền tảng Local Home chứa dữ liệu quét của một
LocalIdentifiedDevice
thực thể. Chỉ có một thực thể device
được điền sẵn, dựa trên cấu hình quét
phát hiện ra thiết bị.
Nếu kết quả quét khớp với thiết bị của bạn, trình xử lý IDENTIFY
sẽ trả về một
IdentifyResponsePayload
bao gồm đối tượng device
có
siêu dữ liệu của nhà thông minh (chẳng hạn như loại, đặc điểm và trạng thái báo cáo).
Google thiết lập một mối liên kết với thiết bị nếu
verificationId
trong phản hồi IDENTIFY
khớp với một trong
Các giá trị otherDeviceIds
do phản hồi SYNC
trả về.
Ví dụ:
Các đoạn mã sau đây cho biết cách bạn có thể tạo trình xử lý IDENTIFY
cho
tích hợp độc lập trên thiết bị
và thiết bị trung tâm.
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; };
Xác định các thiết bị sau một trung tâm
Nếu xác định được một thiết bị trung tâm, Google sẽ coi thiết bị trung tâm này là một ống dẫn với thiết bị cuối đã kết nối của trung tâm và cố gắng xác minh các thiết bị cuối đó.
Để cho phép Google xác nhận rằng có một thiết bị trung tâm, hãy làm theo các bước sau
cho trình xử lý IDENTIFY
:
- Nếu phản hồi của
SYNC
báo cáo mã nhận dạng của các thiết bị cuối cục bộ đã kết nối với trung tâm, hãy đặtisProxy
làmtrue
trong phần tửIdentifyResponsePayload
. - Nếu phản hồi của
SYNC
không báo cáo thiết bị trung tâm, hãy đặtisLocalOnly
trong vaitrue
trongIdentifyResponsePayload
. - Trường
device.id
chứa mã thiết bị cục bộ của chính thiết bị trung tâm đó.
Triển khai trình xử lý REACHABLE_DEVICES (chỉ dành cho tính năng tích hợp trung tâm)
Google gửi ý định REACHABLE_DEVICES
để xác nhận thiết bị cuối nào
có thể được kiểm soát cục bộ. Ý định này được kích hoạt mỗi khi Google chạy một
quét khám phá (khoảng một lần mỗi phút), miễn là trung tâm được phát hiện để
trực tuyến.
Bạn triển khai trình xử lý REACHABLE_DEVICES
tương tự như IDENTIFY
ngoại trừ việc trình xử lý của bạn cần thu thập thêm mã thiết bị
có thể truy cập được bằng thiết bị proxy cục bộ (tức là thiết bị trung tâm). Chiến lược phát hành đĩa đơn
Trường device.verificationId
chứa mã thiết bị cục bộ của thiết bị cuối
được kết nối với trung tâm.
Chiến lược phát hành đĩa đơn
ReachableDevicesRequest
trên nền tảng Local Home chứa một phiên bản của
LocalIdentifiedDevice
.
Thông qua trường hợp này, bạn có thể nhận được mã thiết bị proxy cũng như dữ liệu từ
kết quả quét.
Trình xử lý REACHABLE_DEVICES
của bạn sẽ trả về một
ReachableDevicesPayload
đối tượng bao gồm đối tượng devices
chứa một mảng
Các giá trị verificationId
đại diện cho các thiết bị cuối mà trung tâm này kiểm soát. Chiến lược phát hành đĩa đơn
Các giá trị của verificationId
phải khớp với một trong các giá trị otherDeviceIds
của
SYNC
phản hồi.
Đoạn mã sau đây hướng dẫn cách tạo REACHABLE_DEVICES
trình xử lý.
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; };
Triển khai trình xử lý EXECUTE
Trình xử lý EXECUTE
của bạn trong ứng dụng sẽ xử lý lệnh người dùng và sử dụng
Local Home SDK để truy cập vào các thiết bị thông minh của bạn thông qua một giao thức hiện có.
Nền tảng Local Home truyền cùng một tải trọng đầu vào đến trình xử lý EXECUTE
thực hiện giống như đối với EXECUTE
ý định thực hiện trên đám mây. Tương tự, trình xử lý EXECUTE
sẽ trả về
dữ liệu đầu ra có cùng định dạng như từ quá trình xử lý ý định EXECUTE
.
Để đơn giản hoá quá trình tạo câu trả lời, bạn có thể sử dụng
Execute.Response.Builder
mà SDK Home cục bộ cung cấp.
Ứng dụng của bạn không có quyền truy cập trực tiếp vào địa chỉ IP của thiết bị. Thay vào đó,
sử dụng
CommandRequest
giao diện để tạo lệnh dựa trên một trong các giao thức sau: UDP, TCP hoặc HTTP. Sau đó, gọi phương thức
deviceManager.send()
để gửi lệnh.
Khi nhắm mục tiêu lệnh đến thiết bị, hãy sử dụng mã thiết bị (và các thông số từ
trường customData
, nếu có) trong phản hồi SYNC
để giao tiếp
với thiết bị.
Ví dụ:
Đoạn mã sau đây cho biết cách bạn có thể tạo trình xử lý 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()); };
Triển khai trình xử lý QUERY
Trình xử lý QUERY
trong ứng dụng sẽ xử lý yêu cầu của người dùng và sử dụng
Local Home SDK để báo cáo trạng thái của các thiết bị thông minh.
Nền tảng Local Home truyền cùng một tải trọng yêu cầu đến hàm 'QUERY' trình xử lý
đối với QUERY
ý định thực hiện trên đám mây. Tương tự, trình xử lý QUERY
trả về dữ liệu
ở cùng định dạng như khi xử lý ý định QUERY
.
Gửi lệnh đến các thiết bị sau một trung tâm
Để kiểm soát các thiết bị cuối được nối sau một trung tâm, bạn có thể cần cung cấp thêm thông tin
trong tải trọng lệnh dành riêng cho giao thức được gửi đến trung tâm để
để xác định xem lệnh đó nhắm đến thiết bị nào. Trong một số trường hợp, đây có thể là
được suy luận trực tiếp từ giá trị device.id
, nhưng khi không phải như vậy,
bạn nên thêm dữ liệu bổ sung này vào trường customData
.
Nếu bạn sử dụng TypeScript để tạo ứng dụng, hãy nhớ biên dịch ứng dụng thành JavaScript. Bạn có thể sử dụng hệ thống mô-đun mà bạn chọn để viết mã. Đảm bảo trình duyệt Chrome hỗ trợ mục tiêu của bạn.