스마트 홈 디버깅

1. 시작하기 전에

사물 인터넷 (IoT) 개발자는 사용자가 Google Home 앱의 터치 컨트롤과 Google 어시스턴트의 음성 명령으로 기기를 제어할 수 있는 스마트 홈 작업을 빌드할 수 있습니다.

a4657871181b5ad2.gif

스마트 홈 작업의 디버깅 도구를 배우는 것은 Google 어시스턴트와 프로덕션 수준의 통합을 빌드하는 중요한 단계입니다. 간편한 모니터링 및 디버깅을 위해 Google Cloud Platform (GCP) 측정항목, Logging, 스마트 홈용 테스트 모음을 사용하여 작업 관련 문제를 식별하고 해결할 수 있습니다.

기본 요건

빌드할 항목

이 Codelab에서는 결함이 2개 있는 스마트 홈 작업을 배포하고 어시스턴트에 연결한 다음 스마트 홈 및 기능 관련 테스트 모음을 통해 작업의 결함을 디버그합니다. Google Cloud Platform (GCP) 측정항목 및 로깅

학습할 내용

  • GCP 측정항목 및 Logging을 사용하여 프로덕션 문제를 식별하고 해결하는 방법
  • 스마트 홈용 테스트 모음을 사용하여 기능 및 API 문제를 식별하는 방법

필요한 항목

2. 문제가 있는 앱 실행

소스 코드 가져오기

다음 링크를 클릭하여 개발 머신에 이 Codelab의 샘플을 다운로드합니다.

...또는 명령줄에서 GitHub 저장소를 복제할 수도 있습니다.

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

프로젝트 정보

세탁기 앱에는 다음과 같은 하위 디렉터리가 있습니다.

Firebase에 연결

개발 머신에서 터미널을 엽니다. washer-faulty 디렉터리로 이동한 후 스마트 홈 기기를 Google 어시스턴트에 연결 Codelab에서 빌드된 작업 프로젝트로 Firebase CLI를 설정합니다.

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

Firebase에 배포하기

functions 폴더로 이동하고 npm.를 사용하여 필요한 모든 종속 항목을 설치합니다.

$ cd functions
$ npm install

참고: 아래 메시지가 표시되면 무시하고 계속 진행할 수 있습니다. 이 경고는 일부 오래된 종속 항목으로 인해 표시되며 여기에서 자세한 내용을 확인할 수 있습니다.

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

이제 종속 항목을 설치하고 프로젝트를 구성했으므로 결함이 있는 세탁기 앱을 배포할 준비가 되었습니다.

$ firebase deploy

콘솔에 다음과 같은 결과가 표시됩니다.

...

✔ Deploy complete!

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

HomeGraph 업데이트

