2.2.4.139 Z-Wave Woes - C7

Hello friends!

Long time reader, first time topic-starter. I'm a reasonably knowledgeable tech guy who's recently made the migration to Habitat with the purchase of a C7. I'm going to try to provide as much detail as I can below with the hopes that those with more knowledge than I can extract what may be useful. Of course, I welcome calls for more information and apologize in advance if I'm unable to reply in a timely fashion. Things are a bit chaotic these days..! Alas, here goes:

Use Case

I live in a ~800 sqft condo and use Habitat to control lighting. My hub is centrally located. My devices are limited to:

  • 2 IKEA E26 bulbs (ZigBee, mains-powered)
  • 5 Somfy blinds (Z-Wave, mains-powered)
  • ~20 Inovelli dimmers (Z-Wave, mains-powered)
  • 4 GE Enbrighten Plug-In dimmers (Z-Wave, mains-powered)
  • 2 Leviton Plug-In dimmers (Z-Wave, mains powered)
  • 2 Leviton VRSC-4 1-gang scene controllers (Z-Wave, mains powered)
  • 2 Ecolink contact sensors (Z-Wave, battery powered)
  • 1 Aeotec Wallmote (Z-Wave, battery powered)

All devices are evenly spread throughout the condo, with nothing being more than 30 linear feet from the hub.

Where applicable, devices were paired without security.

Devices were paired per best-practices over several days, starting with those located nearest the hub.

System has no cloud integrations other than SharpTools.

System reboots nightly at 16h00 EST via the Rebooter app.

Automations are all very simple. I use SharpTools to either manually control devices as-needed, or to call any of 8 Habitat Scenes (created via the Groups & Scenes app). The Scenes control all devices within the condo. Additionally, the 2 contact sensors are used to turn lights on in the entryway closet or bathroom as needed. There are a few additional specifics re: button configurations which I can't imagine are relevant just yet.

Experience prior to 2.2.4 update (whilst running 2.2.3.148)

  • Individual device control (via Devices page or Sharptools) was immediate
  • Rules triggered via Contact Sensors would fire immediately
  • Scenes would fire immediately, but after activating several, Z-Wave devices would start to chug. "Popcorning" would become more and more evident, until some or all Z-Wave devices would fail to respond to the Scene. ZigBee devices unaffected by slowdown.
  • Individual control of devices largely still successful.
  • Countless reboots and Z-Wave repairs did not provide a sustainable fix.
  • Held breath and patiently awaited the release of 2.2.4.

Experience after updating to 2.2.4

  • Backed-up configuration and updated to 2.2.4.139 on Nov 17, 2020.
  • Noted that Scenes activate notably slower, and appear to start immediately bogging down Z-Wave response.
  • Noted that even after a fresh re-boot, the rules triggered by Contact Sensors were very slow (10 seconds to action, at a minimum. Noteworthy - the hub sees the status change of the contact sensors immediately, but the resulting action is considerably delayed)
  • Using Scenes at all seems to cripple the hub very, very quickly. As this occurs, even direct control of individual devices is lost until a reboot.

Things I've tried on both 2.2.3 and 2.2.4

  • Countless Z-Wave repairs
  • Countless reboots
  • Simplifying Scenes (i.e: trying out scenes that control 5 devices instead of 20, then 4 devices, 3 devices etc.). Z-Wave transmission would still get bogged-down.
  • Studiously verified logs for device "chattiness" - none present.
  • Tried building "scenes" using RM. Arguably slower activation, and Z-Wave would still quickly bog-down.
  • Tried relocating hub. No change.
  • Checked for Z-Wave "phantom devices". Nada.
  • Tried multiple safe shutdowns, with power then pulled for several mins. No change.

Alas, I'm at a bit of a loss and am reaching out to this awesome community for some collective troubleshooting! :slight_smile: Do bare with me as I'm very new at this, but know that I'm appreciative and grateful for any and all guidance. I've shared below an example of one of my Scenes. I'd also love to share a copy of my "Z-Wave Details" page, but am uncertain of the best way to place that in a forum post.

Let's see what we can figure out! :smile:

