Custom Capability not showing in SmartThings app — followed official example

Hi,

I’m working on a Direct Connected Device (ESP32) and trying to add a custom capability to the SmartThings app. I followed the official custom capability documentation and example (perfectlife6617.customGarageDoor), but the capability is not appearing in the app at all.

What I’ve done:

Created a custom capability snug.testDoor under my organization’s namespace (snug) via CLI:

smartthings capabilities:create -i testDoor.json
Created and uploaded a capability presentation via CLI:

smartthings capabilities:presentation:create snug.testDoor --capability-version 1 -i presentation.json
Added snug.testDoor to my Device Profile (main component, optional: true) and included it in detailView and automation sections.

Uploaded the updated Device Profile via the web portal — upload succeeded.

The device firmware registers the capability handle and reports an initial door attribute value (“closed”) on connection.

What I see in the app:

The snug.testDoor capability does not appear anywhere in the device detail view. All standard capabilities (switch, fanSpeed, fanMode, etc.) are visible and working correctly.

What I’ve verified:

The capability and its presentation are correctly registered (confirmed via smartthings capabilities --namespace snug -j and smartthings capabilities:presentation snug.testDoor --capability-version 1 -j)
The Device Profile on the server correctly includes snug.testDoor in main component (confirmed via smartthings deviceprofiles:view -j)
The firmware is reporting the door attribute value on initial connection
I’m attaching the current Device Profile JSON for reference.

Question:

Is there something specific required to make a custom capability visible in the SmartThings app that I’m missing? Does the app treat custom capabilities differently from standard ones in terms of rendering?

Any guidance would be greatly appreciated. Thank you!

