Anything like "Enhanced-Dimmer-Switch" for 45857GE zigbee switches?

I just looked at my dimmer and the OnOffTransitionTime zigbee attribute. This attribute represents the time taken to move to or from the target level when on or off commands are received. When I checked the attribute it stated unsupported. So it looks like GE did not implement that ability.

cluster: 0008, size: 06, attrId: 0010, result: unsupported attr

2 Likes

Thanks for taking a look! I will definitely take this into account when I change other switches. I have 8 (not smart) Lutron dimmer switches in my home theater that I need to change so I will definitely do some more research now that I know what to look for.

So after looking some more I think there is a way to do this. It will require more changes than I thought (as the simple fix above is not supported). I’ll update you when I have some sample code.

2 Likes

You’re awesome! The more I use the switches the more it bugs me. I even formulated a plan to move them elsewhere in the house and replace them with a model that works the way I want. Please let me know if you get it worked out!

After doing more work I can kind of simulate it through SmartThings zigbee commands but unfortunately I can’t change how the physical button presses act. The only way to do that was with the attribute that GE does not support.

1 Like

Here is what I’ve put together. Unfortunately it is kludgy as the official method to do this is not supported. Also to note: off now sets the current level to 0%. This is different than how all other DTHs work. Let me know if this is helpful.

/**
*  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.
*
*/
metadata {
    definition (name: "Enhanced ZigBee Dimmer Power", namespace: "smartthings", author: "SmartThings") {
        capability "Actuator"
        capability "Configuration"
        capability "Refresh"
        capability "Power Meter"
        capability "Sensor"
        capability "Switch"
        capability "Switch Level"
        capability "Health Check"

        fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0B04"
        fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702"
        fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702, 0B05", outClusters: "0019", manufacturer: "sengled", model: "Z01-CIA19NAE26", deviceJoinName: "Sengled Element touch"
        fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702, 0B05", outClusters: "000A, 0019", manufacturer: "Jasco Products", model: "45852", deviceJoinName: "GE Zigbee Plug-In Dimmer"
        fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0702, 0B05", outClusters: "000A, 0019", manufacturer: "Jasco Products", model: "45857", deviceJoinName: "GE Zigbee In-Wall Dimmer"
    }

    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.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
                attributeState "off", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
                attributeState "turningOn", label:'${name}', action:"switch.off", icon:"st.switches.switch.on", backgroundColor:"#79b821", nextState:"turningOff"
                attributeState "turningOff", label:'${name}', action:"switch.on", icon:"st.switches.switch.off", backgroundColor:"#ffffff", nextState:"turningOn"
            }
            tileAttribute ("device.level", key: "SLIDER_CONTROL") {
                attributeState "level", action:"switch level.setLevel"
            }
            tileAttribute ("power", key: "SECONDARY_CONTROL") {
                attributeState "power", label:'${currentValue} W'
            }
        }
        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"])
    }
    preferences {
        section ("Zigbee Dimmer Properties"){
            input "transitionTime", "number", title: "Tranistion Time (0-15)", description: true, defaultValue: 5, required: false, range: "0..15"
            input "minLevel", "number", title: "Minimum Dimmer Level (1-50)", description: true, defaultValue: 1, required: false, range: "1..50"
            input "maxLevel", "number", title: "Maximum Dimmer Level (51-100)", description: true, defaultValue: 100, required: false, range: "51..100"
        }
    }
}

private getCLUSTER_LEVEL() { 0x0008 }
private getLEVEL_CMD_MOVE_TO_LEVEL_ON_OFF() { 0x04 }
private getLEVEL_ATTR_ON_LEVEL() { 0x0011 }

    // Parse incoming device messages to generate events
def parse(String description) {
    log.debug "description is $description"

    def event = zigbee.getEvent(description)
    if (event) {
        log.info event
        if (event.name == "power") {
            if (device.getDataValue("manufacturer") != "OSRAM") {       //OSRAM devices do not reliably update power
                event.value = (event.value as Integer) / 10             //TODO: The divisor value needs to be set as part of configuration
                sendEvent(event)
            }
        }
        else {
            sendEvent(event)
        }
    }
    else {
        def cluster = zigbee.parse(description)
        if (cluster && cluster.clusterId == 0x0006 && cluster.command == 0x07) {
            if (cluster.data[0] == 0x00){
                log.debug "ON/OFF REPORTING CONFIG RESPONSE: " + cluster
                sendEvent(name: "checkInterval", value: 60 * 12, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
            }
            else {
                log.warn "ON/OFF REPORTING CONFIG FAILED- error code:${cluster.data[0]}"
            }
        }
        else {
            log.warn "DID NOT PARSE MESSAGE for description : $description"
            log.debug zigbee.parseDescriptionAsMap(description)
        }
    }
}

def off() {
    //zigbee.off()
    state.currentLevel = (device.currentValue('level')) ? device.currentValue('level') : state.currentLevel
    def onLevel = (state.currentLevel && state.currentLevel < 100) ? state.currentLevel * 2.55 : 254
    def cmds = setLevel(0, true) + zigbee.writeAttribute(CLUSTER_LEVEL, LEVEL_ATTR_ON_LEVEL, 0x20, zigbee.convertToHexString(onLevel,2))
    log.info "off() -- cmds: $cmds -- $state.currentLevel"
    return cmds
}

def on() {
    //zigbee.on()
    def value = (state.currentLevel) ? state.currentLevel : myMaxLevel
    def cmds = setLevel(value)
    log.info "on() -- cmds: $cmds -- $state.currentLevel"
    return cmds
}

def setLevel(value, dontSetOnLevel=false) {
    //zigbee.setLevel(value)
    def cmds
    def myTime = (transitionTime) ? transitionTime : 5
    def myMinLevel = (minLevel) ? minLevel : 1
    def myMaxLevel = (maxLevel) ? maxLevel : 100
    if ( value && value < myMinLevel ) {
        value = myMinLevel
    } else if ( value > myMaxLevel ) {
        value = myMaxLevel
    }
    def myLevel = ( value < 100 ) ? value * 2.55 : 254
    if (dontSetOnLevel) {
        cmds = zigbee.command(CLUSTER_LEVEL, LEVEL_CMD_MOVE_TO_LEVEL_ON_OFF, zigbee.convertToHexString(myLevel,2) + zigbee.convertToHexString(myTime,2) + "00")
    } else {
        def myOnLevel = myLevel
        state.currentLevel = value
        if ( ! value ) {
            myOnLevel = ( myMaxLevel < 100 ) ? myMaxLevel * 2.55 : 254
            state.currentLevel = myMaxLevel
        }
        cmds = zigbee.command(CLUSTER_LEVEL, LEVEL_CMD_MOVE_TO_LEVEL_ON_OFF, zigbee.convertToHexString(myLevel,2) + zigbee.convertToHexString(myTime,2) + "00") +
               zigbee.writeAttribute(CLUSTER_LEVEL, LEVEL_ATTR_ON_LEVEL, 0x20, zigbee.convertToHexString(myOnLevel,2))
    }
    log.info "setLevel() -- cmds: $cmds -- $state.currentLevel"
    return cmds
}

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

def refresh() {
    zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.simpleMeteringPowerRefresh() + zigbee.electricMeasurementPowerRefresh() + zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.simpleMeteringPowerConfig() + zigbee.electricMeasurementPowerConfig()
}

def configure() {
    log.debug "Configuring Reporting and Bindings."

    // Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
    // enrolls with default periodic reporting until newer 5 min interval is confirmed
    sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
    refresh()
}
1 Like

We just got home and I installed it on my switches… Works like a charm!! We tend to use voice commands more than anything these days so the fact that the switch doesn’t dim isn’t a big deal at all for my application.

Thank you for taking the time to make this and share it! I appreciate the work.

1 Like

I think there may have been a bug (I updated the code above but have not gotten a chance to test). To experience the bug:

  1. Turn off switch via SmartThings
  2. Turn on switch (manually or by SmartThings)
  3. Change the dimmer level (manually or by SmartThings)
  4. Turn off the switch manually
  5. Turn on the switch manually

I think if you do that, the switch will turn on the original dimmer level before your change. Not a big deal but the code above should fix it.

1 Like

I can confirm the bug. You’re right that it’s not a big deal but I am updating the code and will reply if anything odd happens.

One thing I have noticed a couple of times is that a switch will be at 0% when I try to turn the light manually (resulting in nothing happening). To fix it I just have to press and hold the switch ‘up’ to bring the brightness up but it confused me the first time it happened. I think it has only happened in my bedroom where I have “Gentle Wake Up” enabled so that’s likely what’s causing the issue. I am going to play around with it and pay more attention as to when it happens.

Thanks again!!

With the new code I can turn on the lights with SmartThings but can not turn them off with SmartThings (manual switch still works). When giving the command to the Echo “Turn off the lights” it will give an “OK” response but nothing happens. Pressing the button in SmartThings changes it to “turningoff” but nothing happens.

Unfortunately I overwrote the old code without saving it so I am reverting back to the original DH for now.

Sorry about that. I’ll have some time this evening to work on it. Should have the revised code within a few hours.

Also due to how the DTH works you will likely have some weird legacy artifacts when switching back to the old DTH (such as the dimmer level going to 0% when off and always turning back on to the same %). To fix you’ll need to reset the switch by pulling the air gap.

2 Likes

OK I believe it is fixed. I also added the capability to add a max and/or min dimmer level. I have some bulbs that don’t turn on below 25%. I used CoRE before but if someone specified a value less than 25% they turned off then back on - now they stay on with this DTH.

1 Like

That one works to turn off the lights but there is about a 3 second delay in turning them off through SmartThings. Turning them on is relatively ‘instant’ but turning them off seems to lag. Is that by design?

Let me fix that. It is because I send two commands to the switch. By default now SmartThings adds a 2 second delay between zigbee commands.

This line in off

def cmds = zigbee.writeAttribute(CLUSTER_LEVEL, LEVEL_ATTR_ON_LEVEL, 0x20, zigbee.convertToHexString(onLevel,2)) + setLevel(0, true)

became

def cmds = setLevel(0, true) + zigbee.writeAttribute(CLUSTER_LEVEL, LEVEL_ATTR_ON_LEVEL, 0x20, zigbee.convertToHexString(onLevel,2))
1 Like

Sadly… We are back to not turning them off at all. :-/ It’s definitely in that line because swapping them back out allows them to be turned off but with the delay. I wish I knew more about code!

Apparently I can’t type myself. I changed it in my code but edited it above incorrectly. Had a lowercase L instead of capital. Give it one more try.

1 Like

Bingo! That one works. I obviously don’t have the eye for detail to do this kind of code. I would have never caught a lower case L being the problem. :slight_smile:

Thanks again (again)! :slight_smile:

Is there anything you can think of that might cause this to set the brightness level to 0% (or very close to it) after the lights have been off for a while?

Last night I turned off the lights in my kitchen and living room with SmartThings. This morning when I turned them on the kitchen was very low (like 5% or so) and the living room was at 0%. The levels were high when I turned them off last night so I know they weren’t dimmed at last use. A command to Alexa to put them to 100% caused them to turn up and they seem to work fine when I cycle them on and off with SmartThings.

This is the issue I mentioned earlier and since those two rooms aren’t tied to the “Gentle Wake Up” function I don’t think that’s the issue. Once they have been turned on and the brightness set they work normally but it’s like when they are off for an extended amount of time the brightness is turned down.

I’ll see if I can get that to happen as well and let you know. I’ve seen the SmartThings app slider bar report the low number but the switch actually was at the correct level.

The level the light is when turned off is stored in a state variable. That variable is used to specify the level when on is run through SmartThings. Somehow that variable must be getting lost or overwritten. I’ll look at it some more.

1 Like

I did change one line but I’m not sure if that will solve your issue. Unfortunately, there is one limitation since I’m doing this outside of the official ZigBee method. If you change the dimmer level manually with the paddle, that won’t be reflected in a manual off then on (should go back to last setting before you manually changed the dimmer). There is no reliable way to fix that.

I actually can think of a way you could experience what you are seeing. This could happen if two off commands through SmartThings were sent to the cloud very close together. Do you use any automations like Smart Lighting or CoRE? I could perhaps put a timing wrapper so you can’t send more than one command in a few seconds.

This would have been so much easier if GE just supported the OnOffTransition attribute.

1 Like