SmartThings SDK Subscribing to Devices Dynamically

Nevermind, the smartapp is reporting the hub status but the deviceId is malformed thus the 400 status error. I’m still missing some config information about the deviceID. Some information about the hub needs to be added in the page section of CONFIGURATION cycle.

@nayelyz @erickV I’m good here… I’m getting the 400 error because there is no deviceID for the hub…sheez…

1 Like

Hello,
I have a problem connected with unsubscribing devices. I am using NodeJS SDK. When I’m adding subscriptions, I’m getting in a response information about subscription with subscription name for example: subscriptionName:‘generalDeviceEventHandler_0’

Subscriptions works well. I’m getting events from devices etc. I can also unsubscribe all using
await currentContext.api.subscriptions.unsubscribeAll();
But when I’m trying to unsubscribe the specific subscription using this:
await currentContext.api.subscriptions.unsubscribe(subscriptionId, installedAppId);

I am getting error:
Error: Request failed with status code 400: {“requestId”:“44XXXXXXX-4531-8BEE-88XXXXXXXXX”,“error”:{“code”:“ConstraintViolationError”,“message”:“The request is malformed.”,“details”:[{“code”:“PatternError”,“target”:“subscriptionId”,“message”:“subscriptionId is not a properly formed UUID.”,“details”:}]}}
at createError (/proj/node_modules/axios/lib/core/createError.js:16:15)
at settle (/proj/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/proj/node_modules/axios/lib/adapters/http.js:269:11)
at IncomingMessage.emit (node:events:539:35)
at endReadableNT (node:internal/streams/readable:1345:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {config: {…}, request: ClientRequest, response: {…}, isAxiosError: true, toJSON: ƒ, …}

In this case subscriptionId = ‘generalDeviceEventHandler_0’. No matter If I am passing installed installedAppId to unsubscribe(…) or not.

I will be appreciate for help. Is it possible that there is some issue in SDK ?

There may be a user about with experience of this but otherwise @nayelyz should be able to help.

For my part I am a bit puzzled, being on the outside looking in. The Core SDK, which is the wrapper for the API, now favours delete over unsubscribe but uses subscriptionName in both. However the published API expects the subscriptionId, which is a UUID, and that is consistent with the error.

1 Like

Thanks, @orangebucket!

Yes, Graham is right, the SDK refers that the parameter used is the subscriptionName and I’ll report that but if we use the correct UUID, we can delete a single subscription using delete().
For example:

//Get all the SmartApp subscriptions created
let app_subs = await context.api.subscriptions.get("",context.installedAppId)

//It will give you a result like:
{
   "items":[
      {
         "id":"979d5603-...",
         "installedAppId":"f4bb949a-0d2f-...",
         "sourceType":"DEVICE",
         "device":{
            "deviceId":"5e9aacc2-68f8-4ae4-...",
            "componentId":"main",
            "capability":"switch",
            "attribute":"switch",
            "value":"off",
            "stateChangeOnly":true,
            "subscriptionName":"offDeviceEventHandler_0",
            "modes":[]
         }
      },
      {
         "id":"673cc4b8-cbb4-40be-...",
         "installedAppId":"f4bb949a-0d2f-4df9-...",
         "sourceType":"DEVICE",
         "device":{
            "deviceId":"5e9aacc2-68f8-4ae4-...",
            "componentId":"main",
            "capability":"switch",
            "attribute":"switch",
            "value":"on",
            "stateChangeOnly":true,
            "subscriptionName":"onDeviceEventHandler_0",
            "modes":[]
         }
      }
   ],
   "_links":{}
}

//You can get the subscriptionID from there, and you can verify its name to get the correct item
for(let i=0;i<app.items.length; i++){
    if(app.items[i].device.subscriptionName.includes("offDeviceEventHandler")){
         context.api.subscriptions.delete(app.items[i].id) //delete the subscription
    }
}

Thanks ! It works for “id”. I was a little misleaded by description from SDK:

	/**
	 * Deletes one or more subscriptions of an installed app
	 * @param name name of the subscription to delete. If not specified then all subscriptions associated with the
	 * installed app instance are deleted.
	 * @param installedAppId UUID of the installed app. This parameter is not required if the client id configured
	 * with an installedAppId
	 */
	public delete(name?: string, installedAppId?: string): Promise<Count>

Yes, that’s what I reported. Thank you for bringing this to our attention :smiley: