My solution to Z-Wave jamming (ZWA-2) by Z-Wave optimization

I want to share my experiences with Z-Wave jamming and my solution to massively reduce jamming.

My setup is Home Assistant and Z-Wave JS UI, a Nabu Casa ZWA-2 Z-Wave controller, and 57 mainly Fibaro devices (50 on mains power, and 17 on battery).

I used to run my system on a Aeotec Gen 5 controller, but switched to the ZWA-2 a few months ago. All worked well, and I really liked the better sensitivity of it (less hops in the mesh network, most devices communicate directly to the ZWA-2).

Only after I added some more devices to the network I started noticing that not all my devices reported the correct state in HA anymore. Digging further into the matter I noticed massive numbers of “Jammed” and “not responding” reports in the ZWA-2 status. I read numerous posts in this forum about this issue, and possible solutions like the USB3 interference, USB cable quality, and flashing the newest ZWA-2 firmware. Non of them really had any noticeable influence.

Obviously 700 and 800 series controllers like the ZWA-2 are much more sensitive to jamming than the older 500 series controllers. Nabu Casa is still on an older firmware version, but reports in the forum show that even other brands running on the newest firmware suffer from jamming.

As I dug deeper into the problem, I realized that problem, and the solution, is mainly in the Z-wave network configuration, e.g. what and how the devices communicate. After I got a better understanding of Z-Wave, I started to optimize my Z-Wave devices, and managed to reduce the number of reported “jammed” events to only 2 or 3 a day, with durations of only a few seconds maximum. A huge improvement, with no noticeable lag or drop-outs.

Let me first explain what jamming is. Jamming is basically the effect of too many data packages sent by devices at the same time, colliding and interfering in the ether with other data packages (“jammed”). The receiving device checks the integrity of the received packages, and if that is OK it sends back an Acknowledgement (ACK) message. If the sending device received the ACK it knows the information is successfully transmitted, but if that ACK stays out for too long, the sender re-sends the message, hoping it is not colliding again. After a few unsuccessful attempts, the sender will give up.

As most of the data packages are sent by devices to the Z-Wave controller, the controller is mostly impacted by this “jamming”. It can be seen in the number of dropped TX (transmitted) and RX (received) packages. These are basically a count of packages the controller received incompletely and were resent by the devices (RX packages), or the count of sent packages that the controller didn’t reicieve an ACK from a device.

The more device there are in your network, the more data they are sending, and the chances of data package collisions increase. As a consequence, the devices start resending the data when a sent package wasn’t acknowleged by the receiver. This in itself increases the number of network traffic, amplifying the number of collisions. The network is flooded with traffic, and somewhere the controller is no longer able to recognise individual packages, and goes into “jammed” mode, stopping the communication (answering to each package) until the devices stop their attempts. If the network traffic is low enough, the controller comes back online. Until the next flood of network traffic …

So the simple conclusion is to reduce the number of data messages being transmitted. Voila, that’s it! Or … ???
Yes and no. Data reduction is one step, optimizing what and how data packages are sent is another massive improvement. I will explain both.

I have about 60 devices, and they all send information on regular basis. Switches and dimmers send their state changes, and this we absolutely need to know for proper home automation. So we can’t refrain from this information. But many devices also report power level (Watt) and power consumption (kWh). The update intervals of these measurements can be tweaked with the parameters/settings of the device. Ask yourself how often you need to know these measurements. Sometimes they may be needed for automation triggers, but more often they are just informative, e.g. for energy consumption tracking of lamps and other devices. If your device also reports voltage and current, you really have to ask yourself if these are of any use. If the answer is yes, then tweak them to report as less as possible, if the answer is no disable reporting completely.

I tuned the level of power consumption change that leads to a measurement update (data package sent to the controller) for each device, especially when the load is very dynamic, e.g. a laundry dryer. Increasing the reporting level (percentage of previously measured value) massively tuned reduced the number of reports for that device. Similarly, the power consumption update was tuned for high-consuming devices to higher delta values, like 0.1 or 1.0 kWh, wheras LED lamps need small delta as they consume very little energy.
If your device has 2 outputs, but you only use one, make sure you disable power and consumption updates of those completely (often set the intervals to zero).

