[OBSOLETE] Support for Nodon OCTAN z-wave Remote (DTH in post 32) (also works for Soft Remote)

Did a smal add on to enable blue light when button is pushed.

Find this section and change to this.
Parameter 8 1 bit and value 1 = blue

def configurationCmds() {
[ zwave.configurationV1.configurationSet(parameterNumber: 250, scaledConfigurationValue: 1).format(),
zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: 1),
zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId).format() ]
}

zwave.configurationV1.configurationSet(parameterNumber: 8, size: 1, scaledConfigurationValue: 3),

This one results in.
Blue when pressed, and blink green when response is sent from hub.

If anyone is interested Iā€™ve modified the template Aeon key fob DTH to support both push and hold function to give you 8 useable actions from the Octan. Actually went with hold release instead of hold as hold fires every second while your holding the button which was a pain in the backside when mapped to toggle a light on and off :wink:

If anyone would like a copy let me know. Iā€™ve not got round to setting up a git hub account yet but happy to either try to post the code here or mail to anyone that would find it useful.

1 Like

Iā€™d like to give this a try, I use one to control hue and lightify lamps. Can you post the code please. Thanks Richard

First time posting code so hopefully this works OKā€¦

posted version will fire the hold event while held instead of on release as per my previous post. You can change the behaviour by changing the def buttonevent as per the details in the comments.

Hope it works out for you.

 /**
 *  Copyright 2015 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.
 *
 * ===== Nodon Octan =====
 * 	version 1.0
 *	Modified for NodOn Octan Remote (CRC-3-1-0x) by Richard_Woodward
 *
 *	Octan supports 4 actions per button	Pushed
 *										Double Tap
 *										Held
 *										Hold Released
 *
 *	This Device Handler will currently provide only 8 of the possible 16 button events
 *	to maintain Smartthings standard compatibility. Push & Hold for each 4 buttons.
 *
 */
metadata {
	definition (name: "Aeon Key Fob", namespace: "smartthings", author: "SmartThings") {
		capability "Actuator"
		capability "Button"
		capability "Holdable Button"
		capability "Configuration"
		capability "Sensor"
		capability "Battery"

		fingerprint deviceId: "0x0101", inClusters: "0x86,0x72,0x70,0x80,0x84,0x85"
	}

	simulator {
		status "button 1 pushed":  "command: 2001, payload: 01"
		status "button 1 held":  "command: 2001, payload: 15"
		status "button 2 pushed":  "command: 2001, payload: 29"
		status "button 2 held":  "command: 2001, payload: 3D"
		status "button 3 pushed":  "command: 2001, payload: 51"
		status "button 3 held":  "command: 2001, payload: 65"
		status "button 4 pushed":  "command: 2001, payload: 79"
		status "button 4 held":  "command: 2001, payload: 8D"
		status "wakeup":  "command: 8407, payload: "
	}
	tiles {
		standardTile("button", "device.button", width: 2, height: 2) {
			state "default", label: "", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
			state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 2 pushed", label: "pushed #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 3 pushed", label: "pushed #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 4 pushed", label: "pushed #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 1 held", label: "held #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
			state "button 2 held", label: "held #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
			state "button 3 held", label: "held #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
			state "button 4 held", label: "held #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
		}
		valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
			state "battery", label:'${currentValue}% battery', unit:""
		}
		main "button"
		details(["button", "battery"])
	}
}

def parse(String description) {
	def results = []
	if (description.startsWith("Err")) {
	    results = createEvent(descriptionText:description, displayed:true)
	} else {
		def cmd = zwave.parse(description, [0x80: 1, 0x84: 1])
        //log.debug("cmd=$cmd")
		if(cmd) results += zwaveEvent(cmd)
		if(!results) results = [ descriptionText: cmd, displayed: false ]
	}
	//log.debug("Parsed '$description' to $results")
	return results
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
	def results = [createEvent(descriptionText: "$device.displayName woke up", isStateChange: false)]

	def prevBattery = device.currentState("battery")
	if (!prevBattery || (new Date().time - prevBattery.date.time)/60000 >= 60 * 53) {
		results << response(zwave.batteryV1.batteryGet().format())
	}
	results += configurationCmds().collect{ response(it) }
	results << response(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
	return results
}

def buttonEvent(button, held) {
	button = button as Integer
    held = held as Integer
    //log.debug("button=$button Held=$held")
    // if (held==1) {		will map the 'hold release' event to hold.
    // if (held==2) {		will map the 'held' state to event hold
    // if (held==3) {		will map the 'double click' event to hold.
	if (held == 2) {
		createEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true)
    }
    else if (held == 0) {
		createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
	}
}

