Bind Aeotec Z-Wave Stick to a static name

Hi,
I have just installed Home Assistant Supervised in Docker on a Debian 11 machine.
I know that the USB devices can change names after reboot or if they are unplugged and plugged in again.
How do I give my Aeotec Z-Wave stick a static name ?
It seems to be connected to ttyACM0
But when I run

udevadm info -a -n /dev/ttyACM0 | less

The ttyACM0 don’t have any idVendor or idProduct numbers!
As I understand you should create i udev-rule with symlink but if there is no specific parameters for the device then I guess it’s hard to determind the device!

Futher have I read that Docker dosen’t work with symlink, right or wrong?
Question how should I achieve a static name on my Aeotec Z-wave stick that’s work in Docker?

There should already be one in /dev/serial/by-id.

Which Aeotec?
For zstick 5 and older aeotec below works in debian and ubuntu

/etc/udev/rules.d/99-usb-serial.rules

SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0660", GROUP="zwave", SYMLINK+="zwave"

SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", MODE="0660", GROUP="zwave", SYMLINK+="zwave0"

shows as /dev/zwave0 or /dev/zwave based on device

EDIT

works without issue. I actually run zwavejs as non root user and still work

try simpler command and make sure you verify zstick is actully /dev/ttyACM0

udevadm info /dev/ttyACM0

EDIT
If you use my example I forget I create zwave user/group so you must remove GROUP=“zwave” from my example

SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0660", SYMLINK+="zwave"

SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", MODE="0660", SYMLINK+="zwave0"

The easiest solution is map using /dev/serial/by-id as pointed out above, then no udev rule is needed.

If you still want to do a udev rule try listing the full attributes by running

udevadm info --name=/dev/ttyACM0 --attribute-walk

Here’s a guide that helped me write mine

Also checkout this post/thread - it was a synology system but has some info that might help

If I check the ttyACM0 I get following

fredda@Fredda-HaSup:/etc/udev/rules.d$ udevadm info --name=/dev/ttyACM0 --attribute-walk

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/tty/ttyACM0':
    KERNEL=="ttyACM0"
    SUBSYSTEM=="tty"
    DRIVER==""
    ATTR{power/async}=="disabled"
    ATTR{power/control}=="auto"
    ATTR{power/runtime_active_kids}=="0"
    ATTR{power/runtime_active_time}=="0"
    ATTR{power/runtime_enabled}=="disabled"
    ATTR{power/runtime_status}=="unsupported"
    ATTR{power/runtime_suspended_time}=="0"
    ATTR{power/runtime_usage}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0':
    KERNELS=="3-1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="cdc_acm"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="02"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="01"
    ATTRS{bInterfaceSubClass}=="02"
    ATTRS{bNumEndpoints}=="01"
    ATTRS{bmCapabilities}=="0"
    ATTRS{power/async}=="enabled"
    ATTRS{power/runtime_active_kids}=="0"
    ATTRS{power/runtime_enabled}=="enabled"
    ATTRS{power/runtime_status}=="suspended"
    ATTRS{power/runtime_usage}=="0"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3/3-1':
    KERNELS=="3-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="02"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 2"
    ATTRS{bcdDevice}=="0000"
    ATTRS{bmAttributes}=="80"
    ATTRS{busnum}=="3"
    ATTRS{configuration}==""
    ATTRS{devnum}=="4"
    ATTRS{devpath}=="1"
    ATTRS{idProduct}=="0200"
    ATTRS{idVendor}=="0658"
    ATTRS{ltm_capable}=="no"
    ATTRS{maxchild}=="0"
    ATTRS{power/active_duration}=="738528444"
    ATTRS{power/async}=="enabled"
    ATTRS{power/autosuspend}=="2"
    ATTRS{power/autosuspend_delay_ms}=="2000"
    ATTRS{power/connected_duration}=="738528444"
    ATTRS{power/control}=="on"
    ATTRS{power/level}=="on"
    ATTRS{power/persist}=="1"
    ATTRS{power/runtime_active_kids}=="0"
    ATTRS{power/runtime_active_time}=="738528169"
    ATTRS{power/runtime_enabled}=="forbidden"
    ATTRS{power/runtime_status}=="active"
    ATTRS{power/runtime_suspended_time}=="0"
    ATTRS{power/runtime_usage}=="1"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="removable"
    ATTRS{rx_lanes}=="1"
    ATTRS{speed}=="12"
    ATTRS{tx_lanes}=="1"
    ATTRS{urbnum}=="9"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb3':
    KERNELS=="usb3"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0510"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="3"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0002"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Linux 5.10.0-9-amd64 xhci-hcd"
    ATTRS{maxchild}=="4"
    ATTRS{power/active_duration}=="748936520"
    ATTRS{power/async}=="enabled"
    ATTRS{power/autosuspend}=="0"
    ATTRS{power/autosuspend_delay_ms}=="0"
    ATTRS{power/connected_duration}=="748995352"
    ATTRS{power/control}=="auto"
    ATTRS{power/level}=="auto"
    ATTRS{power/runtime_active_kids}=="1"
    ATTRS{power/runtime_active_time}=="748940726"
    ATTRS{power/runtime_enabled}=="enabled"
    ATTRS{power/runtime_status}=="active"
    ATTRS{power/runtime_suspended_time}=="54223"
    ATTRS{power/runtime_usage}=="0"
    ATTRS{power/wakeup}=="disabled"
    ATTRS{power/wakeup_abort_count}==""
    ATTRS{power/wakeup_active}==""
    ATTRS{power/wakeup_active_count}==""
    ATTRS{power/wakeup_count}==""
    ATTRS{power/wakeup_expire_count}==""
    ATTRS{power/wakeup_last_time_ms}==""
    ATTRS{power/wakeup_max_time_ms}==""
    ATTRS{power/wakeup_total_time_ms}==""
    ATTRS{product}=="xHCI Host Controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{rx_lanes}=="1"
    ATTRS{serial}=="0000:00:14.0"
    ATTRS{speed}=="480"
    ATTRS{tx_lanes}=="1"
    ATTRS{urbnum}=="138"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/pci0000:00/0000:00:14.0':
    KERNELS=="0000:00:14.0"
    SUBSYSTEMS=="pci"
    DRIVERS=="xhci_hcd"
    ATTRS{ari_enabled}=="0"
    ATTRS{broken_parity_status}=="0"
    ATTRS{class}=="0x0c0330"
    ATTRS{consistent_dma_mask_bits}=="64"
    ATTRS{d3cold_allowed}=="1"
    ATTRS{device}=="0x1e31"
    ATTRS{dma_mask_bits}=="64"
    ATTRS{driver_override}=="(null)"
    ATTRS{enable}=="1"
    ATTRS{irq}=="28"
    ATTRS{local_cpulist}=="0-3"
    ATTRS{local_cpus}=="f"
    ATTRS{msi_bus}=="1"
    ATTRS{msi_irqs/28}=="msi"
    ATTRS{numa_node}=="-1"
    ATTRS{power/async}=="enabled"
    ATTRS{power/control}=="on"
    ATTRS{power/runtime_active_kids}=="1"
    ATTRS{power/runtime_active_time}=="748996041"
    ATTRS{power/runtime_enabled}=="forbidden"
    ATTRS{power/runtime_status}=="active"
    ATTRS{power/runtime_suspended_time}=="0"
    ATTRS{power/runtime_usage}=="1"
    ATTRS{power/wakeup}=="enabled"
    ATTRS{power/wakeup_abort_count}=="0"
    ATTRS{power/wakeup_active}=="0"
    ATTRS{power/wakeup_active_count}=="0"
    ATTRS{power/wakeup_count}=="0"
    ATTRS{power/wakeup_expire_count}=="0"
    ATTRS{power/wakeup_last_time_ms}=="0"
    ATTRS{power/wakeup_max_time_ms}=="0"
    ATTRS{power/wakeup_total_time_ms}=="0"
    ATTRS{revision}=="0x04"
    ATTRS{subsystem_device}=="0x1e31"
    ATTRS{subsystem_vendor}=="0x8086"
    ATTRS{vendor}=="0x8086"

  looking at parent device '/devices/pci0000:00':
    KERNELS=="pci0000:00"
    SUBSYSTEMS==""
    DRIVERS==""
    ATTRS{power/async}=="enabled"
    ATTRS{power/control}=="auto"
    ATTRS{power/runtime_active_kids}=="19"
    ATTRS{power/runtime_active_time}=="0"
    ATTRS{power/runtime_enabled}=="disabled"
    ATTRS{power/runtime_status}=="unsupported"
    ATTRS{power/runtime_suspended_time}=="0"
    ATTRS{power/runtime_usage}=="0"

