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 meter.

My goal is to provide a free, opensource alternative to the one proprietary Linux multi-seat solution by userful.com which has both initial per workstation license fees and a maintenance subscription fee for access to updates. Network attached zero clients for Userful use the SMSC video chip. Their solution uses a single video frame buffer for all displays which lends itself to offloading to a gpu card. In contrast, the DisplayLink approach has individual frame buffers for each display and does not use a gpu to compress and prepare data for zeroclients. Its server could even be headless.

I have received the .rpm package for the network to USB chip in the ZE7000 directly from Elite Silicon Technologies and have permission to redistribute.

[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 and initialized some user definable fields such as branding. In a terminal, run the command “man virtualusbc” for detailed documentation of virtualusbc options, including most importantly how to lock a specific device to the desired computer hostname.

ZE7000 Zero Client
Bottom view of unit with detachable rubber feet in the Vesa 100mm holes. Next to the network connector is an audio out for amplified speakers. The separate headphone jack mechanically disconnects the audio out signal when using headphones. There is also a mic connector next to the headphone connector.
ZE 7000 and monitor power adapter both mounted with Velcro 2″ x 4″ adhesive backed strips. ZE7000 getting its power from monitor power supply. Dual DVI to HDMI adapters , one right angle up, because I could not find a short DVI cable. White cable is audio for my headphones.
Note the reset button just below the three LEDs. If a power interruption or something else leaves the ZE7000 in an undefined state, disconnect the network cable and while pressing the reset button, power the unit on. On an HP T200 zero client with the same EST chip, keeping the reset button pressed for more than 7 seconds will in addition clear all user configurable data like name, location, etc.

Hardware and OS listing for screenshots below.

[asm32@asus-centos7 ~]$ lsb_release -d
Description: CentOS Linux release 7.8.2003 (Core)

[asm32@asus-centos7 ~]$ uname -r
3.10.0-862.el7.x86_64

[asm32@asus-centos7 ~]$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 2
Core(s) per socket: 2
Socket(s): 1
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 42
Model name: Intel(R) Core(TM) i3-2120 CPU @ 3.30GHz
Stepping: 7
CPU MHz: 1599.645
CPU max MHz: 3300.0000
CPU min MHz: 1600.0000
BogoMIPS: 6584.98
Virtualization: VT-x
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
NUMA node0 CPU(s): 0-3
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 popcnt tsc_deadline_timer xsave avx lahf_lm epb tpr_shadow vnmi flexpriority ept vpid xsaveopt ibpb ibrs stibp dtherm arat pln pts spec_ctrl intel_stibp
[asm32@asus-centos7 ~]$
ZE7000 login screen
Screenshot of two monitors directly connected to server. In addition, there are two seats (one ZE7000 and one HP T200 with DL-165 adapter) also each playing a youtube music video full screen at the same time. System monitor displaying total resource use for these three workstations.
Here is the resource usage for system monitor running on server display and a single ZE7000 zero client playing a commercial DVD movie using VLC. As you can see, This requires much more resources than youtube videos.

I see the important niche for the ZE700 being professional work environments where datasecurity and privacy are important. 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.

There are no US distributors, but my ZE7000 only took one week to ship from PHiStek in Taiwan.

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

  1. Install the EST rpm package (a usb over IP server supporting the chip in the ZE7000). I recommend CentOS 7. 8. This is stable for an i3 based computer. It was not satisfactory with my AMD Athlon II x2 270, a cpu that CentOS has not been testing.

    CentOS 8 changed from iptables to nftables. The EST rpm package still installs without error messages, translating firewall rules when starting. However, CentOS 8 is not yet stable for network attached zeroclients and I don’t believe that EST plans to work on this.

    The EST deb package for deb based distributions did not correctly support audio in Ubuntu 16.xx and 18.xx and that problem brings Youtube videos to almost complete halt. To test where the problem was, I connected an HP T200 zero client with a DL-165 video adapter (instead of its internal SMSC FX6000 which Linux does not see). When connected by network cable it has the same audio problem. When connected by USB cable, the audio is fine. Thus the EST deb package handling of audio no longer interfaces correctly with the Ubuntu 4.xx kernels. It also doesn’t support newer Linux kernel versions 5.xx which have redefined some shared variables so that the EST kernel module can not compile successfully.

  2. Each ZE7000 has a unique serial number and MAC address 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 lock 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 unique MAC (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.

To start the EST daemon, in a terminal do:

su -c 'nhci start'

If you always want this to happen on boot, edit as root the default system file, /etc/rc.d/rc.local and then give it execute privileges:

#!/bin/bash
$ THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
# In contrast to previous versions due to parallel execution during 
# boot this script will NOT be run after all other services.
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to 
# ensure that this script will be executed during boot.

touch /var/lock/subsys/local

# adding the following script to automatically start EST
# Lawrence E. Boothby, multi-seat.com, 4-07-2020
/usr/sbin/nhci start

The utility, loginctl, can be used to discover a specific zero client 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.

loginctl attach seat-04C9913008BA /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 "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 "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. Note that in CentOS, you are probably not in the sudo user file, so would execute su instead to gain root privileges first, before executing the loginctl attach commands.

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/ The original intent of Linux developers was that /usr/lib/udev/rules.d/ would contain the distributions default rules and that /etc/udev/rules.d/ would contain only overrides and additions to those defaults.

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"
 TAG=="seat", ENV{ID_FOR_SEAT}=="usb-platform-nh04C9913008BA", ENV{ID_SEAT}="seat-04C9913008BA"  # Phistek ZE7000 zero client added by loginctl attach command
 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 ~]$