Skip to content

Instantly share code, notes, and snippets.

@ginjo
Created February 15, 2024 04:37
Show Gist options
  • Save ginjo/87d5fc8f783df78fa7c5b3a854fc08d8 to your computer and use it in GitHub Desktop.
Save ginjo/87d5fc8f783df78fa7c5b3a854fc08d8 to your computer and use it in GitHub Desktop.
Home Assistant, Docker, zwave-js-ui, ser2net

Home Assistant running in Docker, using zwave-js-ui and ser2net to access zwave USB stick over TCP.

Basic setup for HomeAssistant using zwave-js-ui for z-wave, and ser2net to host the z-wave usb stick on TCP port. We use ser2net, because USB device passthru doesn't work on Docker Mac, Docker Windows, or Swarm-mode (even on Linux).

This system is running on a Raspberry Pi 3 B+, however I also had it running on a Mac (Mojave) using 'nix' package manager to install ser2net.

Some paths and device names are specific to my setup. Change them to work with your own setup.

This setup works well for me, however I give no guarantees for success.

Hardware

  • Raspberry Pi 3 B+
  • Raspbian 32-bit Bullseye installed from the official RPi imager for Mac.
  • Zooz 800 USB z-wave stick.

Docker

Ser2net (serves serial devices over tcp)

  • Runs on Raspbian host, not in Docker.
  • Installed on Raspbian host using apt.

Ser2net yaml config

  • This is the v1 ser2net yaml config.
  • It is not legit yaml, but it's what this ser2net version (4.3.3) uses.
  • The default ser2net install automatically boots with the /etc/ser2net.yaml config file installed by ser2net.
  • You can use that config file, or disable it (with systemctl) and use your own config file.
  %YAML 1.1
  ---
  connection: &zwave
    accepter: tcp,3333
    #timeout: <number>
    enable: on
    connector: serialdev,/dev/serial/by-id/usb-Zooz_800_Z-Wave_Stick_533D004242-if00,115200N81,nobreak,local
    options:
      kickolduser: true

Ser2net startup command

  /usr/sbin/ser2net -n -d -l -c "$PWD"/ser2net_zwave.yaml -P /run/ser2net.pid
  
  # I get no output from this command, but it works.

Ser2net systemd unit

  • I installed this on the Pi system to automatically bring up my ser2net instance at system boot.
  • This is optional, as you can start ser2net manually with the above command.
  [Unit]
  Description=ser2net_zwave_service
  ConditionPathExists=/usr/sbin/ser2net
  After=network.target
  After=network-online.target
  Wants=network-online.target

  [Service]
  WorkingDirectory=/home/wbr/ha
  ExecStart=/home/wbr/ha/ser2net_startup.sh
  Restart=on-failure
  RestartSec=5

  [Install]
  WantedBy=multi-user.target

Ser2net startup script called from systemd

  • Optional, use this if you implement the systemd unit above.
  {
    until (ss -tulpn | grep -Eq 'LISTEN.*0\.0\.0\.0'); do
      #echo "Waiting for network to become active..."
      sleep 1
    done

    sleep 5

    /usr/sbin/ser2net -n -d -l -l -l -c "$PWD"/ser2net_zwave.yaml -P /run/ser2net.pid

  } 2>&1 >> /var/log/ser2net_zwave.log

Z-Wave-JS-UI running in Docker

  • I'm using Docker Swarm, but docker compose should work too.
  • Compose file service block.
  zwavejsui:
    container_name: zwavejsui
    hostname: zwavejsui
    image: zwavejs/zwave-js-ui:9.7.1
    restart: always
    tty: true
    stop_signal: SIGINT
    environment:
      - SESSION_SECRET=mysupersecretkey
      - ZWAVEJS_EXTERNAL_CONFIG=/usr/src/app/store/.config-db
      # Uncomment if you want log times and dates to match your timezone instead of UTC
      # Available at https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
      - TZ=America/Los_Angeles
    # devices:
    #   # Not supported on Mac, Windows, or in Swarm mode.
    #   - /dev/serial/by-id/usb-Zooz_800_Z-Wave_Stick_533D004242-if00:/dev/zwave
    volumes:
      - /$PWD/zwave_js_ui:/usr/src/app/store
      - /$PWD:/ha_app
    ports:
      - "8091:8091" # port for web interface
      - "3000:3000" # port for zwave-js-ui websocket server

In the zwave-js-ui web admin, where you would normally enter the path to your z-wave USB device, enter the host (or IP) and port of the ser2net instance that's hosting the z-wave stick.

Home Assistant

  • I'm using Docker Swarm, but docker compose should work too.
  • Compose file service block.
  homeassistant:
    container_name: homeassistant
    hostname: homeassistant
    image: "homeassistant/home-assistant:2024.1.6"
    volumes:
      - $PWD/config2:/config
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 8123:8123
    environment:
      - TZ=America/Los_Angeles
    restart: unless-stopped
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment