0

As suggested in codelabs sample code I am implementing report state as follows:

function reportState(devid, actionVal) {
  console.log('INSIDE REPORT STATE');
  if (!app.jwt) {
    console.warn('Service account key is not configured');
    console.warn('Report state is unavailable');
    return;
  }




const postData = {
    requestId: 'hgrwbj', /* Any unique ID */
    agentUserId: '123', /* Hardcoded user ID */
    payload: {
      devices: {
        states: {
          [devid]: {
            on: actionVal,
          },
        },
      },
    },
  };



  console.log('POSTDATA %j', postData);

  return app.reportState(postData)
     .then((data) => {
       console.log('Report state came back');
       console.info(data);
     });
};

But it gives me response as follows:

{
  "error": {
    "code": 400,
    "message": "Request contains an invalid argument.",
    "status": "INVALID_ARGUMENT"
  }
}

where value for post data is :

{"requestId":"hgrwbj","agentUserId":"123","payload":{"devices":{"states":{"0123456789:01":{"on":"true"}}}}}

So I tried implementing it the other way which is as follows:

function reportState(devid, actionVal) {
  console.log('INSIDE REPORT STATE');
  if (!app.jwt) {
    console.warn('Service account key is not configured');
    console.warn('Report state is unavailable');
    return;
  }

  const jwtClient = new google.auth.JWT(
    jwt.client_email,
    null,
    jwt.private_key,
    ['https://www.googleapis.com/auth/homegraph'],
    null
  );
  console.log('JWT',jwt);
  console.log('JWTCLIENT',jwtClient);

  const postData = {
    requestId: 'hgrwbj', /* Any unique ID */
    agentUserId: '123', /* Hardcoded user ID */
    payload: {
      devices: {
        states: {
          [devid]: {
            on: actionVal,
          },
        },
      },
    },
  };

  jwtClient.authorize((err, tokens) => {
    if (err) {
      console.error(err);
      return;
    }
    console.log('ACCESS TOKEN',tokens.access_token);
    const options = {
      hostname: 'homegraph.googleapis.com',
      port: 443,
      path: '/v1/devices:reportStateAndNotification',
      method: 'POST',
      headers: {
        Authorization: ` Bearer ${tokens.access_token}`,
      },
    };
    return new Promise((resolve, reject) => {
      let responseData = '';
      const req = https.request(options, (res) => {
        res.on('data', (d) => {
          responseData += d.toString();
        });
        res.on('end', () => {
          resolve(responseData);
        });
      });
      req.on('error', (e) => {
        reject(e);
      });
      // Write data to request body
      req.write(JSON.stringify(postData));
      req.end();
    }).then((data) => {
      console.info('REPORT STATE RESPONsE', data);
    });
  });


  console.log('POSTDATA %j', postData);

};

But this time it only gives request ID in response:

{"requestId":"hgrwbj"} 

This time Postdata is:

{"requestId":"hgrwbj","agentUserId":"123","payload":{"devices":{"states": {"0123456789:01":{"on":true}}}}}

Any suggestion on where I am issing to get the correct response ? Thanks in advance .

Sanu
  • 3
  • 3

1 Answers1

0

In your report state:

"on": "true"

You are sending the property "true" as a string. The server expects a boolean type, without quotes:

"on": true

That should work as expected.

Nick Felker
  • 11,536
  • 1
  • 21
  • 35
  • Thanks @Nick Felker for your quick reply. Hope this will solve the issue. I’ll let you know once I compile and test the code again. – Sanu Nov 14 '18 at 02:31
  • Hi @nick-felker, After the edit aslo, I am getting the same response i.e. '{"requestId":"hgrwbj"} ' . Probably, in this case the status code is included in the header only. As in case of invalid request, the response JSON body also contained the code:400, I was expecting the code:200 in the response body. Hope it is working. However I have one more doubt, if I have opened Google Home in two devices simultaneously and viewing the Smart Plug in Single Device View. When the device is switched in one . it is not getting reflected in the other unless it is minimized and maximized again. Is it fine? – Sanu Nov 14 '18 at 06:35
  • If the HTTP response is 200, that is passed back as one of the response headers, not in the body. If you are getting the request ID, and not an error, that's good. There may be a state issue in the app itself, but you should expect that to be fine. – Nick Felker Nov 14 '18 at 20:20