Phistek ZE7000

The Phistek ZE7000 is the only network attached zero client currently manufactured, that uses a Display Link DL-165 supported by Linux and is therefore compatible with all USB 2.0 connected DL-1×5 zero clients connected to the same computer, that you may already have, such as the Plugable UD-160-A, while extending the USB 2.0 cable length limit of 5 meters, to the gigabit network cable length limit to 100 meters.

EST has provided Phistek the most recent support software for their chip

nhci_0.9.59-1zeroclient1_amd64.deb

and authorized them to provide it as a download. I have received the .rpm version directly from Elite Silicon Technologies.

[root@Asus-CentOS7 Downloads]# rpm -qip ./nhci-0.9.59-1zeroclient1.x86_64.rpm
 Name        : nhci
 Epoch       : 1
 Version     : 0.9.59
 Release     : 1zeroclient1
 Architecture: x86_64
 Install Date: (not installed)
 Group       : System/Kernel
 Size        : 850839
 License     : Copyright (C) 2008-2018 Elite Silicon, Inc. All rights reserved.
 Signature   : (none)
 Source RPM  : nhci-0.9.59-1zeroclient1.src.rpm
 Build Date  : Tue 25 Feb 2020 05:03:44 PM PST
 Build Host  : localhost
 Relocations : (not relocatable)
 Packager    : Elite Silicon Technology www.elitesilicon.com.tw
 Vendor      : Elite Silicon Technology
 URL         : www.elitesilicon.com.tw
 Summary     : nhci 0.9.59 dkms package
 Description :
 Network USB Host Controller kernel module and daemon.
  This package installs the Network USB Host Controller software for E386x chips.
 [root@Asus-CentOS7 Downloads]# 

Use my contact form to request this rpm as an email attachment (220,372 bytes).

root@Asus-CentOS7 asm32]# virtualusbc -S
 WMS Zero Client||pt05|1|1|192.168.10.117|255.255.255.0|04:C9:91:30:08:BA|2|8|00|048.101||1000|PhistekZC|3|1|
 [root@Asus-CentOS7 asm32]# virtualusbc -DI
 192.168.10.117|0|17E9|017D|10|0|DisplayLink|ZE7000|202001210056   |
 192.168.10.117|1|0D8C|013C|11|0|C-Media Electronics Inc.      |USB PnP Sound Device          ||
 [root@Asus-CentOS7 asm32]# 

PHiStek has updated the firmware of my new ZE7000 to 048.101

It has mounting holes for both Vesa standard 75mm and 100mm centers. My monitor lacked Vesa mounting but had a flat surface available for use of Velcro adhesive pad to mount the unit. Adapters are available for converting its DVI-I to HDMI, DisplayPort, and VGA. Uses 12 vdc, same as many monitors, so could use same power adapter as monitor if that power adapter has adequate watts capacity for both.

The ZE7000 does not store any user data, only a bit map of the display. When the user logs out, the new login screen completely over writes the last screen of the former session. With its 100 meter network cable length, its server computer can be located in a physically secure room with no windows or a secure utility cabinet. The workstations with their ZE7000 can be located in a creative space with nice views. All data remains secure, even if someone breaks in and steals the workstations. There are many professions that require keeping client data secure – legal, financial, medical, psychiatric, even trade secrets of software developers.

Other solutions, such as the Raspberry Pi and the x96 MAX Android 9.0, while competing on price, can not provide the same security because they contain a whole OS with potential vulnerabilities.

To compete on TCO, devices like the ZE7000 which can run on free, opensource Linux are needed. The cost of Userful licenses (they have the only Linux SMSC driver and it is proprietary) or of Microsoft Server and individual client licenses, have made multi-seat unable to compete with individual commodity priced Chromebooks in public libraries. Consequently I see the important niche for the ZE700 being professional work environments where data security and privacy is important. The applications needed in an office are all free on Linux and Linux and its updates are also free. Linux office applications can export in the standard pdf so Microsoft’s attempts to make its formats incompatible in new ways will not be entirely successful.