I'm still on 2.2.3 (I'll wait a few weeks for some of the hotfixes), and had some of what you are describing. In my case it was my 2 Leviton plug-in dimmers, that were old z wave not plus. I bought upgrades, and have not seen the problem since. Unless it has changed with this new release, those Leviton plug-in dimmers are not offically compatible, though I've been told that the plus versions are the same electricly as the Leviton DZ6HD-1BZ which is compatible.

Yep - if I were more responsible, that's what I would have done :wink: I'll try unpairing the Leviton Plug-In Dimmers (indeed, they are the older non Z- Wave Plus model) to see if that makes a difference. I'll also restore my 2.2.3 backup to see if it at least restores the "snappiness" of my contact sensor automations.

I'll report back with results!

Just reverted back to 2.2.3, and can confirm that the rules & scenes triggered via contact sensors are back to being super snappy.

I'm jumping into a meeting, but will try removing the 2 older Leviton dimmers as soon as my schedule allows.

r.

I have a number of "old" Leviton plug in dimmers Model VRPD3-1LW .

I found the ported Smartthings driver works best for me:

    /**
 *  
 * https://github.com/SmartThingsCommunity/SmartThingsPublic/tree/    master/devicetypes/smartthings/zwave-dimmer-switch-generic.src 
 *
 *  originally was SmartThings "switch - dimmer" driver.
 *   2018-12-09 - in process of converting to Hubitat for WD500Z-1     dimmers (never completed)
 *	 2019-01-18 - Installed to work the Leviton Dimmer Modules     VRPD3
 * 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:
 *
 *
 *
 */
metadata {
	definition(name: "Z-Wave Dimmer Switch Generic (Leviton)",     namespace: "smartthings", author: "SmartThings") {
		capability "Switch Level"
		capability "Actuator"
		capability "Health Check"
		capability "Switch"
		capability "Polling"
		capability "Refresh"
		capability "Sensor"
		capability "Light"

		fingerprint inClusters: "0x26", deviceJoinName: "Z-Wave     Dimmer"
		fingerprint mfr: "001D", prod: "1902", deviceJoinName:     "Z-Wave Dimmer"
		fingerprint mfr: "001D", prod: "3301", model: "0001",     deviceJoinName: "Leviton Dimmer Switch"
		fingerprint mfr: "001D", prod: "3201", model: "0001",     deviceJoinName: "Leviton Dimmer Switch"
		fingerprint mfr: "001D", prod: "1B03", model: "0334",     deviceJoinName: "Leviton Universal Dimmer"	// this     matches our Leviton
		fingerprint mfr: "001D", prod: "1001", model: "0334",     deviceJoinName: "Leviton 3-Speed Fan Controller"
		fingerprint mfr: "001D", prod: "0602", model: "0334",     deviceJoinName: "Leviton Magnetic Low Voltage Dimmer"
		fingerprint mfr: "001D", prod: "0401", model: "0334",     deviceJoinName: "Leviton 600W Incandescent Dimmer"
		fingerprint mfr: "0039", prod: "5044", model: "3033",     deviceJoinName: "Honeywell Z-Wave Plug-in Dimmer (Dual     Outlet)"
		fingerprint mfr: "0039", prod: "5044", model: "3038",     deviceJoinName: "Honeywell Z-Wave Plug-in Dimmer"
		fingerprint mfr: "0039", prod: "4944", model: "3038",     deviceJoinName: "Honeywell Z-Wave In-Wall Smart Dimmer"
		fingerprint mfr: "0039", prod: "4944", model: "3130",     deviceJoinName: "Honeywell Z-Wave In-Wall Smart Toggle     Dimmer"
		fingerprint mfr: "0063", prod: "4944", model: "3034",     deviceJoinName: "GE In-Wall Smart Fan Control"
		fingerprint mfr: "0063", prod: "4944", model: "3131",     deviceJoinName: "GE In-Wall Smart Fan Control"
		fingerprint mfr: "0039", prod: "4944", model: "3131",     deviceJoinName: "Honeywell Z-Wave Plus In-Wall Fan Speed     Control"
		//fingerprint mfr: "014F", prod: "5744", model: "3530",     deviceJoinName: "Linear In-Wall Dimmer"
	}  // --- end of definition ---

}  //  --- end of metadata ---s
/*
WD500Z-1
deviceType: 17495
inClusters: 0x26,0x2B,0x2C,0x27,0x73,0x70,0x86,0x72
deviceId: 12340  
manufacturer: 335  (0x014F)

Z-Wave Product ID: 0x3034   <--- fingerprint seems to be :  low     byte, hi byte
Z-Wave Product Type: 0x4457
*/


def installed() {
// Device-Watch simply pings if no device events received for 32min    (checkInterval)
	sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60,     displayed: false, data: [protocol: "zwave", hubHardwareId:     device.hub.hardwareID, offlinePingable: "1"])
	def commands = refresh()
	
/*
	if (zwaveInfo?.mfr?.equals("001A")) {
		commands << "delay 100"
		//for Eaton dimmers parameter 7 is ramp time. We set it to     1s for devices to work correctly with local execution
		commands << zwave.configurationV1.configurationSet(    configurationValue: [1], parameterNumber: 7, size:     1).format()
	} else if (isHoneywellDimmer()) {
		//Set ramp time to 1s for this device to turn off dimmer     correctly when current level is over 66.
		commands << "delay 100"
		//Parameter 7 - z-wave ramp up/down step size, Parameter 8     - z-wave step interval equals configurationValue times 10     ms
		commands << zwave.configurationV1.configurationSet(    configurationValue: [1], parameterNumber: 7, size:     1).format()
		commands << "delay 200"
		commands << zwave.configurationV1.configurationSet(    configurationValue: [0, 1], parameterNumber: 8, size:     2).format()
		commands << "delay 200"
		//Parameter 7 - manual operation ramp up/down step size,     Parameter 8 - z-wave manual operation interval equals     configurationValue times 10 ms
		commands << zwave.configurationV1.configurationSet(    configurationValue: [1], parameterNumber: 9, size:     1).format()
		commands << "delay 200"
		commands << zwave.configurationV1.configurationSet(    configurationValue: [0, 1], parameterNumber: 10, size:     2).format()
	}
*/
	response(commands)
}

def updated() {
// Device-Watch simply pings if no device events received for 32min    (checkInterval)
	sendEvent(name: "checkInterval", value: 2 * 15 * 60 + 2 * 60,     displayed: false, data: [protocol: "zwave", hubHardwareId:     device.hub.hardwareID, offlinePingable: "1"])
}

def getCommandClassVersions() {
	[
		0x20: 1,  // Basic
		0x26: 1,  // SwitchMultilevel
		0x56: 1,  // Crc16Encap
	]
}

def parse(String description) {
	def result = null
	if (description != "updated") {
		//log.debug "parse() >> zwave.parse($description)"
		def cmd = zwave.parse(description, commandClassVersions)
		if (cmd) {
			result = zwaveEvent(cmd)
		}
	}
	return result
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(    hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelReport     cmd) {
	dimmerEvents(cmd)
}

def zwaveEvent(    hubitat.zwave.commands.switchmultilevelv1.SwitchMultilevelSet cmd)     {
	dimmerEvents(cmd)
}

private dimmerEvents(hubitat.zwave.Command cmd) {
	def value = (cmd.value ? "on" : "off")
	def result = [createEvent(name: "switch", value: value)]
	if (cmd.value && cmd.value <= 100) {
		result << createEvent(name: "level", value: cmd.value ==     99 ? 100 : cmd.value)
	}
	return result
}

def zwaveEvent(hubitat.zwave.commands.hailv1.Hail cmd) {
	createEvent([name: "hail", value: "hail", descriptionText:     "Switch button was pressed", displayed: false])
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.Manufa    cturerSpecificReport cmd) {
	log.debug "manufacturerId:   $cmd.manufacturerId"
	log.debug "manufacturerName: $cmd.manufacturerName"
	log.debug "productId:        $cmd.productId"
	log.debug "productTypeId:    $cmd.productTypeId"
	def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId,     cmd.productTypeId, cmd.productId)
	updateDataValue("MSR", msr)
	updateDataValue("manufacturer", cmd.manufacturerName)
	createEvent([descriptionText: "$device.displayName MSR: $msr",     isStateChange: false])
}

