Gỡ lỗi Home chính

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

Tích hợp nhà thông minh cho phép Trợ lý Google điều khiển các thiết bị thông minh trong nhà của người dùng. Để xây dựng một Hành động nhà thông minh, 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 chính về nhà thông minh. Ví dụ: khi người dùng nói: "Ok Google, hãy bật các đèn", Trợ lý sẽ ra lệnh gửi yêu cầu thực hiện đám mây của bạn để cập nhật trạng thái của thiết bị.

SDK Nội bộ gia đình nâng cao khả năng tích hợp nhà thông minh của bạn bằng cách thêm đường dẫn cục bộ để định tuyến ý định nhà thông minh trực tiếp đến 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. Dịch vụ này cho phép bạn viết và triển khai ứng dụng thực hiện cục bộ trong TypeScript hoặc JavaScript giúp xác định thiết bị và thực thi lệnh trên màn hình thông minh Google Home hoặc màn hình thông minh Google Nest bất kỳ. Sau đó, ứng dụng 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 chuẩn hiện có để thực hiện lệnh.

72ffb320986092c.png.

Gỡ lỗi cho Hành động nhà thông minh là một bước tối quan trọng để xây dựng Hành động bằng chất lượng sản xuất. Tuy nhiên, việc này sẽ khó khăn và tốn thời gian khi không có công cụ kiểm tra và khắc phục sự cố hữu ích, cung cấp nhiều thông tin. Để hỗ trợ gỡ lỗi cho Hành động dành cho nhà thông minh, chúng tôi cung cấp Chỉ số, Ghi nhật kýBộ thử nghiệm cho nhà thông minh của Google Cloud Platform (GCP) nhằm giúp bạn xác định và giải quyết các vấn đề liên quan đến Hành động của bạn.

Đ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ẽ xây dựng một phương thức thực hiện cục bộ cho Hành động nhà thông minh và kết nối ứng dụng đó với Trợ lý, sau đó gỡ lỗi ứng dụng Local Home thông qua Bộ thử nghiệm cho tính năng Ghi nhật ký và các chỉ số của Google Cloud Platform (GCP) và nhà thông minh.

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

  • Cách sử dụng Chỉ số và ghi nhật ký GCP để xác định và giải quyết các vấn đề sản xuất.
  • Cách sử dụng Bộ thử nghiệm để xác định các vấn đề về chức năng và API.
  • Cách sử dụng Công cụ dành cho nhà phát triển Chrome trong khi phát triển ứng dụng Local Home.

Bạn cần có

2. Chạy ứng dụng máy giặt

Lấy mã nguồn

Nhấp vào đường liên kết sau để tải mẫu dành cho lớp học lập trình này xuống máy phát triể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-debug-local.git

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

Ứng dụng khởi động chứa các thư mục con và chức năng đám mây tương tự như lớp học lập trình Bật thực hiện đơn hàng cục bộ cho Hành động dành cho nhà thông minh. Tuy nhiên, thay vì app-start, chúng ta có app-faulty ở đây. Chúng ta sẽ bắt đầu với một ứng dụng tại nhà hoạt động tốt nhưng không hiệu quả.

Kết nối với Firebase

Chúng tôi sẽ sử dụng cùng một dự án mà bạn đã tạo trong lớp học lập trình Bật tính năng thực hiện cục bộ cho Hành động dành cho nhà thông minh, nhưng chúng tôi sẽ triển khai các tệp đã tải xuống trong lớp học lập trình này.

Chuyển đến thư mục app-faulty, sau đó thiết lập Giao diện dòng lệnh (CLI) của Firebase bằng dự án Hành động đã tạo trong lớp học lập trình Bật tính năng thực hiện cục bộ cho Hành động dành cho nhà thông minh:

$ cd app-faulty
$ firebase use <project-id>

Triển khai cho Firebase

Chuyển đến thư mục app-faulty/functions và cài đặt tất cả các phần phụ thuộc cần thiết bằng npm:

$ cd functions
$ npm install

