Custom Capability and CLI Developer Preview

I suspected that might be the answer! Can you elaborate on the purpose of putting capabilities into components other than ‘main’? What impact, if any, does this have on the way those capabilities (both stock and custom) are rendered on the device details screen?

Using components, allow you to have the same capability more than once. There are some devices (eg. Zigbee) that have different components (endpoints) which use the same capability such as a 3-gang switch. You can identify which element was actioned based on the endpoints and reflect the status in the corresponding component or vice-versa.

About the order, each component follows the specifications shared in the post below but it’ll depend on which capabilities you use:

1 Like

What is the recommended way to clear out (set to blank) a text string field? I’m unable to set an attribute to nil or ‘’ from an Edge driver; I can only set it to a blank character (’ '). I have fields I want to clear out each time a button is pressed, but that results in a bunch of undesirable changes being shown in history, and may also cause unwanted effects on automations watching the attribute. I’ve seen the use of {state_change = true} in some capabilities like momentary button, but don’t know if a {state_change = false} could be used or if it would help me eliminate the extraneous history changes or triggers of an automation when blanking a field.

Are you displaying this attribute in a specific display type?

Which undesirable changes do you mean?

How are you configuring your automation that is also triggered by this value? Have you tried to set something like - or none

Example capability:

{
    "id": "partyvoice23922.httpcode",
    "version": 1,
    "status": "proposed",
    "name": "httpcode",
    "attributes": {
        "httpcode": {
            "schema": {
                "type": "object",
                "properties": {
                    "value": {
                        "type": "string"
                    }
                },
                "additionalProperties": false,
                "required": [
                    "value"
                ]
            },
            "enumCommands": []
        }
    },
    "commands": {}
}

Presentation:

{
    "dashboard": {
        "states": [],
        "actions": [],
        "basicPlus": []
    },
    "detailView": [
        {
            "label": "HTTP Response Code",
            "displayType": "state",
            "state": {
                "label": "{{httpcode.value}}"
            }
        }
    ],
    "automation": {
        "conditions": [
            {
                "label": "HTTP Response Code",
                "displayType": "textField",
                "textField": {
                    "value": "httpcode.value",
                    "valueType": "string"
                }
            }
        ],
        "actions": []
    },
    "id": "partyvoice23922.httpcode",
    "version": 1
}

Every time you set an attribute to a blank, that gets listed in history.

I could set it to anything, but I’d rather be able to nil-out an attribute without it triggering anything.

Nayely,

Consider the button capability and attribute. The only actual events generated have the values pushed, held etc but in the mobile app we get to see ‘Standby’ displayed.

Similarly for momentary which doesn’t have an attribute at all and yet can display ‘Pushed’ when activated and then return to ‘Standby’.

So in both cases the app display can be changed without an event being generated.

For stateless attributes, such as the HTTP code example @TAustin presented, it makes no sense to permanently display the value of the last event. At the very least it should be possible to display an intermediate message as was possible in the Classic app.

It seems our only option to change the status reported in the app is to set the attribute and if we do that an event is generated in the device history and propagated to apps. Both are undesirable, with the event being a particular problem.

So are we overlooking something?

Another issue, which is related but off topic for this particular thread, relates to state change.

With the Classic platform, the ‘system’ would only propagate events where there was a state change. For stateless events, like pushing a button, developers could override this behaviour and force the event to be considered as a state change.

It appears the same is possible in Edge drivers, although undocumented, which seems odd as it would be critical. Does the ‘new’ platform behave the same as the old one in this respect? My assumption had been that as subscriptions can be limited to state changes, all events must be propagated. But then I saw a state change added to direct connected devices and I’ve seen it used in Edge drivers. So unless it is purely for back compatibility with the legacy platform I am confused.

2 Likes

Ok, I understand what you mean. Please, allow me some time to check this with the internal team. I’ll come back as soon as I get some news.

Update:
@TAustin
The engineering team mentioned that currently, there’s not an option to control the displayed events in the device history, so, they have opened a feature request to provide a better option for this kind of use case.

The state_change option is available to set manually, there are some examples in the button drivers.
However, consider the following:

  • This property helps mostly when we want to trigger a state change despite the “new” value is the same as the previous one (Eg. a button press). For that we should use state_change:true.
  • If the new value is different, the property will be set automatically to true even if we set it to false because a change is detected.
1 Like

Is there any way to define a switch that can only be controlled by the device, and not the user in the mobile app? I’d like to use a toggleSwitch, for example, as a way to display an on/off status, but I don’t want it to respond to a user tapping it in the mobile app. I was going to try just leaving the command definition out, but the API shows it as mandatory.

The alternative is a little clunky but could work: in the device driver, respond to an ‘on’ command with an ‘off’, and visa versa. That way it would kind of appear that any taps on the switch were being ignored. But it leaves the door open to unexpected things to happen. I’d rather just have a switch capability presentation definition that is ‘output only’, if that’s possible.

Yes, you can use the visibleCondition in the device-config.
When the defined condition is met (True), the capability with the visibleCondition property is enabled in the ST app otherwise, the user cannot send commands from there.

You could declare a condition that would always be evaluated as True. Here’s an example:

  • Imagine we have a device with the switch capability and a custom capability named “vacation”.
  • If we want to disable the Switch control when the vacation mode is “enabled”, we should set the following condition:
"visibleCondition": {
    "capability": "namespace.vacation",/*compared capability*/
    "version": 1,
    "component": "main", /*device's component where the capability is located*/
    "value": "vacationMode.value", /*reference to which attribute will be compared*/
    "operator": "DOES_NOT_EQUAL",
    "operand": "enabled" /*value assigned to the attribute compared in this condition*/
}

Does the visibleCondition property affect the color highlighting of the button on the device details screen? I’d still want the switch button to turn to blue color when set to ‘on’ from the driver like it normally would. I haven’t tried it, but I’m worried if I used that and set it to false, it would grey the button out completely and I’d lose the visible on/off cue.

@TAustin when switched on physical device, device status is updated on Details page even that app control is disabled. I think that @krlaframboise has this implemented on his Zooz driver for double switch. This allows control from app, or from physical device or both

Best I can think of is to leave the switch out of the device config for the details page and to use a custom capability for the on/off status using the state (?) tile.

1 Like

Yea, I was trying to avoid yet another custom capability but that’s probably what I’ll need to do. After thinking about it some more, what would really work for this case would be a custom contact sensor - it has the graphical element I’m looking for, PLUS it has no button. But don’t think I can reproduce that in a custom capability, as there is no ‘contact’ display type.

The button remains with the blue color, not as bright but we can still differentiate visibly the state.

Hi, I created two custom capabilities after reading this page.
Unfortunately, two components that I desired to see are never shown up on dashboard or detail view in my app. I have no clue at all how I fix this.

My custom capabilites are below
appleinside37634.plantFertility
appleinside37634.plantMoisture

and VID 70f5bc6f-646a-3b7b-8ee8-a469d9f6b6ac

Please help me.

It seems it is caused by the special characters you use in the labels of both capabilities’ presentations. I tried to use them but I got a 400 error creating the device-config. I created new ones changing this value and I got them to work:
VID: 8573113c-9c49-377f-a752-24cb862a9765

I will still report this to the engineering team to get their feedback.

Thanks for help

At first, I put all characters in English without any special characters. But no luck
So I did change everythings from attributes to presentations. It wasn’t working at all.

I put VID as you mention into DTH. It’s working well.
I will try to re-create attributes as the same as yours.

Thanks again.

1 Like

I tried to create attributes as new and put labels in English. It’s not working.
I put both custom capabilites and standard capablilites (“Temperature Measurement” ,“Illuminance Measurement”). Two standards capabilities are only shown up.

So I removed two standard capabilities to test. An error is occured when generating VID hash

Error: Request failed with status code 400: {"requestId":"F309B299-0DBD-4E0D-9922-459B6C93773F","erro r":{"code":"UnexpectedError","message":"unsuccessful-http-call status=400","details":[]}}"

With standard capabiliteis. VID is generated without errors. But custom capablities are never shown up

Below is generated JSON from command “presentation:device-config:generate”

{
“dashboard”: {
“states”: [
{
“component”: “main”,
“capability”: “appleinside37634.plantFertility”,
“version”: 1,
“values”:
}
],
“actions”: [
{
“component”: “main”,
“capability”: “appleinside37634.plantFertility”,
“version”: 1
}
]
},
“detailView”: [
{
“component”: “main”,
“capability”: “appleinside37634.plantFertility”,
“version”: 1,
“values”: ,
“patch”:
},
{
“component”: “main”,
“capability”: “appleinside37634.plantMoisture”,
“version”: 1,
“values”: ,
“patch”:
}
],
“automation”: {
“conditions”: [
{
“component”: “main”,
“capability”: “appleinside37634.plantFertility”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “appleinside37634.plantMoisture”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
}
],
“actions”: [
{
“component”: “main”,
“capability”: “appleinside37634.plantFertility”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
},
{
“component”: “main”,
“capability”: “appleinside37634.plantMoisture”,
“version”: 1,
“values”: ,
“patch”: ,
“exclusion”:
}
]
},
“type”: “dth”
}

What do you mean by this?
Did you delete the custom capability and create it again using the same name?
I tried to create the device-config using your capability and I got the same error.
The capabilities I used seem to have the same configuration, so if only yours are not working I suggest you create other ones with a different name.
There’s no error using the standard capabilities because they are not faulty, it only happens when we leave those two.

yes, I meant delete and create it again using the same name. I just wanted to start over without
non-english characters in label of capability presentation. ( you commented special characters can be a problem)

I tried to create new attribute with diffrent name. The result is the same as before. It’s not working
appleinside37634.moisture / appleinside37634.fertility
vid : 211653d3-8d30-3cb6-810d-3f658e39aeb9

1 Like