Cree to offer Zigbee LED smart bulb

I’m still not a fan of the intelligence being in the bulb. I find that it works so much better having it in the switch. You can still use it like a regular old manual switch, but you can also automate things too.
Just my two cents - you results may vary.

I am getting success with 2 of these-- thanks to @Joshua_Gray for the code. As reported, working on-off, no dimming.

Steps:

The 2 cree bulbs were added and showed as “unknown”.
I added the code reformatted by @dckirker to “my device types”, “by code”.
Then, I edited the two bulbs in “my devices” and changed the type.

Success!

Thank you! for the reformat

I see my local HD has these in stock, so I’m going to try them out. I’m a newb to the IDE, so what exactly do I do with the code posted above from dckirker?

FWIW, that isn’t my code. Just a re-post. So, hat tip to @Joshua_Gray.

A co-worker and I are working on supported code. However, I can’t comment on a time-line, yet. That said, they are pretty solid bulbs (from the bit that I have seen).

OK, but with that being said, do I just go to the IDE -> My Device Types -> New Device Type -> From Code, and then paste this code in?

Thanks

Yes exactly just paste it in

Getting an error with that code. Anyway to get that code in a attachment as copying from this thread seems to be an issue.

Org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: script14223306656351899370164.groovy: 185: Invalid variable name. Must start with a letter but was:  . At [185:1] @ line 185, column 1.  ^ 1 error

I pasted the code into a new device type and it works fine for me (for off/on, not dimming). I will look forward to future enhancements to support dimming! Thanks SmartThings community!

So for yourself and @Joshua_Gray, do you have newer firmware from ST or just the stock firmware?
Also curious to compare the device ids:

Raw Description: 0A C05E 0100 02 07 0000 1000 0004 0003 0005 0006 0008 02 0000 0019
Zigbee Id: E20DB9FFFE004165
Device Network Id: 5BE7

I adjusted @Joshua_Gray’s code to use endpoint 10 in the setLevel command, so hopefully it’ll get dimming working. It should also get refresh() working.

Good luck!

 /**
     *  Cree Connected from GE Link Bulb
     *
     *  Copyright 2014 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.
     *
     *  Thanks to Chad Monroe @cmonroe and Patrick Stuart @pstuart
     *
     */
    metadata {
        definition (name: "Cree Connected Beta TEMP", namespace: "Temp", author: "JGray") {
        
            capability "Actuator"
            capability "Configuration"
            capability "Refresh"
            capability "Sensor"
            capability "Switch"
            capability "Switch Level"
    
            fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019"
        }
    
        // simulator metadata
        simulator {
            // status messages
            status "on": "on/off: 1"
            status "off": "on/off: 0"
    
            // reply messages
            reply "zcl on-off on": "on/off: 1"
            reply "zcl on-off off": "on/off: 0"
        }
    
        // UI tile definitions
        tiles {
            standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
                state "off", label: '${name}', action: "switch.on", icon: "st.switches.light.off", backgroundColor: "#ffffff"
                state "on", label: '${name}', action: "switch.off", icon: "st.switches.light.on", backgroundColor: "#79b821"
            }
            standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
                state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
            }
            controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 3, inactiveLabel: false) {
                state "level", action:"switch level.setLevel"
            }
            valueTile("level", "device.level", inactiveLabel: false, decoration: "flat") {
                state "level", label: 'Level ${currentValue}%'
            }
            
    
            main(["switch"])
            details(["switch", "level", "levelSliderControl", "refresh"])
        }
    }
    
    // Parse incoming device messages to generate events
    def parse(String description) {
        log.trace description
        if (description?.startsWith("catchall:")) {
            //def msg = zigbee.parse(description)
            //log.trace msg
            //log.trace "data: $msg.data"
            if(description?.endsWith("0100"))
            {
                def result = createEvent(name: "switch", value: "on")
                log.debug "Parse returned ${result?.descriptionText}"
                return result
            }
            if(description?.endsWith("0000"))
            {
                def result = createEvent(name: "switch", value: "off")
                log.debug "Parse returned ${result?.descriptionText}"
                return result
            }
        }
        if (description?.startsWith("read attr")) {
            log.debug description[-2..-1]
            def i = Math.round(convertHexToInt(description[-2..-1]) / 256 * 100 )
            
            sendEvent( name: "level", value: i )
        }
        
        
    }
    
    def on() {
        log.debug "on()"
        sendEvent(name: "switch", value: "on")
        "st cmd 0x${device.deviceNetworkId} 10 6 1 {}"
    }
    
    def off() {
        log.debug "off()"
        sendEvent(name: "switch", value: "off")
        "st cmd 0x${device.deviceNetworkId} 10 6 0 {}"
    }
    
    def refresh() {
        [
        "st rattr 0x${device.deviceNetworkId} 10 6 0", "delay 500",
        "st rattr 0x${device.deviceNetworkId} 10 8 0"
        ]
    }
    
    def setLevel(value) {
        log.trace "setLevel($value)"
        def cmds = []
    
        if (value == 0) {
            sendEvent(name: "switch", value: "off")
            cmds << "st cmd 0x${device.deviceNetworkId} 10 8 0 {0000 0000}"
        }
        else if (device.latestValue("switch") == "off") {
            sendEvent(name: "switch", value: "on")
        }
    
        sendEvent(name: "level", value: value)
        def level = new BigInteger(Math.round(value * 255 / 100).toString()).toString(16)
        cmds << "st cmd 0x${device.deviceNetworkId} 10 8 4 {${level} 0000}"
    
        //log.debug cmds
        cmds
    }
    
    def configure() {
    
        String zigbeeId = swapEndianHex(device.hub.zigbeeId)
        log.debug "Confuguring Reporting and Bindings."
        def configCmds = [    
      
            //Switch Reporting
            "zcl global send-me-a-report 6 0 0x10 0 3600 {01}", "delay 500",
            "send 0x${device.deviceNetworkId} 10 1", "delay 1000",
            
            //Level Control Reporting
            "zcl global send-me-a-report 8 0 0x20 5 3600 {0010}", "delay 200",
            "send 0x${device.deviceNetworkId} 10 1", "delay 1500",
            
            "zdo bind 0x${device.deviceNetworkId} 10 1 6 {${device.zigbeeId}} {}", "delay 1000",
            "zdo bind 0x${device.deviceNetworkId} 10 1 8 {${device.zigbeeId}} {}", "delay 500",
        ]
        return configCmds + refresh() // send refresh cmds as part of config
    }
    
    
    
    private hex(value, width=2) {
        def s = new BigInteger(Math.round(value).toString()).toString(16)
        while (s.size() < width) {
            s = "0" + s
        }
        s
    }
    
    private Integer convertHexToInt(hex) {
        Integer.parseInt(hex,16)
    }
    
    private String swapEndianHex(String hex) {
        reverseArray(hex.decodeHex()).encodeHex()
    }
    
    private byte[] reverseArray(byte[] array) {
        int i = 0;
        int j = array.length - 1;
        byte tmp;
        while (j > i) {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
            j--;
            i++;
        }
        return array
    }

