Bật phương thức thực hiện đơn hàng tại địa phương cho các chế độ tích hợp đám mây với đám mây

1. Trước khi bắt đầu

Tính năng tích hợp nhà thông minh cho phép Trợ lý Google điều khiển các thiết bị được kết nối trong nhà của người dùng. Để tạo một chế độ tích hợp từ đám mây đến đám mây, bạn cần cung cấp một điểm cuối webhook trên đám mây có khả năng xử lý ý định cho thiết bị nhà thông minh. Ví dụ: khi người dùng nói "Ok Google, bật đèn", Trợ lý sẽ gửi lệnh đến dịch vụ thực hiện trên đám mây để cập nhật trạng thái của thiết bị.

Local Home SDK giúp nâng cao khả năng tích hợp nhà thông minh bằng cách thêm một đường dẫn cục bộ để định tuyến trực tiếp các ý định cho nhà thông minh đến một thiết bị Google Home. Điều này giúp tăng độ tin cậy và giảm độ trễ khi xử lý các lệnh của người dùng. Thư viện này cho phép bạn viết và triển khai một ứng dụng thực hiện tại địa phương bằng TypeScript hoặc JavaScript để xác định các thiết bị và thực thi các lệnh trên mọi loa thông minh Google Home hoặc màn hình thông minh Google Nest. Sau đó, ứng dụng của bạn sẽ giao tiếp trực tiếp với các thiết bị thông minh hiện có của người dùng qua mạng cục bộ bằng cách sử dụng các giao thức tiêu chuẩn hiện có để thực hiện các lệnh.

72ffb320986092c.png

Điều kiện tiên quyết

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ triển khai một giải pháp tích hợp nhà thông minh đã được xây dựng trước đó với Firebase, sau đó áp dụng một cấu hình quét trong Developer Console và tạo một ứng dụng cục bộ bằng TypeScript để gửi các lệnh được viết bằng Node.js đến một thiết bị máy giặt ảo.

Kiến thức bạn sẽ học được

  • Cách bật và định cấu hình tính năng thực hiện đơn hàng tại địa phương trong Developer Console.
  • Cách sử dụng Local Home SDK để viết một ứng dụng thực hiện yêu cầu qua hệ thống mạng cục bộ.
  • Cách gỡ lỗi ứng dụng thực hiện đơn hàng tại địa phương được tải trên loa Google Home hoặc Màn hình thông minh Google Nest.

Bạn cần có

2. Bắt đầu

Bật chế độ Kiểm soát hoạt động

Để sử dụng Trợ lý Google, bạn phải chia sẻ một số dữ liệu hoạt động nhất định với Google. Trợ lý Google cần dữ liệu này để hoạt động đúng cách; tuy nhiên, yêu cầu chia sẻ dữ liệu không dành riêng cho SDK. Để chia sẻ dữ liệu này, hãy tạo một Tài khoản Google nếu bạn chưa có. Bạn có thể sử dụng bất kỳ Tài khoản Google nào, không nhất thiết phải là tài khoản nhà phát triển của bạn.

Mở trang Kiểm soát hoạt động cho Tài khoản Google mà bạn muốn dùng với Trợ lý.

Đảm bảo bạn đã bật các nút bật/tắt sau:

  • Hoạt động trên web và ứng dụng – Ngoài ra, hãy nhớ chọn hộp đánh dấu Bao gồm cả nhật ký duyệt web trên Chrome cũng như hoạt động trên những trang web, ứng dụng và thiết bị sử dụng các dịch vụ của Google.
  • Thông tin về thiết bị
  • Hoạt động bằng giọng nói và âm thanh

Tạo dự án Tích hợp từ đám mây sang đám mây

  1. Chuyển đến Developer Console.
  2. Nhấp vào Tạo dự án, nhập tên cho dự án rồi nhấp vào Tạo dự án.

Đặt tên cho dự án

Chọn chế độ Tích hợp từ đám mây sang đám mây