Lưu ý: Nếu thấy thông báo bên dưới, bạn có thể bỏ qua và tiếp tục. Cảnh báo là do một số phần phụ thuộc cũ hơn và bạn có thể tìm thêm chi tiết tại đây.

found 5 high severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

Chuyển đến thư mục app-faulty/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 các nội dung sau vào thư mục app-faulty/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 nhằm thử nghiệm trên thiết bị.

Sau khi 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ả 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://<projectcd -id>.web.app

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

Cập nhật HomeGraph

Mở URL lưu trữ trong trình duyệt của bạn (https://<project-id>.web.app) để xem ứng dụng web. Trên giao diện người dùng web, hãy nhấp vào nút Làm mới ae8d3b25777a5e30.png. để cập nhật HomeGraph qua Yêu cầu đồng bộ hóa với siêu dữ liệu mới nhất của thiết bị từ ứng dụng máy giặt bị lỗi:

fa3c47f293cfe0b7.png

Mở ứng dụng Google Home và xác minh rằng bạn có thể nhìn thấy thiết bị giặt là của mình bằng tên mới là "Máy giặt gặp lỗi". Hãy nhớ chỉ định thiết bị cho một phòng có thiết bị Nest.

2a082ee11d47ad1a.png

3. Bật máy giặt thông minh

Nếu đã chạy lớp học lập trình Bật phương thức thực hiện cục bộ cho Hành động dành cho nhà thông minh, thì bạn đã bắt đầu máy giặt thông minh ảo. Nếu thiết bị đã dừng, hãy nhớ khởi động lại thiết bị ảo.

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

4. Thử nghiệm ứng dụng Home

Gửi lệnh đến thiết bị của bạn thông qua lệnh thoại tới 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 cho tôi."

"Ok Google, bắt buộc dùng cục bộ."

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

Bạn sẽ thấy Trợ lý Google phản hồi với nội dung "Rất tiếc, có vẻ như Máy giặt bị lỗi hiện không hoạt động" khi bạn cố điều khiển máy giặt sau khi "buộc cục bộ".

Điều này có nghĩa là thiết bị không thể truy cập được qua đường dẫn cục bộ. Tính năng này hoạt động trước khi đưa ra yêu cầu "Ok Google, buộc cục bộ" vì chúng ta sẽ quay lại sử dụng đường dẫn đám mây khi không thể truy cập thiết bị thông qua đường dẫn cục bộ. Tuy nhiên, sau khi "buộc cục bộ", tùy chọn quay lại đường dẫn đám mây bị tắt.

Để tìm hiểu xem vấn đề là gì, hãy sử dụng các công cụ mà chúng tôi có: Chỉ số Google Cloud Platform (GCP), Nhật ký và Công cụ dành cho nhà phát triển Chrome.

5. Gỡ lỗi ứng dụng Local Home

Trong phần sau, bạn sẽ sử dụng các công cụ do Google cung cấp để tìm hiểu lý do không thể truy cập thiết bị qua đường dẫn cục bộ. Bạn có thể sử dụng Công cụ dành cho nhà phát triể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 Home. Bạn cũng có thể gửi nhật ký tùy chỉnh đến Nhật ký đám mây để có thể nhận biết các lỗi hàng đầu mà người dùng của bạn đang tìm thấy trong ứng dụng Local Home.

Kết nối Công cụ dành 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 đơn hàng trên máy, 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 Bảng điều khiển Actions.
  2. Khởi động lại thiết bị Google Home để thiết bị này có được URL của HTML cũng như cấu hình quét mà bạn đặt trong bảng điều khiển Actions.
  3. Khởi chạy Chrome trên máy phát triển của bạn.
  4. Mở thẻ Chrome mới rồi nhập chrome://inspect vào trường địa chỉ để mở 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 dưới tên của 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 để khởi chạy Công cụ dành 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ể xem nội dung của ý định IDENTIFY do ứng dụng TypeScript in.

774c460c59f9f84a.png.

Kết quả này có nghĩa là trình xử lý IDENTIFY đã được kích hoạt thành công, nhưng verificationId được trả về trong IdentifyResponse không khớp với bất kỳ thiết bị nào trong HomeGraph của bạn. Hãy thêm một số nhật ký tuỳ chỉnh để tìm hiểu lý do.

Thêm nhật ký tuỳ chỉnh

Mặc dù SDK Trang chủ cục bộ gặp lỗi DEVICE_VERIFICATION_FAILED nhưng lỗi này không giúp ích nhiều trong việc tìm ra nguyên nhân gốc rễ. Hãy thêm một số nhật ký tuỳ chỉnh để đảm bảo chúng ta đang đọc và xử lý dữ liệu quét đúng cách. Xin lưu ý rằng nếu từ chối lời hứa kèm theo lỗi, thông báo lỗi thực sự cũng sẽ được gửi tới Cloud Logging.

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.
  // Is there something wrong here?
  const localDeviceId = Buffer.from(scanData.data);
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  // Add custom logs
  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
        'invalid_device', 'Invalid device id from scan data ' +
        localDeviceId);
    return Promise.reject(err);
  }

  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);
}