I tried to update the beta code above, with this version. It’s giving me an error:

org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
script1422382441385995219444.groovy: 119: unexpected token: & @ line 119, column 22.
cmds << “st cmd 0x${device.deviceNetworkId} 10 8 0 {0000 0000}”
^

1 error

Looks like a few ampersands got added in on a few lines - also 127, 157 lines…I just got rid of the ampersands and was able to update the device type. Haven’t tested it yet…

I looked at the code, it is more than just ampersands. The “<” was replaced by “ampersand lt;” and “>” was replaced by “ampersand gt;”, where the word ampersand is an actual ampersand character. I set these back properly and now dimming is working!!

1 Like

Ok, so I took the code posted previously and fixed the broken parts:

Tested and working.

/**
 *  Cree Connected from GE Link Bulb
 *
 *  Copyright 2014 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.
 *
 *  Thanks to Chad Monroe @cmonroe and Patrick Stuart @pstuart
 *
 */
metadata {
    definition (name: "Cree Connected Beta TEMP", namespace: "Temp", author: "JGray") {

        capability "Actuator"
        capability "Configuration"
        capability "Refresh"
        capability "Sensor"
        capability "Switch"
        capability "Switch Level"

        fingerprint profileId: "0104", inClusters: "0000,0003,0004,0005,0006,0008,1000", outClusters: "0019"
    }

    // simulator metadata
    simulator {
        // status messages
        status "on": "on/off: 1"
        status "off": "on/off: 0"

        // reply messages
        reply "zcl on-off on": "on/off: 1"
        reply "zcl on-off off": "on/off: 0"
    }

    // UI tile definitions
    tiles {
        standardTile("switch", "device.switch", width: 2, height: 2, canChangeIcon: true) {
            state "off", label: '${name}', action: "switch.on", icon: "st.switches.light.off", backgroundColor: "#ffffff"
            state "on", label: '${name}', action: "switch.off", icon: "st.switches.light.on", backgroundColor: "#79b821"
        }
        standardTile("refresh", "device.switch", inactiveLabel: false, decoration: "flat") {
            state "default", label:"", action:"refresh.refresh", icon:"st.secondary.refresh"
        }
        controlTile("levelSliderControl", "device.level", "slider", height: 1, width: 3, inactiveLabel: false) {
            state "level", action:"switch level.setLevel"
        }
        valueTile("level", "device.level", inactiveLabel: false, decoration: "flat") {
            state "level", label: 'Level ${currentValue}%'
        }


        main(["switch"])
        details(["switch", "level", "levelSliderControl", "refresh"])
    }
}

