Reputation: 88
The documentation doesn't appear to cover how to respond to a QUERY request when you genuinely do not know the state of a given device. Even though I say that willReportState
is false for every device and include various commandOnly
attributes in the SYNC response, I am nevertheless sent a QUERY request. The same issue also applies to using ReportState calls triggered by a SYNC or QUERY request.
The state is unknown because it's proprietary lighting. I can send it commands, and cache the values of those commands, but at the outset I have no means of telling the existing state. I'm very much aware that I could cache all historic values I see in a database and retrieve them, but that doesn't stop the hardware being controlled from elsewhere without me knowing, so I never truly know the state except at the moment I'm executing an EXECUTE command (which I then report accordingly).
This is very similar to this question (Google Home - Is reporting state mandatory?), but in my case I genuinely don't/can't know the state, so any implementation I give providing a state is a guess/hack.
{
"requestId": "SomeMatchingRequestId",
"payload": {
"devices": [{
"id": "SomeValidDeviceId",
"online": true,
"status": "SUCCESS"
}]
}
}
The following seems to satisfy the request. The issue with this is not only that these values might be wrong in real life, after a few commands they might contradict what's in the UI, too.
{
"requestId": "SomeMatchingRequestId",
"payload": {
"devices": [{
"id": "SomeValidDeviceId",
"online": true,
"on": 0, /* Adding a default value */
"brightness": 0, /* Adding a default value */
"color": { "spectrumRGB": 0 }, /* Adding a default value */
"status": "SUCCESS"
}]
}
}
Note the attributes, one of which is undocumented, but I added it based on the pattern of the naming.
var device = new SyncResponseDevice
{
Id = deviceName,
Type = Types.Light.ToString(),
Traits = new List<string>
{
Traits.Brightness,
Traits.ColorSetting,
Traits.OnOff,
},
Name = new SyncResponseDeviceName { Name = zoneName },
WillReportState = false,
Attributes = new Dictionary<string, object>
{
{"commandOnlyBrightness", true},
{"commandOnlyOnOff", true},
{"commandOnlyColorSetting", true},
{"colorModel", colorModel.ToString().ToLower()}
}
};
Upvotes: 1
Views: 346
Reputation: 88
We've now been published / certified. Unfortunately this process contradicted some of what Nick's suggested. I suspect Nick's answer is the best one for an implementation, but in order to be certified here's what we had to do...
Every single device MUST be marked as willReportState=true
in the Test Suite tests, even if you can't report a genuine state, otherwise it will be rejected.
ReportState
MUST be implemented in relation to responding specifically to EXECUTE
requests. In our case we could implement this, in that you trigger an asynchronous ReportState
call with the exact same state provided in the command. In real life it's possible the state may have changed regardless, but doing the above satisfies the tests.
From what I can tell it's not necessary to implement ReportState
in response to QUERY
and SYNC
calls in order to be certified, although it's probably advisable if you can. In our case we're forced to respond with a fake/default state in this case.
You can responding to QUERY
and SYNC
responses with either the error response Nick suggested or a fake/default state. Either "work" and have no visible side effects to end users, but probably best to take Nick's approach.
Mentioning Nick suggested an exception should be granted will be ignored. :(
Good luck passing the tests in the Test Suite even with a flawless implementation. It relies on an artificial voice coming out of your speakers being correctly interpreted by a Google Home device. It might be because my device is UK English vs US. I had around a 90% success rate for this, but where I had around 20 tests to run this meant it failed the batch over and over. It took more than an hour of repeating the tests for it to pass. I was using studio grade monitor speakers at a loud volume adjacent to the Google Home device, and it didn't seem to help. I had things like "Set {device} brightness to 75%" be picked up as "You want me to set the device, is that correct?". Good grief. Why this test involves any audio whatsoever confuses me. Why not just message the command handler directly? Anyway, good luck!
It's my hope that having raised this as an issue the Google Home team will take a look at the above situation, and in turn the certification process updated, too. At that point this answer will hopefully become redundant.
Upvotes: 1
Reputation: 11978
If you claim you only support commands, but you still send state data, that may lead into an odd condition where you are still expected to know that state at any time. If you don't consistently know, it may be better to not send state data ever.
Additionally, rather than sending a "SUCCESS" in your QUERY response, you may want to send an "ERROR" status with an "errorCode" of something like "notSupported" which would be a more accurate response.
Upvotes: 1