[OBSOLETE] Ikea Tradfri Wireless Dimmer Device Handler draft

Good point!

UK hub here

I also use UK V2 hub

I bought a TrƄdfri Gateway today just to update the firmware in all of my TrƄdfri devices and the dimmer now has this firmware: 0x12248572

Still no go. Only difference was that the ST hub no longer automatically detected it as a Tradfri Dimmer v0.1 DH, but a thing.

Am i right in believing you cant use the dimmers or 5 button controllers direct with smartthings yet? P.s im in the U.K.
Thanks

Hi there, so i have successfuly integrated several Tradfri white spectrum bulbs (GU10 and E27) with Smartthings using the ZLL white colour temperature bulb device type.

I have seen the Tradfri device handler etc listed here and in other threads and wantd to ask what using that instead would give me over the ZLL one i am using at the mo?

Can anyone help?

UK V2 hub here, Iā€™ve tried the above and although paired, Iā€™m not getting anything out of the dimmer even logging. Iā€™ve reset and paired again, and sadly again nothing. Bummer. I donā€™t see any states at all
Current States
No states found

different than your screenshot.

UK v2 hub here and Iā€™m getting the same as everyone else, the dimmer is doing nothing

dont the ikea dimmers communicate directly with the bulbs? I didnt think they could be connected to the hub.

Hello all, it seems that the updated software that comes on the new Tradfri dimmer does not work in the same way as when I wrote the device handler.
My dimmer is still working fine through ST, so your milage may vary depending on when you bought one!
Some people are reporting that there are no events reported at all from the dimmer, in this case Iā€™m afraid there may not be much that can be done to make it work, perhaps it sends non-standard commands to the Tradfri bulb that ST canā€™t understand or pick up.
Anyway, Iā€™m not really an expert so maybe there is something that can be done, if anyone would like to have a go at adapting my code please do feel free to use it and please post back in this thread.
Also, my ST hub is a UK v2.
Thanks for your interest, I hope at least one other person got it to work!
Kris.

Iā€™m just starting with SmartThings development, and I chose this device to start playing withā€¦

I seem to have the same problem as a number of people above, when paired, my dimmer emits no commands when turned. Iā€™ve tried removing pretty much everything from my Device Handler apart from a debug notification, but I still get nothing.

My firmware version as per the Device page in the developer console is 0x11115720 - perhaps this is the problem. I do wonder if the device is waiting for either 1) some sort of manufacturer command before sending commands of its own or 2) is refusing to send to the SmartThings hub as its not an IKEA device. I might fire an email to IKEA and see if I get anything back.

As an aside - have you used zigbee.parseDescriptionAsMap() on the returned commands (ā€œcatchall:ā€¦ā€) to get back a bit more of structured response? I did that with your commands and got:

[raw:0104 0008 01 01 0100 00 D035 01 00 0000 05 00 00C3, profileId:0104, clusterId:0008, sourceEndpoint:01, destinationEndpoint:01, options:0100, messageType:00, dni:D035, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:05, direction:00, data:[00, C3], clusterInt:8, commandInt:5]

Cross referencing with the Zigbee Cluster Library Spec on page 159 shows that this particular command - 05 - is a Move with On/Off, and the payload indicates the move is in the Up direction (00), and it moved at a rate of 195 (00C3) ā€œunitsā€ per second.

I tried this handler andā€¦ it seems thereā€™s a big problem with it. Iā€™m also not an expert in Zigbee and still experimenting, but here some problems I think there is in the code of this handler:

  1. The catchall should not be used that way, because it contains the destination address of your device on the network. It wonā€™t work for anybody else than yours. I mean this kind of comparison:
    if (description == "catchall: 0104 0008 01 01 0140 00 D035 01 00 0000 07 00 ") (The D035 is probably the address of your device on your zigbee network)
  2. There is no ā€œconfigure()ā€ method to set up the zigbee reportings from the dimmer.
  3. This device handler is exposing the Switch & Switch Level capabilities. Those capabilities are for the controlled device (usually a lamp or a switch/dimmer on which the lamp is connected), not the controller itself.

But Iā€™m also wondering how Smartthings can handle this device. Let me explain : the cluster #0006 (Level Control) is in the OUT/CLIENT clustersā€¦ I think it means (I repeat Iā€™m not an expert) the device expect to control another one exposing this cluster and a IN/SERVER cluster.

I really donā€™t know how to tell the device itself which one to control. In this case, it should send the commands to the hubs as if it was a ZLL lamp. I donā€™t know how to do that and if ST can handle this well.

Iā€™ve been using a modified version of this device handler which does work for my Tradfri dimmers (both came with firmware 11115720).

Iā€™m by no means an expert on Zigbee, but the key to get the dimmers to respond does seem to be the configure() function:

