How Far Does Z-Wave Long Range Reach?

Z-Wave Long Range (ZWLR) claims to reach over 1 mile, but does it actually reach that far in the real world? The answer is YES. However, in the real world we are operating inside a building and surrounded by trees and other buildings. The more important answer is how does ZWLR do in a building and in an neighborhood? I recently captured some data in my home town just outside of Boston which shows ZWLR easily reaches the entire yard and then some.

The first thing to understand about the RF range of Z-Wave are the different power levels used by regular Z-Wave (ZW) and ZWLR. I’m comparing the values used in the US but the rules are different in each region. In the EU the max transmit power is +13dBm with regular Z-Wave which is why the range in the EU is so much further than in the US. But let’s focus just on the US for now.

RF Transmit Power

There are 3 levels of Z-Wave RF transmit power in the US:

  • -1dBm – Regular Z-Wave GFSK modulation – 12mA
  • +14dBm – ZWLR DSSS-OQPSK modulation – 41mA
  • +20dBm – ZWLR DSSS-OQPSK modulation – 92mA

The huge increase in transmit power is why ZWLR has over double the range of ZW. The reason ZWLR can transmit at such high power levels is that the spread spectrum modulation spreads that energy across a 1MHz carrier compared to the narrow band FSK of ZW. The FCC allows the transmit power to be as high as +30dBm but that would be a challenge for a battery powered device as it would likely need half an amp of current!

Why are there two power levels for ZWLR? The RF transmit power is matched to the power supply of the typical use case. The ZGM230 module is limited to +14dBm since it is most often used in battery powered devices where even the 41mA current is a bit challenging for low-cost batteries. The +20dBm ZG23 is best suited to mains-powered devices to get the maximum range. ZWLR utilizes dynamic RF power so for nodes that are close enough, the battery life is extended by using only enough RF power to reliably reach the controller. the dynamic power algorithm is built into the Z-Wave protocol so you don’t have to manage it at all.