{
  "deviceProfile": {
    "id": "a101d4da-2c96-4a4c-88e2-2ccfc379eeb5",
    "name": "v2.1.1",
    "metadata": {
      "deviceType": "Vent",
      "ocfDeviceType": "x.com.st.d.vent",
      "deviceTypeId": "Vent",
      "manufacturerName": "snug",
      "mnId": "Uimh",
      "vid": "9eacfb7a-52fe-4d26-8d15-9b098a8cdbf0",
      "mnmn": "snug",
      "presentationId": "snug.9eacfb7a-52fe-4d26-8d15-9b098a8cdbf0",
      "integrationType": "direct",
      "mainState": "main~switch~1",
      "ocfSpecVer": "core 1.1.0",
      "mainAction": "main~switch~1",
      "resourceType": "x.com.st.d.vent"
    },
    "migrationStatus": "NOT_MIGRATED",
    "status": "DEVELOPMENT",
    "preferences": [],
    "components": [
      {
        "label": " ",
        "id": "main",
        "capabilities": [
          {
            "id": "healthCheck",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "switch",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "fanSpeed",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "mode",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "fanMode",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "snug.testDoor",
            "version": 1,
            "optional": true,
            "ephemeral": false
          }
        ],
        "categories": [
          {
            "name": "Vent",
            "categoryType": "manufacturer"
          }
        ],
        "optional": false
      },
      {
        "label": " ",
        "id": "sensor",
        "capabilities": [
          {
            "id": "temperatureMeasurement",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "dustSensor",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "carbonDioxideMeasurement",
            "version": 1,
            "optional": false,
            "ephemeral": false
          }
        ],
        "categories": [],
        "optional": false
      }
    ]
  },
  "deviceConfiguration": {
    "mnmn": "snug",
    "vid": "9eacfb7a-52fe-4d26-8d15-9b098a8cdbf0",
    "version": "0.0.1",
    "type": "profile",
    "dashboard": {
      "states": [
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "idx": 0,
          "group": "main",
          "values": [],
          "composite": false
        }
      ],
      "actions": [
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "idx": 0,
          "group": "main"
        }
      ],
      "basicPlus": []
    },
    "detailView": [
      {
        "component": "main",
        "capability": "healthCheck",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "main",
        "capability": "switch",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "main",
        "capability": "fanSpeed",
        "version": 1,
        "values": [
          {
            "enabledValues": [],
            "range": [
              0,
              100
            ],
            "step": 25,
            "key": "fanSpeed.value"
          }
        ],
        "patch": [
          {
            "op": "replace",
            "path": "/0/slider/alternatives",
            "value": [
              {
                "key": "0",
                "value": "1",
                "type": "active"
              },
              {
                "key": "1",
                "value": "1",
                "type": "active"
              },
              {
                "key": "2",
                "value": "2",
                "type": "active"
              },
              {
                "key": "3",
                "value": "3",
                "type": "active"
              },
              {
                "key": "4",
                "value": "4",
                "type": "active"
              }
            ]
          }
        ],
        "visibleCondition": {
          "value": "fanMode.value",
          "operator": "ONE_OF",
          "operand": "[\"auto\",\"turbo\"]",
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "hideOnUnmatch": false
        }
      },
      {
        "component": "main",
        "capability": "fanMode",
        "version": 1,
        "values": [],
        "patch": [
          {
            "op": "replace",
            "path": "/0/label",
            "value": "동작모드"
          },
          {
            "op": "replace",
            "path": "/0/list/command/alternatives",
            "value": [
              {
                "key": "auto",
                "value": "수동",
                "type": "active"
              },
              {
                "key": "high",
                "value": "온도",
                "type": "active"
              },
              {
                "key": "medium",
                "value": "CO2감지",
                "type": "active"
              },
              {
                "key": "low",
                "value": "연기감지",
                "type": "active"
              },
              {
                "key": "turbo",
                "value": "주기환기",
                "type": "active"
              }
            ]
          },
          {
            "op": "replace",
            "path": "/0/list/state/alternatives",
            "value": [
              {
                "key": "auto",
                "value": "수동",
                "type": "active"
              },
              {
                "key": "high",
                "value": "온도",
                "type": "active"
              },
              {
                "key": "medium",
                "value": "CO2감지",
                "type": "active"
              },
              {
                "key": "low",
                "value": "연기감지",
                "type": "active"
              },
              {
                "key": "turbo",
                "value": "주기환기",
                "type": "active"
              },
              {
                "key": "off",
                "value": "꺼짐",
                "type": "inactive"
              }
            ]
          }
        ],
        "visibleCondition": {
          "value": "fanMode.value",
          "operator": "ONE_OF",
          "operand": "[\"auto\",\"high\",\"medium\",\"low\",\"turbo\"]",
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "hideOnUnmatch": false
        }
      },
      {
        "component": "main",
        "capability": "mode",
        "version": 1,
        "values": [
          {
            "enabledValues": [],
            "label": "주기",
            "key": "mode.value"
          }
        ],
        "patch": [],
        "visibleCondition": {
          "value": "fanMode.value",
          "operator": "EQUALS",
          "operand": "turbo",
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "hideOnUnmatch": false
        }
      },
      {
        "component": "sensor",
        "capability": "temperatureMeasurement",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "sensor",
        "capability": "dustSensor",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "sensor",
        "capability": "carbonDioxideMeasurement",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "main",
        "capability": "snug.testDoor",
        "version": 1,
        "displayType": "list",
        "list": {
          "command": {
            "name": "setDoor",
            "alternatives": [
              { "key": "open",   "value": "Open",   "type": "active" },
              { "key": "closed", "value": "Closed", "type": "inactive" }
            ],
            "argumentType": "string"
          },
          "state": {
            "value": "door.value",
            "valueType": "string",
            "alternatives": [
              { "key": "open",    "value": "Open",    "type": "active" },
              { "key": "opening", "value": "Opening", "type": "active" },
              { "key": "closed",  "value": "Closed",  "type": "inactive" },
              { "key": "closing", "value": "Closing", "type": "active" },
              { "key": "partial", "value": "Partial", "type": "active" }
            ]
          }
        },
        "values": [],
        "patch": []
      }
    ],
    "automation": {
      "conditions": [
        {
          "component": "main",
          "capability": "healthCheck",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanSpeed",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "mode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "sensor",
          "capability": "temperatureMeasurement",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "sensor",
          "capability": "dustSensor",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "sensor",
          "capability": "carbonDioxideMeasurement",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "snug.testDoor",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        }
      ],
      "actions": [
        {
          "component": "main",
          "capability": "healthCheck",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanSpeed",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "mode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        }
      ]
    },
    "presentationId": "9eacfb7a-52fe-4d26-8d15-9b098a8cdbf0",
    "manufacturerName": "snug"
  }
}