브라우저 (https://<project-id>.firebaseapp.com)에서 호스팅 URL을 열어 웹 앱을 확인합니다. 웹 UI에서 새로고침 ae8d3b25777a5e30.png 버튼을 클릭하여 동기화 요청을 통해 결함이 있는 세탁기 앱의 최신 기기 메타데이터로 HomeGraph를 업데이트합니다.

6f2b1344179977cf.png

Google Home 앱을 열고 Faulty Washer라는 세탁기 기기가 표시되는지 확인합니다.

e357de6a7faff925.png

3. 작업 테스트하기

프로젝트를 배포한 후 작업이 세탁기를 제어하는지 테스트합니다.

세탁기 테스트하기

휴대전화를 통해 다음 음성 명령을 시도할 때 변경된 값을 확인합니다.

"Hey Google, 세탁기 켜 줘."

"Hey Google, 세탁기 시작해 줘."

"Hey Google, 세탁기 일시중지해 줘."

"Hey Google, 세탁기 다시 시작해 줘."

"Hey Google, 세탁기 중지해 줘."

세탁기를 일시중지 / 재개하면 어시스턴트가 음성을 통해 문제가 있다고 응답합니다.

'죄송합니다. <프로젝트 표시 이름>에 연결할 수 없습니다.'

이 문제를 디버그하려면 먼저 오류에 대한 추가 정보를 통해 범위를 좁혀 근본 원인을 파악해야 합니다.

Smarthome 분석 대시보드

오류를 검사하기에 좋은 곳은 클라우드 처리의 사용량 및 상태 측정항목 차트를 집계하는 Smarthome Analytics 대시보드입니다.

  • 사용량 측정항목은 일일 활성 사용자 수, 처리에 대한 총 요청 수 등 스마트 홈 작업의 사용 동향을 반영합니다.
  • 상태 측정항목을 사용하면 요청 지연 시간, 성공률, 오류 분류를 비롯하여 스마트 홈 작업의 이상 발생을 모니터링할 수 있습니다.

오류 원인의 범위를 좁히려면 아래 단계에 따라 프로젝트 대시보드에 액세스하세요.

  1. 작업 콘솔에서 프로젝트 페이지로 이동합니다.
  2. 스마트 홈 프로젝트를 선택합니다.
  3. 애널리틱스 탭을 선택하고 Google Cloud Platform으로 이동을 클릭합니다.

b1735bbe11a7aff8.png

  1. 그러면 Google Cloud에서 프로젝트의 대시보드 목록이 표시됩니다. Google Home Analytics - Cloud Integration 대시보드를 선택합니다.

5edd3751323176dd.png

  1. Cloud fulfillment 오류 - 상태 분류 차트까지 아래로 스크롤하여 강조 표시된 기간의 오류 코드를 확인합니다.

c468743c20a11c15.png

PARTNER_RESPONSE_MISSING_DEVICE 오류 코드는 근본 원인에 관한 힌트를 제공합니다. 다음으로 오류 코드에 따라 이벤트 로그를 검색하여 자세한 내용을 확인합니다.

이벤트 로그 액세스

오류에 관해 자세히 알아보려면 Cloud Logging을 통해 스마트 홈 작업의 이벤트 로그에 액세스하세요.

Google Cloud Platform에서 탐색 메뉴를 열고 작업에서 로깅을 선택합니다. 프로젝트의 이벤트 로그에 액세스할 수 있는 로그 탐색기. 검색창에서 로그 탐색기를 검색할 수도 있습니다.

쿼리 섹션에서 PARTNER_RESPONSE_MISSING_DEVICE 쿼리를 입력하고 쿼리 실행을 클릭합니다. 쿼리와 일치하는 로그가 쿼리 결과 섹션에 표시됩니다.

747cca0f1249a5a.png

오류 로그에는 다음과 같은 오류 세부정보가 포함된 스마트 홈 이벤트가 표시됩니다.

  • 사용자가 취한 조치는 '세탁 재개'입니다. (actionType: "STARTSTOP_UNPAUSE"). 최근에 실패한 음성 명령에 해당합니다.
  • 연결된 디버깅 메시지는 'JSON response does not include device.'입니다.

디버깅 메시지에 따라 세탁기 앱의 EXECUTE 응답에 올바른 기기가 포함되지 않은 이유를 확인해야 합니다.

오류의 근본 원인 파악하기

functions/index.jsonExecute 배열에서 각 명령어의 상태와 새 기기 상태를 반환하는 EXECUTE 핸들러를 찾습니다. EXECUTE 응답에 기기 ID를 삽입하는 것은 updateDevice 함수의 확인에 따라 다릅니다.

index.js

app.onExecute(async (body) => {
 ...

 for (const command of intent.payload.commands) {
   for (const device of command.devices) {
     for (const execution of command.execution) {
       executePromises.push(
           updateDevice(execution, device.id)
               .then((data) => {
                 result.ids.push(device.id);
                 Object.assign(result.states, data);
               })
               .catch((e) =>
                 functions.logger.error('EXECUTE',
                     device.id, e.message)));
     }
   }
 }

updateDevice 함수가 세탁기에서 일시중지 / 재개를 처리하는 방법을 추가로 확인하면 일시중지 / 재개 명령어와 일치하는 문자열이 잘못되었음을 알 수 있습니다.

index.js

const updateDevice = async (execution, deviceId) => {
 const {params, command} = execution;
 let state; let ref;
 switch (command) {
   ...
   case 'action.devices.commands.PauseUnpausePause':
     state = {isPaused: params.pause};
     if (params.pause) state.isRunning = false;
     ref = firebaseRef.child(deviceId).child('StartStop');
     break;
 }

 return ref.update(state)
     .then(() => state);
};

오류 수정하기

오류의 근본 원인을 파악했으므로 이제 일시중지 / 재개 명령어의 문자열을 수정할 수 있습니다.

index.js

const updateDevice = async (execution, deviceId) => {
 const {params, command} = execution;
 let state; let ref;
 switch (command) {
   ...
   case 'action.devices.commands.PauseUnpause':
     state = {isPaused: params.pause};
     if (params.pause) state.isRunning = false;
     ref = firebaseRef.child(deviceId).child('StartStop');
     break;
 }

 return ref.update(state)
     .then(() => state);
};

수정 결과 테스트

Firebase CLI를 사용하여 업데이트된 코드를 배포합니다.

firebase deploy --only functions

다음 음성 명령을 다시 시도해 보세요. 세탁기를 일시중지 / 재개할 때 어시스턴트가 올바르게 대답하는 것을 확인하실 수 있습니다.

"Hey Google, 세탁기 일시중지해 줘."

=&gt;

"물론입니다. 세탁기를 일시중지합니다."

"Hey Google, 세탁기 다시 시작해 줘."

=&gt;

"알겠습니다. 세탁기를 다시 시작합니다."

질문을 통해 세탁기의 현재 상태를 테스트할 수도 있습니다.

"Hey Google, 세탁기 켜져 있어?"

"Hey Google, 내 세탁기 돌아가고 있어?"

"Hey Google, 세탁기가 지금 무슨 모드야?"

4. 테스트 모음으로 작업 테스트

수동으로 테스트하는 것 외에도 자동화된 스마트 홈용 테스트 모음을 사용하여 작업과 관련된 기기 유형 및 특성을 기반으로 사용 사례를 검증할 수 있습니다. 테스트 모음은 작업의 문제를 감지하기 위해 일련의 테스트를 실행하고, 이벤트 로그를 자세히 살펴보기 전에 디버깅을 신속하게 처리할 수 있도록 실패한 테스트 사례에 관한 유용한 메시지를 표시합니다.

스마트 홈용 테스트 모음 실행

다음 안내에 따라 테스트 모음별 스마트 홈 작업을 테스트합니다.

  1. 웹브라우저에서 스마트 홈용 테스트 모음을 엽니다.
  2. 오른쪽 상단의 버튼을 사용하여 Google에 로그인합니다. 이렇게 하면 테스트 모음에서 Google 어시스턴트로 명령어를 직접 전송할 수 있습니다.
  3. 프로젝트 ID 필드에 스마트 홈 작업의 프로젝트 ID를 입력합니다. 그런 다음 다음을 클릭하여 계속 진행합니다.
  4. 테스트 설정 단계에서 테스트 모음에 세탁기의 기기 유형 및 특성이 표시됩니다.

78ed6a1ebdb581bf.png

  1. 샘플 세탁기 앱에는 세탁기를 추가/삭제하거나 이름을 변경할 UI가 없으므로 테스트 요청 동기화 옵션을 사용 중지합니다. 프로덕션 시스템에서는 사용자가 기기를 추가/삭제하거나 기기 이름을 변경할 때마다 동기화 요청을 트리거해야 합니다.
  2. 다음을 클릭하여 테스트 실행을 시작합니다.

테스트 모음 실행이 완료되면 테스트 사례의 결과를 확인합니다. 실패한 테스트 사례 2개가 해당 오류 메시지와 함께 표시됩니다.

5838d10631c98ed2.png

스마트 홈 작업을 디버그하려면 먼저 오류 메시지를 분석하여 오류의 근본 원인을 파악해야 합니다.

오류 메시지 분석

개발자가 근본 원인을 파악할 수 있도록 테스트 모음에서는 실패한 각 테스트 사례에 실패 이유를 나타내는 오류 메시지를 표시합니다.

위의 첫 번째 실패한 테스트 사례의 경우

99e4e5d06965a8a7.png

오류 메시지는 테스트 모음이 스마트 홈 작업에서 보고된 상태에서 "isPause": true를 예상한다고 나타내지만 실제 상태에는 "isPause": false만 포함되어 있습니다.

또한 두 번째 실패한 테스트 사례의 오류 메시지는 스마트 홈 작업의 QUERY 응답에 "isPause": true가 포함되어 있음을 나타냅니다. 이는 스마트 홈 작업에서 보고된 상태의 "isPause": false와 다릅니다.

fdb5124102e3a37.png

두 오류 메시지에 따라 작업이 올바른 값으로 isPaused 상태를 보고하는지 확인해야 합니다.

오류의 근본 원인 파악하기

보고서 상태를 통해 Home Graph에 상태 변경사항을 게시하는 reportstate 함수가 포함된 functions/index.js를 엽니다. 보고서 상태 페이로드를 검사하여 페이로드에 isPaused 상태가 누락되어 있음을 확인할 수 있습니다. 이는 테스트 모음이 실패한 테스트 사례에서 확인한 상태 그대로입니다.

index.js

exports.reportstate = functions.database.ref('{deviceId}').onWrite(
    async (change, context) => {
      ...

      const requestBody = {
        requestId: 'ff36a3cc', /* Any unique ID */
        agentUserId: USER_ID,
        payload: {
          devices: {
            states: {
              /* Report the current state of our washer */
             [context.params.deviceId]: {
                online: true,
                on: snapshot.OnOff.on,
                isRunning: snapshot.StartStop.isRunning,
                currentRunCycle: [{
                  currentCycle: 'rinse',
                  nextCycle: 'spin',
                  lang: 'en',
                }],
                currentTotalRemainingTime: 1212,
                currentCycleRemainingTime: 301,
              },
            },
          },
        },
      };

      const res = await homegraph.devices.reportStateAndNotification({
        requestBody,
      });
      ...
    });

오류 수정하기

오류의 근본 원인을 확인했으므로 이제 보고서 상태 페이로드에 isPaused 상태를 추가하여 functions/index.js를 수정합니다.

index.js

exports.reportstate = functions.database.ref('{deviceId}').onWrite(
    async (change, context) => {
      ...

      const requestBody = {
        requestId: 'ff36a3cc', /* Any unique ID */
        agentUserId: USER_ID,
        payload: {
          devices: {
            states: {
              /* Report the current state of our washer */
             [context.params.deviceId]: {
                online: true,
                on: snapshot.OnOff.on,
                isPaused: snapshot.StartStop.isPaused,
                isRunning: snapshot.StartStop.isRunning,
                currentRunCycle: [{
                  currentCycle: 'rinse',
                  nextCycle: 'spin',
                  lang: 'en',
                }],
                currentTotalRemainingTime: 1212,
                currentCycleRemainingTime: 301,
              },
            },
          },
        },
      };
      ...
    });

수정 결과 테스트

Firebase CLI를 사용하여 업데이트된 코드를 배포합니다.

$ firebase deploy --only functions

스마트 홈의 테스트 모음을 다시 실행하면 모든 테스트 사례가 통과된 것을 확인할 수 있습니다.

148837f85d377dd6.png

5. 축하합니다

17d485868a6771bc.png

축하합니다. 스마트 홈 및 기능 테스트 모음을 통해 스마트 홈 작업 문제를 해결하는 방법을 알아봤습니다. GCP 측정항목 및 로깅

자세히 알아보기

이 Codelab을 기반으로 다음 실습을 해 보고 추가 리소스를 살펴보세요.

사용자에게 작업을 게시하는 인증 프로세스 등 검토를 위해 작업을 테스트하고 제출하는 방법도 자세히 알아볼 수 있습니다.