def configure() {
	//log.debug "Configure called"
	["zdo bind 0x${device.deviceNetworkId} 0x01 0x01 8 {${device.zigbeeId}} {}"]
}

Also, I had to pair the dimmers multiple times to get them to respond. And I also had to re-pair one of them after I dropped it which triggered the pairing button.

After that, how do you use this device handler to do something useful ?

Hello All, thanks for feedback. Iā€™m happy if anyone wants to improve the code and share again.

I must admit I struggled to find much detailed information on the Zigbee standard, Iā€™ll have another go and see if I can find the reference you are talking about.

Basically, this handler creates a device that can send on/off and brightness commands to the ST hub based on the rotation of the dimmer and then control other devices. You can also control the level and on/off of the dimmer using the ST app, in the same way as you would control a single bulbā€¦ this then sends those commands in turn to the hub and again controls whatever it is linked to.

Anyway, I just deleted my dimmer and tried adding it againā€¦ now I donā€™t get any events either :slight_smile:
I bet I first added it with another handler and then changed to this one.

If anyone can solve it please do!!

OK, some progress.

I commented out the device fingerprint in my handler so it would not be automatically selected and used the handler that haoto linked to here to pair the dimmer.

This seems to register for events as the logged shows events from the dimmer. When I then changed the device handler back to my one it continues to report events and shows all the expected log output.

One remaining problem, as Charlie Halford pointed out the D035 was the device ID in my network, I updated the catchalls with the new ID and it is now dimming properly again.

So, problems that need to be solved:

  1. Figure out what is different in the other device handler that causes the dimmer to report events, then update my one to include this.
  2. Figure out a better way to process the events that doesnā€™t include the device ID (or dynamically update the device ID into the string comparison)

If anyone could help to test/confirm the above it would help me to get motivated to make these changes :slight_smile:

Cheers,
Kris.

OK too many posts tonight :slight_smile:

I have updated the code and tried removing and re-adding the dimmer, it is working fine for me now as I have removed the reference to the device ID and borrowed the configuration from the other handler.

Can someone give it a go and let me know how you get on?

/**
 *  Tradfri Dimmer v0.2
 *
 *  Copyright 2017 Kristian Andrews
 *
 *  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.
 *
 *  In this handler the following actions are recognised
 *    turning clockwise slowly increased the level, the amount is determined by the time turning
 *    turning clockwise fast increased the level by 50
 *    turning anticlockwise slowly decreases the level, the amount is determined by the time turning
 *    turning anticlockwise fast decreases the level by 50
 *
 *  There are several reported actions that I can't decipher
 *    
 *  When the level reaches 0 the switch is turned off, any level above 0 the switch is on
 *  
 *  Can be used to control lights by the use of a SmartApp such as Synchronised Dimming
 *
 *  To do:
 *  1) Debug why the light flashes when I turn off, maybe I don't need to report events for the ones that are set or the commands should be reversed?
 *  e.g. when Off is set from the app GUI do I need to send an Off event as well?
 *  2) Update so that a fast turn clockwise/anticlockwise can turn the lights on and off but maintain the set level
 */