Hi, @JohnJo
You created the profile through the SmartThings Console and then changed the device config and uploaded it, correct?
Can you confirm if the device presentation is updated in the device’s instance, please? It should be snug.9eacfb7a-52fe-4d26-8d15-9b098a8cdbf0.
This is to check if the presentation used is the correct one.

Are the other changes in the presentation, like the one for “fanMode,” working correctly?
I used your custom capability in a test integration, but it’s C2C, and it appeared correctly in the ST App so it doesn’t seem to be about its configuration.

It would be helpful if you could open support access to your account so I can take a look at the device’s details, please:

  1. Confirm the email account registered in the forum is the same one you use for SmartThings. If not, please share it with me over DM
  2. Enable support access to your account:
  1. Go to the SmartThings Web (my.smartthings.com)
  2. Log in to your Samsung Account
  3. Select Menu (⋮) and choose Settings
  4. Toggle on Account Data Access
  5. Select the time period and confirm - In this step, please select “Until turned off”, once the team finishes, we’ll let you know so you can disable it again.

See more information about this access here: https://support.smartthings.com/hc/en-us/articles/36170233944852-Enabling-Account-Data-Access-for-Support

Hi @nayelyz , thank you! :slight_smile:

My forum account and SmartThings account use different emails, so I’ve sent you a message.

I’ve also enabled account data access.

The VID has changed since I posted the question, as I did some additional testing. Here is the current device profile.

The presentation ID is now snug.5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5.

