Dynamic symlinks for 3D printers

From HacDC Wiki
Jump to: navigation, search


Executive Summary

From the 3d printing server (reachable from the network via pronterhost.local and pronterhost.hacdc.org) 3d printers can be referenced by /dev/TAZ, /dev/MINI, and /dev/ROSTOCK. (added by Tom 9/9/2019)

The problem

When powering cycling computers and various USB devices attached to said computer, one does not necessarily get the same /dev/ttyACM... associated with the same physical device every time. This makes it a royal pain in the ass to use pronsole or other applications that need to be explicitly told what to connect to, because each time you want to connect to a specific printer you have to do somersaults to determine the ACM number du jour for the printer (or other device) you want.

The solution

So, on the artist currently known as pronterhost.local, as of 2019.01.21... Julia had previously created /etc/udev/rules.d/80-printer-names.rules, the contents of which were:

# This file was automatically generated by the /lib/udev/write_net_rules
# program, run by the persistent-net-generator.rules rules file.
#
# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.

SUBSYSTEM=="tty", KERNEL=="ttyACM?", ATTRS{serial}=="7403431393835160C070", SYMLINK+="MINI"
# old
#SUBSYSTEM=="tty", KERNEL=="ttyACM?", ATTRS{serial}=="6403636363835110D101", SYMLINK+="TAZ"
SUBSYSTEM=="tty", KERNEL=="ttyACM?", ATTRS{serial}=="640363534303516070A1", SYMLINK+="TAZ"
SUBSYSTEM=="tty", KERNEL=="ttyACM?", ATTRS{serial}=="64032373833351906091", SYMLINK+="ROSTOCK"

Following directions at How to write udev Rules for USB Devices,

$ lsusb
Bus 005 Device 006: ID 0bda:0158 Realtek Semiconductor Corp. USB 2.0 multicard reader
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 003: ID 413c:2003 Dell Computer Corp. Keyboard
Bus 002 Device 002: ID 27b1:0001
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 003: ID 27b1:0001
Bus 001 Device 002: ID 27b1:0001
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

I'm going to take a guess at the new TAZ being one of the three lines above which contain no human-readable vendor information (while the other two lines will correspond to the known 3D printers in the space -- the ROSTOCK and MINI):

  • Bus 002 Device 002: ID 27b1:0001
  • Bus 001 Device 003: ID 27b1:0001
  • Bus 001 Device 002: ID 27b1:0001

Testing two of them (Bus 001 Devices 003 and 002) yielded:

$ udevadm info -a -p $(udevadm info -q path -n /dev/bus/usb/001/003) | \
   egrep "(7403431393835160C070|6403636363835110D101|640363534303516070A1|64032373833351906091)"
   ATTR{ID_SERIAL}=="UltiMachine__ultimachine.com__RAMBo_64032373833351906091"
   ATTR{ID_SERIAL_SHORT}=="64032373833351906091"

$ udevadm info -a -p $(udevadm info -q path -n /dev/bus/usb/001/002) | \
   egrep "(7403431393835160C070|6403636363835110D101|640363534303516070A1|64032373833351906091)"
   ATTR{ID_SERIAL}=="UltiMachine__ultimachine.com__RAMBo_7403431393835160C070"
   ATTR{ID_SERIAL_SHORT}=="7403431393835160C070"

Note that the first udevadm ... yields a serial number that matches Julia's serial number for the ROSTOCK and the second udevadm ... matches that of the MINI.

Testing Bus 002 Device 002 did not match any of the existing numbers but did provide a serial number with RAMBo in the name. Looking a the entire output of the command,

$ udevadm info -a -p $(udevadm info -q path -n /dev/bus/usb/002/002)

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:1d.1/usb2/2-1':
    KERNEL=="2-1"
    SUBSYSTEM=="usb"
    DRIVER=="usb"
    ATTR{SUBSYSTEM}=="usb"
    ATTR{DRIVER}=="usb"
    ATTR{DEVTYPE}=="usb_device"
    ATTR{PRODUCT}=="27b1/1/1"
    ATTR{TYPE}=="2/0/0"
    ATTR{BUSNUM}=="002"
    ATTR{DEVNUM}=="002"
    ATTR{MAJOR}=="189"
    ATTR{MINOR}=="129"
    ATTR{USEC_INITIALIZED}=="3639901"
    ATTR{ID_VENDOR}=="UltiMachine__ultimachine.com_"
    ATTR{ID_VENDOR_ENC}=="UltiMachine\x20\x28ultimachine.com\x29"
    ATTR{ID_VENDOR_ID}=="27b1"
    ATTR{ID_MODEL}=="RAMBo"
    ATTR{ID_MODEL_ENC}=="RAMBo"
    ATTR{ID_MODEL_ID}=="0001"
    ATTR{ID_REVISION}=="0001"
    ATTR{ID_SERIAL}=="UltiMachine__ultimachine.com__RAMBo_6403335373035101E171"
    ATTR{ID_SERIAL_SHORT}=="6403335373035101E171"
    ATTR{ID_BUS}=="usb"
    ATTR{ID_USB_INTERFACES}==":020201:0a0000:"

And so, the second TAZ line in /etc/udev/rules.d/80-printer-names.rules gets commented out and

SUBSYSTEM=="tty",  KERNEL=="ttyACM?", ATTRS{serial}=="6403335373035101E171", SYMLINK+="TAZ"      # Current

gets appended to the file (and the lines, rearranged). The end result:

# You can modify it, as long as you keep each rule on a single
# line, and change only the value of the NAME= key.
#
# Last modified by Ubuntourist <ubuntourist@hacdc.org> 2019.01.21 (kjc) 
#
# 2019.01.21 KJC - Updated the serial number of the TAZ to our current beastie
#

#SUBSYSTEM=="tty", KERNEL=="ttyACM?", ATTRS{serial}=="6403636363835110D101", SYMLINK+="TAZ"      # Oldest
#SUBSYSTEM=="tty", KERNEL=="ttyACM?", ATTRS{serial}=="640363534303516070A1", SYMLINK+="TAZ"      # Older (Julia's)
SUBSYSTEM=="tty",  KERNEL=="ttyACM?", ATTRS{serial}=="6403335373035101E171", SYMLINK+="TAZ"      # Current
SUBSYSTEM=="tty",  KERNEL=="ttyACM?", ATTRS{serial}=="64032373833351906091", SYMLINK+="ROSTOCK"
SUBSYSTEM=="tty",  KERNEL=="ttyACM?", ATTRS{serial}=="7403431393835160C070", SYMLINK+="MINI"

Reboot (because I'm too lazy to figure out which service(s) I need to restart) and done! I hope.