There are no US distributors, but my ZE7000 only took one week to ship from PHiStek in Taiwan. I am working on detailed instructions on how to create an entirely free, opensource, multi-seat system for the ZE7000 on both Manjaro and Mint Linux distributions. 2-28-2020

There are three steps to configuring the ZE7000 for a multi-seat workstation.

  1. Install the EST package (a usb over IP server supporting the chip in the ZE7000).
  2. Each ZE7000 has a unique serial number and will have a different IP address on the same LAN as the EST server. The utility, virtualusbc, furnished in the EST package, is used to identify each ZE7000 and to connect it to the hostname of its server (there can be more than one server on the same LAN if it has a different hostname). When connected, each ZE7000 will have its own unique virtual USB port that looks something like this to Linux:
    /sys/devices/platform/nh04C9913008BA/usb3
    where nh refers to the EST server and the 04:C9:91:30:08:BA is the network hardware address of this device.
  3. Once locked to the host with the virtualusbc utility, this zero client will become another display that can mirror or extend the primary desktop. To become an independent workstation it has to be attached to a named seat. If you want all network attached zero clients to be independent workstations, then you can get Linux to do this automatically by the script below. It presents a GUI request for the root password because root privileges are required to write the udev rule.
!/bin/bash
est-udev.sh
writes or removes udev rule for network attached zero client auto seat configuration
L=Enable
if [ -f "/etc/udev/rules.d/72-est-seats.rules" ]; then L=Disable
zenity --info --title='Networked Zero Clients' --window-icon='question' --icon-name='' --width=200 --text='Auto seat configuration' --ok-label=$L 2>/dev/null
case $? in
0) zenity --password 2>/dev/null|su -c 2>/dev/null 'rm -f /etc/udev/rules.d/72-est-seats.rules '
;;
esac
else
zenity --info --title='Networked Zero Clients' --window-icon='question' --icon-name='' --width=200 --text='Auto seat configuration' --ok-label=$L 2>/dev/null
case $? in
0)zenity --password 2>/dev/null|su -c 2>/dev/null 'touch /etc/udev/rules.d/72-est-seats.rules
echo SUBSYSTEM==”usb”,ATTR{product}==”E386X Network USB Host Driver”, ENV{ID_AUTOSEAT}=”1” >/etc/udev/rules.d/72-est-seats.rules '
;;
esac
fi

If you don’t want all network attached zero station to be independent seats automatically, the utility, loginctl, can be used to discover a specific zero cient and to attach it to a seat that you name anything other than seat0 which is always the desktop integrated, or video card, display. If a program is going to make this decision for you, the MAC address would be a good choice because it will be unique. So also will be the virtual usb# which may be either one or two digits.

loginctl attach seat-04C9913008BA /sys/devices/platform/nh04C9913008BA/usb3

Or you might prefer loginctl attach seat-nhusb3 /sys/devices/platform/nh04C9913008BA/usb3

The following script will search for EST network attached zero clients that have been locked to this hostname. Unlike USB attached zero clients, we will search for part of the EST server signature, m/nh as searching for usb would be redundant and not separate out usb zero clients from network attached zero clients. This scrip displays the needed loginctl attach commands, it does not execute these commands for you.

#!/bin/bash
# search-nh.sh
echo "
copyleft, Lawrence E. Boothby (multi-seat.com), 2020"
echo " under current GPL license"
echo "
searching for network attached DisplayLink device(s), if none, just exit
"
readlink -f /sys/class/drm/card?|grep platform/nh | xargs -L 1 -r bash -c '
echo "sudo loginctl attach seat-${0:24:12}  ${0:0:42}" | sed "s/\/$//" '
# repeat for cases when card number is 2 digits
readlink -f /sys/class/drm/card??|grep platform/nh | xargs -L 1 -r bash -c '
echo "sudo loginctl attach seat-${0:24:12}  ${0:0:42}" | sed "s/\/$//" '
# note that the length of the device path
# can vary with distro because the usb
# number can be 1 or 2 digits. sed fixes
# the case of one digit by removing "/"
# which would follow a single digit here