Trên Trang chủ dự án trong Developer Console, hãy chọn Thêm tính năng tích hợp đám mây với đám mây trong mục Đám mây với đám mây.

Thêm tính năng tích hợp từ đám mây sang đám mây

Cài đặt Giao diện dòng lệnh (CLI) của Firebase

Giao diện dòng lệnh (CLI) của Firebase sẽ cho phép bạn phân phát các ứng dụng web cục bộ và triển khai ứng dụng web của bạn cho dịch vụ lưu trữ Firebase.

Để cài đặt CLI, hãy chạy lệnh npm sau đây trong thiết bị đầu cuối:

npm install -g firebase-tools

Để xác minh rằng bạn đã cài đặt CLI đúng cách, hãy chạy:

firebase --version

Uỷ quyền cho Giao diện dòng lệnh (CLI) của Firebase bằng Tài khoản Google của bạn bằng cách chạy:

firebase login

Bật HomeGraph API

HomeGraph API cho phép lưu trữ và truy vấn các thiết bị cũng như trạng thái của chúng trong Home Graph của người dùng. Để sử dụng API này, trước tiên bạn phải mở Google Cloud Console và bật HomeGraph API.

Trong Google Cloud Console, hãy nhớ chọn dự án khớp với <project-id>. của quá trình tích hợp. Sau đó, trong màn hình Thư viện API cho HomeGraph API, hãy nhấp vào Bật.

5SVCzM8IZLi_9DV8M0nEklv16NXkpvM0bIzQK2hSyKyvnFHBxPOz90rbr72ayxzmxd5aNROOqC_Cp4outbdlwJdObDs0DIE_8vYzw6dovoVrP9IZWlWsZxDS7UHOi1jiRbDMG8MqUA

3. Chạy ứng dụng khởi đầu

Giờ đây, sau khi thiết lập môi trường phát triển, bạn có thể triển khai dự án bắt đầu để xác minh rằng mọi thứ đã được định cấu hình đúng cách.

Lấy mã nguồn

Nhấp vào đường liên kết sau đây để tải mẫu cho lớp học lập trình này xuống máy phát triển của bạn:

...hoặc bạn có thể sao chép kho lưu trữ GitHub từ dòng lệnh:

git clone https://github.com/google-home/smarthome-local.git

Giới thiệu về dự án

Dự án khởi đầu chứa các thư mục con sau:

  • public– Giao diện người dùng web trên giao diện người dùng để kiểm soát và giám sát máy giặt thông minh
  • functions – Cloud Functions triển khai tính năng thực hiện đơn hàng trên đám mây cho chế độ tích hợp Từ đám mây sang đám mây
  • local– Dự án ứng dụng thực hiện đơn hàng tại địa phương cơ bản với các trình xử lý ý định được tạo sẵn index.ts

Dịch vụ thực hiện đơn hàng qua đám mây mà bạn cung cấp bao gồm các chức năng sau trong index.js:

  • fakeauth – Điểm cuối uỷ quyền để liên kết tài khoản
  • faketoken – Điểm cuối mã thông báo để liên kết tài khoản
  • smarthome – Điểm cuối thực hiện ý định cho nhà thông minh
  • reportstate – Gọi HomeGraph API khi có thay đổi về trạng thái thiết bị
  • updateDevice – Điểm cuối mà thiết bị ảo dùng để kích hoạt Trạng thái báo cáo

Kết nối với Firebase

Chuyển đến thư mục app-start, sau đó thiết lập Firebase CLI bằng dự án tích hợp Đám mây với đám mây:

cd app-start
firebase use <project-id>

Định cấu hình dự án Firebase

Khởi chạy một dự án Firebase.

firebase init

Chọn các tính năng CLI, Realtime Database và tính năng Functions.

? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter
 to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to
 proceed)
>( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore
 ( ) Genkit: Setup a new Genkit project with Firebase
 (*) Functions: Configure a Cloud Functions directory and its files
 ( ) App Hosting: Configure an apphosting.yaml file for App Hosting
 ( ) Hosting: Configure files for Firebase Hosting and (optionally) 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
 (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision
default instance
 ( ) Data Connect: Set up a Firebase Data Connect service
 ( ) Firestore: Configure security rules and indexes files for Firestore

Thao tác này sẽ khởi chạy các API và tính năng cần thiết cho dự án của bạn.

Khi được nhắc, hãy khởi chạy Cơ sở dữ liệu theo thời gian thực. Bạn có thể sử dụng vị trí mặc định cho phiên bản cơ sở dữ liệu.

? 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

Vì bạn đang sử dụng mã dự án khởi đầu, hãy chọn tệp mặc định cho Quy tắc bảo mật và đảm bảo bạn không ghi đè tệp quy tắc cơ sở dữ liệu hiện có.

? 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

Nếu bạn đang khởi động lại dự án, hãy chọn Ghi đè khi được hỏi liệu bạn có muốn khởi động hay ghi đè một cơ sở mã hay không.

? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

Khi định cấu hình các Hàm, bạn nên sử dụng các tệp mặc định và đảm bảo rằng bạn không ghi đè các tệp index.jspackage.json hiện có trong mẫu dự án.

? 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

Nếu bạn đang khởi động lại dự án, hãy chọn Không khi được hỏi liệu bạn có muốn khởi động hoặc ghi đè các hàm/.gitignore hay không.

? File functions/.gitignore already exists. Overwrite?
No
? Do you want to install dependencies with npm now?
Yes

Nếu bạn vô tình bật ESLint, bạn có thể tắt công cụ này bằng hai phương thức sau:

  1. Sử dụng GUI, hãy chuyển đến thư mục ../functions trong dự án, chọn tệp ẩn .eslintrc.js rồi xoá tệp đó. Đừng nhầm lẫn với .eslintrc.json có tên tương tự.
  2. Sử dụng dòng lệnh:
    cd functions
    rm .eslintrc.js
    

Để đảm bảo bạn có cấu hình Firebase chính xác và đầy đủ, hãy sao chép tệp firebase.json từ thư mục washer-done sang thư mục washer-start, ghi đè tệp trong washer-start.

Trong thư mục washer-start:

cp -vp ../washer-done/firebase.json .

Triển khai lên Firebase

Giờ đây, bạn đã cài đặt các phần phụ thuộc và định cấu hình dự án, bạn đã sẵn sàng chạy ứng dụng lần đầu tiên.

firebase deploy

Đây là kết quả đầu ra của bảng điều khiển mà bạn sẽ thấy:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

Lệnh này triển khai một ứng dụng web, cùng với một số Cloud Functions cho Firebase.

Mở URL lưu trữ trong trình duyệt (https://<project-id>.web.app) để xem ứng dụng web. Bạn sẽ thấy giao diện sau:

L60eA7MOnPmbBMl2XMipT9MdnP-RaVjyjf0Y93Y1b7mEyIsqZrrwczE7D3RQISRs-iusL1g4XbNmGhuA6-5sLcWefnczwNJEPfNLtwBsO4Tb9YvcAZBI6_rX19z8rxbik9Vq8F2fwg

Giao diện người dùng web này đại diện cho một nền tảng bên thứ ba để xem hoặc sửa đổi trạng thái thiết bị. Để bắt đầu điền thông tin thiết bị vào cơ sở dữ liệu, hãy nhấp vào CẬP NHẬT. Bạn sẽ không thấy bất kỳ thay đổi nào trên trang, nhưng trạng thái hiện tại của máy giặt sẽ được lưu trữ trong cơ sở dữ liệu.

Giờ là lúc kết nối dịch vụ đám mây mà bạn đã triển khai với Trợ lý Google bằng Developer Console

Định cấu hình dự án Developer Console

Trên thẻ Phát triển, hãy thêm Tên hiển thị cho hoạt động tương tác của bạn. Tên này sẽ xuất hiện trong ứng dụng Google Home.

Thêm tên hiển thị

Trong phần Thương hiệu ứng dụng, hãy tải một tệp png có kích thước 144 x 144 px và tên là .png lên cho biểu tượng ứng dụng.

Thêm biểu tượng ứng dụng

Để bật chế độ Liên kết tài khoản, hãy sử dụng các chế độ cài đặt liên kết tài khoản sau:

ID khách hàng

ABC123

Mật khẩu ứng dụng khách

DEF456

URL Uỷ quyền

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

URL mã thông báo

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

Cập nhật URL liên kết tài khoản

Trong mục URL thực hiện trên đám mây, hãy nhập URL cho hàm đám mây cung cấp dịch vụ thực hiện cho các ý định nhà thông minh.

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

Thêm URL hàm trên đám mây

Nhấp vào Lưu để lưu cấu hình dự án, sau đó nhấp vào Tiếp theo: Kiểm thử để bật tính năng kiểm thử trên dự án của bạn.

Kiểm thử quá trình tích hợp đám mây với đám mây

Giờ đây, bạn có thể bắt đầu triển khai các webhook cần thiết để kết nối trạng thái thiết bị với Trợ lý.

Để kiểm thử hoạt động tích hợp Đám mây với đám mây, bạn cần liên kết dự án của mình với một Tài khoản Google. Nhờ đó, bạn có thể kiểm thử thông qua các nền tảng của Trợ lý Google và ứng dụng Google Home đã đăng nhập vào cùng một tài khoản.

  1. Trên điện thoại, hãy mở phần cài đặt Trợ lý Google. Xin lưu ý rằng bạn phải đăng nhập bằng cùng một tài khoản như trong bảng điều khiển.
  2. Chuyển đến phần Trợ lý Google > Cài đặt > Điều khiển nhà (trong phần Trợ lý).
  3. Nhấp vào biểu tượng tìm kiếm ở trên cùng bên phải.
  4. Tìm ứng dụng kiểm thử bằng tiền tố [test] để tìm ứng dụng kiểm thử cụ thể của bạn.
  5. Chọn mục đó. Sau đó, Trợ lý Google sẽ xác thực với dịch vụ của bạn và gửi một yêu cầu SYNC, yêu cầu dịch vụ của bạn cung cấp danh sách thiết bị cho người dùng.

Mở ứng dụng Google Home và xác minh rằng bạn có thể thấy thiết bị máy giặt.

XcWmBVamBZtPfOFqtsr5I38stPWTqDcMfQwbBjetBgxt0FCjEs285pa9K3QXSASptw0KYN2G8yfkT0-xg664V4PjqMreDDs-HPegHjOc4EVtReYPu-WKZyygq9Xmkf8X8z9177nBjQ

Xác minh rằng bạn có thể điều khiển máy giặt bằng lệnh thoại trong ứng dụng Google Home. Bạn cũng sẽ thấy trạng thái thiết bị thay đổi trong giao diện người dùng web của dịch vụ thực hiện qua đám mây.

Giờ đây, bạn có thể bắt đầu thêm tính năng thực hiện đơn hàng tại địa phương vào quy trình tích hợp.

4. Cập nhật dịch vụ thực hiện đơn hàng trên đám mây

Để hỗ trợ việc thực hiện đơn hàng tại địa phương, bạn cần thêm một trường mới cho mỗi thiết bị có tên là otherDeviceIds vào phản hồi SYNC trên đám mây. Trường này chứa một giá trị nhận dạng duy nhất tại địa phương cho thiết bị. Trường này cũng cho biết khả năng kiểm soát thiết bị đó tại địa phương.

Thêm trường otherDeviceIds vào phản hồi SYNC như minh hoạ trong đoạn mã sau:

functions/index.js

app.onSync((body) => {
  return {
    requestId: body.requestId,
    payload: {
      agentUserId: '123',
      devices: [{
        id: 'washer',
        type: 'action.devices.types.WASHER',
        traits: [ ... ],
        name: { ... },
        deviceInfo: { ... },
        willReportState: true,
        attributes: {
          pausable: true,
        },
        otherDeviceIds: [{
          deviceId: 'deviceid123',
        }],
      }],
    },
  };
});

Triển khai dự án đã cập nhật lên Firebase:

firebase deploy --only functions

Sau khi quá trình triển khai hoàn tất, hãy chuyển đến giao diện người dùng web rồi nhấp vào nút Làm mớiae8d3b25777a5e30.png trong thanh công cụ. Thao tác này sẽ kích hoạt thao tác Request Sync (Yêu cầu đồng bộ hoá) để Trợ lý nhận được dữ liệu phản hồi SYNC đã cập nhật.

bf4f6a866160a982.png

5. Định cấu hình tính năng thực hiện đơn hàng tại địa phương

Trong phần này, bạn sẽ thêm các lựa chọn cấu hình cần thiết cho tính năng thực hiện đơn hàng tại địa phương vào chế độ tích hợp từ đám mây sang đám mây. Trong quá trình phát triển, bạn sẽ xuất bản ứng dụng thực hiện tại địa phương lên Firebase Hosting, nơi thiết bị Google Home có thể truy cập và tải ứng dụng xuống.

Trong Google Home Developer Console, hãy chuyển đến Project > Cloud-to-cloud (Dự án > Đám mây với đám mây) ở bên trái màn hình, sau đó chọn Edit (Chỉnh sửa) cho hoạt động tích hợp. Trên trang Thiết lập và định cấu hình, hãy di chuyển đến mục Thực hiện đơn hàng tại địa phương rồi bật chế độ cài đặt này. Nhập URL sau đây vào từng trường URL kiểm thử, chèn mã dự án của bạn rồi nhấp vào Lưu:

https://<project-id>.web.app/local-home/index.html

local-fulfillment.png

Tiếp theo, chúng ta cần xác định cách thiết bị Google Home phát hiện các thiết bị thông minh tại địa phương. Nền tảng Local Home hỗ trợ một số giao thức để phát hiện thiết bị, bao gồm mDNS, UPnP và thông báo UDP. Bạn sẽ dùng thông báo UDP để phát hiện máy giặt thông minh.

Nhấp vào + Add scan configuration (Thêm cấu hình quét) trong mục Device discovery (Phát hiện thiết bị) để thêm một cấu hình quét mới. Chọn UDP làm giao thức và điền các thuộc tính sau:

Trường

Nội dung mô tả

Giá trị đề xuất

Địa chỉ khám phá

Địa chỉ khám phá UDP

255.255.255.255

Cổng truyền tin

Cổng mà Google Home gửi thông báo UDP

3311

Cổng nghe

Cổng mà Google Home dùng để chờ phản hồi

3312

Gói khám phá

Tải trọng dữ liệu truyền tin UDP

48656c6c6f4c6f63616c486f6d6553444b

device-discovery.png

Cuối cùng, hãy nhấp vào Lưu ở cuối cửa sổ để xuất bản các thay đổi.

6. Triển khai phương thức thực hiện tại địa phương

Bạn sẽ phát triển ứng dụng thực hiện đơn hàng tại địa phương bằng TypeScript bằng cách sử dụng gói định kiểu Local Home SDK. Xem cấu trúc được cung cấp trong dự án khởi đầu:

local/index.ts

/// <reference types="@google/local-home-sdk" />

import App = smarthome.App;
import Constants = smarthome.Constants;
import DataFlow = smarthome.DataFlow;
import Execute = smarthome.Execute;
import Intents = smarthome.Intents;
import IntentFlow = smarthome.IntentFlow;

...

class LocalExecutionApp {

  constructor(private readonly app: App) { }

  identifyHandler(request: IntentFlow.IdentifyRequest):
      Promise<IntentFlow.IdentifyResponse> {
    // TODO: Implement device identification
  }

  executeHandler(request: IntentFlow.ExecuteRequest):
      Promise<IntentFlow.ExecuteResponse> {
    // TODO: Implement local fulfillment
  }

  ...
}

const localHomeSdk = new App('1.0.0');
const localApp = new LocalExecutionApp(localHomeSdk);
localHomeSdk
  .onIdentify(localApp.identifyHandler.bind(localApp))
  .onExecute(localApp.executeHandler.bind(localApp))
  .listen()
  .then(() => console.log('Ready'))
  .catch((e: Error) => console.error(e));

Thành phần cốt lõi của tính năng thực hiện đơn hàng tại địa phương là lớp smarthome.App. Dự án khởi đầu sẽ đính kèm các trình xử lý cho ý định IDENTIFYEXECUTE, sau đó gọi phương thức listen() để thông báo cho Local Home SDK rằng ứng dụng đã sẵn sàng.

Thêm trình xử lý IDENTIFY

Local Home SDK sẽ kích hoạt trình xử lý IDENTIFY khi thiết bị Google Home phát hiện thấy các thiết bị chưa được xác minh trên mạng cục bộ dựa trên cấu hình quét được cung cấp trong Developer Console.

Trong khi đó, nền tảng sẽ gọi identifyHandler bằng dữ liệu quét thu được khi Google phát hiện thấy một thiết bị phù hợp. Trong ứng dụng của bạn, quá trình quét diễn ra bằng cách sử dụng một thông báo truyền tin UDP và dữ liệu quét được cung cấp cho trình xử lý IDENTIFY bao gồm cả tải trọng phản hồi do thiết bị cục bộ gửi.

Trình xử lý này trả về một thực thể IdentifyResponse chứa giá trị nhận dạng duy nhất cho thiết bị cục bộ. Thêm mã sau vào phương thức identifyHandler để xử lý phản hồi UDP đến từ thiết bị cục bộ và xác định mã thiết bị cục bộ thích hợp:

local/index .ts

identifyHandler(request: IntentFlow.IdentifyRequest):
    Promise<IntentFlow.IdentifyResponse> {
  console.log("IDENTIFY intent: " + JSON.stringify(request, null, 2));

  const scanData = request.inputs[0].payload.device.udpScanData;
  if (!scanData) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_request', 'Invalid scan data');
    return Promise.reject(err);
  }

  // In this codelab, the scan data contains only local device ID.
  const localDeviceId = Buffer.from(scanData.data, 'hex');

  const response: IntentFlow.IdentifyResponse = {
    intent: Intents.IDENTIFY,
    requestId: request.requestId,
    payload: {
      device: {
        id: 'washer',
        verificationId: localDeviceId.toString(),
      }
    }
  };
  console.log("IDENTIFY response: " + JSON.stringify(response, null, 2));

  return Promise.resolve(response);
}

Xin lưu ý rằng trường verificationId phải khớp với một trong các giá trị otherDeviceIds trong phản hồi SYNC, trường này sẽ gắn cờ thiết bị là có thể thực hiện tại địa phương trong Home Graph của người dùng. Sau khi Google tìm thấy một thiết bị trùng khớp, thiết bị đó sẽ được coi là đã xác minh và sẵn sàng để thực hiện đơn đặt hàng tại địa phương.

Thêm trình xử lý EXECUTE

Local Home SDK sẽ kích hoạt trình xử lý EXECUTE khi một thiết bị hỗ trợ tính năng thực hiện yêu cầu tại nhà nhận được lệnh. Nội dung của ý định cục bộ tương đương với ý định EXECUTE được gửi đến dịch vụ thực hiện trên đám mây của bạn, vì vậy, logic để xử lý ý định cục bộ tương tự như cách bạn xử lý ý định đó trên đám mây.Actions

Ứng dụng có thể sử dụng các socket TCP/UDP hoặc yêu cầu HTTP(S) để giao tiếp với các thiết bị cục bộ. Trong lớp học lập trình này, HTTP đóng vai trò là giao thức dùng để điều khiển thiết bị ảo. Số cổng được xác định trong index.ts dưới dạng biến SERVER_PORT.

Thêm mã sau vào phương thức executeHandler để xử lý các lệnh đến và gửi các lệnh đó đến thiết bị cục bộ qua HTTP:

local/index.ts

executeHandler(request: IntentFlow.ExecuteRequest):
    Promise<IntentFlow.ExecuteResponse> {
  console.log("EXECUTE intent: " + JSON.stringify(request, null, 2));

  const command = request.inputs[0].payload.commands[0];
  const execution = command.execution[0];
  const response = new Execute.Response.Builder()
    .setRequestId(request.requestId);

  const promises: Array<Promise<void>> = command.devices.map((device) => {
    console.log("Handling EXECUTE intent for device: " + JSON.stringify(device));

    // Convert execution params to a string for the local device
    const params = execution.params as IWasherParams;
    const payload = this.getDataForCommand(execution.command, params);

    // Create a command to send over the local network
    const radioCommand = new DataFlow.HttpRequestData();
    radioCommand.requestId = request.requestId;
    radioCommand.deviceId = device.id;
    radioCommand.data = JSON.stringify(payload);
    radioCommand.dataType = 'application/json';
    radioCommand.port = SERVER_PORT;
    radioCommand.method = Constants.HttpOperation.POST;
    radioCommand.isSecure = false;

    console.log("Sending request to the smart home device:", payload);

    return this.app.getDeviceManager()
      .send(radioCommand)
      .then(() => {
        const state = {online: true};
        response.setSuccessState(device.id, Object.assign(state, params));
        console.log(`Command successfully sent to ${device.id}`);
      })
      .catch((e: IntentFlow.HandlerError) => {
        e.errorCode = e.errorCode || 'invalid_request';
        response.setErrorState(device.id, e.errorCode);
        console.error('An error occurred sending the command', e.errorCode);
      });
  });

  return Promise.all(promises)
    .then(() => {
      return response.build();
    })
    .catch((e) => {
      const err = new IntentFlow.HandlerError(request.requestId,
          'invalid_request', e.message);
      return Promise.reject(err);
    });
}

Biên dịch ứng dụng TypeScript

Chuyển đến thư mục local/ rồi chạy các lệnh sau để tải trình biên dịch TypeScript xuống và biên dịch ứng dụng:

cd local
npm install
npm run build

Thao tác này sẽ biên dịch nguồn index.ts (TypeScript) và đặt nội dung sau vào thư mục public/local-home/:

  • bundle.js – Đầu ra JavaScript đã biên dịch chứa ứng dụng cục bộ và các phần phụ thuộc.
  • index.html – Trang lưu trữ cục bộ dùng để phân phát ứng dụng cho hoạt động kiểm thử trên thiết bị.

Triển khai dự án kiểm thử

Triển khai các tệp dự án đã cập nhật lên Firebase Hosting để bạn có thể truy cập vào các tệp đó từ thiết bị Google Home.

firebase deploy --only hosting

7. Khởi động máy giặt thông minh

Bây giờ là lúc bạn cần kiểm thử hoạt động giao tiếp giữa ứng dụng thực hiện đơn hàng tại địa phương và máy giặt thông minh! Dự án khởi đầu của lớp học lập trình này bao gồm một máy giặt thông minh ảo (được viết bằng Node.js) mô phỏng một máy giặt thông minh mà người dùng có thể kiểm soát cục bộ.

Định cấu hình thiết bị

Bạn cần định cấu hình thiết bị ảo để sử dụng cùng các thông số UDP mà bạn đã áp dụng cho cấu hình quét để phát hiện thiết bị trong Developer Console. Ngoài ra, bạn cần cho thiết bị ảo biết mã thiết bị cục bộ nào cần báo cáo và mã dự án của tính năng tích hợp Đám mây với đám mây cần dùng cho các sự kiện Báo cáo trạng thái khi trạng thái thiết bị thay đổi.

Tham số

Giá trị đề xuất

deviceId

deviceid123

discoveryPortOut

3311

discoveryPacket

HelloLocalHomeSDK

projectId

Mã dự án của chế độ tích hợp Đám mây với đám mây

Khởi động thiết bị

Chuyển đến thư mục virtual-device/ và chạy tập lệnh thiết bị, truyền các tham số cấu hình dưới dạng đối số:

cd virtual-device
npm install
npm start -- \
  --deviceId=deviceid123 --projectId=<project-id> \
  --discoveryPortOut=3311 --discoveryPacket=HelloLocalHomeSDK

Xác minh rằng tập lệnh thiết bị chạy với các tham số dự kiến:

(...): UDP Server listening on 3311
(...): Device listening on port 3388
(...): Report State successful

8. Gỡ lỗi ứng dụng TypeScript

Trong phần sau, bạn sẽ xác minh rằng thiết bị Google Home có thể quét, xác định và gửi lệnh đến máy giặt thông minh ảo một cách thích hợp qua mạng cục bộ. Bạn có thể sử dụng Công cụ dành cho nhà phát triển trên Google Chrome để kết nối với thiết bị Google Home, xem nhật ký bảng điều khiển và gỡ lỗi ứng dụng TypeScript.

Kết nối Công cụ cho nhà phát triển Chrome

Để kết nối trình gỡ lỗi với ứng dụng thực hiện cục bộ, hãy làm theo các bước sau:

  1. Đảm bảo rằng bạn đã liên kết thiết bị Google Home với một người dùng có quyền truy cập vào dự án Developer Console.
  2. Khởi động lại thiết bị Google Home để thiết bị có thể lấy URL của HTML cũng như cấu hình quét mà bạn đặt trong Developer Console.
  3. Khởi chạy Chrome trên máy phát triển của bạn.
  4. Mở một thẻ mới trong Chrome rồi nhập chrome://inspect vào trường địa chỉ để chạy trình kiểm tra.

Bạn sẽ thấy danh sách thiết bị trên trang và URL ứng dụng của bạn sẽ xuất hiện bên dưới tên thiết bị Google Home.

567f97789a7d8846.png

Khởi chạy trình kiểm tra

Nhấp vào Kiểm tra trong URL ứng dụng của bạn để chạy Công cụ cho nhà phát triển Chrome. Chọn thẻ Console (Bảng điều khiển) và xác minh rằng bạn có thể thấy nội dung của ý định IDENTIFY do ứng dụng TypeScript của bạn in.

6b67ded470a4c8be.png

Đầu ra này có nghĩa là ứng dụng thực hiện đơn hàng tại địa phương đã tìm thấy và xác định thành công thiết bị ảo.

Kiểm thử tính năng thực hiện đơn hàng tại địa phương

Gửi lệnh đến thiết bị bằng cách dùng các nút điều khiển cảm ứng trong ứng dụng Google Home hoặc thông qua lệnh thoại cho thiết bị Google Home, chẳng hạn như:

"Ok Google, bật máy giặt."

"Ok Google, khởi động máy giặt."

"Ok Google, dừng máy giặt."

Thao tác này sẽ kích hoạt nền tảng gửi một ý định EXECUTE đến ứng dụng TypeScript của bạn.

bc030517dacc3ac9.png

Xác minh rằng bạn có thể thấy trạng thái của máy giặt thông minh tại địa phương thay đổi theo từng lệnh.

...
***** The washer is RUNNING *****
...
***** The washer is STOPPED *****

9. Xin chúc mừng

764dbc83b95782a.png

Xin chúc mừng! Bạn đã sử dụng Local Home SDK để tích hợp tính năng thực hiện đơn hàng tại địa phương vào một hệ thống tích hợp Cloud-to-cloud.

Tìm hiểu thêm

Bạn có thể thử một số cách khác như sau:

  • Thay đổi cấu hình quét để hoạt động. Ví dụ: hãy thử dùng một cổng UDP hoặc gói khám phá khác.
  • Sửa đổi cơ sở mã của thiết bị thông minh ảo để chạy trên một thiết bị nhúng (chẳng hạn như Raspberry Pi) và sử dụng đèn LED hoặc màn hình để hình dung trạng thái hiện tại.