{
  "deviceProfile": {
    "id": "a101d4da-2c96-4a4c-88e2-2ccfc379eeb5",
    "name": "v2.1.1",
    "metadata": {
      "deviceType": "Vent",
      "ocfDeviceType": "x.com.st.d.vent",
      "deviceTypeId": "Vent",
      "manufacturerName": "snug",
      "mnId": "Uimh",
      "vid": "5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5",
      "mnmn": "snug",
      "presentationId": "snug.5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5",
      "integrationType": "direct",
      "mainState": "main~switch~1",
      "ocfSpecVer": "core 1.1.0",
      "mainAction": "main~switch~1",
      "resourceType": "x.com.st.d.vent"
    },
    "migrationStatus": "NOT_MIGRATED",
    "status": "DEVELOPMENT",
    "preferences": [],
    "components": [
      {
        "label": " ",
        "id": "main",
        "capabilities": [
          {
            "id": "healthCheck",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "switch",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "fanSpeed",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "mode",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "fanMode",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "snug.testDoor",
            "version": 1,
            "optional": true,
            "ephemeral": false
          }
        ],
        "categories": [
          {
            "name": "Vent",
            "categoryType": "manufacturer"
          }
        ],
        "optional": false
      },
      {
        "label": " ",
        "id": "sensor",
        "capabilities": [
          {
            "id": "temperatureMeasurement",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "dustSensor",
            "version": 1,
            "optional": false,
            "ephemeral": false
          },
          {
            "id": "carbonDioxideMeasurement",
            "version": 1,
            "optional": false,
            "ephemeral": false
          }
        ],
        "categories": [],
        "optional": false
      }
    ]
  },
  "deviceConfiguration": {
    "mnmn": "snug",
    "vid": "5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5",
    "version": "0.0.1",
    "type": "profile",
    "dashboard": {
      "states": [
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "idx": 0,
          "group": "main",
          "values": [],
          "composite": false
        }
      ],
      "actions": [
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "idx": 0,
          "group": "main"
        }
      ],
      "basicPlus": []
    },
    "detailView": [
      {
        "component": "main",
        "capability": "healthCheck",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "main",
        "capability": "switch",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "main",
        "capability": "fanSpeed",
        "version": 1,
        "values": [
          {
            "enabledValues": [],
            "range": [
              0,
              100
            ],
            "step": 25,
            "key": "fanSpeed.value"
          }
        ],
        "patch": [
          {
            "op": "replace",
            "path": "/0/slider/alternatives",
            "value": [
              {
                "key": "0",
                "value": "1",
                "type": "active"
              },
              {
                "key": "1",
                "value": "1",
                "type": "active"
              },
              {
                "key": "2",
                "value": "2",
                "type": "active"
              },
              {
                "key": "3",
                "value": "3",
                "type": "active"
              },
              {
                "key": "4",
                "value": "4",
                "type": "active"
              }
            ]
          }
        ],
        "visibleCondition": {
          "value": "fanMode.value",
          "operator": "ONE_OF",
          "operand": "[\"auto\",\"turbo\"]",
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "hideOnUnmatch": false
        }
      },
      {
        "component": "main",
        "capability": "fanMode",
        "version": 1,
        "values": [],
        "patch": [
          {
            "op": "replace",
            "path": "/0/label",
            "value": "동작모드"
          },
          {
            "op": "replace",
            "path": "/0/list/command/alternatives",
            "value": [
              {
                "key": "auto",
                "value": "수동",
                "type": "active"
              },
              {
                "key": "high",
                "value": "온도",
                "type": "active"
              },
              {
                "key": "medium",
                "value": "CO2감지",
                "type": "active"
              },
              {
                "key": "low",
                "value": "연기감지",
                "type": "active"
              },
              {
                "key": "turbo",
                "value": "주기환기",
                "type": "active"
              }
            ]
          },
          {
            "op": "replace",
            "path": "/0/list/state/alternatives",
            "value": [
              {
                "key": "auto",
                "value": "수동",
                "type": "active"
              },
              {
                "key": "high",
                "value": "온도",
                "type": "active"
              },
              {
                "key": "medium",
                "value": "CO2감지",
                "type": "active"
              },
              {
                "key": "low",
                "value": "연기감지",
                "type": "active"
              },
              {
                "key": "turbo",
                "value": "주기환기",
                "type": "active"
              },
              {
                "key": "off",
                "value": "꺼짐",
                "type": "inactive"
              }
            ]
          }
        ],
        "visibleCondition": {
          "value": "fanMode.value",
          "operator": "ONE_OF",
          "operand": "[\"auto\",\"high\",\"medium\",\"low\",\"turbo\"]",
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "hideOnUnmatch": false
        }
      },
      {
        "component": "main",
        "capability": "mode",
        "version": 1,
        "values": [
          {
            "enabledValues": [],
            "label": "주기",
            "key": "mode.value"
          }
        ],
        "patch": [],
        "visibleCondition": {
          "value": "fanMode.value",
          "operator": "EQUALS",
          "operand": "turbo",
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "hideOnUnmatch": false
        }
      },
      {
        "component": "sensor",
        "capability": "temperatureMeasurement",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "sensor",
        "capability": "dustSensor",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "sensor",
        "capability": "carbonDioxideMeasurement",
        "version": 1,
        "values": [],
        "patch": []
      },
      {
        "component": "main",
        "capability": "snug.testDoor",
        "version": 1,
        "values": [],
        "patch": []
      }
    ],
    "automation": {
      "conditions": [
        {
          "component": "main",
          "capability": "healthCheck",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanSpeed",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "mode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "sensor",
          "capability": "temperatureMeasurement",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "sensor",
          "capability": "dustSensor",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "sensor",
          "capability": "carbonDioxideMeasurement",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "snug.testDoor",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        }
      ],
      "actions": [
        {
          "component": "main",
          "capability": "healthCheck",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "switch",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanSpeed",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "mode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        },
        {
          "component": "main",
          "capability": "fanMode",
          "version": 1,
          "values": [],
          "patch": [],
          "exclusion": []
        }
      ]
    },
    "presentationId": "5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5",
    "manufacturerName": "snug"
  }
}