The above code displays the code you need to execute in a terminal to attach ZE7000 zero clients that you have already locked to your computer hostname with virtualusbc command, to named seat, for multiple workstations connected to a single computer. The script executes quickly because the computer already has the information needed.

The code below will scan the entire local network for zero clients, including ones that may not yet be locked to your computer. This takes longer since your computer doesn’t yet have that information.

#!/bin/bash
# search-mac.sh
echo "
copyleft, Lawrence E. Boothby (multi-seat.com), 2020"
echo " under current GPL license"
echo "
scanning network for MAC address(es) of network attached DisplayLink device(s)…
"
# list MAC addresses of all EST connected zero clients
su -c 'virtualusbc -S' | cut -d "|" -s -f 8 | sed 's/://g' | xargs -L 1 -r bash -c '
echo  TAG==\"seat\", ENV{ID_FOR_SEAT}==\"usb-platform-nh$0\", ENV{ID_SEAT}=\"seat-$0\"
'
echo $'\n'

Linux stores information about zero clients attached to named seats in a file which persists between boots and may include named seats whose hardware is only connected sometimes. In CentOS, you will have /usr/lib/udev/rules.d/71-seat.rules. In Ubuntu there will be separate files for each zero client added with loginctl attach command and the path to these files is different /etc/udev/rules.d/.

asm32@t1600:~$ lsb_release -d
 Description:    Ubuntu 16.04.6 LTS
 asm32@t1600:~$
 asm32@t1600:~$ cd /etc/udev/rules.d
 asm32@t1600:/etc/udev/rules.d$ ls
 72-seat-usb-platform-nh001FD8001937.rules
 72-seat-usb-platform-nh04C9913008BA.rules
 asm32@t1600:/etc/udev/rules.d$
 asm32@t1600:/etc/udev/rules.d$ cat 72-seat-usb-platform-nh001FD8001937.rules
 TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh001FD8001937", ENV{ID_SEAT}="seat-m220"
 asm32@t1600:/etc/udev/rules.d$
 asm32@t1600:/etc/udev/rules.d$ cat 72-seat-usb-platform-nh04C9913008BA.rules
 TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh04C9913008BA", ENV{ID_SEAT}="seat-04C9913008BA"
 asm32@t1600:/etc/udev/rules.d$ 

Note the filenames and individual content for two evdev rules in Ubuntu created by loginctl attach commands. If editing udev rule files, it would be well to adhere to the standards of the relevant distro – otherwise loginctl flush-devices may have trouble finding them when attempting to remove attachments to seats.

[asm32@asus-centos7 ~]$ hostname
asus-centos7
[asm32@asus-centos7 ~]$

[asm32@asus-centos7 ~]$ su
 Password: 
 [root@asus-centos7 asm32]# virtualusbc -S
 WMS Zero Client||asus-centos7|1|1|192.168.10.128|255.255.255.0|04:C9:91:30:08:BA|3|3|00|048.101|asus-centos7|1000|PhistekZC|3|1|
 m220-1|Location-1|t1600|1|1|192.168.10.129|255.255.255.0|00:1F:D8:00:19:37|2|8|00|055.103||0|ATRUSTZC|2|0|
 m220-2|Location-2|Asus-CentOS7|1|1|192.168.10.130|255.255.255.0|00:1F:D8:00:28:AE|2|8|00|055.103||0|ATRUSTZC|2|0|
 HPt200|Location-3|Asus-CentOS7|1|1|192.168.10.131|255.255.255.0|F8:0F:41:47:A4:81|2|8|00|035.226||1000|HPT200|3|0|
 [root@asus-centos7 asm32]#
 
