Search code examples
node.jsactions-on-googlegoogle-smart-home

Test suite for smart home doesn't pass with one action, but it does with another one with the exact same code


we've developed a smart home action for Google Assistant and our "staging action" passed the test suite for smart home. Now that we wanted to get the "production action" certified, the test suite didn't pass, not a single command worked. The devices' states changed correctly, but the test suite returned the following error: AssertionError: Expected state to include: {"on":true}, actual state: {}: expected false to be true

We've had the problem before with the "staging action" and identified it to be a HomeGraph Sync problem. We fixed it and afterwards it worked. The "production action's" code is the exact same as the "staging action's" and the settings are also the same. So we have no idea what we could do to make the test suite pass. Does anyone have an idea of what the problem might be?

Here is an excerpt of our code:

const { smarthome } = require('actions-on-google');

// creating app in constructor
this._app = smarthome({ jwt, debug: this._options.debug || false });


// code-snipped sending state to HomeGraph after creating the state object from our device states
console.info('Report state:');
console.info(inspect(state, {depth: null, showHidden: false}));

this._app.reportState(state)
.then(res => console.info('report state succeeded', res))
.catch(err => console.error('report state failed', err));

And here is the corresponding log:

Report state:
{
  requestId: 'c82c0c20-a10d-4ded-a456-319109188501',
  agentUserId: '730f1842168ade4dcf9be3e40ea279e7ac4e6f21c002c09909f9d9a0341d2214',
  payload: {
    devices: {
      states: {
        '500dc011398fd3c191efdfa8e13a1062f7ef4d1c': { on: true, online: true }
      }
    }
  }
}
report state succeeded {
  "requestId": "c82c0c20-a10d-4ded-a456-319109188501"
}

In case of an error we expect something like:

  • 404: agentUserId unknown or HomeGraph not enabled
  • 401: access rights misconfigured
  • or any other error

but it succeeds.

EDITED:

We adjusted our code by reading the state from HomeGraph directly after sending it to HomeGraph in order to see whether HomeGraph gets anything from us at all:

    const auth = new google.auth.GoogleAuth({
      credentials: jwt,
      scopes: ['https://www.googleapis.com/auth/homegraph']
    });

    this._hg = google.homegraph({
      version: 'v1',
      auth: auth,
    });

    this._app = smarthome({ jwt, debug: this._options.debug || false });


this._app.reportState(state).then(async res => {

      const request = {
        requestBody: {
          agentUserId: state.agentUserId,
          inputs: [{
            payload: {
              devices: Object.keys(state.payload.devices.states).map(id => ({id}))
            }
          }]
        }
      };

      console.info(require('util').inspect(request, {depth: null}));

      const readStates = await this._hg.devices.query(request);
      console.info('########## STATES in HOMEGRAPH #######################');
      console.info(readStates.data);
      return res;
    })
.catch(err => console.error('report state failed', err));

The state is empty.

We also implemented a simple node.js app to read all device states via HomeGraph API. All device states are empty at any time.

The main question is: Why does calling this._app.reportState(state) never run into catch handler? There must be something wrong with our sending the state to HomeGraph, but we do not get any error back...?


Solution

  • Thanks! The problem has sorted itself out somehow. Maybe Google had a bug, but without doing anything on our part the tests pass now.