Smart App Multiple Device Subscriptions

Glad to hear!!

Can you help me on how you’re creating the capability subscription? I think what I was trying was a device subscription and i realized I can’t even list subscriptions via the API. I get a 403 error.

Here is my exact Function.

There is a little bit of Debug and error diagnostics if you get anything other than a 200 response.

Copied below.

#function(3): Capability Subscription

def alldevicesubscriptions(authtoken,AppID,capability,attribute,SubName):
BaseURL = ‘https://api.smartthings.com/v1/installedapps/
headers = {‘Authorization’: 'Bearer '+authtoken
EndURL = ‘/subscriptions’
#debug to print what is passed in
print(‘Heres the full request within the function…’+BaseURL+str(AppID)+EndURL)
datasub = {
“sourceType”: “CAPABILITY”,
“capability”: {
“locationId”: “YOUR LOCATION ID HERE”,
“capability”: capability,
“attribute”: attribute,
“value”: “*”,
“stateChangeOnly”: “true”,
“subscriptionName”: SubName
}
}
r = requests.post(BaseURL+str(AppID)+EndURL,headers=headers,json=datasub)
print(r.status_code)
if r.status_code == 200:
print('All ‘+str(capability)+ ’ Subscription successfully created’)
else:
print('Error Creating all '+str(capability)+ ‘subscription’)
print(‘The below is the content for the fault code’)
print(r.text)
print(r.content)
return BaseURL

When you call this function in your code in the INSTALL or UPDATE Lifecycle, just pass in the capability and attribute with a unique subscription name. You also need to pass in the auth token and appid which are retrieved from the update/install data. Also, add your location ID.

Hope this solves it for you.

It did!!! Thanks!

Great stuff. Glad you got sorted :+1:

I spent the weekend fighting through a similar problem with the Javascript SmartApp. Adding some notes for anybody that follows as I couldn’t find much online.

This is a personal, single use application that ties into my own custom home automation solution. My intention is just to use the smartapp for event subscriptions and use the direct REST API for actions.

In your smartapp definition, add:
.clientId(ClientID)
.clientSecret(ClientSecret)
.appId(AppId)
.permissions([
‘r:devices:’,
'r:locations:
’])

I found that adding w:devices:* crashed the android app. That said, I tried so many variations, I can’t trust that I remember each set of variations that didn’t work. I know I had execute in the last at one time as well. Note, setting the appId was required. clientId, clientSecret and appId all come from your workspace (automation definition). And, if it isn’t obvious, those permissions need to be there as well.

Since there are no devices to define, my page setup is simple:
.page(‘mainPage’, (context, page, configData) => {
})

Because there are no devices or config changes (guessing) .updated, never gets fired. I believe I switched to hooking installed. But, I need to do some more testing to see which lifecycle methods are actually called.

Even with capability subscriptions, there might be a bunch, so I intent to call list on the API to get existing subscriptions and only change the ones that are relevant. This should minimize the impact every time I make a code change. This should also allow me to hook any other life cycle methods is the impact of multiple subscription attempts should be minimal (ie a call to list subscriptions).

Thanks for sharing, @JimRush.
About the w:devices:* scope, this is intended to be used for SmartApp connectors because it creates/deletes a device, and, in your case, you’re creating an automation.
Using the .permissions() property is needed when the config page is empty because the scopes selected at the workspace are just white-listed for the SmartApp, but this doesn’t mean they’ll be used, the permissions included are defined in the SmartApp config. For example, “r:devices:*” includes all the devices at the location, a device setting, generates the scope “r:devices:device-ID”.

You’re right, this is required when you use the .permissions() property, it can be omitted when using the device setting because it includes the permission by each device. (In this case, the token generated will have access only for the selected devices).

In which cases would you need to change the subscriptions?

2 Likes

I would only need to change the subscriptions during development or if I add a new device to the collection that has a new capability.

I am assuming I can’t just use a “*” for the capability. I didn’t try, but the source code docs usually made it clear when you could. While I am collecting events for all of my devices, I will be nice and not to subscribe to capabilities I don’t currently use.

Oh, so you want to create a subscription for the capability, so every device that uses this capability is monitored?
The SmartApp SDK is based on the Core SDK, so you can check the Subscription endpoint to see which ones are available (eg. subscribeToCapability) and which parameters they need.
The Update life cycle is called every time you open the SmartApp, so, don’t worry about having an empty config page.