Im trying to add battery capability to my app. I added the same in developer workspace under my devices profile as a capability and wrote code accordingly. But Im unable to see the battery status in my schema app even after removing the device and adding it again
Hi, @namithathomas
Weâve noticed that sometimes when we add new capabilities to profiles in the Developer Workspace, the presentation is not updated, so, you might be able to send a new state for this capability from your connector but you wonât see it in the UI. If the capability doesnât belong to the profile either, youâll get an error when trying to send a new state for it.
So, the quickest suggestion would be to create a new profile with all the necessary capabilities and use that one instead.
The other would be to verify the presentation is being updated and try to update it manually if it isnât.
The last can be done as follows:
- In the Developer Workspaceâs profile, youâll see the tab âUI Displayâ
- Download the file that contains the device configuration to see its content
a. Check if the battery capability is included there - Then, check the presentationâs config by making a query to the API.
a. You can call the APIâs/presentation
endpoint (see the documentation here)
b. If you have the ST CLI set up, you can use this command:
smartthings presentation vid mnmn -j
//Example:
smartthings presentation ST_e976b515-9b04-46a2-... 0AJJ -j
The values of vid and mnmn are in the file you downloaded in #2
Thank you for the solution. I came across another doubt. It is about state refresh.
How does the state refresh works in ST Schema App? Because the changes happening in the dynamodb table is not refelcting timely in the App UI. I have to go to the app settings everytime-linked services-refresh to see the new changes. Is it because of something i missed in the code?
Is there any other ways to automate this? so that the clients get the updates in timely manner?
Do you mean the status changes on your cloud but you donât see it in SmartThings?
For that, you need to implement device state callbacks. This interaction type is used to update the status on demand when it changes on your side and doesnât depend on a command sent from SmartThings.
Remember you need to get a Reciprocal Access Token to authenticate such callbacks and that the token is linked to the instance of the Schema, this means that when you send a state callback, you send the deviceId
but internally we know to which connector it belongs based on the Access Token. Thatâs why you cannot update several devices from different users with a single request.
Please, let me know if you have questions and we can go step by step.
Yes. The changes happening in the cloud is not updating in App.
Could you please tell me the steps to add the device state callback? like the how the cloud connector code should be.
And another issue is in the grantcallbackaccess, even though the client id is same as that of in the developer work space it is showing an error like
âglobalErrorâ: {
âdetailâ: âClient ID xxxx is invalidâ,
âerrorEnumâ: âINVALID-CLIENTâ
}
Interesting, are you using the same account in your ST app and the Developer Workspace?
In this sample, you can see how I configured the connector, itâs simplified in the statusRefresh
and command
handlers for reference purposes:
const connector = new SchemaConnector()
.enableEventLogging(2)
.clientId(process.env.ST_CLIENT_ID)
.clientSecret(process.env.ST_CLIENT_SECRET)
.discoveryHandler((accessToken, response) => {
const d = response.addDevice('smartThermostat4', 'smartThermostat4', 'ed0f1f26-3365-4b90-903f-cc2f1973495e')
//Device manufacturer
d.manufacturerName('smartThermostat4');
//Device model
d.modelName('smartThermostat4');
})
.stateRefreshHandler((accessToken, response) => {
response.addDevice('smartThermostat4', [...])
})
.commandHandler((accessToken, response, devices) => {
//...
})
.callbackAccessHandler((accessToken, callbackAuthentication, callbackUrls) => {
//Here's where we receive the tokens for the callbacks
accessTokens = {
callbackAuthentication,
callbackUrls
}
console.log("granted accessTokens ",accessTokens)
})
.integrationDeletedHandler(accessToken => {
accessTokens = {};
});
If everything seems correct, have you tried getting a new set of client ID and secret to see if that makes a difference?
About the code of the callback, hereâs an example:
const {StateUpdateRequest,...} = require('st-schema');
accessTokens=getaccessTokens()
/*Sample of accessTokens structure:
accessTokens={
callbackAuthentication: {
tokenType: 'Bearer',
accessToken: 'xxxxx',
refreshToken: 'xxxx',
expiresIn: 86400
},
callbackUrls: {
oauthToken: 'https://c2c-us.smartthings.com/oauth/token',
stateCallback: 'https://c2c-us.smartthings.com/device/events'
}
}
*/
const updateRequest = new StateUpdateRequest(process.env.ST_CLIENT_ID, process.env.ST_CLIENT_SECRET);
const deviceState = [
{
externalDeviceId: 'externalDeviceId',
states: [
{
"component": "main",
"capability": "st.thermostatMode",
"attribute": "thermostatMode",
"value": "auto"
}
]
}
];
I have regenerated the client id and its fine now. But the statecallback function is not working properly.
async function sendStateUpdate(deviceId, states, oauthToken, stateCallbackUrl) {
if (!stateCallbackUrl || !oauthToken) {
console.error(âState callback URL or OAuth token not setâ);
return;
}
const updateRequest = new StateUpdateRequest(process.env.ST_CLIENT_ID, process.env.ST_CLIENT_SECRET);
updateRequest.callbackAuthentication.tokenType = 'Bearer';
updateRequest.callbackAuthentication.accessToken = oauthToken;
updateRequest.callbackUrls = {
oauthToken: 'https://c2c-us.smartthings.com/oauth/token',
stateCallback: stateCallbackUrl
};
updateRequest.addDeviceState({
externalDeviceId: deviceId,
states: states
});
const response = await fetch(stateCallbackUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${oauthToken}`
},
body: JSON.stringify(updateRequest)
});
if (!response.ok) {
throw new Error(`Failed to update state: ${response.status} ${response.statusText}`);
}
}
Could you please tell me the way to correct this. The device has temp humidity contact sensor and battery as capabilitites.
Hi, @namithathomas
As you mentioned you solved the issue over DM, could you let us know what you did? This is for other Community membersâ reference.
Hi, I have just followed the Schema SDK code you mentioned. So state changes are refelcting timely in the app now. Thank you.
SmartThingsCommunity/st-schema-nodejs/blob/master/lib/callbacks/StateUpdateRequest.js
Another doubt I have is rather than routines, is there any way to do the proactive notifications in the schema app like for example, the temperature is too high or low ? I couldnât find this in the documentation.
Do you mean sending push notifications using the Schema Connector? If so, it isnât possible, only certain capabilities send notifications without the configuration of a routine:
- waterSensor
- carbonMonoxideDetector
- smokeDetector
But the others require this configuration from the User, you cannot set a configuration from the Schema integration.