Salta ai contenuti

Z-Wave Cheat Sheet

Overview

Z-Wave is a wireless communication protocol designed specifically for home automation and IoT, operating in the sub-GHz frequency band (908.42 MHz in North America, 868.42 MHz in Europe) to avoid interference with WiFi and Zigbee devices. It uses a mesh networking topology where mains-powered devices act as repeaters, extending the network range. Z-Wave supports up to 232 devices per network and provides AES-128 encryption (Security S0 and S2 frameworks) for secure communication between devices such as smart locks, sensors, switches, thermostats, and garage door controllers.

The Z-Wave ecosystem includes certified interoperable devices from hundreds of manufacturers, all managed through a Z-Wave controller (USB stick or hub). Open-source tools like Z-Wave JS (the modern standard), OpenZWave (legacy), and the Zniffer protocol analyzer enable developers and home automation enthusiasts to build custom integrations. Z-Wave JS is the recommended library, providing a complete implementation of the Z-Wave protocol with support for Home Assistant’s Z-Wave JS integration, making it the de facto way to integrate Z-Wave into open-source smart home platforms.

Installation

# Install Z-Wave JS Server
npm install -g @zwave-js/server

# Run Z-Wave JS Server
zwave-server /dev/ttyUSB0

# Or using Docker
docker run -d \
  --name zwavejs \
  --restart=unless-stopped \
  --device /dev/ttyUSB0:/dev/ttyUSB0 \
  -p 3000:3000 \
  -p 8091:8091 \
  -v /opt/zwavejs:/usr/src/app/store \
  zwavejs/zwave-js-ui:latest

Z-Wave JS UI (zwavejs2mqtt)

# docker-compose.yml
version: '3.8'
services:
  zwavejs:
    image: zwavejs/zwave-js-ui:latest
    restart: unless-stopped
    tty: true
    stop_signal: SIGINT
    devices:
      - /dev/ttyUSB0:/dev/ttyUSB0
    ports:
      - "8091:8091"   # Web UI
      - "3000:3000"   # WebSocket
    volumes:
      - ./zwavejs-store:/usr/src/app/store
    environment:
      - TZ=America/New_York
docker compose up -d
# Access UI at http://localhost:8091

Finding Your Z-Wave Controller

# List USB devices
ls -la /dev/ttyUSB* /dev/ttyACM*

# Check USB device details
dmesg | grep -i "z-wave\|aeotec\|zooz\|silicon"

# Identify device
udevadm info -a -n /dev/ttyUSB0 | grep -E "vendor|product|serial"

# Create persistent device path (udev rule)
cat > /etc/udev/rules.d/99-zwave.rules << 'EOF'
SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="zwave"
EOF
sudo udevadm control --reload-rules

Z-Wave JS UI Configuration

Initial Setup

1. Open http://localhost:8091
2. Settings > Z-Wave:
   - Serial Port: /dev/ttyUSB0
   - Security Keys: Generate (S0, S2 Unauthenticated, S2 Authenticated, S2 Access Control)
3. Settings > MQTT (optional):
   - Host: mqtt://localhost:1883
   - Enable MQTT gateway
4. Click Save and restart

Security Keys

{
  "S2_Unauthenticated": "auto-generated-32-byte-hex",
  "S2_Authenticated": "auto-generated-32-byte-hex",
  "S2_AccessControl": "auto-generated-32-byte-hex",
  "S0_Legacy": "auto-generated-16-byte-hex"
}

Device Management

Inclusion (Adding Devices)

Via Z-Wave JS UI:
1. Click "Manage Nodes" > "Include"
2. Choose security level:
   - S2 Access Control (locks, garage doors)
   - S2 Authenticated (sensors, thermostats)
   - S2 Unauthenticated (lights, switches)
   - S0 Legacy (older devices)
   - No Security (non-critical devices)
3. Put device in inclusion mode (usually triple-click button)
4. Confirm DSK if S2 inclusion

Exclusion (Removing Devices)

Via Z-Wave JS UI:
1. Click "Manage Nodes" > "Exclude"
2. Put device in exclusion mode (usually triple-click button)
3. Device will be removed from network

Node Management

ActionDescription
Heal NodeRediscover routes for a specific node
Heal NetworkRediscover routes for entire network
Ping NodeCheck if node is reachable
Interview NodeRe-query device capabilities
Refresh ValuesUpdate all values from device
Remove FailedRemove a dead/failed node
Replace FailedReplace failed node with new hardware
Firmware UpdateOTA update device firmware

MQTT Integration

Topic Structure

# State topics
zwave/<node_name>/status                # online/offline
zwave/<node_name>/<command_class>/<property>

# Set topics
zwave/<node_name>/<command_class>/<property>/set

# Examples
zwave/living_room_dimmer/38/currentValue    # Current brightness
zwave/living_room_dimmer/38/targetValue/set # Set brightness
zwave/front_door_lock/98/currentMode        # Lock state
zwave/thermostat/67/setpoint/1/set          # Set temperature

Control Examples

# Turn on a switch
mosquitto_pub -t "zwave/office_light/37/targetValue/set" -m "true"

# Turn off
mosquitto_pub -t "zwave/office_light/37/targetValue/set" -m "false"

