How to modify a DTH to reverse labels

In an effort to increase compatibility with App status information I would like to make what I think are very minor changes to a couple of device handlers but I can’t find the correct section of the DTH to modify. I am versed in installing custom device handlers but not creating them.

  • In particular I would like to change a garage tilt sensor to register as Open when it is vertical and Closed when it is horizontal. This is opposite of normal operation. The device manual tells me normal operation for horizontal is Basic Set, value: 0xFF and for vertical Basic Set, value: 0x00

  • I would also like to modify a DTH for a relay from Open/Closed to Locked/Unlocked.

Is this possible by switching a couple of labels in the DTH? How should I go about the whole process of modifying the DTH and applying the new DTH to an existing device to have my best chance for success?

OK let’s pick a stock device handler to play with, say Z-Wave Garage Door Opener.

Firstly take a look at the definition() method. That says …

definition (name: "Z-Wave Garage Door Opener", namespace: "smartthings", author: "SmartThings", runLocally: true, minHubCoreVersion: '000.017.0012', executeCommandsLocally: false, ocfDeviceType: "oic.d.garagedoor") {

You may, or may not, wish to change the name to make it easier to identify, and the namespace (usually your github username) and author so it is more obviously not stock. You do want to lose the local execution stuff though. So something like:

definition (name: "Modified Z-Wave Garage Door Opener", namespace: "whstrain", author: "whstrain", ocfDeviceType: "oic.d.garagedoor") {

To flip the attributes you need to change the values used in the events, and the particular attributes you will be interested are door and/or contact. You need to look for a sendEvent(), a createEvent(), or some map manipulation that is clearly working with name: "door" (or name: "contact") and value: "open" (or value: "closed").

The particular DTH I chose uses:

map.value = "closed"
result << createEvent(name: "contact", value: "closed", displayed: false)

and (in two places)

map.value = "open"
result << createEvent(name: "contact", value: "open", displayed: false)

In this handler the map.value is being used to set the door attribute of the Door Control capability (the createEvent appears later in the code) with the Contact Sensor looking like a later addition, so there are two attributes you might want to consider changing (it also uses map.value = "opening" and map.value = "closing").

Anyway the bottom line is that you can safely flip the values around to do what you want to do.

If you want to change a DTH from Open/Closed to Locked/Unlocked you need to add the Lock capability (capability "Lock") and whereever events are created with name: "contact" (assuming the Contact Sensor capability), and value: "open" or value: "closed" you lose "lock", "locked" and "unlocked" instead. Alternatively you could add the capability rather than replace the old one and add additional code.

1 Like

Thanks Graham, I chose to use the Z-Wave Door/Window Sensor template as a base because it naturally is chosen on installation of the device.

I found this section that seems to tie a sensor event to a notification event. But I can’t find anywhere that Event with value Open is defined.

def sensorValueEvent(value) {
	if (value) {
		createEvent(name: "contact", value: "open", descriptionText: "$device.displayName is open")
	} else {
		createEvent(name: "contact", value: "closed", descriptionText: "$device.displayName is closed")
	}

I took a wild stab that swapping the entries in the IF ELSE might help and it gave me what I wanted.

This is the only stuff I can find in the DTH that seems to define sensorValueEvent but I don’t understand how it works.

}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicReport cmd) {
	sensorValueEvent(cmd.value)
}

def zwaveEvent(physicalgraph.zwave.commands.basicv1.BasicSet cmd) {
	sensorValueEvent(cmd.value)
}

def zwaveEvent(physicalgraph.zwave.commands.switchbinaryv1.SwitchBinaryReport cmd) {
	sensorValueEvent(cmd.value)
}

def zwaveEvent(physicalgraph.zwave.commands.sensorbinaryv1.SensorBinaryReport cmd) {
	sensorValueEvent(cmd.sensorValue)
}

def zwaveEvent(physicalgraph.zwave.commands.sensoralarmv1.SensorAlarmReport cmd) {
	sensorValueEvent(cmd.sensorState)
}

I want to understand this better before I move on to changing capabilities.

When the device sends a message to the hub it results in the parse() method being called.

If you follow the logic of that you will see that any message that doesn’t meet a couple of special cases results in a library method being called by

cmd = zwave.parse( description, commandClassVersions)

That will recognise standard Z-Wave messages and return different types of objects accordingly and pass them onto different methods in the DTH using

result = zwaveEvent( cmd )

Groovy allows overloading of method names so there are multiple methods with the same name but different parameter types. I don’t really speak Z-Wave but I believe a contact sensor status report would appear as a Binary Sensor Report.

All the methods eventually either call sensorValueEvent(), which returns maps for contact events, or return maps for other attributes like battery reports. These returned maps end up back in parse() where they are used as the return value.

‘The system’ will use event maps returned by parse() to actually create device events and that is what actually results in attributes changing.

2 Likes

Graham,
I started working through your suggestions for the relay and realized if I just get rid of the Contact Sensor capability then I’ll get what I want. The relay I am using is the MIMOlite and it has a dry contact input which I don’t use and I think this is what is using the “Contact Sensor” capabilities. I’m trying to create another device handler with the Contact Sensor commented out but I’m getting errors when I try to save. Any Ideas?

expecting anything but ‘’\n’'; got it anyway @ line 40, column 316. alse, displayDuringSetup: true ^ 1 error<

Line 49 is below, starting with ‘input’.

preferences {
input “RelaySwitchDelay”, “decimal”, title: “Delay between relay switch on and off in seconds. Only numbers 0 to 3.0 allowed. 0 value will remove delay and allow relay to function as a standard switch”, description: “Only numbers 0 to 3.0 allowed.", defaultValue: 0, required: false, displayDuringSetup: true
}

I think you have got ‘smart quotes’ in the code. If you look at your code extract above you can see it is mostly using specific opening and closing double quotes instead of the generic straight ones. That can happen when you post code into this forum but in this case I think your code really has them.