Ngoài ra, hãy thay đổi phiên bản ứng dụng cục bộ để chúng tôi có thể xác định xem mình có đang sử dụng đúng phiên bản hay không.

local/index.ts

const localHomeSdk = new App('1.0.1');

Sau khi thêm nhật ký tùy chỉnh, bạn cần biên dịch lại ứng dụng và triển khai lại cho Firebase.

$ cd ../app-faulty/local
$ npm run build
$ firebase deploy --only hosting

Bây giờ, hãy khởi động lại thiết bị Google Home để thiết bị có thể tải ứng dụng Home đã cập nhật. Bạn có thể xem thiết bị Google Home có đang sử dụng phiên bản mong muốn hay không bằng cách xem nhật ký Console trong Công cụ dành cho nhà phát triển Chrome.

ecc56508ebcf9ab.png

Truy cập vào nhật ký trên đám mây

Hãy tìm hiểu cách sử dụng tính năng Ghi nhật ký trên đám mây để tìm lỗi của bạn. Cách truy cập vào tính năng ghi nhật ký trên đám mây cho dự án của bạn:

  1. Truy cập vào trang Dự án trong bảng điều khiển Cloud Platform.
  2. Chọn dự án nhà thông minh của bạn.
  3. Trong mục Thao tác, hãy chọn Ghi nhật ký > Trình khám phá nhật ký.

Người dùng dự án Hành động của bạn sẽ được quản lý quyền truy cập vào dữ liệu ghi nhật ký thông qua tính năng Quản lý danh tính và quyền truy cập (IAM). Để biết thêm thông tin chi tiết về các vai trò và quyền đối với việc ghi nhật ký dữ liệu, hãy xem phần kiểm soát quyền truy cập của tính năng ghi nhật ký trên đám mây.

Sử dụng bộ lọc nâng cao

Chúng ta biết rằng lỗi xảy ra trong ý định IDENTIFY, vì đường dẫn cục bộ không hoạt động vì thiết bị cục bộ không xác định được. Tuy nhiên, chúng ta muốn biết chính xác vấn đề là gì, vì vậy trước tiên, hãy lọc ra các lỗi xảy ra trong trình xử lý IDENTIFY.

Mở rộng hộp Xem trước truy vấn, hộp này sẽ chuyển thành hộp Trình tạo truy vấn. Nhập jsonPayload.intent="IDENTIFY" vào hộp Trình tạo truy vấn và nhấp vào nút Chạy truy vấn.

4c0b9d2828ee2447.png.

Do đó, bạn sẽ nhận được tất cả nhật ký lỗi được gửi vào trình xử lý IDENTIFY. Tiếp theo, mở rộng lỗi cuối cùng. Bạn sẽ tìm thấy errorCodedebugString mà bạn vừa thiết lập khi từ chối lời hứa trong trình xử lý IDENTIFY.

71f2f156c6887496.png.

Từ debugString, chúng ta có thể biết được mã thiết bị cục bộ có định dạng không như dự kiến. Ứng dụng Home sẽ nhận mã thiết bị cục bộ ở dạng chuỗi bắt đầu bằng deviceid, theo sau là 3 chữ số nhưng mã thiết bị cục bộ ở đây là một chuỗi hex.

