스마트 홈 디버깅

1. 시작하기 전에

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

a4657871181b5ad2.gif

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

기본 요건

빌드할 항목

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

학습할 내용

  • GCP 측정항목 및 로깅을 사용하여 프로덕션 문제를 식별하고 해결하는 방법
  • 스마트 홈용 테스트 모음을 사용하여 기능 및 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에서 Refresh(새로고침) ae8d3b25777a5e30.png 버튼을 클릭하여 Request Sync(동기화 요청)를 통해 결함이 있는 세탁기 앱의 최신 기기 메타데이터로 HomeGraph를 업데이트합니다.

6f2b1344179977cf.png

Google Home 앱을 열고 고장 난 세탁기라는 이름의 세탁기 기기가 표시되는지 확인합니다.

e357de6a7faff925.png

3. 작업 테스트하기

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

세탁기 테스트하기

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

"Hey Google, 세탁기 켜 줘."

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

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

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

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

세탁기를 일시중지하거나 다시 시작하면 어시스턴트가 음성으로 문제가 있다고 응답하는 것을 확인할 수 있습니다.

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

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

스마트홈 분석 대시보드

오류를 검사하는 것은 스마트홈 분석 대시보드로, 클라우드 처리의 사용량 및 상태 측정항목 차트가 집계되어 있습니다.

  • 사용량 측정항목은 일일 활성 사용자 수와 처리에 필요한 총 요청 수를 포함하여 스마트 홈 작업의 사용량 추세를 반영합니다.
  • 상태 측정항목은 요청 지연 시간, 성공률, 오류 분류를 포함하여 스마트 홈 작업의 이상치를 모니터링하는 데 도움이 됩니다.

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

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

b1735bbe11a7aff8.png

  1. 그러면 Google Cloud 프로젝트의 대시보드 목록으로 이동합니다. Google Home 애널리틱스 - Cloud 통합 대시보드를 선택합니다.

5edd3751323176dd.png

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

c468743c20a11c15.png

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

이벤트 로그 액세스

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

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

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

747cca0f1249a5a.png

오류 로그에는 스마트 홈 이벤트와 함께 다음을 나타내는 오류 세부정보가 표시됩니다.

  • 수행한 사용자 작업은 '세탁 다시 시작' (actionType: 'STARTSTOP_UNPAUSE')입니다. 이는 최근에 실패한 음성 명령에 해당합니다.
  • 연결된 디버깅 메시지는 'JSON response does not include device.'입니다.

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

오류의 근본 원인 파악

functions/index.js에서 각 명령어의 상태와 새 기기 상태를 반환하는 EXECUTE 핸들러 (onExecute 배열에 있음)를 찾습니다. 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 함수가 세탁기에서 일시중지 / 재개를 처리하는 방식을 자세히 살펴보면 pause / Resume 명령어와 일치하는 문자열이 잘못된 것을 확인할 수 있습니다.

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, 세탁기 일시중지해 줘."

=>

"알겠습니다. 세탁기를 일시중지합니다."

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

=>

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

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

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

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

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

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

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

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

테스트 모음으로 스마트 홈 작업을 테스트하려면 다음 안내를 따르세요.

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

78ed6a1ebdb581bf.png

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

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

5838d10631c98ed2.png

장애에 관한 스마트 홈 작업을 디버그하려면 먼저 오류 메시지를 분석하여 오류의 근본 원인을 식별해야 합니다.

오류 메시지 분석

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

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

99e4e5d06965a8a7.png

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

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

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을 기반으로 다음 실습을 해 보고 추가 리소스를 살펴보세요.

사용자에게 작업을 게시하기 위한 인증 프로세스를 비롯하여 검토를 위해 작업을 테스트 및 제출하는 방법도 자세히 알아보세요.