Michael Bergeron

A Quick Guide to Writing udev Rules

I recently re-installed Ubuntu on a system, and with that I have a couple of devices that would appear as a ttyUSB-type devices that I’d like to have specific /dev entries for. This post will cover the high-level basics of how to identify the device, and create a udev rule to change /dev/ttyUSB# in to something more meaningful.

We’ll start with identifying the devices as they are added by udev. The simplest way to do this is to watch dmesg or sudo udevadm monitor and then plug in the USB cable of the radio. When I do this using udevadm with my Yaesu FT991a the following is printed:

KERNEL[334072.416640] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3 (usb)
KERNEL[334072.417238] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3:1.0 (usb)
KERNEL[334072.418795] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3:1.0 (usb)
KERNEL[334072.418902] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3 (usb)
UDEV  [334072.431794] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3 (usb)
UDEV  [334072.437466] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3:1.0 (usb)
UDEV  [334072.440708] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3:1.0 (usb)
UDEV  [334072.443294] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3 (usb)
KERNEL[334072.814377] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1 (usb)
KERNEL[334072.815475] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0 (usb)
KERNEL[334072.819443] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0 (usb-serial)
KERNEL[334072.820350] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0/tty/ttyUSB0 (tty)
KERNEL[334072.820416] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0 (usb-serial)
KERNEL[334072.820479] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0 (usb)
KERNEL[334072.820842] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1 (usb)
KERNEL[334072.822020] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1/ttyUSB1 (usb-serial)
KERNEL[334072.822704] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1/ttyUSB1/tty/ttyUSB1 (tty)
KERNEL[334072.822780] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1/ttyUSB1 (usb-serial)
KERNEL[334072.822848] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1 (usb)
KERNEL[334072.822929] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1 (usb)
UDEV  [334072.856133] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1 (usb)
UDEV  [334072.859277] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0 (usb)
UDEV  [334072.860347] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1 (usb)
UDEV  [334072.861379] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0 (usb-serial)
UDEV  [334072.862413] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1/ttyUSB1 (usb-serial)
UDEV  [334072.867049] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0/tty/ttyUSB0 (tty)
UDEV  [334072.869245] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0 (usb-serial)
UDEV  [334072.870446] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0 (usb)
UDEV  [334072.870604] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1/ttyUSB1/tty/ttyUSB1 (tty)
UDEV  [334072.872279] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1/ttyUSB1 (usb-serial)
UDEV  [334072.873320] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.1 (usb)
UDEV  [334072.874517] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1 (usb)
KERNEL[334073.005455] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2 (usb)
KERNEL[334073.006220] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0 (usb)
KERNEL[334073.024462] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3 (sound)
KERNEL[334073.024634] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3/controlC3 (sound)
KERNEL[334073.024781] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3/pcmC3D0p (sound)
KERNEL[334073.024899] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3/pcmC3D0c (sound)
KERNEL[334073.025008] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0 (usb)
KERNEL[334073.025086] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.1 (usb)
KERNEL[334073.025160] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.1 (usb)
KERNEL[334073.025225] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.2 (usb)
KERNEL[334073.025289] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.2 (usb)
KERNEL[334073.025351] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3 (usb)
KERNEL[334073.025975] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011 (hid)
KERNEL[334073.026209] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011/input/input31 (input)
KERNEL[334073.084189] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011/input/input31/event20 (input)
KERNEL[334073.084223] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011/hidraw/hidraw4 (hidraw)
KERNEL[334073.084249] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011 (hid)
KERNEL[334073.084268] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3 (usb)
KERNEL[334073.084287] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2 (usb)
UDEV  [334073.091747] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2 (usb)
UDEV  [334073.093243] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0 (usb)
UDEV  [334073.093400] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.1 (usb)
UDEV  [334073.093832] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.2 (usb)
UDEV  [334073.093955] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3 (usb)
UDEV  [334073.094373] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.1 (usb)
UDEV  [334073.094844] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.2 (usb)
UDEV  [334073.095004] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3 (sound)
UDEV  [334073.095198] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011 (hid)
UDEV  [334073.096400] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011/hidraw/hidraw4 (hidraw)
UDEV  [334073.097141] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011/input/input31 (input)
KERNEL[334073.097160] change   /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3 (sound)
UDEV  [334073.097527] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3/pcmC3D0p (sound)
UDEV  [334073.097597] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3/pcmC3D0c (sound)
UDEV  [334073.102484] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3/controlC3 (sound)
UDEV  [334073.103688] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0 (usb)
UDEV  [334073.114060] add      /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011/input/input31/event20 (input)
UDEV  [334073.114892] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3/0003:08BB:29B3.0011 (hid)
UDEV  [334073.115471] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.3 (usb)
UDEV  [334073.116181] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2 (usb)
UDEV  [334073.117189] change   /devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.2/1-1.4.3.2:1.0/sound/card3 (sound)

The radio creates a few devices including serial interfaces for control (ttyUSB0 and ttyUSB1), as well as audio input and output devices for transferring data between the computer and the radio. For this demo I care about the ttyUSB devices for radio control.