fredda@Fredda-HaSup:/etc/udev/rules.d$

I don’t know but for me it doesn’t look like the ttyACM0 has any parameters.
But I have tried different things in my udev-rule. But nothing works for me.
For the monent the udev-rule looks like this

# Zwave controller
KERNEL=="ttyACM0" SUBSYSTEM=="tty", ATTRS{idVendor}="0658", ATTRS{idProduct}=="0200", SYMLINK+="ZwaveController"

But when I run, to see if the symlinks work I get this

fredda@Fredda-HaSup:/etc/udev/rules.d$ ls -l /dev/ZwaveController
ls: cannot access '/dev/ZwaveController': No such file or directory
fredda@Fredda-HaSup:/etc/udev/rules.d$

Can any see what I’m doing wrong?

Or should I skip the udev-rule and use the /dev/serial/by-id mapping in a docker-compose file instead ?
Same here I don’t really know how to set up a docker-compose file.
I only have a Docker installation today with Home Assistant Supervised

Which of udev-rule or docker-compose file is the easiest way?

If you have a supervised install you should be able to go to the supervisor addon store and install the zwavejs addon. Then you can specify the usb in the addon config to dev/serial/by-id. See the zwave documentation.

Post back if it doesn’t show up using dev/serial/by-id . You can do a udev rule using some of the atttrs values you pasted above. These two should work to help write a udev rule if necessary.

ATTRS{idProduct}=="0200"
ATTRS{idVendor}=="0658"

Did you reboot or restart services after adding rule? just want to verify

your missing an equal sign after ATTRS{idVendor} I believe. == not =
Honestly, I forget if both are OK or must be ==

Probably should remove "KERNEL==“ttyACM0”. I think this will make it always expect it to be at that location but what if it move? Also, you missing a comma after that so 2 bird 1 stone

I post a working example before. cut/paste/modify

I believe it needs to be there but should be KERNEL==“ttyACM*” using a wild card

Here’s mine that works for my Aeotec Zstick:

KERNEL=="ttyACM*", ATTRS{serial}=="0000:00:1d.7", SYMLINK+="ttyusb.zstick"

Yes, now it’s working!
I changed to this

# Zwave controller
KERNEL=="ttyACM*" SUBSYSTEM=="tty", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="ZwaveController"

image

Thank for the help!

1 Like