def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {
    Integer button = (cmd.sceneId / 10) as Integer
    Integer held = cmd.sceneId - (button*10) as Integer
	buttonEvent(button, held)
}


def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "${device.displayName} has a low battery"
	} else {
		map.value = cmd.batteryLevel
	}
	createEvent(map)
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
	[ descriptionText: "$device.displayName: $cmd", linkText:device.displayName, displayed: false ]
}

def configurationCmds() {
	delayBetween([ zwave.configurationV1.configurationSet(parameterNumber: 250, scaledConfigurationValue: 1).format(),
   // zwave.associationV1.associationSet(groupingIdentifier: 2, nodeId: zwaveHubNodeId).format(),
   // zwave.associationV1.associationSet(groupingIdentifier: 3, nodeId: zwaveHubNodeId).format(),
  //  zwave.associationV1.associationSet(groupingIdentifier: 4, nodeId: zwaveHubNodeId).format(),
   // zwave.associationV1.associationSet(groupingIdentifier: 5, nodeId: zwaveHubNodeId).format(),
    zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format(),
    zwave.configurationV1.configurationSet(configurationValue: [3], parameterNumber: 8, size: 1).format(),
	  zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId).format() ],500)
}

def configure() {
	def cmd = configurationCmds()
	log.debug("Sending configuration: $cmd")
	return cmd
}


def installed() {
	initialize()
}

def updated() {
	initialize()
}

def initialize() {
	sendEvent(name: "numberOfButtons", value: 4)
}

@Richard_Worwood

Nice work! :sunglasses:

BTW, If you want to add the other actions, such as double tap, you certainly can, there are a number of other devices that now support this. The remotec 8 button device allows for 24 different actions. Thereā€™s no longer any standard for how many buttons a device can have. You just have to include the ā€œnumber of buttonsā€ parameter and then smartapps like core and smart lighting will use it correctly.

If youā€™d like to see some examples, take a look at the homeseer switch (which allows for single, double, and triple tap both top and bottom) and the remotec.

@JDRoberts thanks for the info. Iā€™ll look into that later. The wife I dragging me out to boxing day sales though so wonā€™t be for a few hours :wink:

As a new Smartthings owner / developer adhering to standards is confusing still, I guess so many of the posts and links to documentation in all the developer threads are now out of date I guess as all info I found seemed to indicate you could only have 2 states for a max of 4 buttons. Iā€™ll certainly follow the links you sent me though as it would be great to have native 16 action support in Smartlighting :+1:

1 Like

Right, everything used to be based on the minimote, but that has changed. There are now several button controller devices with many more buttons and multiple states per button, as in the examples in the previous post.

@Jim is in charge of the documentation. If thereā€™s a section where it says the device canā€™t have more than four buttons, that should definitely be updated, because now itā€™s based on the numberofbuttons parameter. Even the official SmartLighting recently changed to reference this parameter.

If you happen to find the documentation sections where it listed a maximum, and you list them here, iā€™m sure they can get updated.

Smartthings evolves so quickly that itā€™s pretty common for the documentation to lag a bit behind the implementation. :sunglasses:

Thanks to @JDRoberts advice of 'go do more research :wink: and @AdamV code examples to look at version 1.1 now supports all 16 functions in a hopefully fairly standard manner.

Smartlighting sees 8 buttons
1-4 Pushed and Hold work very obviously
5-8 Pushed and Hold are actually 1-4 Double Tap and 1-4 Hold release respectively.

Not sure how much use hold release will really be unless you start using core and set up complicated conditions :slight_smile:

Common use i guess will be Button 1 - 4 push and hold along with button 5-8 push to get access to the double tap event.

