Sengled RGBW LED Strip


#41

No idea...


#42

What driver?


#43

It auto selected Geneic Zigbee Bulb HE driver if that’s what you’re asking.

The device is an TRÅDFRI LED driver


#44

Bought a Giderwel from amazon. Can’t get it to connect to Hubitat via Zigbee. Just can’t find it.

Thoughts?


#45

I paired mine to my hue hub. Never tried directly to Hubitat. Although I don't see why it wouldn't work.


#46

Same here. Paired and work great through Hue hub. Didn't try direct to Hubitat.


#47

It appears the Giderwel device only supports Zigbee Light Link (ZLL). Hubitat only supports Zigbee Home Automation (ZHA). These are two different Zigbee protocols.

image

Phillips Hue supports ZLL which is why it pairs with the Hue bridge.


#48

It's my understanding that ZLL devices are supposed to fall over to ZHA if they can't find a ZLL network to join--that's why people are able to get other ZLL devices like Hue and Tradfri bulbs paired directly to Hubitat. That being said, I wouldn't recommend it--it doesn't take much searching to find that ZLL devices paired to ZHA networks seem to be poor routers for non-lighting ZHA devices, which can cause headaches with other devices seeming to not work properly (if they're the only Zigbee devices you have on that hub, that appears to be fine).

However, my understanding of the ZLL/ZHA thing could be wrong. That's just what I've head reputable people say, so I'm inclined to believe it. If that's true, what might be happening here is that this LED driver might support only ZLL channels (ZLL supports only a subset of what ZHA allows). Is your Hubitat hub on a ZLL-compatible channel?

But I'll repeat the advice above to not try it unless you don't have "regular" ZHA devices also on this hub. :slight_smile:


#49

That is only true if the device supports both ZLL and ZHA keys, since they are different. It does not appear, at least to me, that supporting ZHA is a requirement for ZLL.


#50

Ask and ye shall receive.

Finally got around to it... For some reason, and maybe someone with more Groovy experience can explain, the motion detection doesn't "kick in" for about 10/15 minutes (and there are log errors until then) but here you go... A Hubitat driver for the Sengled PAR38 with built in motion sensors.

/**
 *  Copyright 2019 cstory777
 *
 *  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.
 *
 */
import hubitat.zigbee.clusters.iaszone.ZoneStatus

metadata {
	definition (name: "Singled PAR38 with Motion Sensor", namespace: "cstory777", author: "cstory777", ocfDeviceType: "oic.d.light", runLocally: true, minHubCoreVersion: '000.019.00012', executeCommandsLocally: true) {
		capability "Actuator"
		capability "Configuration"
		capability "Refresh"
		capability "Light"
		capability "Switch"
		capability "Switch Level"
		capability "Motion Sensor"
		capability "Health Check"

		fingerprint profileId: "0104", inClusters: "0000, 0003, 0004, 0005, 0006, 0008, 0500, 0702, 0B05, FC01", outClusters: "0019", manufacturer: "sengled", model: "E13-N11", deviceJoinName: "Sengled Smart LED with Motion Sensor PAR38 Bulb"
	}

	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("motion", "device.motion", decoration: "flat", width: 2, height: 2) {
			state "active", label: 'motion', icon: "st.motion.motion.active", backgroundColor: "#00A0DC"
			state "inactive", label: 'no motion', icon: "st.motion.motion.inactive", backgroundColor: "#cccccc"
		}
		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", "motion", "refresh"])
	}
}

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

	Map map = zigbee.getEvent(description)
	if (!map) {
		if (description?.startsWith('zone status')) {
			map = parseIasMessage(description)
		} else {
			def descMap = zigbee.parseDescriptionAsMap(description)
			if (descMap && descMap.clusterInt == 0x0006 && descMap.commandInt == 0x07) {
				if (descMap.data[0] == "00") {
					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 if (device.getDataValue("manufacturer") == "sengled" && descMap && descMap.clusterInt == 0x0008 && descMap.attrInt == 0x0000) {
				// This is being done because the sengled element touch/classic incorrectly uses the value 0xFF for the max level.
				// Per the ZCL spec for the UINT8 data type 0xFF is an invalid value, and 0xFE should be the max.  Here we
				// manually handle the invalid attribute value since it will be ignored by getEvent as an invalid value.
				// We also set the level of the bulb to 0xFE so future level reports will be 0xFE until it is changed by
				// something else.
				if (descMap.value.toUpperCase() == "FF") {
					descMap.value = "FE"
				}
				sendHubCommand(zigbee.command(zigbee.LEVEL_CONTROL_CLUSTER, 0x00, "FE0000").collect { new hubitat.device.HubAction(it) }, 0)
				map = zigbee.getEventFromAttrData(descMap.clusterInt, descMap.attrInt, descMap.encoding, descMap.value)
			} else if (descMap?.clusterInt == 0x0500 && descMap.attrInt == 0x0002) {
				def zs = new ZoneStatus(zigbee.convertToInt(descMap.value, 16))
				map = translateZoneStatus(zs)
			} else if (descMap?.clusterInt == zigbee.IAS_ZONE_CLUSTER && descMap.attrInt == zigbee.ATTRIBUTE_IAS_ZONE_STATUS && descMap?.value) {
				map = translateZoneStatus(new ZoneStatus(zigbee.convertToInt(descMap?.value)))
			} else {
				log.warn "DID NOT PARSE MESSAGE for description : $description"
				log.debug "${descMap}"
			}
		}
	} else if (map.name == "level" && map.value == 0) {
		map = [:]
	}

    //log.info "${device.data}"
	log.debug "Parse returned $map"
	def result = map ? createEvent(map) : [:]

	return result
}

private Map parseIasMessage(String description) {
	ZoneStatus zs = zigbee.parseZoneStatus(description)

	return translateZoneStatus(zs)
}

private Map translateZoneStatus(ZoneStatus zs) {
	// Some sensor models that use this DTH use alarm1 and some use alarm2 to signify motion
	return getMotionResult(zs.isAlarm1Set() || zs.isAlarm2Set())
}

private Map getMotionResult(value) {
	def descriptionText = value ? "${device.displayName} detected motion" : "${device.displayName} motion has stopped"
	return [
			name			: 'motion',
			value			: value ? 'active' : 'inactive',
			descriptionText : descriptionText,
			translatable	: true
	]
}

def off() {
	zigbee.off()
}

def on() {
	zigbee.on()
}

def setLevel(value, rate = null) {
	zigbee.setLevel(value)
}
/**
 * PING is used by Device-Watch in attempt to reach the Device
 * */
def ping() {
	return zigbee.onOffRefresh() + zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS)
}

def refresh() {
    zigbee.onOffRefresh() + zigbee.levelRefresh() + zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS)
}

def setupHealthCheck() {
	// 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 * 10 * 60 + 1 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}

def installed() {
	setupHealthCheck()
}

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

	// OnOff minReportTime 0 seconds, maxReportTime 5 min. Reporting interval if no activity
	zigbee.onOffConfig(0, 300) + zigbee.levelConfig() + zigbee.enrollResponse() + refresh()
}