The next command is going to give us everything we need to write an effective rule (and a lot more we don’t). The command to run is udevadm info --attribute-walk --name /dev/ttyUSB0 and the pertinent part of the info we want is at the top:

  looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0/tty/ttyUSB0':
    KERNEL=="ttyUSB0"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0/ttyUSB0':
    KERNELS=="ttyUSB0"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="cp210x"
    ATTRS{port_number}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1/1-1.4.3.1:1.0':
    KERNELS=="1-1.4.3.1:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="cp210x"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="00"
    ATTRS{bInterfaceSubClass}=="00"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{interface}=="Enhanced Com Port"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.4/1-1.4.3/1-1.4.3.1':
    KERNELS=="1-1.4.3.1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 2"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bmAttributes}=="80"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="51"
    ATTRS{devpath}=="1.4.3.1"
    ATTRS{idProduct}=="ea70"
    ATTRS{idVendor}=="10c4"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Silicon Labs"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="CP2105 Dual USB to UART Bridge Controller"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="00988D08"
    ATTRS{speed}=="12"
    ATTRS{urbnum}=="116"
    ATTRS{version}==" 2.00"

This information is how udev works its way through the rule chain to create /dev/ttyUSB0. If you were to diff this against /dev/ttyUSB1 (for the Yaesu FT991a) you’ll see that only the highest levels have changed. This is because all of the lower USB layers are the same. The Silicon Labs CP2105 chip is the same between the interfaces, but provides two serial interfaces; one “standard” and one “enhanced.”

To create appropriate device entries we will create, as root, a couple of new udev rules. This is pretty simple; we’ll create a new file in /etc/udev/rules.d/ that is almost a simple copy-paste from the output of udevadm info ... above. The sections which will help us define the symlink are the first and the third. In the first we see that the KERNEL=="ttyUSB0" which is what we want to create the symlink against.

#FT991a UART Interfaces
SUBSYSTEM=="tty", DRIVERS=="cp210x", ATTRS{interface}=="Enhanced*", SYMLINK+="yaesu991e"
SUBSYSTEM=="tty", DRIVERS=="cp210x", ATTRS{interface}=="Standard*", SYMLINK+="yaesu991s"

PROTIP: Make sure your file starts with two digits (the priority order in which rules files are loaded), and ends in .rules, or udev will likely not pick it up when we reload the rules.

The high level overview of these rules is that we ware telling udev:

  • When you see an item in the tty subsystem…
  • Which is also using the cp210x driver…
  • And has an interface attribute which starts with ‘Standard’ or ‘Enhanced’…
  • Add an appropriate symlink to the tty’s KERNEL

To get these rules loaded we need to tell udev that the rules have been updated. This is simply done by running sudo udevadm trigger.

Now, unplug and re-plug the radio’s USB and you should see two new symlinks named /dev/yaesu991e and /dev/yaesu991s. We can now use these when pointing programs to these radio specifically instead of the (potentially) changing slew of ttyUSB devices.


OK, so now that we’ve done this for the radio, let’s try to expand it for a Monoprice Maker Select 3D v2.

Again, let’s watch udevadm monitor while we plug the printer’s USB in…

KERNEL[336840.110293] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8 (usb)
KERNEL[336840.113238] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0 (usb)
KERNEL[336840.113306] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3 (usb-serial)
KERNEL[336840.113701] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3/tty/ttyUSB3 (tty)
KERNEL[336840.113770] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3 (usb-serial)
KERNEL[336840.113851] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0 (usb)
KERNEL[336840.113943] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-8 (usb)
UDEV  [336840.146597] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8 (usb)
UDEV  [336840.153069] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0 (usb)
UDEV  [336840.157093] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3 (usb-serial)
UDEV  [336840.165463] add      /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3/tty/ttyUSB3 (tty)
UDEV  [336840.167750] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3 (usb-serial)
UDEV  [336840.169561] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0 (usb)
UDEV  [336840.171109] bind     /devices/pci0000:00/0000:00:14.0/usb1/1-8 (usb)

It looks pretty similar to what we posted above for the radio. It’s another ttyUSB device (this time ttyUSB3), so this should be pretty similar. Let’s check the attributes with (almost) the same command we used above:

  looking at device '/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3/tty/ttyUSB3':
    KERNEL=="ttyUSB3"
    SUBSYSTEM=="tty"
    DRIVER==""

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/ttyUSB3':
    KERNELS=="ttyUSB3"
    SUBSYSTEMS=="usb-serial"
    DRIVERS=="ftdi_sio"
    ATTRS{latency_timer}=="16"
    ATTRS{port_number}=="0"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0':
    KERNELS=="1-8:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="ftdi_sio"
    ATTRS{authorized}=="1"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bInterfaceClass}=="ff"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceProtocol}=="ff"
    ATTRS{bInterfaceSubClass}=="ff"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{interface}=="FT232R USB UART"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:14.0/usb1/1-8':
    KERNELS=="1-8"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="8"
    ATTRS{bMaxPower}=="90mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0600"
    ATTRS{bmAttributes}=="a0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="56"
    ATTRS{devpath}=="8"
    ATTRS{idProduct}=="6001"
    ATTRS{idVendor}=="0403"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="FTDI"
    ATTRS{maxchild}=="0"
    ATTRS{product}=="FT232R USB UART"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="removable"
    ATTRS{serial}=="AH068NME"
    ATTRS{speed}=="12"
    ATTRS{urbnum}=="10749"
    ATTRS{version}==" 2.00"

It’s pretty similar. Another tty SUBSYSTEM, but now we have, what I will call, bit more generic of a device. The product is a bit different, and might be seen in more common devices. So, we’ll have to make sure we make a more specific rule. We’ll leverage items from the third section such as the idProduct, idVendor, and serial number to create our symlink:

SUBSYSTEM=="tty", DRIVERS=="usb", ATTRS{idProduct}=="6001", ATTRS{idVendor}=="0403", ATTRS{serial}=="AH068NME", SYMLINK+="maker3d"

Now, once we sudo udevadm trigger and replug the USB cable, /dev/maker3d is now a symlink to the correct /dev/ttyUSB device.

Comments and questions welcome. I hope this helps!