Sửa lỗi

Quay lại mã nguồn nơi chúng tôi phân tích cú pháp mã thiết bị cục bộ từ dữ liệu quét, chúng tôi nhận thấy rằng chúng tôi đã không cung cấp mã hóa khi chuyển đổi chuỗi thành byte. Dữ liệu quét nhận được dưới dạng chuỗi hex, vì vậy hãy truyền hex dưới dạng mã hóa ký tự khi gọi Buffer.from().

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');
  console.log(`IDENTIFY handler: received local device id
      ${localDeviceId}`);

  if (!localDeviceId.toString().match(/^deviceid[0-9]{3}$/gi)) {
    const err = new IntentFlow.HandlerError(request.requestId,
      'invalid_device', 'Invalid device id from scan data ' +
      localDeviceId);
    return Promise.reject(err);
  }

  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);
}

Ngoài ra, hãy thay đổi phiên bản ứng dụng cục bộ để chúng tôi có thể xác định xem mình có đang sử dụng đúng phiên bản hay không.

local/index.ts

const localHomeSdk = new App('1.0.2');

Sau khi khắc phục lỗi, hãy biên dịch ứng dụng và triển khai lại sang Firebase. Trong app-faulty/local, hãy chạy:

$ npm run build
$ firebase deploy --only hosting

Kiểm tra bản sửa lỗi của bạn

Sau khi triển khai, hãy khởi động lại thiết bị Google Home để thiết bị có thể tải ứng dụng Home mới cập nhật. Đảm bảo phiên bản ứng dụng Home cục bộ là 1.0.2 và lần này bạn sẽ không thấy lỗi trong Bảng điều khiển Công cụ dành cho nhà phát triển Chrome.

c8456f7b5f77f894.png

Bây giờ, bạn có thể thử gửi lại lệnh đến thiết bị của mình.

"Ok Google, bắt buộc bật."

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

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

...

"Ok Google, buộc dùng mật khẩu mặc định."

6. Chạy Bộ thử nghiệm cho nhà thông minh

Sau khi xác minh thiết bị của bạn bằng điều khiển cảm ứng trong ứng dụng Google Home hoặc thông qua lệnh thoại, bạn có thể sử dụng Bộ thử nghiệm dành cho nhà thông minh tự động để xác thực các trường hợp sử dụng dựa trên loại thiết bị và đặc điểm liên quan đến Hành động của bạn. Bộ thử nghiệm chạy một loạt các thử nghiệm để phát hiện sự cố trong Hành động của bạn và hiển thị thông báo cung cấp thông tin cho các trường hợp thử nghiệm không thành công để đẩy nhanh quá trình gỡ lỗi trước khi đi sâu vào nhật ký sự kiện.

Chạy Bộ thử nghiệm cho nhà thông minh

Hãy làm theo các hướng dẫn sau để kiểm tra Hành động cho nhà thông minh của bạn bằng Bộ thử nghiệm:

  1. Trong trình duyệt web, hãy mở Bộ thử nghiệm cho nhà thông minh.
  2. Đăng nhập vào Google bằng cách sử dụng nút ở góc trên cùng bên phải. Điều này cho phép Bộ thử nghiệm gửi lệnh trực tiếp đến Trợ lý Google.
  3. Trong trường Mã dự án, hãy nhập mã dự án cho Hành động nhà thông minh của bạn. Sau đó, nhấp vào TIẾP THEO để tiếp tục.
  4. Trong bước Test Settings (Cài đặt thử nghiệm), bạn sẽ thấy Trình vệ sinh bị lỗi trong phần Thiết bị và Trais.
  5. Tắt tùy chọn Thử nghiệm yêu cầu đồng bộ hóa vì ứng dụng máy giặt mẫu không có giao diện người dùng để thêm / xóa / đổi tên máy giặt. Trong hệ thống sản xuất, bạn phải kích hoạt Yêu cầu đồng bộ hóa bất cứ khi nào người dùng thêm / xóa / đổi tên thiết bị.
  6. Bật tùy chọn Local Home SDK vì chúng tôi sẽ thử nghiệm cả đường dẫn cục bộ và đường dẫn đám mây.
  7. Nhấp vào TIẾP THEO để bắt đầu chạy kiểm thử.