def zwaveEvent(hubitat.zwave.commands.switchmultilevelv1.SwitchMult    ilevelStopLevelChange cmd) {
	[createEvent(name: "switch", value: "on"), response(    zwave.switchMultilevelV1.switchMultilevelGet().format())]
}

def zwaveEvent(hubitat.zwave.commands.crc16encapv1.Crc16Encap cmd)     {
	def versions = commandClassVersions
	def version = versions[cmd.commandClass as Integer]
	def ccObj = version ? zwave.commandClass(cmd.commandClass,     version) : zwave.commandClass(cmd.commandClass)
	def encapsulatedCommand = ccObj?.command(cmd.command)?.parse(    cmd.data)
	if (encapsulatedCommand) {
		zwaveEvent(encapsulatedCommand)
	}
}

def zwaveEvent(hubitat.zwave.Command cmd) {
	// Handles all Z-Wave commands we aren't interested in
	[:]
}

def on() {
	delayBetween([
		zwave.basicV1.basicSet(value: 0xFF).format(),
		zwave.switchMultilevelV1.switchMultilevelGet().format()
	], 5000)
}

def off() {
	delayBetween([
		zwave.basicV1.basicSet(value: 0x00).format(),
		zwave.switchMultilevelV1.switchMultilevelGet().format()
	], 5000)
}

def setLevel(value) {
	log.debug "setLevel >> value: $value"
	def valueaux = value as Integer
	def level = Math.max(Math.min(valueaux, 99), 0)
	if (level > 0) {
		sendEvent(name: "switch", value: "on")
	} else {
		sendEvent(name: "switch", value: "off")
	}
	delayBetween([zwave.basicV1.basicSet(value: level).format(),     zwave.switchMultilevelV1.switchMultilevelGet().format()], 5000)
}

def setLevel(value, duration) {
	log.debug "setLevel >> value: $value, duration: $duration"
	def valueaux = value as Integer
	def level = Math.max(Math.min(valueaux, 99), 0)
	def dimmingDuration = duration < 128 ? duration : 128 +     Math.round(duration / 60)
	def getStatusDelay = duration < 128 ? (duration * 1000) + 2000     : (Math.round(duration / 60) * 60 * 1000) + 2000
	delayBetween([zwave.switchMultilevelV2.switchMultilevelSet(    value: level, dimmingDuration: dimmingDuration).format(),
				  zwave.switchMultilevelV1.switchMultilevelGet().fo    rmat()], getStatusDelay)
}

def poll() {
	refresh()
}

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

def refresh() {
	log.debug "refresh() is called"
	def commands = []
	commands <<     zwave.switchMultilevelV1.switchMultilevelGet().format()
	if (getDataValue("MSR") == null) {
		commands << zwave.manufacturerSpecificV1.manufacturerSpecif    icGet().format()
	}
	delayBetween(commands, 100)
}
//   --- eof ---

/*
def isHoneywellDimmer() {
	zwaveInfo?.mfr?.equals("0039") && (
		(zwaveInfo?.prod?.equals("5044") &&     zwaveInfo?.model?.equals("3033")) ||
			(zwaveInfo?.prod?.equals("5044") &&     zwaveInfo?.model?.equals("3038")) ||
			(zwaveInfo?.prod?.equals("4944") &&     zwaveInfo?.model?.equals("3038")) ||
			(zwaveInfo?.prod?.equals("4944") &&     zwaveInfo?.model?.equals("3130"))
	)
}
*/


/*
Get Command Class Report: 
dev:9712018-12-09 08:37:53.919 pm infoCommandClassReport-     class:0x72, version:1
dev:9712018-12-09 08:37:53.419 pm infoCommandClassReport-     class:0x86, version:1
dev:9712018-12-09 08:37:52.915 pm infoCommandClassReport-     class:0x70, version:1
dev:9712018-12-09 08:37:52.415 pm infoCommandClassReport-     class:0x73, version:1
dev:9712018-12-09 08:37:51.914 pm infoCommandClassReport-     class:0x27, version:1
dev:9712018-12-09 08:37:51.411 pm infoCommandClassReport-     class:0x2C, version:2
dev:9712018-12-09 08:37:51.030 pm infoCommandClassReport-     class:0x2B, version:1
dev:9712018-12-09 08:37:50.462 pm infoCommandClassReport-     class:0x26, version:1
*/