Thank you!

Hi, @JohnJo
When you created v2.1.1, was it from scratch, or did you clone the device profile?
I see the device profile is correct, but checking the device via the API shows that the capability snug.testDoor is missing, which doesn’t make sense.
So, I’m wondering if the configuration is being cached somewhere, preventing this from appearing.

I will also ask the engineering team about this. Please, don’t delete the device and the device profile.

Hi @nayelyz, thank you as always for your quick and helpful responses!

To answer your question: I cloned v2.1.1 from v1.2.4 using the web portal’s clone feature.

One thing I noticed is that when you clone a device profile, the custom patches I had added to the JSON (like the one below) are not carried over — only the default fields are cloned:

“patch”: [{“op”: “replace”,“path”: “/0/label”,“value”: “동작모드”}]

So my actual workflow was as follows:

Clone v1.2.4 via the web portal to create a new profile named “v2.1.1”. Then download both the v2.1.1 and v1.2.4 JSON files from the portal.

Open the v1.2.4 JSON file and replace its id, name, vid, and presentationId fields with the corresponding values from the newly created v2.1.1.

Upload this modified file (which now contains v2.1.1’s identifiers but v1.2.4’s full configuration) to the v2.1.1 profile via the web portal.
This way, all my custom changes are applied to v2.1.1.

That said, I’m wondering if the caching issue you mentioned could be related to this workflow. Looking forward to your response and the engineering team’s findings!

Hi @nayelyz, I hope you’re doing well! I just wanted to check in — it’s been about 4 days since your last update mentioning the engineering team. I completely understand these things take time, and I really appreciate the effort you’re putting into this. Just curious if there’s any update or if the team has had a chance to look into it. No rush at all — I’ll keep the device and profile untouched as requested. Thanks again!

Two observations.

First is a general one. In the API Reference a Device Profile can include an embedded Device configuration but this isn’t documented elsewhere. What is documented is that an Edge driver profile can incorporate config information (but not a whole device config) but that doesn’t make the API Reference. The CLI can combine a Device Profile and a Device Configuration into a ‘view’ which doesn’t seem to be used anywhere else. Finally it would appear the the Console also combines a Device Profile and a Device Configuration but does it differently. None of this is very helpful.

Secondly, despite supposedly having been deprecated in favour of manufacturerName and presentationId, mnmn and vid made an unwelcome return to prominence with Edge drivers. However they are supposed to be the same. A vid or presentationId is a string and it is conventionally either a UUID or something friendly. In the latter case it normally has the mnmn/manufacturerName prepended because er, umm … well it does.

The mnmn/manufacturerName also appears as the namespace in the context of capabilities and capability presentations but gets absorbed into the identifier there.

I would observe that in the above posts we see that the Device Profile metadata says:

"vid": "5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5",
"presentationId": "snug.5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5"

I would suggest you can’t have it both ways and the presentationId is incorrect.

Note that the Device Configuration explicitly says:

“presentationId”: “5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5”

So if the mobile app uses the presentationId from the Device Profile it isn’t going to match anything, or at least not what it should be matching.

Or maybe you can have it both ways.

I queried the presentation using both “snug.5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5” and “5e25c857-e4e4-44a3-bfdb-b5f2fb3435f5” and both got the same result.
So, I think that shouldn’t be the issue. Also, the capability is missing from the device’s metadata, not the presentation.

@JohnJo, the engineering team was investigating an issue with the productID for the device registered in the platform because we had some issues seeing the device from our tool. We could only see it by making direct calls to the API.
However, we’re not sure if this issue is related to what you’re seeing.

The only thing I can think of to see if it lets you continue testing is creating everything from scratch. The device profile, product, etc.

Sorry, I completely missed that.

I am assuming that the capability was intentionally marked as optional in the profile? I believe they aren’t enabled by default.

Optional capabilities are a relatively new concept to me and I’ve only seen them used in stock Edge drivers so I’ve no idea how they get enabled in other integrations. So I’ll sit back and maybe I’ll learn something.