67433d9190fa770e.png.

Khi các kiểm thử đã hoàn tất, bạn sẽ nhận thấy các kiểm thử Tạm dừng/Tiếp tục trong đường dẫn cục bộ đều không thành công trong khi các kiểm thử Tạm dừng/Tiếp tục trong đường dẫn trên đám mây đang vượt qua.

d1ebd5cfae2a2a47.png.

Thông báo lỗi phân tích

Hãy xem xét kỹ các thông báo lỗi trong các trường hợp kiểm thử không thành công. Chúng cho bạn biết trạng thái dự kiến cho kiểm thử đó và trạng thái thực tế. Trong trường hợp này, đối với "Pause the Washer", trạng thái dự kiến là isPaused: true, nhưng trong trạng thái thực tế, chúng ta nhận được isPaused: false. Tương tự, đối với "Pause the Washer", trạng thái dự kiến là isPaused: true, nhưng trong trạng thái thực tế, chúng ta nhận được isPaused: false.

6bfd3acef9c16b84.png.

Từ thông báo lỗi, có vẻ như trong đường dẫn cục bộ, chúng ta sẽ đặt trạng thái isPaused theo cách ngược lại.

Xác định và khắc phục lỗi

Hãy tìm mã nguồn nơi ứng dụng Home Home gửi lệnh thực thi đến thiết bị. getDataCommand() là hàm được executeHandler() gọi để đặt payload trong lệnh thực thi được gửi đến thiết bị.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                // Is there something wrong here?
                isPaused: params.pause ? false : true
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

Chúng ta thực sự đang đặt isPause ở trạng thái đảo ngược, nó phải được đặt thành true khi params.pausetruefalse. Vì vậy, hãy khắc phục vấn đề đó.

local/index.ts

getDataForCommand(command: string, params: IWasherParams): unknown {
    switch (command) {
        case 'action.devices.commands.OnOff':
            return {
                on: params.on ? true : false
            };
        case 'action.devices.commands.StartStop':
            return {
                isRunning: params.start ? true : false
            };
        case 'action.devices.commands.PauseUnpause':
            return {
                isPaused: params.pause ? true : false
            };
        default:
            console.error('Unknown command', command);
            return {};
    }
}

Thay đổi phiên bản ứng dụng Home cục bộ để chúng tôi có thể xác định xem liệu chúng tôi có đang sử dụng đúng phiên bản hay không.

local/index.ts

const localHomeSdk = new App('1.0.3');

Hãy nhớ biên dịch lại ứng dụng và triển khai lại cho Firebase. Trong app-faulty/local, hãy chạy:

$ npm run build
$ firebase deploy --only hosting

Bây giờ, hãy khởi động lại thiết bị Google Home để thiết bị có thể tải ứng dụng Home cục bộ đã cập nhật. Đảm bảo rằng phiên bản ứng dụng Home cục bộ là 1.0.3.

Kiểm tra bản sửa lỗi của bạn

Bây giờ, hãy chạy lại Bộ thử nghiệm cho nhà thông minh có cùng cấu hình và bạn sẽ thấy rằng tất cả các trường hợp kiểm thử đều đạt.

b7fc8c5d3c727d8d.png.

7. Xin chúc mừng

764dbc83b95782a.png.

Xin chúc mừng! Bạn đã tìm hiểu thành công cách khắc phục sự cố ứng dụng Home Home thông qua Bộ thử nghiệm cho nhà thông minh và Ghi nhật ký đám mây.

Tìm hiểu thêm

Dưới đây là một số thao tác bổ sung mà bạn có thể thử:

Bạn cũng có thể tìm hiểu thêm về cách thử nghiệm và gửi một Hành động để chúng tôi xem xét, bao gồm cả quy trình cấp giấy chứng nhận để phát hành Hành động đó cho người dùng.