metadata {
	definition (name: "Tradfri Dimmer v0.2", namespace: "andrews.k", author: "Kristian Andrews") {
		capability "Sensor"
		capability "Switch"
		capability "Switch Level"
        capability "Configuration"

		fingerprint endpointId: "01", profileId: "0104", deviceId: "0810", deviceVersion: "02", inClusters: "0000, 0001, 0003, 0009, 0B05, 1000", outClusters: "0003, 0004, 0006, 0008, 0019, 1000"
	}


	simulator {
		// TODO: define status and reply messages here
	}
    
    // UI tile definitions
    tiles(scale: 2) {
        multiAttributeTile(name:"switch", type: "lighting", width: 6, height: 4, canChangeIcon: true){
            tileAttribute ("device.switch", key: "PRIMARY_CONTROL") {
                attributeState "on", label:'${name}', action:"switch.off", icon:"st.switches.light.on", backgroundColor:"#00A0DC", nextState:"turningOff"
                attributeState "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 ("device.level", key: "SLIDER_CONTROL") {
                attributeState "level", action:"switch level.setLevel"
            }
        }

        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 events into attributes
def parse(String description) {
	log.debug "Parsing '${description}'"
	// TODO: handle 'switch' attribute
	// TODO: handle 'level' attribute
	def name = null
    def value = null
    def name2 = null
    def value2 = null
    
    // Check if the stored variables are initialised
    if (state.level == null) {
    	state.level = 100
    }
    
    if (state.OnOff == null) {
    	state.OnOff = 1
    }
    
    if (state.start == null) {
    	state.start = now()
    }
    
    if (state.clockwise == null) {
    	state.clockwise = 0
    }
    
    if (description?.startsWith("catchall:")) {
    	//def descMap = zigbee.parseDescriptionAsMap(description)
        
        log.debug "Catch all: $description"
        log.debug zigbee.parseDescriptionAsMap(description)
        
        // Responds to Zigbee events sent by the dimmer
        // Probably not the most elegant solution
        if (description.endsWith("00 0000 05 00 00C3")) {
        
        	// Start Turn clockwise
            log.debug "cw"
            
            // Store when the turning started and the direction
            state.start = now()
            state.clockwise = 1
        } else if (description.endsWith("00 0000 01 00 01C3")) {
        	// Start turn anticlockwise
            log.debug "acw"
            
            // Store when the turning started and the direction
            state.start = now()
            state.clockwise = -1
        } else if (description.endsWith("00 0000 07 00 ")) {
        	// Stop turning
            log.debug "Stop"
            
            // Calculate duration of turn
            def turnTime = now() - state.start
            //log.debug "Turn ms: $turnTime"
            
            // If the turn is too long ignore it, it probably came from a missed event
            if (turnTime > 2500) {
            	turnTime = 0
            }
            
            // How much change to the level
            // 2000 ms = full up or down
            int change = turnTime / 20
            
            //log.debug change
            
            if (state.clockwise == 1) {
            	// If clockwise, increase the level and turn on
            	
                // Update the stored state
                state.level = state.level + change
                
                // If above 100 reset to 100
                if (state.level > 100){
                	state.level = 100
                }
                
                // Create the ST event details
                name = "level"
                value = state.level
                
                // Turn on switch if off
                if (state.OnOff == 0){
                	// Create the ST event details
                	name2 = "switch"
                	value2 = "on"
                    
                    // Update the stored state
                    state.OnOff = 1
                }
                
                // Set state to not turning
                state.clockwise = 0
            } else if (state.clockwise == -1){
            	// If anticlockwise, decrease the level
                
                // Reduce the stored level
                state.level = state.level - change
                
                // If below 0 reset to 0
                if (state.level < 0){
                	// Make sure it doesn't go below 0
                	state.level = 0
                }
                
                // Create the ST event details
                name = "level"
                value = state.level
                
                // If level = 0 then turn off switch
                if (state.level == 0) {
                	// Update stored state
                	state.OnOff = 0
                    
                    // Create ST event details
                    name2 = "switch"
                    value2 = "off"
                }
                
                // Set state to not turning
                state.clockwise = 0
            }
        } else if (description.endsWith("00 0000 04 00 000100")) {
        	// Fast turn anti-clockwise
            log.debug "fast acw"
            
            // turn down level by 50
            state.level = state.level - 50
            
            // If below 0 reset to 0
            if (state.level < 0){
            	state.level = 0
            }
            
            // Create ST event details
            name = "level"
            value = state.level
            
            // if reached 0 turn off switch
            if (state.level == 0) {
            	if (state.OnOff == 1) {
	            	state.OnOff = 0
    	            name2 = "switch"
        	        value2 = "off"
                }
            }
        } else if (description.endsWith("00 0000 04 00 FF0100")) {
        	// Fast turn clockwise
            log.debug "fast cw"
            
            // turn up level by 50
            state.level = state.level + 50
            
            // make sure it doesn't go above 100
            if (state.level > 100) {
            	state.level = 100
            }
            
            name = "level"
            value = state.level
            
            if (state.OnOff == 0) {
            	state.OnOff = 1
            	name2 = "switch"
            	value2 = "on"
            }
        } else if (description.endsWith("00 0000 07 00 ")) {
        	// Unknown reply - appears after most turns
            log.debug "Unknown catchall 1"
        } else {
            log.debug "Other Catch all: '$description'"
            // The output I have seen so far from the dimmer
            // catchall: 0104 0008 01 01 0100 00 D035 01 00 0000 04 00 000100 - fast turn anti-clockwise
            // catchall: 0104 0008 01 01 0140 00 D035 01 00 0000 04 00 000100 - different type of fast turn anti-clockwise?
            // catchall: 0104 0008 01 01 0100 00 D035 01 00 0000 04 00 FF0100 - fast turn clockwise
            // catchall: 0104 0008 01 01 0140 00 D035 01 00 0000 04 00 FF0100 - different type of fast turn clockwise?
            
            //def descMap = zigbee.parseDescriptionAsMap(description)
        	//log.debug zigbee.parseDescriptionAsMap(description)
        }
    } else {
    	log.debug "Not catch all: $description"
    }
    
    // createEvent returns a Map that defines an Event
    def result = createEvent(name: name, value: value)
    def result2 = createEvent(name: name2, value: value2)
    
    // If there is any result log it
    if (name != null) {
		log.debug "Result 1: ${result?.descriptionText}"
    }
    if (name2 != null) {
    	log.debug "Result 2: ${result2?.descriptionText}"
	}
    
    // returning the Event definition map creates an Event
    // in the SmartThings platform, and propagates it to
    // SmartApps subscribed to the device events.
    return [result, result2]
}

// handle commands
def on() {
	log.debug "Executing 'on'"
	// Handles 'on' commands from the SmartThings app or others
    
    // if switched off, turn on and set level to 50
    state.level = 50
    state.OnOff = 1
    
    // Send switch on and level events
    sendEvent(name: "switch", value: "on")
    sendEvent(name: "level", value: 50)
}

def off() {
	log.debug "Executing 'off'"
	// Handles 'off' commands from the SmartThings app or others
    
    // Update the stored state
    state.level = 0 // Set level to 0
    state.OnOff = 0 // Set to off
    
    // Send events to report set level and switch off
    sendEvent(name: "switch", value: "off")
    sendEvent(name: "level", value: 0)
}

def setLevel(int lev) {
	log.debug "Executing 'setLevel' $lev"
	// Handles 'setLevel' commands from the SmartThings app or others
    
    // If the level has changed
    if (lev != state.level) {
        if (lev == 0) {
        	// If 0 switch off
        	
            // Update the stored state
            state.level = lev
            state.OnOff = 0
            
            // Send events for the updates
            sendEvent(name: "switch", value: "off")
            sendEvent(name: "level", value: 0)
        } else {
        	// Set the stored level
            state.level = lev
            
            // If above 100 set to 100
            if (state.level > 100) {
            	state.level = 100
            }
            
            // If the switch is off turn it on
            if (state.OnOff == 0) {
            	state.OnOff = 1 // Update stored state to on
                sendEvent(name: "switch", value: "on")
            }
            
            // Send event to set the level (needed?)
            sendEvent(name: "level", value: state.level)
        }
    }
}

def configure() {
	log.debug "Configure called"
	["zdo bind 0x${device.deviceNetworkId} 0x01 0x01 8 {${device.zigbeeId}} {}"]
}
1 Like

I did a major refactoring to this handler and published it to my Github repository under the ā€œv0.2ā€ version.

It should solve a LOT OF PROBLEMS. Butā€¦ itā€™s reported as a simple dimmer-switchā€¦ next step is to control something else from it :-).

1 Like

Hello, thanks for the update, nice to see it done properly rather than my ā€œit kinda worksā€ code :slight_smile:
Your handler is working for me but a couple of points Iā€™m not sure if they are your intended operation:

  1. When turning the wheel slowly the change in the dimming level is very slow for me, I have to rotate the dimmer for about a second to get a 10% change in level. This isnā€™t so bad, it just depends how sensitive you want it to be (my one goes from 0-100 in 2 seconds of turning).
  2. Fast turning the wheel clockwise/anticlockwise instantly goes from 0-100% and off to on (and vice versa), but slow turning the wheel only changes the level, it doesnā€™t change the switch state.

On another note, Iā€™m not sure what kind of functionality people would find most useful from this device. We know it can report a limited set of events (slow turns and fast turns and the direction of turning).
These events could be used in different ways e.g.

  1. Slow turn adjusts the level, fast turn adjusts it faster (as my handler, jumps 50%)
  2. Slow turn adjusts the level, fast turn turns on and off without changing the current level
  3. Slow turn adjusts the level, fast turn goes all the way up or down (as your handler)

Maybe we should aim to replicate the way it works with the Ikea bulbs, I havenā€™t tried linking it with the bulb to see what a fast turn does, can anyone tell us?

When I created the initial handler it was more for my own interest, I linked it up to the Synchronised Dimming smart app to control lights but to be honest I havenā€™t really used it much since then. It would be interesting to know what people want to use it for.

Cheers,
Kris.

The dimmer is designed to control a light bulb directly, so instead of emitting positions, itā€™s emitting lights instructionsā€¦ Iā€™m just interpreting those instructions.

The biggest problem is the delay between the ā€œstart movingā€ and the ā€œstopā€ā€¦ specially yesterday when there was lag problems in the cloud, it was not very smooth. The best would be to run the handler locally on the device, but thatā€™s not something we can force on ST.

If you want to change the speed for slow moves, change the values at lines 103 and 122.

Carl.

This evening (Iā€™m in Montreal so itā€™s the day here) Iā€™ll add settings pages for few tweaks.

Alsoā€¦ do you have an idea how we can make this useful? I meanā€¦ it should be able to control a real lamp. Maybe we should be able to connect to a real light in the settings instead of being declared as a ā€œlevel switchā€ itself. What do you think ? Or maybe it should be a smartappā€¦

Carl.