Dual Switch Zigbee 2 endpoints


I’m trying to integrate a device which is a lighting Relay Switch who can control 2 lighting.

I would like to have only one display with either 2 buttons which manage the 2 endpoints or an On / Off button and a toggle which juggles between the lights.

For the moment, my code look like this. But the second button takes the action of 1. I don’t understand. Could someone help me?

 *  Copyright 2019 SmartThings
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not
 *  use this file except in compliance with the License. You may obtain a copy
 *  of the License at:
 *		http://www.apache.org/licenses/LICENSE-2.0
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *  License for the specific language governing permissions and limitations
 *  under the License.

metadata {
	definition(name: "Zigbee ON/OFF Lighting Relay Switch", namespace: "SmartThings", author: "NodOn", ocfDeviceType: "oic.d.smartplug", mnmn: "SmartThings", vid: "generic-switch-power") {
		capability "Actuator"
		capability "Configuration"
		capability "Refresh"
		capability "Health Check"
		capability "Switch"
        command "on2"
        command "off2"

	tiles(scale: 2) {
		multiAttributeTile("switch1", "device.switch1", type: "lighting", width: 6, height: 4, canChangeIcon: true) {
			tileAttribute("device.switch", key: "PRIMARY_CONTROL") {
				attributeState "light1 ON", label: '${name}', action: "switch.off", icon: "st.switches.light.on", backgroundColor: "#00A0DC", nextState: "turningOff"
				attributeState "light1 OFF", label: '${name}', action: "switch.on", icon: "st.switches.light.off", backgroundColor: "#ffffff", nextState: "turningOn"
				attributeState "turningOn", label: '${name}', action: "switch.off", icon: "st.switches.light.on", backgroundColor: "#00A0DC", nextState: "turningOff"
				attributeState "turningOff", label: '${name}', action: "switch.on", icon: "st.switches.light.off", backgroundColor: "#ffffff", nextState: "turningOn"
			tileAttribute("switch1", "device.switch1", key: "SECONDARY_CONTROL") {
				attributeState "light2 ON", label: '${name}', action: "off2", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState: "turningOff"
				attributeState "light2 OFF", label: '${name}', action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
				attributeState "turningOn", label: '${name}', action: "off2", icon: "st.switches.switch.on", backgroundColor: "#00A0DC", nextState: "turningOff"
				attributeState "turningOff", label: '${name}', action: "on2", icon: "st.switches.switch.off", backgroundColor: "#ffffff", nextState: "turningOn"
		standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
			state "default", label: "", action: "refresh.refresh", icon: "st.secondary.refresh"

		main "switch"
		details(["switch", "refresh"])

// Parse incoming device messages to generate events
def parse(String description) {
	log.debug "description is $description"
	def event = zigbee.getEvent(description)
	if (event) {
	else {
		log.warn "DID NOT PARSE MESSAGE for description : $description"
		log.debug zigbee.parseDescriptionAsMap(description)

//def off() {

//def on() {
def on() {
    "st cmd 0x${device.deviceNetworkId} 1 6 1 {}"

def off() {
"st cmd 0x${device.deviceNetworkId} 1 6 0 {}"

def on2() {
    "st cmd 0x${device.deviceNetworkId} 2 6 1 {}"

def off2() {
"st cmd 0x${device.deviceNetworkId} 2 6 0 {}"


 * PING is used by Device-Watch in attempt to reach the Device
 * */
def ping() {
	return refresh()

def refresh() {
	zigbee.onOffRefresh() + zigbee.onOffConfig()

def configure() {
	// Device-Watch allows 2 check-in misses from device + ping (plus 2 min lag time)
	sendEvent(name: "checkInterval", value: 2 * 10 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
	log.debug "Configuring Reporting and Bindings."
	zigbee.onOffRefresh() + zigbee.onOffConfig()

What’s the brand and model of the device?

The Zigbee protocol allows for the use of “manufacturer proprietary” commands, which means not all Zigbee certified devices work in exactly the same way. This is especially true for multi endpoint devices.

For example many, but not all, Tuya models use a proprietary cluster, EF00, to send commands to different endpoints.

And since Tuya is resold by many different manufacturers under their own brand, often with additional firmware changes, it can be really challenging to get these to work. So that’s why the model number matters so much.

Thanks very much for your answer!

To test my device, i put the fingerprint with my brand.

But i don’t have my two button to control the both endpoint on the app only. With the simulator tool, i have it.

SmartThings is currently in the middle of a major transition, as the Groovy cloud is slated to be shut down. Legacy Groovy DTHs like the one you’re working on will no longer function after the Groovy cloud shutdown. The replacements for DTHs are Edge drivers that are written in Lua and installed directly on the ST hub. We don’t know when the Groovy shutdown will happen, but I would suggest looking at Edge as your development platform if you intend for this integration to still be working a year from now.

Also, there’s a chance that work has already been done by another community member to get your particular device working. Posting the device fingerprint as @JDRoberts asked might turn up a suggestion for an integration option that is already built and will work with your device.

Assuming you want to continue working on your DTH, you should know that there have been a number of changes to the Groovy platform as ST has prepared to transition away from it. Two things that stand out in your code are the tiles section and the command declarations. While those used to be important parts of a DTH (and are likely in every DTH example you’ll find in the community) they no longer impact how the device behaves in the app. The device presentation in the app and the commands that can be called are now controlled by the capabilities that the device has. In the case of your DTH, the only commands that can be called are on and off for the switch capability and refresh for the refresh capability. You would need to add another capability (or define a custom capability) to have a way to toggle on/off state for the second endpoint.

1 Like

Hello @philh30, thanks for your clear answer!

We are going to finish and publish our DHT for our devices since the work is almost done, and it can also give our user the possibility of using our products with SmartThings quickly. Then we will proceed to do the work in LUA with edge drivers.

Do you know if as today it’s actually possible to create, test and publish an edge working driver or things are not totally ready yet ?

For now, we are implementing a DHT for three of our Zigbee devices
Please, @JDRoberts, you can find below the associated fingerprint, however we have tested to add the device, and it seems that out of the box they are not handle correctly by ST.

On/Off Lighting Relay switch

Link to the official product page

fingerprint profileId: “0104”, inClusters: “0000, 0003, 0004, 0005, 0006, 0007, 0008, FC57”, outClusters: “0021”, manufacturer: “NodOn”, model: “SIN-4-2-20”, deviceJoinName: “NodOn Lighting Switch”

Multifunction Relay Switch

Link to the official product page

fingerprint profileId: "0104", deviceId: "0002", inClusters: "0000, 0003, 0004, 0005, 0006, 0019", outClusters: "0019", manufacturer: "NodOn", model: "SIN-4-1-20", deviceJoinName: "NodOn multi Switch"

Roller Shutter Relay Switch

Link to the official product page

fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006", outClusters: "0021", manufacturer: "NodOn", model: "SIN-4-RS-20", deviceJoinName: "Zigbee Roller Shutter Relay Switch" 

@philh30 concerning the actual DHT we had realized that anything related to tiles and command are not being used anymore as you said it.

In the case of our double switch with our second endpoint, you are talking of adding another capability.
Is it possible in that case to add the same capability twice, (switch) ?
In the case of a custom capability, will it work once publish inside the ST SmartThings app ?

Thanks again for your precious help.

Edge is still in Beta.

Several individual community members are currently writing and sharing Edge drivers, but most of the device manufacturers are not yet publicly releasing Edge Drivers because they don’t want their customers to have to deal with the unreliability and bugs from the Beta phase. They will wait until Edge itself is out of Beta. They may be running their own private Beta test, though.

You can find available community-written Edge Drivers on the quick browse lists in the community-created wiki.


Also, to avoid confusion, note that the term is “DTH” (Device Type Handler), not “DHT.” There are a couple of community developers whose first language is not English who got in the habit of writing DHT after they shared some code from GitHub that had the acronym backwards, but all the official documentation uses DTH for the groovy versions and Edge Driver for the Lua versions. :sunglasses:

1 Like

Yes, but all of @JDRoberts warnings about it being in beta are valid. I’m all in and like the platform, but I’m not running a company or supporting customers.

A component can only have one instance of each unique capability. A device can have up to 10 components, each of which could have the switch capability. Edge drivers can support multiple components. However, to my knowledge there is no way to define more than 1 component in a Groovy DTH, so you’re limited to 1 instance.

The Groovy solution has been to have the primary endpoint (switch 1) included as a capability on the primary DTH/device (the one that handles communication with the physical device). When the device is onboarded, that primary DTH also creates a child device for the second endpoint, which is represented as a second device within the app. The primary device’s DTH routes commands/events to and from the child. (The child device structure currently isn’t officially supported in Edge for ZigBee or z-wave devices.)

Yes. They work perfectly within the ST app assuming they’re set up correctly. They lack some of the custom UI features that ST has set up for the stock capabilities, but otherwise are identical to the end user. Aside from the UI presentation, the big reason to use a stock capability instead of a custom one is that the stock capabilities have more universal support in third party integrations like Alexa and Google Home. However, those two integrations don’t yet support multiple components, so the only way to currently get a dual switch to show properly is the Groovy child device setup.


I forgot to mention that at present the multiple endpoint architecture in edge has a major flaw in that end users cannot assign their own names to the different components and the separate endpoints are not visible to the voice assistants like Alexa and Google Home. This has been reported to smartthings multiple times and hopefully they understand that this needs to be fixed before Edge comes out of beta and is released to the general public. But they haven’t made any specific promises, just that they’ll look into it.

See the following discussion:

[ST Edge] Issues with multi-component devices and third-party integrations

So I think this is yet another reason why most of the device manufacturers are not yet releasing edge driver versions for their devices. They don’t want to take away functionality, in particular voice control, that their customers have currently.

1 Like