[root@asus-centos7 asm32]# ./search-mac.sh
copyleft, Lawrence E. Boothby (multi-seat.com), 2020
  under current GPL license

scanning network for MAC address(es) of network attached DisplayLink device(s)…

TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh04C9913008BA", ENV{ID_SEAT}="seat-04C9913008BA"
TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh001FD8001937", ENV{ID_SEAT}="seat-001FD8001937"
TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh001FD80028AE", ENV{ID_SEAT}="seat-001FD80028AE"
TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nhF80F4147A481", ENV{ID_SEAT}="seat-F80F4147A481"

[root@asus-centos7 asm32]# 
[root@asus-centos7 asm32]# exit
[asm32@asus-centos7 ~]$

Looking at the output from virtualusbc -S

you can see that my LAN had four network attached zero clients, but that only the first is locked to my hostname, asus-centos7 (case matters).

Running the script search-mac.sh

You see 4 lines of udev rules that loginctl would have added to /usr/lib/udev/rules.d/71-seat.rules if all four zero clients had been locked to this host and we had used my first method using loginctl attach command to do this. Using my second method, we can add these 4 lines of udev rules to /usr/lib/udev/rules.d/71-seat.rules using the nano text editor with root privileges. Then in the future, any network attached zero clients with these MAC addresses that are connected and locked to this host will display login screens for separate multi-seat workstations. It no longer matters what network cable or IP address they were granted.

In contrast, USB connected zero clients obviously don’t have a MAC address, so their udev seat rules depend on their idVendor idProduct values for their internal USB hub which groups their internal child devices. You might have both Plugable USB 2.0 UD-160-A and ZE7000 network attached zero clients in the same system. Both have DisplayLink DL-165 usb graphic connectors. Therefore you could not define the ZE7000 by its idVendor and idProduct value because the system wouldn’t then understand the usb hierarchy of the UD-160-A’s internal child devices.

Finally an example system with one Phistek ZE7000 and one Plugable UD-160-A in an AMD Athlon II x2 280 running CentOS 7.7 with various system utilities displaying information in a terminal.