RF Range at Home

    The Yellow circle is the regular Z-Wave mesh range with a controller in a room on the 2nd floor. My home is surrounded by large pine trees which limit the range. Using 700/800 series Z-Wave chips there are no dead spots anywhere in my home. I still have a few 100 series devices, several 300 series and a lot of 500 series devices many of which need the mesh to hop to reach my controller. This demonstrates the increasing range of each generation of Z-Wave. If I were to upgrade all of my devices there would be little if any routing using regular ZW.

    The Red circle shows over double the range of regular Z-Wave at +14dBm. The combination of higher transmit power and increased sensitivity due to the spread spectrum modulation yields a strong signal over my entire neighborhood. Note the bump on the right side caused by the open field and the swampy area with a lot fewer trees. Each wall or tree or building reduces the range but ZWLR easily reaches well beyond the end of the yard. I couldn’t test 20dBm because there just isn’t enough open space for me to measure it! So I moved to a building in the center of town.

    RF Range in Town

    The photo above shows the relative range of all three transmit powers. In this case the controller is in the upper right corner of a commercial building as shown in the inset in the lower left. Regular Z-Wave is not quite able to reach the two rooms at the far end of this 35m building. But ZWLR easily reaches the entire building and well beyond. Each step, +14 and then +20 roughly doubles the range in this typical application where there are still a number of trees and buildings reducing the signal. Recall from middle school geometry that the circumference of a circle is 2*pi*radius or roughly 6*radius. On the day I performed this test, I doubled my daily step goal and walked over 20,000 steps!

    In both of these measurements the line is roughly where full 2-way, fully secure, supervision encapsulated Basic Set commands were being sent to a battery powered SwitchOnOff sample application using SDK 7.18.3. I used a Raspberry Pi running Unify and a small python program to send Basic Set On/Off commands every half second to the Dev Kit and then noted where the LED stopped blinking. Once I stepped a few paces back toward the controller, the two devices would resync and the blinking would restart. Z-Wave is very adept at re-connecting to devices that are at the margin of the RF range.

    During the Z-Wave summit earlier this month we did a live demonstration of the range versus the transmit power. While regular Z-Wave reached well beyond the conference center, it couldn’t quite get to the adjacent hotel. ZWLR however reliably reached the hallways in the hotel thru the concrete and glass of each building.

    How to Set Tx Power

    For regular Z-Wave the transmit power is normally set pretty close to the maximum of -1dBm. There are two configuration parameters to set based on the results of FCC testing. See INS14664 in Simplicity Studio for details. For ZWLR, setting the transmit power easier. Simply set APP_MAX_TX_POWER_LR in zw_config_rf.h to either 140 for +14dBm or 200 for +20dBm but that only works if the EFR you are using supports +20. The 700 series EFR32ZG14 supports +20 but the balun has to be wired to +3.3V to have enough power to reach +20. The ZGM130/230 are both limited to just +14. The EFR32ZG23 part number chooses either +14 or +20 – EFR32ZG23B0X0F512 – If the X is 1 it’s +14, if 2 then +20.

    One last configuration setting is to make sure ZWLR is enabled. This is in zw_region_config.h and all you need to do is set it to REGION_US_LR. The protocol code completely handles everything relative to ZW or ZWLR for you so just a 3 character change enables ZWLR.


    All new Z-Wave devices for the US market should support Z-Wave Long Range. The low-latency (no routing), high reliability and long range make it a must for any new product. The question is +14 or +20? All controllers should be using the SoC (EFR32ZG23A/B020) to get the most range. The SoC requires calibration of the crystal for each unit as described in UG517. The module (ZGM130/ZGM230) are limited to +14 only and come pre-calibrated from Silicon Labs and thus are ideal for end devices that are battery powered. The SoC should be used for any mains-powered end device since the current draw is not an issue but be careful to specify the right part number with the 020 in it.

    Z-Wave 800 GPIO Decoder Ring

    The two Z-Wave 800 series chips from Silicon Labs have flexible GPIOs but figuring out which one is the best for which function can be challenging. There are a number of restrictions based on the function and the energy (sleep) mode you need the GPIO to operate in. Similar to my posting on the 700 series, this post will guide you to make wise decisions on which pin to use for which function.

    The tables below are a compilation of several reference documents but all of the data here was manually copied out of the documents and I could have made a mistake or two. Please post a comment if you see something wrong and I’ll fix it right away.

    Reference Documents

    • EFR32xG23 Z-Wave 800 SoC Family Datasheet
    • ZGM230 Z-Wave 800 Module Datasheet
    • EFR32xG23 Reference Manual
    • WSTK2 Schematic (available via Simplicity Studio)
    • BRD4210 EFR32ZG23 Radio Board +20dBm Schematic
    • Thunderboard Z-Wave UG532 and Schematic

    Pin Definitions

    The table below lists the pins from the most flexible to the most fixed function. There are more alternate functions than the ones listed in this table. The most commonly used alternate functions are listed here to keep the table readable. Refer to the schematics and datasheets for more details.

    Port A and B are operational down to EM2, other GPIOs will retain their state but will not switch or pass inputs. Thus, use port A and B for anything special and use C and D for simple things not needed when sleeping (LEDs, enables, etc).

    WSTK GPIO Probe Points

    Only the ZG23 QFN48 pin numbers are listed in the table. The QFN48 is expected to be pin compatible with future version of the ZG23 with additional Flash/RAM so I recommend using it over the QFN40. The WSTK2 is the Pro DevKit board with the LCD on it which comes as part of the PK800 kit. There are two sets of holes labeled with Pxx numbers on them which are handy to probe with an oscilloscope. The Thunderboard Z-Wave (TBZ) also has 2 rows of holes which are ideal for probing or connecting to external devices for rapid prototyping.

    Use the pins at the top of this list first as they are the most flexible
    TBZ Qwiic I2C_SDA
    TBZ Qwiic I2C_SCL
    PC1235P1EXP4PC and PD are static in EM2/3
    EM4WUx pins can wake up from EM4 sleep mode on a transition of the GPIO
    PD0_LFXTAL_O4833XC32XC32BRD4210 and TBZ have 32KHz crystal mounted
    PD1_LFXTAL_I4732XC32XC32Accurate timing while sleeping – Time CC
    PA73220P10TraceD3Trace pins for debug & code coverage
    PA63119P8TraceD2Trace is configurable for 4, 2 or 1 data pin
    JTAG data in
    Trace Clock out
    Pins below here should be used primarily for debug
    PD4_PTIDATA4429P25Packet Trace Interface (PTI) data
    PD5_PTISYNC4328P24EM4WU10PTI Sync
    RTT UART printf and Trace D0
    PA2_SWDIO2714P18JTAG_TMSThese two SWD pins should ONLY be used for debug and programming
    PA1_SWCLK2613P20JTAG_TCKSWD debug clock
    Pins below here are fixed function only
    SUBG_O118NANot used by Z-Wave
    SUBG_I116NANot used by Z-Wave
    SUBG_O0193RFIO on ZGM230
    SUBG_I017NAMatching network to SMA
    RESET_N131F4Push buttons on DevKit boards
    HFXTAL_O12NA39MHz crystal
    HFXTAL_I11NA39MHz crystal
    DECOUPLE36181.0uF X8L cap (unconnected on ZGM230)
    VREGSW37NAInductor to DVDD for DCDC – 3.3V
    VREGVDD38253.3V In/Out based on mode
    DVDD4024VDCDC on ZGM230
    AVDD41NAHighest voltage – typically battery voltage
    PAVDD20NA3.3V for +20, 1.8V for +14dBm
    RFVDD14NA1.8V or 3.3V but less than PAVDD
    VREGVSS3927, 44GND
    RFVSS152, 4GND

    Power Supply Pins

    Obviously the power supply pins are fixed function pins. The only really configurable parts to this set of pins is the voltage to apply to the IOVDD, AVDD and whether to use the on-chip DC to DC converter or not. If your device is battery powered, AVDD should be the battery voltage assuming the battery is nominally 3V (coin cells or CR123A). AVDD can be measured by the IADC in a divide by 4 mode to give an accurate voltage reading of the battery. This avoids using GPIOs and resistor dividers to measure the battery level thereby freeing up GPIOs and reducing battery drain. IOVDD should be set to whatever voltage needed by other chips on the board. Typically either 1.8 or 3.3V. The DCDC should be used in most battery powered applications unless a larger DCDC is present on the board already to power other chips.

    The other configurable voltage is the RFVDD and PAVDD and the choice there depends on the radio Transmit Power you wish to use. For +14dBm PA an RF VDD are typically 1.8V. For +20dBm PAVDD must be 3.3V.

    Every product has unique requirements and sources of power so I can’t enumerate all possible combinations here but follow the recommendations in the datasheets carefully. Copy the radio board or Thunderboard example schematics for most typical applications.

    Debug, PTI and Trace Pins

    The two Serial Wire Debug (SWD) pins (SWCLK and SWDIO) are necessary to program the chip FLASH and are the minimum required to be able to debug firmware. While it is possible to use these pins for other simple purposes like LEDs, it is best if they are used exclusively for programming/debug. These should be connected to a MiniSimplicity or other debug header.

    The SWO debug pin is the next most valuable pin which can be used for debug printfs in the firmware and output to a debugging terminal. Alternatively, the UART TX and RX pins can also be used for debugging with both simple printfs and able to control the firmware using the receive side of the UART to send commands.

    The two Packet Trace Interface (PTI) pins provide a “sniffer” feature for the radio. These pins are read by Simplicity Studios Network Analyzer to give a detailed view of all traffic both out of and into the radio. The main advantage of these pins is that they are exactly the received data by the radio. The Z-Wave Zniffer can also be used as a standalone sniffer thereby freeing these pins for any use. The standalone Zniffer however does not show you exactly the same traffic that the PTI pins do especially in noisy or marginal RF conditions. Thus, the PTI pins on the device provide a more accurate view of the traffic to the device under test.

    The Trace pins provide additional levels of debug using the Segger J-Trace tool. These pins output compressed data that the debugger can interpret to track the exact program flow of a running program in real time. This level of debug is invaluable for debugging exceptions, interrupts, multi-tasking RTOS threads as well as tracking code coverage to ensure all firmware has been tested. Often these pins are used for other purposes that would not be necessary during firmware debug and testing. Typically LEDs or push buttons can be bypassed during trace debug. There are options to use either 4, 2 or even 1 trace data pin but each reduction in pins cuts the bandwidth and make debugging less reliable.

    LFXO and EM4WU Pins

    The Low Frequency Crystal Oscillator (LFXO) pins are typically connected to a 32KHz crystal to enable accurate time keeping within several seconds per day. If supporting the Time Command Class, I strongly suggest adding the 32KHz crystal. While you can rely on the LFRCO for time keeping, it can drift by as much as a minute per hour. While you can constantly get updated accurate time from the Hub every now and then, that wastes Z-Wave bandwidth and battery power. Both the Thunderboard and BRD4210 include a 32KHz crystal so you can easily compare the accuracy of each method.

    Reserve the EM4WU pins for functions that need to wake the EFR32 from EM4 sleep mode. These are the ONLY pins that can wake from EM4! Note that ports PC and PD are NOT able to switch or input from peripherals while in EM2. See the datasheet and reference manual for more details.

    Remaining GPIOs

    Many of the remaining GPIOs have alternate functions too numerous for me to mention here. Refer to the datasheet for more details. Most GPIOs can have any of the digital functions routed to them via the PRS. Thus, I2C, SPI, UARTs, Timers and Counters can generally be connected to almost any GPIO but there are some limitations. Analog functions have some flexibility via the ABUS but certain pins are reserved for special functions. Hopefully these tables help you make wise choices about which pin to use for which function on your next Z-Wave product.

    Tiny Headers for Reliable Debug

    Here we go again… Once again I’ve been given yet another board with randomly placed test points instead of a nice neat, reliable header to connect via my MiniSimplicity cable. So I’m spending an hour on my microscope soldering thin little wires to the tiny little test points to be able to flash and then debug the firmware on a new ZG23 based product. Once I’m done soldering, I’m left with a very fragile board which is unreliable at best and at worst will result in even less hair on my thinning head. My post from 2019 described using a zero cost header for a reliable connection, but it seems not everyone is reading my blog!

    On the flip side, a different customer sent me their board with a Tag-Connect Edge-Connect that I had not seen before but is absolutely brilliant. The Edge-Connect uses the EDGE of your PCB for the test points. Barely 1mm wide and about 20mm long it is possible to include this debug connector on virtually any PCB. There is a locking pin to hold the cable secure while the spring loaded tabs press into the castellated notches to ensure solid contact.

    Close up of the locking pin and castellated notches

    There are several sizes of the Edge-Connect but the recommended one is the 10-pin EC10-IDC-050 which matches the MiniSimplicity header on the WSTK DevKit board. Note that the the 6pin cable in the photo above is NOT the one I would recommend but it was the only one in stock at the time and it worked fine for debugging but doesn’t have the UART or PTI pins.

    Tag-Connect has many other types of debug headers/cables of various configurations to hold the cable to the PCB securely. The original Tag-Connect cables have plastic clips that snap into fairly large thru-holes in your PCB. While this is a reliable connection, the thru-holes eat up a lot of PCB real estate. The next evolution was to use a small retaining clip under the PCB that grips onto the metal alignment pins. The photo below shows the PCB pads are not much bigger than an 0805 footprint and only requires three small thru-holes.

    Note the smallest header is about the same as an 0805 in lower left corner

    The lowest cost approach is to simply add a 10-pin header footprint on your PCB that matches the pinout of the MiniSimplicity header. See section 5.1.1 of Application Node AN958 for the pinout of the 10-pin MiniSimplicity header. You don’t need to solder the header onto the PCB except when debugging. Thus the header can be under a battery or some relatively inaccessible location as when you are debugging in the lab the PCB is usually not installed in the product enclosure.

    Please use ANY of these standard connectors on your next project. Without a solid connection between your computer and the chip you will find yourself chasing ghosts and losing hair.

    Best Practices for Z-Wave Door Locks


    Door Locks are critical to the security of the home and thus communication must be reliable and fast. This document brings together the many issues unique to door locks and guides the developer toward the most robust and interoperable implementation. These are mostly recommendations, not requirements and do not guarantee Z-Wave certification. Z-Wave allows for plenty of product differentiation, but it is important that common lock functions operate in the most interoperable fashion.

    Z-Wave door locks entered the market in 2008. The problem was that at the time the Z-Wave Command Classes were missing standardized reporting of status of the lock and user codes. Initially Alarm CC was used by the locks to send various notifications to the hub to deliver status updates. The problem with this method is that each manufacturer used a unique set of commands to deliver the different status updates. Shortly after these initial locks hit the market and with the arrival of the Z-Wave Alliance, the Z-Wave specifications were updated and now locks can send standardized messages to deliver status changes. The standardized messages make Hub software much easier as basic operations can be received without the need for specialized code for each lock manufacturer.

    Z-Wave Command Classes for Door Locks

    SDS14224 Z-Wave Plus v2 Device Type Specification section 4.5.1 (in Version 10) specifies the Mandatory and Recommended Command Classes (CC) for Lock Device Types. Some command classes have a minimum version required for certification. However, the developer is free to choose the command class version that meets the product needs. As command classes have matured, commands have been added which in turn adds complexity and more code space. Every command in a command class must be implemented by the lock based on the version supported. If you don’t want to support some commands in a later version, then only declare the earlier versions in the Version CC.

    Mandatory Command Classes

    • Door Lock CC (V4 or later)
    • Battery (V1) – unless the lock is mains powered
    • Basic CC – 00=UNLOCK, FF=LOCK (does not appear in NIF)
    • Security S0 CC – for backwards compatibility to older gateways that don’t support S2
      • S0 may change to recommended in the future but is mandatory in 2020

    Common Mandatory CC for All Z-Wave Plus v2 Devices

    • Association, version 2
    • Association Group Information
    • Device Reset Locally
    • Firmware Update Meta Data, version 5
    • Indicator, version 3
    • Manufacturer Specific
    • Multi-Channel Association, version 3
    • Powerlevel
    • Security 2
    • Supervision – See discussion below – you SHOULD be using Supervision!
    • Transport Service, version 2
    • Version, version 2
    • Z-Wave Plus Info, version 2

    Most of these command classes are handled by the SDK and/or the Z-Wave Application Framework (ZAF). There are some customizations to many of these command classes, but the effort is minimal.

    Recommended Command Classes

    • User Code CC – If the lock has a keypad this CC is used to program/enable the codes
    • Notification CC – Send various lock status messages to the Lifeline NodeID (Gateway/Hub)
    • Time CC – See the section below on the time/clock command classes
      • Clock CC
      • Time Parameters CC
    • Generic Schedule CC – Defines time/date ranges to enable/disable User Codes
    • Schedule CC – Simpler but less flexible schedules using any Z-Wave command
    • Authentication CC – use with RFID, NFC, Mag cards etc. and link ScheduleIDs with User Codes

    Other Command Classes

    • Door Lock Logging CC
      • Door lock logging CC provides a means to retrieve an audit trail of operations
      • Typical use: If the hub is offline, a log of all operations is recorded and can then be sent when the hub comes back online
    • Barrier Operator CC – Typically used with motorized entry gates which are like locks
    • Entry Control CC -Used with RFID or other means that have ASCII strings
      • Relies on the Hub to authenticate the string and then send an unlock command
      • Typically used for Keypads which do not control a lock
      • Use Authentication CC for locks
    • Configuration CC (V3) – configure specific features that are not supported by other CCs
      • See the Door Lock Configuration SET command which should provide most of the needed configuration
      • Configuration CC should only be used if really necessary as it is less interoperable
    • Application Status – Can be used to reply back to the Hub that the lock is currently busy and cannot execute the command just received
      • Use Supervision instead
    • Protection CC – enables a Child Protection mode
    • AntiTheft CC (v3) – Locks the device so if stolen it is a brick
    • Multi-channel – Multichannel should not be necessary
    • Multi-command – Can be used to return several commands in a single frame to reduce battery consumption however with the smaller payload size in S2 it is not recommended
    • Obsolete Command Classes – do not use these
      • Schedule Entry Lock CC – use Generic Schedule CC instead
      • Alarm CC – Use Notification CC (V3 or later)

    Security Levels

    Security S2 has three security levels and S0 has one for a total of four different security levels:

    1. Security S2 Access Control – Strongest Security level only used with devices that provide access to secure areas – door locks
    2. Security S2 Authenticated – SmartStart requires a QR code/DSK – lights/thermostats/sensors
    3. Security S2 UnAuthenticated – used by a small number of early S2 devices – generally not recommended – Does not require QR Code/DSK
    4. Security S0 – Legacy security mode – slower, uses more battery power, less secure than S2

    The Security S2 Unauthenticated and S2 Authenticated keys are NOT recommended due to potential security holes. S2 is rapidly becoming commonplace so it is expected that S0 will no longer be mandatory but will change to recommended. S0 is slower, uses more battery power and is less secure than S2 due to the network key being exchanged using a known encryption key. Security S2 uses Diffie-Hellman elliptic curves to exchange the keys, an out-of-band DSK is required to join the network and Nonces are pre-computed enabling a single frame compared to three for S0 (Nonce Get, Nonce Report, Encrypted frame). Locks are required to use the Security S2 Access Control level.

    Recommended Security Levels:

    • S2 Access Control
    • S0 if supported or if legacy support is desired (mandatory in 2020)

    Reporting State Changes

    All Z-Wave Plus devices are required to send to the Lifeline NodeID (typically the Hub) when their state changes. The Z-Wave Application Framework True-State Engine (TSE) can be used to send state changes. The primary state changes in a lock are:

    • Secured vs. Non-secured (locked vs. unlocked)
    • Keypad entry of a code
    • Battery level


    Currently most locks rely on the Hub to install/remove User Codes and to manage the times and dates when the codes are valid. Thus, the lock need not know the current date/time and does not need to store schedules and apply them to User Codes. This makes the lock firmware simple and keeps the complexity of schedules with the Hub and its significantly greater processing, storage and user interface capabilities. However, many rental property agencies prefer the battery powered lock to have the schedules built-in so that even if there is an extended power or internet failure, the proper User Codes are enabled/disabled at the proper times. Thus, there is a desire to have these schedules managed within the lock itself. Fortunately, Z-Wave already has the command classes in place to support them, but schedules are complicated.

    Generic Schedule CC – Recommended

    Generic Schedule CC can set Time Ranges and then Schedules which are comprised of one or more Time Ranges. A Time Range has Start and Stop Date/Time fields and each field can be enabled or ignored. For example, a Time Range can be every Monday from 1pm to 3pm (date and minute fields are ignored) or can include specific dates like 2022 May 24th from 11:23am to 4:57pm. This makes the Time Range very flexible and able to specify virtually any type of date/time combination.

    A Schedule is a list of Time Ranges that are either Included or Excluded to build the schedule. Thus, a Time Range of M-F 8am-5pm could be included but then 1 Jan 2022 from 4pm to 5pm could be excluded. In this example, the Schedule includes the first Time Range and Excludes the second. Generic Schedule only creates the ScheduleIDs. It does not hold any commands or perform actions. Authentication CC is then used to link a Schedule to a User Code or other authentication method. There are up to 64K Schedule and Time Ranges though each device reports the number supported in the Generic Schedule Capabilities Report. Due to the memory required for schedules and time ranges most devices will typically only have perhaps a dozen or so of each.

    Schedule CC

    Schedule CC is different than Generic Schedule in that Z-Wave commands are used instead of ScheduleIDs/AuthenticationIDs/UserCodes. Schedule CC is usable for any Z-Wave command and not just those that use the Schedule IDs. Schedule CC is most often used with thermostats or other devices that change state automatically based on the time/date. While Schedule CC can be used to execute User Code Set commands to enable/disable User Codes on a schedule, it is less flexible than Generic Schedule CC. For simple weekly schedules this CC will work OK but trying to build more complex schedules quickly becomes cumbersome.

    Schedule Entry Lock CC

    The Schedule Entry Lock CC has been deprecated and thus should not be used in new locks. Use the Generic Schedule CC instead. There are less than a dozen certified locks with Schedule Entry Lock CC. Hubs may want to control this CC to support specific locks but it is not required.

    Authentication CC

    Authentication CC is used to connect a User Code to a Generic Schedule. Authentication CC can also be used in conjunction with RFID, NFC, mag stripes, BLE or other forms of user authentication. It is then used to enable/disable various access methods based on a schedule. Thus, Authentication is flexible but with that flexibility comes complexity.

    Time CC vs. Clock CC vs. Time Parameters CC

    If a lock supports schedules to enable/disable user codes, then it needs some way to determine the date and time. For example, the cleaners code only works on Tuesdays from 2 to 4pm. How is a lock supposed to get the current local time and date so it knows when to enable the cleaners code?

    There are three different command classes for getting various parts of the time/date. Time Command Class is mandatory for all Gateways and is the most full featured method. Unfortunately, not all gateways support it yet, so most devices need to support one of the others for use with older hubs. Clock CC is defined in SDS13781 – Z-Wave Application CC but the other two are defined in SDS13782.

    Time CCClock CCTime Parameters CC
    SecondV1(Local)V1 (UTC)
    MinuteV1(Local)V1V1 (UTC)
    HourV1(Local)V1V1 (UTC)
    Day of Week V1 
    Day of MonthV1(Local)V1 (UTC)
    MonthV1(Local)V1 (UTC)
    YearV1(Local)V1 (UTC)
    Time Zone Offset
    Hour, Minute
    DST OffsetV2
    DST Start
    Month, Day Hour
    DST End
    Month, Day Hour
    Command Classes for setting the Date and Time

    Time CC – Recommended

    Time command class is described in SDS13782 (Z-Wave Management Command Class Specification). Time CC is mandatory for all Z-Wave Plus Gateways and thus is the recommended method for a lock to set its clock to the current local date and time. Time CC Version 2 adds time zones and daylight savings time support if desired however V1 provides the necessary functionality in most cases.

    The Z-Wave specification recommends having an association group to identify the time server node however the Gateway is expected to have an accurate time reference so using the Lifeline is acceptable.

    The Time CC does NOT have a date/time SET command. Thus, the hub cannot set the date/time and instead should wait for the lock to GET it. The hub can send a Time/Date REPORT to the lock when a lock is included in a network. However, the lock must send a Time GET command within the first few minutes to accurately set its internal clock. The lock should then periodically send a Time GET to ensure the internal clock remains accurate to the local time. Only the lock knows the accuracy of its real-time clock. Thus, the lock will determine how often it needs to update its internal clock and send a Time GET when needed. The hub should not send Time Reports unless responding to a Time GET other than immediately after inclusion. Note that for certification purposes a door lock CONTROLs Time CC, it does not SUPPORT it. The Hub is required to SUPPORT Time CC.

    Time Parameters CC – Optional

    The Time Parameters command can SET/GET/REPORT the year, month, day, hour, minute & second of the UTC time. However, it does not set the time zone which must be done via the Time CC V2. Thus, Time Parameters CC relies on the hub to send the current UTC time but the lock can also send a GET and adjust its internal clock to match the one from the hub. However, this requires support on the hub software which is not mandatory so not all hubs will be able to provide the current date/time.

    Clock CC – NOT Recommended

    Clock command class is sent by a Hub and can set the local weekday and time. Thus, it only supports a 7-day schedule since it cannot set the date, just the day of the week. Typically, the Hub would send a Clock Set as part of inclusion in the network. Since the clock on the lock will drift, the lock must periodically send a Clock Get to the Hub and to maintain time accurately. This method is NOT recommended. However, on some old hubs this is the only method available.

    Recommended Time Setting Algorithm

    The algorithm below provides a basic guide for setting the time. The first step is to wait for the inclusion and the security negotiation to complete. Then send a Time GET and start a 30 second timer. If a Time REPORT arrives before the end of the 30 second timer, then the Hub supports Time CC so use that. If the Hub instead sends either a Clock REPORT or a Time Parameters SET then that will set the initial time for the lock. The lock will have to continue to send periodic Clock GET commands to the Hub to maintain clock accuracy. If there is no response from the Hub, then the lock has no choice but to disable the schedule features as they require accurate local time.

    Depending on the accuracy of the local clock circuitry, the functioning time setting command class should be used to update the local clock at a sufficient rate to match the desired settings. Typically, this would be once per day assuming a 100ppm or better 32Khz crystal is used for the clock (see section Real Time Clock (RTC) 32KHz Crystal below).

    Notification CC

    Notification CC was originally called Alarm CC which was deprecated at V2 and replaced with Notification CC. When the first Z-Wave locks were developed there was no standardized method for informing the Hub when a lock state changed. Each lock manufacturer was free to choose an Alarm Type and Alarm Level to communicate various status changes. Unfortunately, this resulted in non-standard and non-interoperable Z-Wave commands. Notification CC V3 defined a set of Access Control notification types and events which are described in SDS13713 which is a spreadsheet listing all standard notification types/events. For new lock developments it is recommended to use the standardized commands described here instead of the old Alarm CC ones (V8 or later is recommended). The Alarm CC can still be sent if the lock is joined using Security S0 for backwards compatibility, but their use is not recommended if the lock is joined using Security S2. Alternatively, a Configuration Parameter could be used to enable/disable the Alarm CC commands. Sending these old commands wastes battery power and clogs up the Z-Wave network.

    Notification CC is typically used to communicate specific state changes beyond Door Lock or User Code CCs. There is overlap between some notifications and some Door Lock commands. The recommendation is to use Door Lock CC and only use Notification for cases that don’t have overlap.  A few examples are shown in the Sample Communication section below.

    Supervision CC

    Supervision CC is mandatory for all S2 devices. Since locks provide property security and users have very high expectations for reliability and robustness of lock operation, it is strongly recommended that all communication to/from a lock be wrapped in Supervision CC. Supervision eliminates the need to send a Notification that a user code has been SET as the Supervision Report confirms that the command was received, decrypted and executed. See Appendix A for a sample implementation of Supervision CC for the door lock firmware.

    The example below shows a lock being unlocked manually by the user. The lock needs to be 100% certain it informs the Hub that the door is now unlocked. To do that, the DoorLock_Operation Report is encapsulated with a Supervision GET command. The first attempt is blocked by RF noise but the protocol will automatically retry sending the frame up to five different routes using the mesh network because the ACK was not received. The second try delivers a frame to the Hub but due to more RF noise, the Hub is unable to decrypt the message. The Hub has already ACKed the frame so the protocol has retired the frame from the transmit queue and will not try again. However, the SDK has started a 500ms timer expecting a Supervision Report within that time. Since the Hub could not decrypt the message, it has discarded the frame. Once the 500ms timeout has expired, the lock will resend the frame. This time it gets thru and the Hub is able to decrypt the message and replies with a Supervision REPORT with a status of Success. At that point, the lock is 100% certain the frame has been delivered, decrypted and executed. The use of Supervision command class ensures delivery and execution of any Z-Wave command and should be used with any critical function of any device.

    Door Lock Command Class

    Most of Door Lock CC is straightforward and documented in SDS13781. The Lock Timeout vs. Auto-Relock function however needs a little extra explanation. The Door Lock Operation Set (V1) command includes the Mode which assigns either Timeout mode or Constant mode. The Door Lock Configuration Set (V1) command sets the timeout in Minutes + Seconds and whether the lock is by default in Constant or Timeout mode. Later versions of Door Lock CC enable sending a Timeout or an Auto-Relock time in the Operation Set command. Auto-Relock is in force ONLY if the lock is in Constant mode. If the lock is in Timeout mode then the normal Timeout Minutes/Seconds is used and the Auto-Relock values are ignored. Given the more common support of the Timeout Mode, it is recommended to use this mode for improved interoperability. Note that some locks have the timeout or mode as a configuration parameter. While it is acceptable to have these modes read/writeable via Configuration CC, the same values must also be reflected in the Door Lock Configuration commands.

    Sample Communication

    This section describes the communication between a lock and a hub in various scenarios. All communication is Security S2 encrypted which is shown in most of the examples. The recommendation is to encapsulate all frames in Supervision to ensure the frames was delivered and decrypted.

    User Manually Locks/Unlocks

    When the user manually locks or unlocks the lock by turning the bolt/lever, the lock must send to the Lifeline NodeID(s) (the Hub) the following:

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    3 Properties1Supervision SessionID incremented with each new GET
    40x09LenSupervision Length
    50x62CmdClassDoor Lock Operation CC V4
    60x03CmdDoor Lock Operation Report
    7 LockMode00=unsecured, FF=secured – See SDS13781 table 44
    8 Properties1In/out Handles Mode – table 45
    9 DoorConditionDoor/bolt/latch state – table 46
    100xFETimeoutMinLock returns to secured after these many minutes
    110xFETimeoutSecLock returns to secured after these many seconds
    12 TargetModeTarget Mode if in transition or LockMode
    130x00DurationSeconds to reach target mode – 0=already at target

    Note that Supervision CC is used to ensure the Hub has received and decrypted the frame.

    A Notification CC can be sent if the lock was included using Security S0 for backwards compatibility. It is not recommended if the lock is using Security S2 which relies on the Supervision CC to ensure delivery.

    Byte #ValueNameDescription
    10x71CmdClassNotification CC
    20x05CmdNotification REPORT
    30x00V1AlarmTypeV1Alarm can be non-zero IF documented in the user manual
    40x00V1AlarmLevelThese are used for backwards compatibility
    60xFFStatus00=notifications are disabled, FF=enabled
    70x06Type06=Access Control
    8 Event01=Manual Lock, 02=Manual Unlock
    90x00Properties1Parameters Length

    User Enters a Good User Code

    A User Code of “1234” has been set in a deadbolt lock with a keypad at UserID=03. The lock is locked and then the user enters 1234 to unlock the lock.

    A Notification CC is sent informing the Hub which User Code was used.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x13Properties1Supervision SessionID incremented since this is a new frame
    40x09LenSupervision Length
    50x71CmdClassNotification CC
    60x05CmdNotification REPORT
    70x00V1AlarmTypeV1Alarm can be non-zero IF documented in the user manual
    80x00V1AlarmLevelThese are used for backwards compatibility
    100xFFStatus00=notifications are disabled, FF=enabled
    110x06Type06=Access Control
    120x06Event05=keypad Lock, 06=keypad Unlock
    130x63ParamUser Code CC
    140x03ParamUser Code CC cmd = REPORT
    160x01ParamUserID Status = occupied & enabled
    170x31ParamUser Code = ASCII “1”
    180x32ParamUser Code = ASCII “2”
    190x33ParamUser Code = ASCII “3”
    200x34ParamUser Code = ASCII “4”

    Optionally a Door Lock Operation could be sent to inform the Hub that the door is now unlocked.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x12Properties1Supervision SessionID=0x12
    40x09LenSupervision Length
    50x62CmdClassDoor Lock Operation CC V4
    60x03CmdDoor Lock Operation Report
    70x00LockMode00=unsecured, FF=secured – See SDS13781 table 44
    80x00Properties1In/out Handles Mode – table 45
    90x00DoorConditionDoor/bolt/latch state – table 46
    100xFETimeoutMinLock returns to secured after these many minutes
    110xFETimeoutSecLock returns to secured after these many seconds
    120x00TargetModeTarget Mode if in transition or LockMode
    130x00DurationSeconds to reach target mode

    User Enters a Bad User Code

    Currently nothing is sent when the user enters a bad code. There have been discussions that the lock should send the bad code so that the Hub could collect statistics on how many times a user has tried to enter a code and what the code was. This would require a new Notification Access Control Event. Let us know what you think of this idea or get involved with the Z-Wave Alliance Standards Development Organization and make a proposal.

    Hub Sends Lock/Unlock Command

    A hub sends a Lock or Unlock command. Most locks take a few seconds to slide a bolt and this sequence shows the use of a Supervision Report with a WORKING status followed by a SUCCESS.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x95Properties1Supervision SessionID=0x15 with Status Updates
    40x03LenSupervision Length
    50x62CmdClassDoor Lock Operation CC V4
    60x01CmdDoor Lock Operation SET
    70xFFLockMode00=unsecured, FF=secured

    The lock immediately responds with a Supervision WORKING report with the More Status Updates bit set indicating another report will come within the next 7 seconds. The WORKING status means the lock is busy moving the bolt and it will take a few seconds to know for sure if it is properly engaged. If the Status Updates bit was 0, then only this supervision report would be sent. If the lock (or more typically a gate) takes more than 10 seconds to reach the final state it is suggested to send a WORKING report every 5-10s. Each time the Duration field should be updated with the estimated time to completion.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x02CmdSupervision REPORT
    30x95Properties1Supervision SessionID=0x15 – More Status Updates set
    40x01StatusWORKING – Once the bolt has finished moving another report will be sent
    50x07DurationNext report will be in 7 seconds or less. The duration should be a worst-case number to handle the case when the lock is jammed.

    When the lock has completed the operation, it sends another Supervision Report this time with the Status Updates bit cleared and a status of SUCCESS (if the Status Updates bit was set in the Supervision GET). This frame should be sent as soon as the lock has completed the operation.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x15Properties1Supervision SessionID=0x15
    50DurationTarget mode completed

    At this point the Hub is assured the lock has completed the operation because Supervision CC confirms the command was executed. However, most Hubs want to receive a status update so either a Notification CC, Access Control and Event of 0x03 (lock) or 0x04 (unlock) could be sent. It is recommended to send a Door Lock Operation Report wrapped in a Supervision Get as shown here.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x0AProperties1Supervision SessionID=0x0A
    40x09LenSupervision Length
    50x62CmdClassDoor Lock Operation CC V4
    60x03CmdDoor Lock Operation REPORT
    70xFFLockMode00=unsecured, FF=secured
    80x00HandlesModeIn/out Handles Mode
    90x00DoorConditionDoor/bolt/latch state
    100xFETimeoutMinLock returns to secured after these many minutes
    110xFETimeoutSecLock returns to secured after these many seconds
    120xFFTargetModeTarget Mode if in transition or LockMode
    130x00DurationSeconds to reach target mode

    Hub Sends User Code Set

    Supervision encapsulated User Code SET enabling the User Code of “1234” for User ID 5.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x01Properties1Supervision SessionID=0x01
    40x08LenSupervision Length
    50x63CmdClassUser Code CC
    60x01CmdUser Code SET
    70x05UserIDUser Identifier = 0x0005
    80x01UserIDStatus0x00=available, 0x01=Access Enabled, 0x02=Disabled, 0x03=Messaging, 0x04=Passage Mode
    90x31UserCode1ASCII ‘1’
    100x32UserCode2ASCII ‘2’
    110x33UserCode3ASCII ‘3’
    120x34UserCode4ASCII ‘4’ – total length of the code is 4 to 10 digits

    The lock would then send the Supervision CC REPORT with a value of SUCCESS if the User Code was properly executed otherwise it would return FAIL. If the UserID is more than 255, the Extended User Code Set command would be used. This command can also set multiple codes in a single frame.

    When a Hub sends a User Code SET, the Hub typically wants confirmation that the code was in fact properly set. While this isn’t necessary if Supervision is used, it is good practice as that is the only method that a pre-S2 lock can confirm that the User Code was set. Since the Supervision Report already confirmed the User Code has been set, it is not necessary to wrap this frame in Supervision as it is merely informational. If the lock is using Security S0, the notification report confirming the User Code is recommended.

    Byte #ValueNameDescription
    10x71CmdClassNotification CC
    20x05CmdNotification REPORT
    30x00V1AlarmTypeV1Alarm can be non-zero IF documented in the user manual
    40x00V1AlarmLevelThese are used for backwards compatibility
    60xFFStatus00=notifications are disabled, FF=enabled
    70x06Type06=Access Control
    80x0EEvent0E=New User Code added
    90x00Properties1Parameters Length = none

    Hub Sends a Duplicate User Code

    If a Hub sends another User Code SET with a different UserID but with the same UserCode, the lock must return a Notification CC Type=Access Control (0x06) with an Event=New User Code Not Added (0x0F). This Notification should be sent encapsulated in Supervision CC if the lock is using S2.

    Lock Sends Low Battery Warning

    Most locks use simple alkaline batteries so version 1 of the battery command class is sufficient. Use the later versions for rechargeable or complex battery situations.

    Battery powered locks should automatically send the Hub the battery level whenever the battery level changes by a significant amount. The lock should send an update if the battery level has changed by more than about 5% from the last report. The amount of change required to trigger an update is up to you, but it should be large enough to only send a battery update every several days or even weeks. Note that changes in temperature can cause the battery level to rise so the trigger should require the level to be lower. Be aware that most Hubs will occasionally poll the battery level which is why sending an update is not needed unless the level has changed significantly from the last report. Zero percent battery level should still allow the lock to operate reliably, but just barely. One Hundred percent battery level should be achievable with a wide range of batteries.

    When the Critical Battery Level has been reached the lock must send a Low Battery warning (0xFF). Each lock will have a different Critical Level but it is typically in the 5% to 20% range. When the Critical level is reached for the first time, a low battery warning must be sent to the Lifeline. This warning must ONLY be sent once. Typically, a RAM variable holds a flag that is set when the low battery warning is sent and is only cleared upon power-on reset when the batteries are replaced. The Low Battery warning should be sent wrapped in Supervision command class to ensure the Hub received it. Normal battery reports do not need to be wrapped in Supervision.

    Battery Report – Low Battery Warning

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x01Properties1Supervision SessionID=0x01
    40x03LenSupervision Length
    50x63CmdClassBattery CC
    60x03CmdBattery Report
    70xFFLevel0xFF=Low Battery Warning, 0-100 otherwise

    Lock Updates Local Time

    If a lock has schedules that enable User Codes at certain days/times, it needs to know the current local time. See the discussion above about the different command classes that can be used and the hardware considerations later in this document for the necessary hardware to support time keeping. Typically, a lock will send this frame once per day to sync to the local time. Note that in this case Supervision is not used as the clock update is not important enough to warrant the extra overhead and battery power. The frame below should be sent within the first five minutes after inclusion if the Hub does not automatically set the time. Note that the time can be off by a few seconds due to system wide delays.

    Lock sends the Hub a Time GET

    Byte #ValueNameDescription
    10x8ACmdClassTime CC
    20x01CmdTime GET

    The Hub responds with Time REPORT that sets the local time to be 5:6:7 (6 minutes and 7 seconds after 5am)

    Byte #ValueNameDescription
    10x8ACmdClassTime CC
    20x02CmdTime Report
    30x05HourLocal Hour
    40x06MinuteLocal Minute
    50x07SecondLocal Second

    Lock sends the Hub a Date GET

    Byte #ValueNameDescription
    10x8ACmdClassTime CC
    20x03CmdDate GET

    The Hub responds with Date REPORT that sets the local date to be 10 September 2019

    Byte #ValueNameDescription
    10x8ACmdClassTime CC
    20x04CmdDate Report
    30x07Year1Local year MSB
    40xE3Year2Local year LSB – 0x7E3=2019
    50x09MonthLocal Month – 0x09=September
    60x0ADayLocal Day – 0x0A=10th day

    The lock must calculate the day of the week based on the current date. The Time Offset Get command in V2 could also be used to get the daylight savings date/time if desired. Checking the local time/date at around 3:10am each day should keep the lock accurate to the current local daylight savings time.

    Generic Schedule to Enable a User Code

    The following sequence assigns User Code 0x05 to be enabled M-F 8am-5pm except on 5 June 2019 from 1:23pm to 6:45pm. First step is to SET two Time Ranges (01 and 02). The Hub should first send a Generic Schedule Capabilities Get to determine how many Time Ranges and Schedules the lock supports.

    Time Range Monday thru Friday 8am to 5pm

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x09Properties1Supervision SessionID=0x09
    40x15LenSupervision Length
    50xA3CmdClassGeneric Schedule
    60x03CmdGeneric Schedule Time Range Set
    80x01TRngID2Time Range ID=0x0001
    90xBEWeekdayWeekday Mask = M-F
    100x00StartYear1Note the InUse bit (MSB) is zero for all fields that are not used
    110x00StartYear2Start Year not used
    130x00StopYear2Stop Year not used
    140x00StartMonStart Month
    150x00StopMonStop Month
    160x00StartDayStart Day
    170x00StopDayStop Day
    180x00StartHourStart Hour
    190x00StopHourStop Hour
    180x00StartMinStart Minute
    190x00StopMinStop Minute
    200x88DayStartHrDaily Start Hour = 8am
    210x91DayStopHrDaily Stop Hour = 17:00=5pm
    220x00DayStartMinDaily Start Minute
    230x00DayStopMinDaily Stop Minute

    Time Range 5 June 2019 from 1:23pm to 6:45pm:

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x0AProperties1Supervision SessionID=0x0A
    40x15LenSupervision Length
    50xA3CmdClassGeneric Schedule
    60x03CmdGeneric Schedule Time Range Set
    80x02TRngID2Time Range ID=0x0002
    90x00WeekdayWeekday Mask not used
    110xE3StartYear2Start Year = 2019
    130xE3StopYear2Stop Year = 2019
    140x86StartMonStart Month = June
    150x86StopMonStop Month = June
    160x85StartDayStart Day = 5th
    170x85StopDayStop Day = 5th
    180x8EStartHourStart Hour = 1pm
    190x92StopHourStop Hour = 6pm
    200x97StartMinStart Minute = 23 minutes after the hour
    210xADStopMinStop Minute = 45 min after the hour
    220x00DayStartHrDaily Start Hour
    230x00DayStopHrDaily Stop Hour
    240x00DayStartMinDaily Start Minute
    250x00DayStopMinDaily Stop Minute

    Now that the two Time Ranges have been defined, the next step is to link them to each other to create a ScheduleID. In this case Time Range 0001 is being INCLUDED and Time Range 0002 is being EXCLUDED to make the desired schedule.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x0BProperties1Supervision SessionID=0x0B
    40x09LenSupervision Length
    50xA3CmdClassGeneric Schedule
    60x06CmdGeneric Schedule Schedule Set
    80x01SchedID2Schedule ID = 0001
    90x02NumIDsNumber of Time Range IDs = 2
    110x01TimeRngID2Include Time Range 0001
    130x02TimeRngID2Exclude Time Range 0002

    Finally, the Authentication CC is used to link the Schedule ID to the User Code CC UserID

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x0CProperties1Supervision SessionID=0x0C
    40x0ALenSupervision Length
    50xA1CmdClassAuthentication CC
    60x06CmdAuthentication Technologies Combination Set
    80x05AuthID2Schedule ID = 0005 – can be any value but matching with the UserID is easier to match them up
    90x01FallBackFallback Status = 01 = enable access based on the schedule
    110x05UserID2User Code CC UserID=0005
    130x01SchedID2Generic Schedule CC ScheduleID=0001
    140x00NumAuthIDOnly the User Code is enabled

    In all cases Supervision should be used to confirm the schedule and time ranges are set properly. Alternatively, a GET should be used if the lock is only using security S0. If NFC, BLE or some other authentication technology is used then the NumAuthID would be more than zero to include these other forms of authentication.

    Lock Has a Hardware Failure

    If a lock has some sort of a hardware failure, there are several Notification Events that can be sent. The most common is the lock is jammed where the bolt is neither in the locked or unlocked position but somewhere in between. Other options are to send a Home Security – Tamper event when the battery cover is removed. The Impact Detected event could be used if an accelerometer detects the lock being smashed. If someone is jamming the RF in an attempt to bypass the lock, then an RF Jamming message could be sent. In this case the lock should store the RF jamming message if the message is not acknowledged by the Hub due to the jamming. The lock should continue to attempt delivery at ever larger timeouts between retries.

    Byte #ValueNameDescription
    10x6CCmdClassSupervision CC
    20x01CmdSupervision GET
    30x01Properties1Supervision SessionID=0x01
    40x08LenSupervision Length
    50x71CmdClassNotification CC
    60x05CmdNotification Report
    70x00V1AlarmTypeV1Alarm can be non-zero IF documented in the user manual
    80x00V1AlarmLevelThese are used for backwards compatibility
    100xFFStatus00=notifications are disabled, FF=enabled
    110x06Type06=Access Control
    120x0BEvent0B=Lock Jammed

    The lock should also send a Door Lock Operation Report with a value of 0xFE (Door Mode Unknown) if the bolt is not in either the Locked or Unlocked mode.

    Z-Wave Long Range

    Z-Wave Long Range (ZWLR) support is recommended for locks. Z-Wave Long Range is a star topology with very long range. ZWLR is ideal for a battery backed up hub to talk directly to a distant lock even if the power is out and the Z-Wave mesh repeaters are offline. ZWLR will be available at the end of 2020 and is a software upgrade that can be OTAed to existing units. RF regulatory testing (FCC) may need to be redone to ensure ZWLR meets the applicable regulatory limits.

    Hardware Considerations

    The 700 series Z-Wave hardware is typically a FLiRS (Frequently Listening Routing Slave) device. Typical power consumption in this mode is on the order of 10uA average with brief peaks of 12mA during a transmit. Once every second the chip briefly wakes up and listens for a Wakeup Beam from the hub or an adjacent node. If the hub wants to talk to the lock it sends the Beam which wakes up the lock and then the two can communicate. Once the communication is complete the lock will again enter a low-power state. The 250ms FLiRS mode can be used to reduce the latency of waking the lock with a tradeoff of additional power draw.

    Real Time Clock (RTC) 32KHz Crystal

    Most locks need to accurately measure time and keep schedules of when to enable User Codes. The 700 series has an internal low power Low Frequency RC Oscillator (LFRCO=32KHz). However, the oscillator is not accurate enough to keep the schedule accurate without frequent updates from the Time Server (LFRCO can drift by more than 1min/hour). Thus, it is recommended to use a 32KHz crystal connected to the LFXO of the EFR32. A low cost 100ppm 32KHz crystal can provide accuracy of 9s per day. Note that if your lock does not support Time CC then an external crystal is not needed.

    • Use a 32KHz crystal for the LFXO if schedules are supported

    One MCU or Multiple?

    The Z-Wave 700 series is an ARM processor with built-in cryptography accelerators and plenty of low power peripherals. The ZGM130S has plenty of GPIOs and can be easily extended using simple GPIO expanders via I2C or SPI. In most cases the ZGM130S is more than powerful enough to run the entire lock using the single processor. This avoids the complexity and security issues involved with using multiple microcontrollers within the lock. If a multi-MCU solution is chosen, the communication method between the ZGM130 and the lock MCU should be a UART, SPI or I2C and should be encrypted. Do NOT use the SerialAPI on the ZGM130! The SerialAPI is intended for use with Internet Gateway processors with large amounts of FLASH/RAM/CPU. The SerialAPI does NOT provide support for security encryption/decryption which is built-in to the embedded SDK. The recommendation is to develop your own encrypted serial protocol between processors.

    Appendix A: Supervision Encapsulation End Device Example

    Z-Wave SDK 7.14 does not have direct support for encapsulating frames with Supervision CC. However, it is easy to add manually. The example below simply wraps the DoorLockOperationReport with the SuperVisionGet IF the device was added as S2 which means the Hub support Supervision CC. The frame is not encapsulated if responding to a GET from the Hub.

    In CC_DoorLock.c - Add the following code to this function:
     static uint8_t prepare_operation_report(ZW_APPLICATION_TX_BUFFER *pTxBuffer, uint8_t enableSuper)
       ZW_APPLICATION_TX_BUFFER * ptr = pTxBuffer;
       memset((uint8_t*)pTxBuffer, 0, sizeof(ZW_APPLICATION_TX_BUFFER) );
       uint8_t len=sizeof(ZW_DOOR_LOCK_OPERATION_REPORT_V4_FRAME);
       if (SECURITY_KEY_S2_ACCESS == GetHighestSecureLevel(ZAF_GetSecurityKeys()) && enableSuper) { // add supervision if S2 enabled
         ptr->ZW_SupervisionGetFrame.cmdClass = COMMAND_CLASS_SUPERVISION;
         ptr->ZW_SupervisionGetFrame.cmd = SUPERVISION_GET;
         DL_SessionID = CC_SUPERVISION_ADD_SESSION_ID((DL_SessionID+1));
         ptr->ZW_SupervisionGetFrame.properties1 = DL_SessionID;
         ptr->ZW_SupervisionGetFrame.encapsulatedCommandLength = sizeof(ZW_DOOR_LOCK_OPERATION_REPORT_V4_FRAME);
         ptr=(ZW_APPLICATION_TX_BUFFER*)((uint8_t*)ptr+sizeof(ZW_SUPERVISION_GET_FRAME)); // skip 4 bytes
       ptr->ZW_DoorLockOperationReportV4Frame.cmdClass = COMMAND_CLASS_DOOR_LOCK_V4;
       ptr->ZW_DoorLockOperationReportV4Frame.cmd = DOOR_LOCK_OPERATION_REPORT_V4;
       cc_door_lock_operation_report_t operation_report;
       ptr->ZW_DoorLockOperationReportV4Frame.currentDoorLockMode = (uint8_t)operation_report.mode;
       ptr->ZW_DoorLockOperationReportV4Frame.properties1 =
           (operation_report.outsideDoorHandleMode << 4) | operation_report.insideDoorHandleMode;
       ptr->ZW_DoorLockOperationReportV4Frame.doorCondition = operation_report.condition;
       ptr->ZW_DoorLockOperationReportV4Frame.lockTimeoutMinutes = operation_report.lockTimeoutMin;
       ptr->ZW_DoorLockOperationReportV4Frame.lockTimeoutSeconds = operation_report.lockTimeoutSec;
       ptr->ZW_DoorLockOperationReportV4Frame.targetDoorLockMode = operation_report.targetMode;
       ptr->ZW_DoorLockOperationReportV4Frame.duration = operation_report.duration;

    ZGM130 GPIO Decoder Ring

    One of the challenges with using the Z-Wave developers kit is trying to figure out which pin is connected to what. Every pin of the ZGM130S can perform multiple functions but some pins are best used for certain things. This guide provides general recommendations, but these are not hard-and-fast rules. The ZGM130S provides a great deal of flexibility so feel free to explore the many options each pin and peripheral has to offer. I’m hoping I can guide you with some initial suggestions but feel free to delve into the details to find your ideal solution.

    This guide is a compilation of a number of documents and while I’ve been thorough, I could easily have made a typo here or there. Please use the online documentation as the official reference and send me an email pointing out my error and I’ll fix it. I couldn’t possibly include every feature for every pin but the details are available in the reference documents below. The Decoder Ring below is an overview of the most commonly used features. The table below contains a lot of information, so you’ll need to view it on a computer with a big screen.

    Reference Documents

    ZGM130S        ZGM130S Datasheet – See section 6 for the pin definitions
    EFR32XG13    Gecko Family Reference Manual – Each peripheral is detailed here
    UG381             ZGM130S Zen Gecko DevKit Users Guide – Section 3 describes connectors

    ZGM130S GPIO Decoder Table

    ZGM130SGPIO port as described in the ZGM130S data sheet
    Pin #GPIO pin number of the ZGM130S SIP package
    BRD4202AZen Gecko Developers kit board for the ZGM130S
    BRD8029AButton/LED board plugged into the WSTK EXP header for the sample apps
    WSTK EXPPin number of the main WSTK board expansion header
    WSTKMain developers kit board with USB, LCD and Segger J-link debugger
     The Pxx pins are the holes across the long side of the board
     The Fxx pins are secondary functions that typically connect to the isolators
    MiniDBGSmall 20 pin ribbon cable used to connect WSTK to a target DUT
    ALT FUNCSAlternate functions the GPIO can perform. All GPIOs can be simple digital 1/0s.
     Some pins have special analog or peripheral functions.
    CommentsBrief comments describing special functions of the GPIO
    Description of the columns in the table below

    General Purpose IOs – Use these for your application first

    ZGM 130SPin #BRD 4202ABRD 8029AWSTK EXPWSTKMini DBGALT FUNCsComments
      P32  LED ON=low, Pullup Ideal for PWM
      P34  LED ON=low, Pullup
      P36  LED ON=low, Pullup
     EXP4P1 F16  Easy to use with WSTK since they are on EXP
    PC759P201-6 EXP6P3   
    BUTN0EXP7P4 F12   
     EXP8P5 F15   
    PB1446P201-30  P27  LFXO – 32Khz osc crystal for accurate time
    PB1547P201-32  P29  LFXO
    PD926P201-33  P30   
      P25 F11   
      P31 F18 OPA1PUse for Analog functions
    PD1534P201-38  P35 OPA1N 
    LED2EXP3P0 F8 OPA0P 
    PA439P201-17  P14 OPA0N 
      P16 F5  VCOM_ENB Must be 1 for WSTK to pass USART0 to USB

    Special Function Pins – Use these for their alternate function

    ZGM 130SPin #BRD 4202ABRD 8029AWSTK EXPWSTKMini DBGALT FUNCsComments
    PC1062P201-15BUTN2EXP15P12 EM4WU12 I2C1_SDAEM4WU pins are the ONLY pins that will wakeup from EM4
    PC1163P201-16BUTN3EXP16P13 I2C1_SCLUse for I2C, will NOT wakeup from EM4
    PD1431P201-36 P200-30  P33 F17 OPA1 EM4WU4 
    PF79P201-9 P200-26BUTN1EXP9P6 F13 EM4WU1 
    PA338P201-5 P200-22LED3EXP5P2 F9 VDAC0 OPA0 EM4WU8 
    PB1141P201-21 P200-34  P18 F21 OPA2P
    PB1242P201-23 P200-33  P20 F2010OPA2PTI_DATA Future Packet Trace debug
    PB1345P201-25 P200-32  P22 F199OPA2N EM4WU9PTI_SYNC Always wire the 2 PTI pins on the ZG14 modem chip to GPIOs on your host CPU

    Fixed Function Pins – Reserved for debug

    ZGM 130SPin #BRD 4202ABRD 8029AWSTK EXPWSTKMini DBGALT FUNCsComments
      P28 F26EM4WU0SWO
    RST_N15P200-17  F4 SW1023 RESET button next to EXP header
    ANT23SMA or PCB     Radio Antenna Move cap R2 for PCB

    Power Pins

    ZGM 130SPin #BRD 4202ABRD 8029AWSTK EXPWSTKMini DBGALT FUNCsComments
    VSS GND1,10,11,
    32,33,43, 48,49,51,
        2 Ground 0 Volts
    AVDD44      Analog Power 1.8-3.8V
    1V850      Leave unconnected
    VREG VDD52      DCDC Reg input
    Tie to AVDD
    2.4V min for DCDC
    DECO UPLE56      No-Connect
    IOVDD57      Digital IO Power 1.62V-VREGVDD AVDD>=IOVDD
         VAEM1 DUT Power

    EXP Port on the WSTK

    BRD8029AWSTKPin #Pin #WSTKBRD8029A
    LED2P0 (PA2)34P1(PC6) 
    BUTN1P6(PF7)910P7(PC9)SW Pull up/dn
     BoardID_SDA19203V3BRDID PWR
    P100 connects to the Button/LED BRD8029A

    WSTK = hole name (ZGM130 GPIO)
    EX: WSTK P100 pin 16 is hole P13, ZGM130S GPIO PC11, Button 3 on the BRD8029A
    BRD8029A is the Button/LED board. Functionality is:
    LEDs are ON when driven high
    BUTN pins are pulled up and go low when the button is pressed
    The SW can pull the pin either up or down depending on the slide setting
    left/on is 1, right/off is 0 thru 1MOhm resistors
    The VMCU powers the LEDs/Buttons but the board ID is powered via pin 20
    Schematic is in Simplicity Studio

    Mini-Simplicity Debug header: Top View

    NamePin #Pin #Name
    VAEM (3V3)12GND
    VCOM_TX (PA0)56SWO(PF2)

    On the DUT board with the ZGM130S on it, connect VCOM_RX to PA1 and VCOM_TX to PA0. The header is a 0.05” pitch 10 pin header. Typically use a Samtec FTSH-110 but to make the pads even smaller use just the pads for a thru-hole connector. See my post “700 series Debug Header” from October 2019 for more details on the debug header.


    Remember that the GPIOs in all the Wireless Gecko chips from Silicon Labs are very flexible and most peripheral functions can be routed to almost any IO pin. That said, there are some pins that have fixed functions and some pins are best at certain other functions. Let’s start with the pins you can’t use.

    Power Pins

    Obviously, the power pins have to be connected to the proper voltage. The ZGM130 has a lot of ground pins so make sure every one of them is connected to a solid ground. The voltages for the power pins have a few rules but in most cases you’ll tie AVDD and VREGVDD to the same power source of 3.3V. The on-chip DC to DC regulator allows a wide voltage range on VREGVDD so there is some additional flexibility which requires careful consideration. But for most applications, tie these two power pins directly to the battery. Most of the time IOVDD is also tied to the battery though depending on other chips in your system you might need an LDO to keep the IOs at the proper voltage.

    Debug Pins

    The next set of pins you should not use for GPIOs are the debug pins. All ten IO pins on the Mini-Simplicity header should be wired up as shown in the table above. The UART pins are very important to print out debug information while the chip is running. The advantage here is that you can see things happening in real-time without using a scope or logic analyzer. And you can easily enable/disable blocks of debug statements as needed. The sample apps print all sorts of debug information so you’ll want to do the same in your code. The UART defaults to only 115200 baud but it’s easy to increase it up to roughly 1Mbaud to reduce the time impact of printing debug messages. Also, keep the messages short or else they may impact the timing so much that your code will fail. If you’re really in a pinch for one more IO, you could use the SWO or VCOM_RX pins as you probably don’t need them.

    Special Function Pins

    A number of pins have specific functions especially for certain analog functions. The ADC/DAC only have their primary and alternate IOs though you can route them thru the ABUS. Only a few of these pins can wake the chip from sleeping in EM4. Be very careful and utilize these pins for buttons or sensors that need to wake the chip up.

    General Purpose IOs  

    The rest of the pins are available for any purpose. Most of the pins can be any digital IO function. Some pins are handy because of their connection on the DevKit. There are three IOs connected to an RGB LED on the 4202 board. These are really handy to visually observe PWM waveforms based on the color of the LED. The pins that are routed to the EXP header on the WSTK are easy to connect to a proto board. Be careful to avoid using PA5 as that is connected to the VCOM enable pin on the WSTK. PA5 has to be high to route the debug UART data to the USB bus. But this is a restriction only when using the DevKit 4202 board. If connecting to your own PCB via the Mini-Simplicity header you can freely use PA5.


    The ZGM130S is a flexible chip with plenty of compute power, RAM and Flash. The GPIOs can largely be routed from any peripheral to any IO though there are some restrictions. The secret decoder ring given here maps out which pin can do what and which ones should be used for your application. This is only a guide and the chip has many more features than I can describe here. Refer to the Reference Documents for more in depth knowledge.

    700 Series Debug Header

    We’re all trying to make the Smart Home products smaller and less visible. Using coin cells instead of bulky cylindrical batteries significantly reduces the size of many products. The challenge with making products smaller is that the area available on the PCB for a debug header is in short supply.

    With the 500 series I usually used a 0.1″ spacing 12 pin header from the ZDP03A programmer to the target board. The header was normally not installed in the final product but for debug purposes the solid thru-hole connector meant I would reliably program a device the first time and every time.

    However, many customers I’ve worked with want to use less PCB real estate which means they come up with a custom set of test points. Typically a jig with spring loaded pins are used to contact to the PCB or more often wires are soldered to the PCB. The problem with this solution is that the jig is large, expensive and fragile. Soldering a cable to a board often results in a fragile connection where the cable can easily break a pin and not be immediately obvious. I’ve spent far too much time trying to figure out why I could program the part a minute ago but now I can’t only to realize the cable has a loose wire.

    Nasty unreliable hand-soldered fragile Z-Wave debugging cable
    Unreliable Z-Wave programming cable

    500 Series Header

    My recommendation for the 500 series is to use a full size 12 pin 0.1″ spacing connector for programming and debug. Either SMT or thru-hole is fine but either way you have a solid, reliable, portable connection. While this worked OK with the 500 series which typically used large cylindrical batteries, the 700 series often uses coin cells which doesn’t have the real estate for a full size connector.

    Reliable 500 series header = 15x5mm

    700 Series Debug Header

    Fortunately Silicon Labs has an even better solution for the 700 series – use a 0.05″ spacing 10 pin SMT header. The Mini Simplicity Debug connector is described in AN958. If you have a little room then use the standard SMT header which is 6x6mm. If you are very tight on real estate then put down the pads for the thru-hole version of the connector but hand-solder the thru-hole header to the pads. Using just the pads results in a header only 3x6mm. You can’t tell me you can’t come up with 18sqmm to make the PCB debug reliable!

    Either solution requires only a small amount of space on a single side of the PCB. Usually the header pads can be under a coin cell since during debug a power supply is used instead of the battery. This same header can be used for production programming using a jig to contact to the pads. Having a standard and reliable connection to the PCB will save you time during debug and on the production floor.

    Reliable 700 series header = 6x6mm


    No matter how tempted you might be to come up with your own cable/connector/test points, DON’T DO IT! Use the standard Mini Simplicity connector to save you so many headaches during debug. A solid, reliable debug connection is an absolute must otherwise you risk spinning your wheels chasing ghosts that are caused by a flakey connector. Take it from me, I’ve tried to debug just way too many of these over the years and it is not fun.