The nest tweak is the time interval the device reports all of its measured values. Some devices may report each time interval, whether or not the power and consumption have sent updates in-between, other devices reset the interval timer on each intermediate report. Anyway, this time interval is like a heartbeat, every x seconds or minutes the device will send an update. So data packages are sent. If all device report in the same or overlapping time interval (some every minute, some every 5 or 10 minutes), the chance is increased that many reports are sent at the same time, which may lead to data collision (jamming). The trick is to reduce this chance of collisions to the minimum, by setting the report interval for each individual device (or for each measurement, depending on the device) to a non-overlapping time. The solution is to use prime numbers for the intervals! Use the low prime numbers for information you would like frequent updates of, and high prime numbers for low priority devices.
To help you, here is a list of prime numbers you can use. I use them for reporting intervals in seconds :
607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297
I use the reporting interval as a heartbeat to monitor each device, and to monitor whether a fuse or group in my electrical installation has gone offline unnoticed (while away, at night, etc.). It has already prevented the freezer to be off-grid too long, or the central heating.

Battery powered devices are often “quiet” sensors like smoke densors, door sensor or motion sensors. They don’t update very often, but can announce themselves like a keep-alive signal in regular intervals. This wake-up interval doen’t need to report very often to save the battery. I use intervals of approx. 1 hour and more. I use these prime numbers:
4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4513, 4517
Here I also use the update interval to monitor the devices, as sometimes the batteries are dead but Home Assistant still shows the last reported battery percentage of 30% or so. I have to rely on motion sensors and smoke sensors for home security and safety, so i need to be informed if these devices are no longer reporting.

Battery devices often contain other than the primary sensors, like illumianance, temperature, motion/accelleration, humidity, etc. Ask yourself which of these data you need, and in which interval. Tweak it to your minimum needs. Or better, disable them if not needed. I had both smoke sensor and motion sensor report room temperature. Besides that my room thermostat also reports temperature. Nice to know which sensor is most accurate, but you really need one reading, don’t you? So disable all the extra sensors to reduce Z-Wave communication.

After optimizing the report intervals and got rid of many redundant information, I saw a noticeable reduction of the jamming reports by the ZWA-2! But not yet enough to my liking.

It appeared I had a device that kept sending power level and consumption each second, whatever setting I tried. As it was a dual switch it send twice a second! Of course, that alone caused many collisions. I replaced the device and saw a reduction of jamming. But still not enough!
FYI: to check if your device has similar issues, or high reporting frequencies in general, look at you device’s Last Seen value.

The last, and probably largest impact on the jamming issue is … comunication security. In my setup, with Home Assistant and Zwave JS UI, when adding new devices (called “nodes” in Z-Wave), I added them with the so-called S0 security. Most of my devices support that, and encrypted communication would make my installation less prone to external interference or hacking. That is certainly the case but it comes with a high cost: jamming!!

S0-security requires 3 rounds of communication between two devices: handshake and security handshake back and forth, and the final encrypted data that needs to be sent. So three times the amount of data compared to non-encrypted (non-security) communication!!! That is really a way to flood network communication! So if I could only go back to non-secure communication, would that reduce jamming even further. The quick answer is YES!!! It was the key parameter in the jamming story, I now have very rarely a jamming status report, and each report stays for only a few seconds maximum. So virtually none or not noticeable.

If you have security relevant devices (door openers, locks, etc.) I really would advise you to use encrypted communication to those devices. A few devices on S0-security will not flood the network. The good thing is that there is now S2-security in newer devices. As the security key exchange is done during the setup of the device in the network (the “inclusion” process), communication with S2-security is as efficient as non-encrypted communication. So if you want your home network be secured from hacking or other manipulation, make sure you use S2-security whenever you can.

Changing security level for each device is not a simple task. You can’t simply select a new security level as a parameter in the device. The device needs to be re-included in the network. But, when you remove that device in the standard way in Home Assistant, or Z-Wave JS UI, not only will that device be removed from the controller and the network, it will be completely removed from HA, with all it’s entities. And you really don’t want that, as you have to set everything up again, with the same entity names because you want your automations to keep working as before. Oh, and a removal from the network will also factory-reset your device, so all your carefully tweaked device settings are reset too …

