{"id":3075,"date":"2017-06-29T12:23:27","date_gmt":"2017-06-29T17:23:27","guid":{"rendered":"http:\/\/lisa.rushworth.us\/?p=3075"},"modified":"2020-05-19T14:49:27","modified_gmt":"2020-05-19T19:49:27","slug":"persisting-port-names-for-openhab","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=3075","title":{"rendered":"Persisting Port Names For OpenHAB"},"content":{"rendered":"<p>If you only have one device connected to your Linux box, your controller may well always be assigned the same port when the system is rebooted. In the real world, multiple connected devices make this unlikely. We use udev rules to create symlinks used within the OpenHAB configuration. The udev rule essentially uses attributes of the device to identify the <em>real<\/em> port and creates a statically named symlink to that port on boot.\u00a0So the first thing you need to identify is something\u00a0<em>unique<\/em> about the device. We have several video capture cards and a Z-Wave\/ZigBee combo controller attached to our server. If you do not have udevinfo, you can use lsusb to find details about the device. First list the devices, then identify the proper one and use the -d switch with the ????:???? formatted ID number. The -v switch outputs verbose information. Find a unique attribute or set of attributes that create a unique identifier. In this case, the interface name is unique and we can stop there.<\/p>\n<pre><small>[lisa@server ~]#  lsusb\r\nBus 001 Device 004: ID 0bda:0111 Realtek Semiconductor Corp. RTS5111 Card Reader Controller\r\nBus 001 Device 003: ID 1058:1230 Western Digital Technologies, Inc. My Book (WDBFJK0030HBK)\r\nBus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub\r\nBus 002 Device 002: ID 10c4:8a2a Cygnal Integrated Products, Inc.\r\nBus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub\r\n[lisa@server ~]# lsusb -d 10c4:8a2a -v\r\nBus 002 Device 002: ID 10c4:8a2a Cygnal Integrated Products, Inc.\r\nDevice Descriptor:\r\n bLength 18\r\n bDescriptorType 1\r\n bcdUSB 2.00\r\n bDeviceClass 0\r\n bDeviceSubClass 0\r\n bDeviceProtocol 0\r\n bMaxPacketSize0 64\r\n idVendor 0x10c4 Cygnal Integrated Products, Inc.\r\n idProduct 0x8a2a\r\n bcdDevice 1.00\r\n iManufacturer 1 Silicon Labs\r\n iProduct 2 HubZ Smart Home Controller\r\n iSerial 5 90F0016B\r\n bNumConfigurations 1\r\n Configuration Descriptor:\r\n bLength 9\r\n bDescriptorType 2\r\n wTotalLength 55\r\n bNumInterfaces 2\r\n bConfigurationValue 1\r\n iConfiguration 0\r\n bmAttributes 0x80\r\n (Bus Powered)\r\n MaxPower 100mA\r\n Interface Descriptor:\r\n bLength 9\r\n bDescriptorType 4\r\n bInterfaceNumber 0\r\n bAlternateSetting 0\r\n bNumEndpoints 2\r\n bInterfaceClass 255 Vendor Specific Class\r\n bInterfaceSubClass 0\r\n bInterfaceProtocol 0\r\n <strong>iInterface 3 HubZ Z-Wave Com Port<\/strong>\r\n Endpoint Descriptor:\r\n bLength 7\r\n bDescriptorType 5\r\n bEndpointAddress 0x81 EP 1 IN\r\n bmAttributes 2\r\n Transfer Type Bulk\r\n Synch Type None\r\n Usage Type Data\r\n wMaxPacketSize 0x0040 1x 64 bytes\r\n bInterval 0\r\n Endpoint Descriptor:\r\n bLength 7\r\n bDescriptorType 5\r\n bEndpointAddress 0x01 EP 1 OUT\r\n bmAttributes 2\r\n Transfer Type Bulk\r\n Synch Type None\r\n Usage Type Data\r\n wMaxPacketSize 0x0040 1x 64 bytes\r\n bInterval 0\r\n Interface Descriptor:\r\n bLength 9\r\n bDescriptorType 4\r\n bInterfaceNumber 1\r\n bAlternateSetting 0\r\n bNumEndpoints 2\r\n bInterfaceClass 255 Vendor Specific Class\r\n bInterfaceSubClass 0\r\n bInterfaceProtocol 0\r\n <strong>iInterface 4 HubZ ZigBee Com Port<\/strong>\r\n Endpoint Descriptor:\r\n bLength 7\r\n bDescriptorType 5\r\n bEndpointAddress 0x82 EP 2 IN\r\n bmAttributes 2\r\n Transfer Type Bulk\r\n Synch Type None\r\n Usage Type Data\r\n wMaxPacketSize 0x0020 1x 32 bytes\r\n bInterval 0\r\n Endpoint Descriptor:\r\n bLength 7\r\n bDescriptorType 5\r\n bEndpointAddress 0x02 EP 2 OUT\r\n bmAttributes 2\r\n Transfer Type Bulk\r\n Synch Type None\r\n Usage Type Data\r\n wMaxPacketSize 0x0020 1x 32 bytes\r\n bInterval 0\r\n<\/small><\/pre>\n<p>We then need to create a file under \/etc\/udev\/rules.d. The file name begins with a number that is used for a load order &#8211; I generally number my custom files 99 to avoid interfering with system operations. The bit in &#8220;ATTRS&#8221; is the attribute name and value to match. The KERNEL section contains the search domain (i.e. look at all of the ttyUSB### devices and find ones where the interface is this). The symlink bit is the name you want to use (more on this later). Set the group and mode to ensure OpenHAB is able to use the symlink.<\/p>\n<pre><small>[<small>lisa@server<\/small> rules.d]# cat 99-server.rules\r\nKERNEL==\"ttyUSB[0-9]*\", ATTRS{interface}==\"HubZ Z-Wave Com Port\", SYMLINK+=\"ttyUSB-5\", GROUP=\"dialout\", MODE=\"0666\"\r\nKERNEL==\"ttyUSB[0-9]*\", ATTRS{interface}==\"HubZ ZigBee Com Port\", SYMLINK+=\"ttyUSB-55\", GROUP=\"dialout\", MODE=\"0666\"<\/small><\/pre>\n<p>The symlink name can be anything &#8211; when I created udev rules for our video capture cards, I named them something immediately obvious: video-hauppauge250 is the Hauppauge 250 card. Tried to do the same thing here, naming the ports controller-zigbee; while the symlink appeared and had the expected ownership and permissions &#8230; OpenHAB couldn&#8217;t use it.<\/p>\n<p>Turns out there&#8217;s a nuance to Java RxTx where non-standard port names need to be accommodated in the java options. So I\u00a0<em>could<\/em> have added -Dgnu.io.rxtxSerialPorts=\/dev\/controller-zigbee and -Dgnu.io.rxtxSerialPorts=\/dev\/controller-zwave to the OpenHAB startup and been OK (in theory), it was\u00a0<em>far<\/em> easier to name the symlinks using the Linux standard conventions. Hence I have symlinks named ttyUSB<em>somethingsomethingsomething.\u00a0<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you only have one device connected to your Linux box, your controller may well always be assigned the same port when the system is rebooted. In the real world, multiple connected devices make this unlikely. We use udev rules to create symlinks used within the OpenHAB configuration. The udev rule essentially uses attributes of &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[63,30],"tags":[578,294,44,577],"class_list":["post-3075","post","type-post","status-publish","format-standard","hentry","category-home-automation","category-system-administration","tag-java","tag-linux","tag-openhab","tag-udev"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/3075","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3075"}],"version-history":[{"count":2,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/3075\/revisions"}],"predecessor-version":[{"id":6454,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/3075\/revisions\/6454"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3075"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3075"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3075"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}