[asm32@asus-centos7 ~]$ lsb_release -d
 Description:    CentOS Linux release 7.7.1908 (Core)
 [asm32@asus-centos7 ~]$ 
 [asm32@asus-centos7 ~]$ cat /usr/lib/udev/rules.d/71-seat.rules
 This file is part of systemd.
 #
 systemd is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.
 ACTION=="remove", GOTO="seat_end"
 TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat"
 SUBSYSTEM=="sound", KERNEL=="card", TAG+="seat" SUBSYSTEM=="input", KERNEL=="input", TAG+="seat"
 SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat", TAG+="master-of-seat"
 SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat"
 'Plugable' USB hub, sound, network, graphics adapter
 SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1"      # Plugable UD-160-A USB 2.0 zero client
 TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh04C9913008BA", ENV{ID_SEAT}="seat-04C9913008BA"  # Phistek ZE7000 zero client
 Mimo 720, with integrated USB hub, displaylink graphics, and e2i
 touchscreen. This device carries no proper VID/PID in the USB hub,
 but it does carry good ID data in the graphics component, hence we
 check it from the parent. There's a bit of a race here however,
 given that the child devices might not exist yet at the time this
 rule is executed. To work around this we'll trigger the parent from
 the child if we notice that the parent wasn't recognized yet.
 Match parent
 SUBSYSTEM=="usb", ATTR{idVendor}=="058f", ATTR{idProduct}=="6254", \
                   ATTR{%k.2/idVendor}=="17e9", ATTR{%k.2/idProduct}=="401a", ATTR{%k.2/product}=="mimo inc", \
                   ENV{ID_AUTOSEAT}="1", ENV{ID_AVOID_LOOP}="1"
 Match child, look for parent's ID_AVOID_LOOP
 SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \
                   ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \
                   IMPORT{parent}="ID_AVOID_LOOP"
 Match child, retrigger parent
 SUBSYSTEM=="usb", ATTR{idVendor}=="17e9", ATTR{idProduct}=="401a", ATTR{product}=="mimo inc", \
                   ATTR{../idVendor}=="058f", ATTR{../idProduct}=="6254", \
                   ENV{ID_AVOID_LOOP}=="", \
                   RUN+="/usr/bin/udevadm trigger --parent-match=%p/.."
 TAG=="seat", ENV{ID_PATH}=="", IMPORT{builtin}="path_id"
 TAG=="seat", ENV{ID_FOR_SEAT}=="", ENV{ID_PATH_TAG}!="", ENV{ID_FOR_SEAT}="$env{SUBSYSTEM}-$env{ID_PATH_TAG}"
 SUBSYSTEM=="input", ATTR{name}=="Wiebetech LLC Wiebetech", RUN+="/usr/bin/loginctl lock-sessions"
 LABEL="seat_end"
 [asm32@asus-centos7 ~]$
 [asm32@asus-centos7 ~]$ lsusb
 Bus 010 Device 003: ID 046d:c52b Logitech, Inc. Unifying Receiver
 Bus 010 Device 002: ID 0d8c:013c C-Media Electronics, Inc. CM108 Audio Controller
 Bus 010 Device 004: ID 17e9:017d DisplayLink 
 Bus 010 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub <---- virtual EST hub
 --------------------------------------------------------------------------------
 Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
 Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
 Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
 --------------------------------------------------------------------------------
 Bus 001 Device 006: ID 046d:c52b Logitech, Inc. Unifying Receiver
 Bus 001 Device 005: ID 0b95:772a ASIX Electronics Corp. AX88772A Fast Ethernet
 Bus 001 Device 004: ID 0d8c:0105 C-Media Electronics, Inc. CM108 Audio Controller
 Bus 001 Device 003: ID 17e9:0377 DisplayLink Plugable UD-160-A (M)
 Bus 001 Device 002: ID 2230:0001 <---- internal USB 2.0 hub in UD-160-A
 --------------------------------------------------------------------------------
 Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub  <---- motherboard usb port
 Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
 Bus 009 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
 Bus 008 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
 [asm32@asus-centos7 ~]$ lsusb -t
 /:  Bus 10.Port 1: Dev 1, Class=root_hub, Driver=nhci_hcd/16p, 480M <--- ZE7000
     |_ Port 3: Dev 4, If 0, Class=Vendor Specific Class, Driver=udl, 480M <--- Displaylink DL-165     |_ Port 4: Dev 2, If 0, Class=Audio, Driver=snd-usb-audio, 12M
     |_ Port 4: Dev 2, If 1, Class=Audio, Driver=snd-usb-audio, 12M     |_ Port 4: Dev 2, If 2, Class=Audio, Driver=snd-usb-audio, 12M
     |_ Port 4: Dev 2, If 3, Class=Human Interface Device, Driver=usbhid, 12M     |_ Port 6: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
     |_ Port 6: Dev 3, If 1, Class=Human Interface Device, Driver=usbhid, 12M     |_ Port 6: Dev 3, If 2, Class=Human Interface Device, Driver=usbhid, 12M
 /:  Bus 09.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 5000M
 /:  Bus 08.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 480M
 /:  Bus 07.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/4p, 12M
 /:  Bus 06.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/2p, 12M
 /:  Bus 05.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/5p, 12M
 /:  Bus 04.Port 1: Dev 1, Class=root_hub, Driver=ohci-pci/5p, 12M
 /:  Bus 03.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/4p, 480M
 /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/5p, 480M
 /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=ehci-pci/5p, 480M
     |_ Port 2: Dev 2, If 0, Class=Hub, Driver=hub/7p, 480M <--- UD-160-A         |_ Port 1: Dev 3, If 0, Class=Vendor Specific Class, Driver=udl, 480M <--- Displaylink DL-165
         |_ Port 2: Dev 4, If 0, Class=Audio, Driver=snd-usb-audio, 12M         |_ Port 2: Dev 4, If 1, Class=Audio, Driver=snd-usb-audio, 12M
         |_ Port 2: Dev 4, If 2, Class=Audio, Driver=snd-usb-audio, 12M         |_ Port 2: Dev 4, If 3, Class=Human Interface Device, Driver=usbhid, 12M
         |_ Port 3: Dev 5, If 0, Class=Vendor Specific Class, Driver=asix, 480M         |_ Port 7: Dev 6, If 0, Class=Human Interface Device, Driver=usbhid, 12M
         |_ Port 7: Dev 6, If 1, Class=Human Interface Device, Driver=usbhid, 12M         |_ Port 7: Dev 6, If 2, Class=Human Interface Device, Driver=usbhid, 12M
 [asm32@asus-centos7 ~]$ 
 [asm32@asus-centos7 ~]$ loginctl list-seats
 SEAT            
 seat-usb-pci-0000_00_12_2-usb-0_2
 seat-04C9913008BA
 seat0           
 3 seats listed.
 [asm32@asus-centos7 ~]$ 
 [asm32@asus-centos7 ~]$ loginctl seat-status -l seat-usb-pci-0000_00_12_2-usb-0_2 seat-04C9913008BA
 seat-usb-pci-0000_00_12_2-usb-0_2
         Sessions: *c4
          Devices:
                   └─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2 <--- case UD-160-A
                     usb:1-2
                     ├─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2.1/1-2.1:1.0/drm/card2
                     │ drm:card2
                     ├─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2.1/1-2.1:1.0/graphics/fb2
                     │ [MASTER] graphics:fb2 "udldrmfb"
                     ├─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2.2/1-2.2:1.0/sound/card3
                     │ sound:card3 "Device_1"
                     ├─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2.2/1-2.2:1.3/input/input17
                     │ input:input17 "C-Media Electronics Inc. USB Multimedia Audio Device"
                     ├─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2.7/1-2.7:1.2/0003:046D:C52B.000F/input/input18
                     │ input:input18 "Logitech Unifying Device. Wireless PID:4055"
                     └─/sys/devices/pci0000:00/0000:00:12.2/usb1/1-2/1-2.7/1-2.7:1.2/0003:046D:C52B.000F/input/input19
                       input:input19 "Logitech Unifying Device. Wireless PID:2011"
 seat-04C9913008BA
         Sessions: *2 c2
          Devices:
                   └─/sys/devices/platform/nh04C9913008BA/usb10        <--- case ZE7000
                     usb:usb10
                     ├─/sys/devices/platform/nh04C9913008BA/usb10/10-3/10-3:1.0/drm/card1
                     │ drm:card1
                     ├─/sys/devices/platform/nh04C9913008BA/usb10/10-3/10-3:1.0/graphics/fb1
                     │ [MASTER] graphics:fb1 "udldrmfb"
                     ├─/sys/devices/platform/nh04C9913008BA/usb10/10-4/10-4:1.0/sound/card2
                     │ sound:card2 "Device"
                     ├─/sys/devices/platform/nh04C9913008BA/usb10/10-4/10-4:1.3/input/input14
                     │ input:input14 "C-Media Electronics Inc.       USB PnP Sound Device"
                     ├─/sys/devices/platform/nh04C9913008BA/usb10/10-6/10-6:1.2/0003:046D:C52B.0009/input/input15
                     │ input:input15 "Logitech Unifying Device. Wireless PID:1024"
                     └─/sys/devices/platform/nh04C9913008BA/usb10/10-6/10-6:1.2/0003:046D:C52B.0009/input/input16
                       input:input16 "Logitech Unifying Device. Wireless PID:2011"
 [asm32@asus-centos7 ~]$