If you have already added version 1.0 DTH and replace it with this code then go into device details in IDE and reselect the DTH so it re-runs the initialise code to send the numberofbuttons command otherwise you will still see only 4 buttons in Smartlighting.

 /**
 *  Copyright 2015 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.
 *
 * ===== Nodon Octan =====
 * 	
 *	Modified for NodOn Octan Remote (CRC-3-1-0x) by Richard_Woodward
 *
 *	Octan supports 4 actions per button	Pushed
 *										Double Tap
 *										Held
 *										Hold Released
 *
 *	v1.01 Updated to support all 16 actions:
 *  
 *  As Smartlighting can only support type "Pushed" or "Hold" events the extra 4 functions have been mapped to 
 *  fictional buttons 5 through 8.
 *
 *  Button 1 double Tap is mapped to   "Button 5 Pushed" in smartlighting
 *  Button 1 Hold Release is mapped to "Button 5 Hold"   in smarlighting
 *  .
 *  Button 4 double Tap is mapped to   "Button 8 Pushed" in Smartlighting
 *  Button 4 Hold Rlease is mapped to  "Button 8 Hold"   in Smartlighting
 *
 */
metadata {
	definition (name: "Aeon Key Fob", namespace: "smartthings", author: "SmartThings") {
		capability "Actuator"
		capability "Button"
		capability "Holdable Button"
		capability "Configuration"
		capability "Sensor"
		capability "Battery"

		fingerprint deviceId: "0x0101", inClusters: "0x86,0x72,0x70,0x80,0x84,0x85"
	}

	simulator {
		status "button 1 pushed":  "command: 2001, payload: 01"
		status "button 1 held":  "command: 2001, payload: 15"
		status "button 2 pushed":  "command: 2001, payload: 29"
		status "button 2 held":  "command: 2001, payload: 3D"
		status "button 3 pushed":  "command: 2001, payload: 51"
		status "button 3 held":  "command: 2001, payload: 65"
		status "button 4 pushed":  "command: 2001, payload: 79"
		status "button 4 held":  "command: 2001, payload: 8D"
		status "wakeup":  "command: 8407, payload: "
	}
	tiles {
		standardTile("button", "device.button", width: 2, height: 2) {
			state "default", label: "", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffffff"
			state "button 1 pushed", label: "pushed #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 2 pushed", label: "pushed #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 3 pushed", label: "pushed #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 4 pushed", label: "pushed #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#79b821"
			state "button 1 held", label: "held #1", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
			state "button 2 held", label: "held #2", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
			state "button 3 held", label: "held #3", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
			state "button 4 held", label: "held #4", icon: "st.unknown.zwave.remote-controller", backgroundColor: "#ffa81e"
		}
		valueTile("battery", "device.battery", inactiveLabel: false, decoration: "flat") {
			state "battery", label:'${currentValue}% battery', unit:""
		}
		main "button"
		details(["button", "battery"])
	}
}

def parse(String description) {
	def results = []
	if (description.startsWith("Err")) {
	    results = createEvent(descriptionText:description, displayed:true)
	} else {
		def cmd = zwave.parse(description, [0x80: 1, 0x84: 1])
        //log.debug("cmd=$cmd")
		if(cmd) results += zwaveEvent(cmd)
		if(!results) results = [ descriptionText: cmd, displayed: false ]
	}
	//log.debug("Parsed '$description' to $results")
	return results
}

def zwaveEvent(physicalgraph.zwave.commands.wakeupv1.WakeUpNotification cmd) {
	def results = [createEvent(descriptionText: "$device.displayName woke up", isStateChange: false)]

	def prevBattery = device.currentState("battery")
	if (!prevBattery || (new Date().time - prevBattery.date.time)/60000 >= 60 * 53) {
		results << response(zwave.batteryV1.batteryGet().format())
        log.debug("  read battery")
	}
	results += configurationCmds().collect{ response(it) }
	results << response(zwave.wakeUpV1.wakeUpNoMoreInformation().format())
	return results
}

def buttonEvent(button, held) {
	button = button as Integer
    held = held as Integer
    //log.debug("button=$button Held=$held")
	if( held == 1) {
    	def ebutton = button +4
    	createEvent(name: "button", value: "held", data: [buttonNumber: ebutton], descriptionText: "$device.displayName button $ebutton was pushed", isStateChange: true)
    }
    else if (held == 2) {
		createEvent(name: "button", value: "held", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was held", isStateChange: true)
    }
    else if (held==3) {
    	def ebutton = button +4
    	createEvent(name: "button", value: "pushed", data: [buttonNumber: ebutton], descriptionText: "$device.displayName button $ebutton was pushed", isStateChange: true)
    }
    else if (held == 0) {
		createEvent(name: "button", value: "pushed", data: [buttonNumber: button], descriptionText: "$device.displayName button $button was pushed", isStateChange: true)
	}
}

def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {
    Integer button = (cmd.sceneId / 10) as Integer
    Integer held = cmd.sceneId - (button*10) as Integer
	buttonEvent(button, held)
}


def zwaveEvent(physicalgraph.zwave.commands.batteryv1.BatteryReport cmd) {
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "${device.displayName} has a low battery"
	} else {
		map.value = cmd.batteryLevel
	}
	createEvent(map)
}

