Forums

Resolved
0 votes
Hi everyone,
If you for instance use Domoticz Home Automation on your ClearOS server, the chance is high that you also have connected one or several USB-dongles for 433MHz communication, Z-wave etc.

Those USD-dongles that in fact enumerates a traditional serial interface will get an address like
/dev/ttyACM0 for the first unit and
/dev/ttyACM1 for the second unit and so on

Now, by design there will be a race condition at boot time so you can not be 100% sure which physical USB dongle will end up at a specific address. This causes problem in a home automation program such as Domoticz since you need to specify the address for each USB-dongle, and you certainly want your application to continue to work after a server reboot. Similar problem occurs also if you unplug and insert your USB-dongle again. Linux will give it a new address at the insertion if there was an ongoing communication when you unplugged it, why your application will not find it anymore.

Luckily there is at least one way to bind a USB dongle to a static address (name):
1. Make sure your USB-dongle is connected to the server
2. Open a command window and enter:
dmesg | grep tty

3. Note what address the USB-dongle has now (for instance /dev/ttyACM0 )
4. Find unique identifiers for your USB-dongle (like Manufacturer ID and Product ID) by entering this command (use the address from step 3)
udevadm info --name=/dev/ttyACM0 --attribute-walk
The output can look somethings like this:
  looking at device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.8/2-1.8:1.0/tty/ttyACM0':
KERNEL=="ttyACM0"
SUBSYSTEM=="tty"
DRIVER==""

looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.8/2-1.8:1.0':
KERNELS=="2-1.8:1.0"
SUBSYSTEMS=="usb"
DRIVERS=="cdc_acm"
ATTRS{bInterfaceClass}=="02"
ATTRS{bmCapabilities}=="0"
ATTRS{bInterfaceSubClass}=="02"
ATTRS{bInterfaceProtocol}=="01"
ATTRS{bNumEndpoints}=="01"
ATTRS{authorized}=="1"
ATTRS{supports_autosuspend}=="1"
ATTRS{bAlternateSetting}==" 0"
ATTRS{bInterfaceNumber}=="00"

looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.8':
KERNELS=="2-1.8"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="1.8"
ATTRS{idVendor}=="0658"
ATTRS{speed}=="12"
ATTRS{bNumInterfaces}==" 2"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="8"
ATTRS{busnum}=="2"
ATTRS{devnum}=="7"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="100mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="80"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="0"
ATTRS{bcdDevice}=="0000"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="12353"
ATTRS{ltm_capable}=="no"
ATTRS{removable}=="removable"
ATTRS{idProduct}=="0200"
ATTRS{bDeviceClass}=="02"

looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2/2-1':
KERNELS=="2-1"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="01"
ATTRS{devpath}=="1"
ATTRS{idVendor}=="8087"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{busnum}=="2"
ATTRS{devnum}=="2"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="0mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="8"
ATTRS{bcdDevice}=="0000"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="116"
ATTRS{ltm_capable}=="no"
ATTRS{removable}=="fixed"
ATTRS{idProduct}=="0024"
ATTRS{bDeviceClass}=="09"

looking at parent device '/devices/pci0000:00/0000:00:1d.0/usb2':
KERNELS=="usb2"
SUBSYSTEMS=="usb"
DRIVERS=="usb"
ATTRS{bDeviceSubClass}=="00"
ATTRS{bDeviceProtocol}=="00"
ATTRS{devpath}=="0"
ATTRS{idVendor}=="1d6b"
ATTRS{speed}=="480"
ATTRS{bNumInterfaces}==" 1"
ATTRS{bConfigurationValue}=="1"
ATTRS{bMaxPacketSize0}=="64"
ATTRS{authorized_default}=="1"
ATTRS{busnum}=="2"
ATTRS{devnum}=="1"
ATTRS{configuration}==""
ATTRS{bMaxPower}=="0mA"
ATTRS{authorized}=="1"
ATTRS{bmAttributes}=="e0"
ATTRS{bNumConfigurations}=="1"
ATTRS{maxchild}=="2"
ATTRS{interface_authorized_default}=="1"
ATTRS{bcdDevice}=="0310"
ATTRS{avoid_reset_quirk}=="0"
ATTRS{quirks}=="0x0"
ATTRS{serial}=="0000:00:1d.0"
ATTRS{version}==" 2.00"
ATTRS{urbnum}=="59"
ATTRS{ltm_capable}=="no"
ATTRS{manufacturer}=="Linux 3.10.0-514.26.2.v7.x86_64 ehci_hcd"
ATTRS{removable}=="unknown"
ATTRS{idProduct}=="0002"
ATTRS{bDeviceClass}=="09"
ATTRS{product}=="EHCI Host Controller"

looking at parent device '/devices/pci0000:00/0000:00:1d.0':
KERNELS=="0000:00:1d.0"
SUBSYSTEMS=="pci"
DRIVERS=="ehci-pci"
ATTRS{irq}=="23"
ATTRS{subsystem_vendor}=="0x1043"
ATTRS{broken_parity_status}=="0"
ATTRS{class}=="0x0c0320"
ATTRS{companion}==""
ATTRS{driver_override}=="(null)"
ATTRS{consistent_dma_mask_bits}=="32"
ATTRS{dma_mask_bits}=="32"
ATTRS{local_cpus}=="f"
ATTRS{device}=="0x1c26"
ATTRS{uframe_periodic_max}=="100"
ATTRS{enable}=="1"
ATTRS{msi_bus}==""
ATTRS{local_cpulist}=="0-3"
ATTRS{vendor}=="0x8086"
ATTRS{subsystem_device}=="0x844d"
ATTRS{numa_node}=="-1"
ATTRS{d3cold_allowed}=="1"

looking at parent device '/devices/pci0000:00':
KERNELS=="pci0000:00"
SUBSYSTEMS==""
DRIVERS==""
The output above is a "USB tree, starting with the lowest level and works its way inwards to the USB host in the server. You therefore want to focus on the first couple of paragraphs for your USB-dongle so you do not look at the info for the USB-hub...In our case we can see that ATTRS{idVendor}=="0658" and ATTRS{idProduct}=="0200" (which says it is a Z-wave+ UZB USB-dongle from Sigma).
5. Open/Create a file where we will give this USB-dongle an alias:
nano /etc/udev/rules.d/10-local.rules
Enter the following text (using our example):
ACTION=="add", ATTRS{idVendor}=="0658", ATTRS{idProduct}=="0200", SYMLINK+="ttyUSB50"
Press Ctrl-o to save and Ctrl-x to exit nano. Note that in this example we used the alias "ttyUSB50", but you could have used "MySigmaUZB" or something. However, I suggest you stick to a "ttyUSBxx" naming convention since that is a "valid" serial port name in Linux so that will save you from some other problems. I also used a "high" number (50) to avoid any potential naming conflict by anything else created in the system.
6. After reboot of the server our USB-dongle will in addition to its random /dev/ttyACM address now also ALWAYS be found at /dev/ttyUSB50. If you do not want to reboot your server you can enable the new alias by entering the following command:
udevadm control --reload-rules && udevadm trigger
and then unplug/insert your USB-dongle.

/Fred
Sunday, August 13 2017, 02:44 PM
Like
1
Share this post:
Responses (0)
  • There are no replies here yet.
Your Reply