However, there is a solution! First thing to do is to save your device’s parameters (settings). In Z-Wave JS UI you can save these under the menu “Templates”. As the name suggests, this is meant to make templates of (default) settings for each newly included device of a certain brand and type. For example, all smoke sensors are setup with the same paramaters so they all behave similarly. If you select “create template” you can choose which sensor you want the settings to be saved from as a template. The further steps are self-explaining. I made a template of each device/node I needed to re-include without security, and saved it under a unique name (with node number and device name).

Next step is to remove the node from the network without removing it from Home Assistant. You can replace “dead” nodes in Z-Wave JS UI. This will replace the old “dead” device with an newly included device. The new device will become the same node number, and all entities will now be linked to the new device. If that device is the same type as before, with the same settings, everything will work as before, including all automations! The trick is to reset the device (see the device’s manual), and include the very same device again (using the “replace” procedure), but now without network security. Once that has been accomplished, you will need to load the previously saved settings from the “Template” in Z-Wave JS UI back into the device (select the “play” button in the Template section next to the saved settings). For battery powered devices you must push the B-button after you started the upload (clicked “run”) to wake-up the device in order to accept the settings. After you have done that, re-interview the device. Repeat this procedure for each device that needs to be changed from S0 to non-secure. And now you have everything running as before without security with only a few steps, and no more jamming!!!

Really, it is as simple as that! And let me tell you a last trick, because you really don’t want to open up every wall box to reset the little device behind the light switch, do you? You can reset a device with a fake exclude (remove) signal! If you have a spare Z-Wave controller lying around, you can have that controller send an Exclude signal. Then, if you enable the device’s exclude function it will see the Exclude signal from the "fake "controller and will reset itself. The include and exclude function can not only be triggered by triple-clicking the B-button on the device, it can also be triggered (at least on Fibaro devices) by triple-clicking the primary (light) switch (often referred to as S0 switch). This is for momentary (push) switches. For toggle switches, you have to flip it quickly 3 times on and off.
I used my old AEON gen 5 controller. It has a built-in battery and you can easily carry it around to each device you want to exclude (reset). Push the button on the AEON controller untill it lights orange to indicate exclusion signal is being sent, tripple-click the S0 light switch of the (Fibaro) device and see that the orange light switches to blue. Your device is now reset by a fake exclusion! On your PC start your Replace-procedure to re-include your device without security, triple-click the S0-switch on the Fibaro device. No screwdriver needed! For other brands please check their manual whether they have similar ways to easily start inclusion and exclusion.

I hope this helps. Let me hear if this solution also works for you to reduce jamming!

What are the makes/models of those devices? Sounds like we would want to avoid them.

This is true for zigbee too and can cause issues with the zigbee network. I assume thread as well i just haven’t seen it yet.

It was a Fibaro FGS-223 Double Switch. No need to avoid this brand or type, I’m very happy with them, and the problem was only on one device (I have 13 of them). I guess it is a software glitch. I still have to reset that device and check whether that will solve the problem.

True, and a bit of advice you see posted here frequently is to look at the z-wave js logs and just look for a lot of traffic (perhaps from a few nodes) and address those.

Isn’t it that the 500 series controllers lacked the ability to report being jammed?

Using the prime numbers is an interesting idea, and what caught my attention here. Is that just a fun idea or do the primes really prevent collisions? I’m curious how that works.

Collisions are normal and expected, so as long a the network isn’t saturated it’s probably fine if they collide once in a while – you can’t know the exact second to turn on a light switch to avoid a collision, so hard to really game that correctly. Reducing unnecessary traffic is key.

I set the device reporting interval very large – like an hour – or just turn it off. Instead, I use the “Last Seen” entity sent by Z-Wave JS to look for devices that haven’t reported in a while where it’s important. For power monitors I only care about significant changes (for some value of significant). I have battery powered water leak sensors, so for those I just need to know that they all woke up once in a while.

You raise a good point: When I first was buying z-wave devices I didn’t pay attention to what parameters could be set on the device, especially related to how frequent power devices report. Now I look at that before purchasing.

@AlCalzone has a good write-up on S2 that’s worth reading, if you haven’t already seen it:

Do you use SmartStart? I put all my devices in SmartStart in Z-Wave JS and then if I remove a device I can re-add it and it gets the same entity IDs and history is preserved. I have rarely factory reset a device.

Great tip on the ZUI Templates!