def zwaveEvent(physicalgraph.zwave.Command cmd) {
	[ descriptionText: "$device.displayName: $cmd", linkText:device.displayName, displayed: false ]
}

def configurationCmds() {
	delayBetween([ zwave.configurationV1.configurationSet(parameterNumber: 250, scaledConfigurationValue: 1).format(),
   // zwave.associationV1.associationSet(groupingIdentifier: 2, nodeId: zwaveHubNodeId).format(),
   // zwave.associationV1.associationSet(groupingIdentifier: 3, nodeId: zwaveHubNodeId).format(),
  //  zwave.associationV1.associationSet(groupingIdentifier: 4, nodeId: zwaveHubNodeId).format(),
   // zwave.associationV1.associationSet(groupingIdentifier: 5, nodeId: zwaveHubNodeId).format(),
    zwave.configurationV1.configurationSet(configurationValue: [1], parameterNumber: 3, size: 1).format(),
    zwave.configurationV1.configurationSet(configurationValue: [3], parameterNumber: 8, size: 1).format(),
	  zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId).format() ],500)
}

def configure() {
	def cmd = configurationCmds()
	//log.debug("Sending configuration: $cmd")
	return cmd
}


def installed() {
	initialize()
}

def updated() {
	initialize()
}

def initialize() {
	sendEvent(name: "numberOfButtons", value: 8)
    log.debug("Sent numberOfButtons 8")
2 Likes

Thank you - this works great

2 Likes

Fantastic. Works great with NodOn wall plug too. :slight_smile:

Will you be maintaining this? Would be nice if you put it up on Github and fixed the namespacing/naming stuff too. :slight_smile:

Using this for a Nodon Soft Remote, Iā€™d previously (decā€™15) written a DTH that was passable. But this blows that out of the water.

Thanks for this.

1 Like

Thanks for this, I have finally integrated this remote on my ST, donā€™t know if itā€™s something with integration or not, but 50% of times that I push the buttons thereā€™s a significant delay on action ( lightā€™s ON/OFF ), thereā€™s nothing wrong with the z-wave network because if I do the same with Alexa controlling those lights the actions are pretty immediate. What I realize is that light status are not being updated fast enough on ST when I use this remote, btw, Iā€™m using it with SmartLighting smartapp.

@anderssv sorry i donā€™t use git, and have not checked forums for ages due to real life busyness. I will at some point update to correct namespace etc but i must admit itā€™s not a high priority right now as my main aim was just to get it working instead of taking up draw space :wink:. If anyone else wants to please go ahead and post update.

@Bruno_Cerqueira is your delay between the two sets of flashing coloured lights? I get pretty instant confirmation in my setup. Have you tried watching live logging while activating to get more info on when things are happening?

No worries, was just wondering. I always put stuff in Git, and really recommend you try. Itā€™s easy when you get going. :slight_smile:ļø

Anyway, for anyone else looking I have mine up on Git with minimal changes. Itā€™s running fine here, but I donā€™t use all the buttons. Iā€™ll try to update the docs with attributions later on.

1 Like

Guys, I just want to say a big Thank you for posting this kind of stuff. I loaded the device driver and it worked like a dream!
It really makes a difference to using Smarthings !

3 Likes

Could someone please tell me what the correct procedure is to pair the Nodon remote I have the one with the magnetic back its well built, unit but for the life of me I cant get ST to pair with it, the instructions confuse me as to what mode it should be in and on how to get ST to find it during pairing. Thanks in advance. I would really like to get this working.

Can anyone please tell me what the pairing process is with this Nodon remote is, I cant seem to get ST to find it and the instructions are confusing the hell out of me sorry but once I can get it paired I can try to use the code listed here to get it to work but right now I cant for the life of me work out what buttons to push to get this paired. Thanks in advance.
This is the model I have.

Hi, I had issues at first. Finally paired once I bounced the hub.

Add the DH then pair by Pressing and holding full circle and Plus buttons (1 and 2)for 1 sec then Full circle again.

I also found DH code and pairing instructions on a Nodon blog here:

2 Likes