// Parse incoming device messages to generate events
def parse(String description) {
    log.trace description
    if (description?.startsWith("catchall:")) {
        //def msg = zigbee.parse(description)
        //log.trace msg
        //log.trace "data: $msg.data"
        if(description?.endsWith("0100"))
        {
            def result = createEvent(name: "switch", value: "on")
            log.debug "Parse returned ${result?.descriptionText}"
            return result
        }
        if(description?.endsWith("0000"))
        {
            def result = createEvent(name: "switch", value: "off")
            log.debug "Parse returned ${result?.descriptionText}"
            return result
        }
    }
    if (description?.startsWith("read attr")) {
        log.debug description[-2..-1]
        def i = Math.round(convertHexToInt(description[-2..-1]) / 256 * 100 )

        sendEvent( name: "level", value: i )
    }


}

def on() {
    log.debug "on()"
    sendEvent(name: "switch", value: "on")
    "st cmd 0x${device.deviceNetworkId} 10 6 1 {}"
}

def off() {
    log.debug "off()"
    sendEvent(name: "switch", value: "off")
    "st cmd 0x${device.deviceNetworkId} 10 6 0 {}"
}

def refresh() {
    [
    "st rattr 0x${device.deviceNetworkId} 10 6 0", "delay 500",
    "st rattr 0x${device.deviceNetworkId} 10 8 0"
    ]
}

def setLevel(value) {
    log.trace "setLevel($value)"
    def cmds = []

    if (value == 0) {
        sendEvent(name: "switch", value: "off")
        cmds << "st cmd 0x${device.deviceNetworkId} 10 8 0 {0000 0000}"
    }
    else if (device.latestValue("switch") == "off") {
        sendEvent(name: "switch", value: "on")
    }

    sendEvent(name: "level", value: value)
    def level = new BigInteger(Math.round(value * 255 / 100).toString()).toString(16)
    cmds << "st cmd 0x${device.deviceNetworkId} 10 8 4 {${level} 0000}"

    //log.debug cmds
    cmds
}

def configure() {

    String zigbeeId = swapEndianHex(device.hub.zigbeeId)
    log.debug "Confuguring Reporting and Bindings."
    def configCmds = [    

        //Switch Reporting
        "zcl global send-me-a-report 6 0 0x10 0 3600 {01}", "delay 500",
        "send 0x${device.deviceNetworkId} 10 1", "delay 1000",

        //Level Control Reporting
        "zcl global send-me-a-report 8 0 0x20 5 3600 {0010}", "delay 200",
        "send 0x${device.deviceNetworkId} 10 1", "delay 1500",

        "zdo bind 0x${device.deviceNetworkId} 10 1 6 {${device.zigbeeId}} {}", "delay 1000",
        "zdo bind 0x${device.deviceNetworkId} 10 1 8 {${device.zigbeeId}} {}", "delay 500",
    ]
    return configCmds + refresh() // send refresh cmds as part of config
}



private hex(value, width=2) {
    def s = new BigInteger(Math.round(value).toString()).toString(16)
    while (s.size() < width) {
        s = "0" + s
    }
    s
}

private Integer convertHexToInt(hex) {
    Integer.parseInt(hex,16)
}

private String swapEndianHex(String hex) {
    reverseArray(hex.decodeHex()).encodeHex()
}

private byte[] reverseArray(byte[] array) {
    int i = 0;
    int j = array.length - 1;
    byte tmp;
    while (j > i) {
        tmp = array[j];
        array[j] = array[i];
        array[i] = tmp;
        j--;
        i++;
    }
    return array
}
2 Likes

This latest one works for me with dimming. Thanks!

https://vine.co/v/OTF6Y7KvHaw

I tried the above code as a custom device type, but it does not seem to be working for me. Is this working for anyone else or any suggestions? Thanks

We’ll hopefully be publishing our official device type soon.

1 Like

From that video, it almost looks like the slider in the UI causes the bulb to roll around on a table (when it isn’t screwed in.)

2 Likes

I am giving up on my ST hub for now. I think it’s broken and yet everyone here says “Yes I can get MY hub to see the bulb…” mine just sits in the “Searching” mode looking for bulbs. I have tried the GE LINK, and now this CREE bulb, none which show up. I have tried the coding here, pasted it and published it, but still my android app keeps searching for devices.

I have spoke to technical service, they reflashed my ST hub with the latest firmware. Still no GE or CREE bulbs found, even as an unknown device. I am getting tired of being afraid to buy any “Zigbee compatible hub” devices anymore as none of them seem to work.