# Set dimmer to 75%
mosquitto_pub -t "zwave/living_room_dimmer/38/targetValue/set" -m "75"

# Lock a door
mosquitto_pub -t "zwave/front_door_lock/98/targetMode/set" -m "255"

# Unlock
mosquitto_pub -t "zwave/front_door_lock/98/targetMode/set" -m "0"

# Set thermostat
mosquitto_pub -t "zwave/thermostat/67/setpoint/1/set" -m "72"

# Set thermostat mode
mosquitto_pub -t "zwave/thermostat/64/mode/set" -m "1"  # Heat

# Subscribe to all Z-Wave events
mosquitto_sub -t "zwave/#" -v

# Subscribe to specific sensor
mosquitto_sub -t "zwave/motion_sensor/#" -v

Z-Wave JS API (Programmatic)

const { Driver } = require("zwave-js");

// Initialize driver
const driver = new Driver("/dev/ttyUSB0", {
  securityKeys: {
    S2_Unauthenticated: Buffer.from("...", "hex"),
    S2_Authenticated: Buffer.from("...", "hex"),
    S2_AccessControl: Buffer.from("...", "hex"),
    S0_Legacy: Buffer.from("...", "hex"),
  },
});

driver.once("driver ready", () => {
  // List all nodes
  for (const [nodeId, node] of driver.controller.nodes) {
    console.log(`Node ${nodeId}: ${node.deviceConfig?.description}`);
  }

  // Get specific node
  const node = driver.controller.nodes.get(5);

  // Get value
  const temp = node.getValue({
    commandClass: 49, // Sensor Multilevel
    property: "Air temperature",
  });
  console.log(`Temperature: ${temp}°F`);

  // Set value (turn on switch)
  node.setValue(
    { commandClass: 37, property: "targetValue" },
    true
  );
});

driver.start();

Command Classes

Common Command Classes

CC IDNameDescription
0x25Binary SwitchOn/Off switches
0x26Multilevel SwitchDimmers, motor controls
0x30Binary SensorMotion, door/window sensors
0x31Multilevel SensorTemperature, humidity, light
0x40Thermostat ModeHeat, cool, auto, off
0x43Thermostat SetpointTemperature setpoints
0x62Door LockSmart locks
0x63User CodeLock PIN codes
0x70ConfigurationDevice parameters
0x71NotificationAlerts and events
0x72Manufacturer SpecificDevice identity
0x80BatteryBattery level
0x84Wake UpSleep/wake schedule
0x86VersionProtocol/firmware version
0x8EMulti Channel Assoc.Multi-endpoint association
0x98Security S0Legacy security
0x9FSecurity S2Modern security

Advanced Usage

Associations

# Direct association: device A controls device B without controller
Via Z-Wave JS UI:
Node > Associations tab
- Group 2 (usually "basic set") 
- Add target node ID
- Commands go directly between devices

Device Parameters

# Configure device parameters
Via Z-Wave JS UI:
Node > Configuration tab
- Parameter 1: LED indicator mode
- Parameter 3: Auto-off timer
- Parameter 4: Power restore state
# Values are device-specific - check manufacturer docs

Network Optimization

# Heal network (rebuild routing tables)
# Via UI: Settings > Z-Wave > Heal Network
# Best done at night when devices are idle

# Priority Return Route
# Assigns optimal routes for time-critical devices

# Check network health
# Via UI: Network Map shows mesh topology
# Look for nodes with few connections (weak mesh)

Firmware Updates

Via Z-Wave JS UI:
1. Node > Firmware Update
2. Select firmware file (.hex, .otz, .ota, .gbl)
3. Target: usually 0 (main chip)
4. Click Begin Firmware Update
5. Wait for completion (can take 5-30 minutes)

Configuration

Z-Wave JS Server Settings

{
  "port": "/dev/ttyUSB0",
  "options": {
    "logConfig": {
      "enabled": true,
      "level": "info",
      "filename": "/var/log/zwave.log"
    },
    "storage": {
      "cacheDir": "/opt/zwavejs/cache"
    },
    "preferences": {
      "scales": {
        "temperature": "°F"
      }
    }
  }
}

Troubleshooting

IssueSolution
Controller not foundCheck USB path, install drivers, try other port
Device won’t includeExclude first, move closer, factory reset device
Device shows “dead”Check battery/power, try ping, heal network
Slow responseAdd repeaters, heal network, check routes
S2 inclusion failsVerify DSK, check security keys configured
MQTT not publishingCheck MQTT broker connection, verify gateway mode
Device drops off networkCheck for interference, add router devices
Wrong values reportedRe-interview node, check configuration params

Diagnostic Commands

# Check Z-Wave JS UI logs
docker logs -f zwavejs

# Check controller info via UI
# Settings > Z-Wave > Controller Info

# Network statistics
# Shows dropped packets, routing failures

# Check USB device health
dmesg | tail -20
lsusb -v | grep -A 5 "Z-Wave\|0658"

# Z-Wave frequency by region
# US/Canada: 908.42 MHz
# Europe: 868.42 MHz
# Australia: 921.42 MHz
# Ensure controller matches your region