Hi @nayelyz,

Before anything else, I’d like to apologize for my previous message. Looking back, I realize I may have come across as rushing you for a reply — that wasn’t my intention at all. In fact, with the weekend in between, it had really only been one working day. I’m sorry about that, and thank you for responding so kindly regardless.

I understand your suggestion. Just to confirm my approach — I’d like to keep the existing product and device profile as they are, and create new ones completely from scratch. I’ve broken it down step by step below — could you let me know if this is correct?

  1. Create a new product and device profile from scratch on the web console (no cloning)

  2. Download the device profile JSON

  3. Manually edit the JSON to add the custom capability and patches

  4. Upload the modified JSON via the web console to apply the changes

Is this the right approach?

Hi @orangebucket , thanks for the tip!

Actually, I believe I originally tested with optional: false, but it still didn’t show up, so I changed it to true at some point. However, my memory isn’t entirely clear on this, so I’ll switch it back to false and test again. I appreciate the suggestion!

Hi, @JohnJo
I’m confused about this part. When you create the device profile, you can also select the custom capability when editing the capabilities and adding them from the list shown in the UI.
Then, you download the file to modify only the presentation. However, it seems that adding custom capabilities in the file makes them appear in the Console.
Have you checked that the custom capability and the direct-connected project belong to the same organization? To avoid any issues related to ownership.

Hi @nayelyz

I didn’t know that! I wasn’t aware that my custom capability would appear in the console UI as a selectable option when editing a device profile. That’s very helpful to know.

As you suggested, I’ll start fresh — I’ll use the web console to set up the device profile, select the custom capability directly from the UI, and then modify the presentation afterward.

I’ll let you know how it goes. Thank you!

Hi @nayelyz

I verified that both the custom capability and the direct-connected project belong to the same organization.

I couldn’t find a CLI command to check the organization of a Product, so I’m sharing a screenshot of the web console instead.

As you can see in the screenshot, the console is set to “Using Console as SNUG”, and the Product v2.1.1 is visible under that organization.

I also verified the custom capability’s organization via the SmartThings CLI:

$ smartthings capabilities snug.testDoor --capability-version 1 -j
{
    "id": "snug.testDoor",
    "version": 1,
    "status": "proposed",
    "name": "Test Door",
    "ephemeral": false,
    "attributes": {
        "door": {
            "schema": {
                "type": "object",
                "properties": {
                    "value": {
                        "type": "string",
                        "enum": [
                            "open",
                            "opening",
                            "closed",
                            "closing",
                            "partial"
                        ]
                    }
                },
                "additionalProperties": false,
                "required": [
                    "value"
                ]
            },
            "setter": "setDoor",
            "enumCommands": []
        }
    },
    "commands": {
        "setDoor": {
            "name": "setDoor",
            "arguments": [
                {
                    "name": "door",
                    "optional": false,
                    "schema": {
                        "type": "string",
                        "enum": [
                            "open",
                            "closed"
                        ]
                    }
                }
            ],
            "sensitive": false
        }
    }
}
$ smartthings capabilities:namespaces -j
[
    {
        "name": "snug",
        "ownerType": "organization",
        "ownerId": "8221d41d-2243-4a7b-a9a5-a0408cea5d71"
    }
]
$ smartthings organizations -j
[
    {
        "label": "SNUG",
        "warehouseGroupId": "cc3f877c-64b3-38de-b387-e6d6563e53e7",
        "name": "SNUG",
        "organizationId": "8221d41d-2243-4a7b-a9a5-a0408cea5d71",
        "isDefaultUserOrg": false
    }
]

The ownerId of the snug namespace matches the organizationId of the SNUG organization, so both the custom capability and the Product appear to belong to the same organization.

If there’s a better way to verify this, or if I’m checking it incorrectly, please let me know.

Hi, @JohnJo
Once you onboard it and if the issue persists, please share the timestamp of the attempt so the team can check the logs and see where is the info disappearing.