So, one of the most difficult things about Home Assistant is that it often must use usb devices to communicate to the external world. Well, this post outlines one way to get Home Assistant setup as a usbip client. Then, it is possible to make home assistant a truly portable and contanered application.

Things To Consider

So, first this is a unsecure protocol it is raw usb over ip. Therefor, if this is sent outside of a LAN type network the data can be inspected. So, If it is planned to be used in a remote connection approach then I would wrap that within some sort of VPN and VLAN configuration. Technically, I would recommend running all of this in its own VLAN and maybe even limiting the access of outbound traffic to HTTP and HTTPS so that the docker images can be received. Anyway, that is beyond the scope of this post. I just wanted to remind everyone that this is not secure and security should be considered with this especially with so many IOT items that may be used with HomeAssistant.

Step 1 - Configure a usbip server

First, we have to have a Debian instance running and attached to a usb device. Raspberry Pi is a good candidate for this option. Especially, if running with a wifi adapter. Then, it is possible to setup the usb dongle in the most central location. Thus, optimizing for use and access to associated devices.

1.a - Install usbip and usbutils

sudo apt install -y usbip usbutils
sudo usbipd -D
sudo modprobe usbip_host
sudo echo "usbip_host" | sudo tee -a /etc/modules
sudo usbip list -lp

This should output:

- busid 2-1 (10c4:ea60)
   Silicon Labs : CP210x UART Bridge (10c4:ea60)

 - busid 2-2 (10c4:ea60)
   Silicon Labs : CP210x UART Bridge (10c4:ea60)

1.b - Create usbip Host Service

So, it appears usbip is installed so now it is time to go ahead and create the needed service on the host server. Its job is simple. It will loop through all of the usb devices attached to this device and bind them. Please note: this may cause problems if it is desired to limit the devices served. I will address that in the next update to this code. Thank you for your patients this entire process is complex. I think I will write simple node.js server and client that will update the list and eventually be run as the services on the host and client to keep desired devices in sync. That is what I would like to do anyway then a simple UI where you add the devices to be served. Vola! Then they are available on the associated client. Even to the point where you can specify what client gets what usb device. Wouldn't that be cool! Someday, I will write it.

For now, here is the simplified service.

Switch to sudo -i for simplicity for now

sudo -i

Create the service file

nano /etc/systemd/system/usbiphost.service

Put the following text in the file.

[Unit]
Description=usbip host daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/sbin/usbipd -D
ExecStartPost=/bin/sh -c "/lib/systemd/system/usbipdup.sh"
ExecStop=/bin/sh -c "/lib/systemd/system/usbipddwn.sh"

[Install]
WantedBy=multi-user.target

Create the Up Script mentioned in the service.

nano /lib/systemd/system/usbipdup.sh

Paste the following text in it

#!/bin/bash
for i in `usbip list -lp | grep 'busid' | cut '-d ' -f4`; do
        usbip bind  -b "$i";
done

Create the Down Script as mention in the service.

nano /lib/systemd/system/usbipddwn.sh
Place the following test in it.
#!/bin/bash
for i in `usbip list -lp | grep 'busid' | cut '-d ' -f4`; do
        usbip unbind  -b "$i";
done

Do a chmod on the shell scripts that were created.

chmod +x /lib/systemd/system/usbipdup.sh
chmod +x /lib/systemd/system/usbipddwn.sh

Now, setup the service. Oh, for now I would recommend running via ssh and not having any usb mouse device plugged in. Otherwise it will be taken over and you will lose the ability to use keyboard and mouse. This is because it is currently designed to take over everything that usbip list -lp can find. Once the service is up and running you can plug your mouse back in!.

systemctl enable usbiphost.service 
service usbiphost start

If any problems arise use journalctl -xeu usbiphost.service to help troubleshoot.

journalctl -xeu usbiphost.service

If you have to make changes to the shell scripts or the service run systemctl daemon-reload to resync everything

systemctl daemon-reload

Step 2 - Configure a usbip client in home assistant pod.

sudo apt install -y usbip usbutils
sudo modprobe vhci-hcd
sudo echo "vhci-hcd" | sudo tee -a /etc/modules
sudo usbip attach -r 192.168.1.172 -d 3-1
lsusb
Bus 002 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge

Step 3a - Make USBIP Run as a Service on server and in Home Assistant Pod.

Final step, At least for this first rendition is to make services for both home assistant pod and usbip server. This way they will auto start on reboot. Now, I have not got this 100 percent yet; however, I wanted to share what I do have working and then as I finalize my setup I will add the other elements to this post.

Below, is the /etc/systemd/system/usbipclient.service

nano /etc/systemd/system/usbipclient.service
[Unit]
Description=usbip client daemon
After=network.target

[Service]
Type=forking
ExecStart=/usr/sbin/usbipd -D
ExecStartPost=/bin/sh -c "/lib/systemd/system/usbipdup.sh"
ExecStop=/bin/sh -c "/lib/systemd/system/usbipddwn.sh"

[Install]
WantedBy=multi-user.target

This is the /lib/systemd/system/usbipdup.sh script so open a text file with a editor such as nano.

nano /lib/systemd/system/usbipdup.sh

Paste in the following code.

#!/bin/bash
for i in `/usr/sbin/usbip list -r 192.168.1.129 -l | grep ':' | cut '-d:' -f1`; do
/usr/sbin/usbip attach -r 192.168.1.129  -d "$i";
echo "Attaching Port: $i"
done

This is the /lib/systemd/system/usbipddwn.sh

nano /lib/systemd/system/usbipddwn.sh
#!/bin/bash
for i in `/usr/sbin/usbip port | grep 'Port' | cut '-d:' -f1 | cut '-d ' -f2`; do
/usr/sbin/usbip detach -p "$i";
done

Now fix permissions and enable the service.

chmod +x /lib/systemd/system/usbipdup.sh
chmod +x /lib/systemd/system/usbipddwn.sh

Oh, and here is how to check the status of the service

journalctl -xeu usbipclient.service

Sometimes it is needed to resync the script to the systemctl daemon

systemctl daemon-reload

So now enable and test start and stop of the service

systemctl enable usbipclient.service 
service usbipclient stop
service usbipclient start

other client commands

sudo usbip list -r 192.168.1.172
Exportable USB devices
======================
 - 192.168.1.172
        3-1: Silicon Labs : CP210x UART Bridge (10c4:ea60)
           : /sys/devices/pci0000:00/0000:00:1d.0/usb3/3-1
           : (Defined at Interface level) (00/00/00)
           :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
sudo usbip port
Imported USB devices
====================
Port 00: <Port in Use> at Full Speed(12Mbps)
       Silicon Labs : CP210x UART Bridge (10c4:ea60)
       2-1 -> usbip://192.168.1.172:3240/3-1
           -> remote bus/dev 003/002

sudo usbip detach -p 00
usbip: info: Port 0 is now detached!

Step 3b - Make Work With Debian 12 Supervisor HomeAssistant

See this article for HomeAssistant Community Once you have installed HomeAssistant then perform Steps in 3a above. With luck, all will work as needed and now HomeAssistant can be move around in the VM environment without a worry.

Common Errors

tcp connect

debian@usbip-2:~$ sudo usbip attach -r 192.168.1.172 -d 3-1
usbip: error: tcp connect

Typically occurs because usbipd -D was not ran on server and so client cannot create a tcp port.

Device busy (exported)

debian@usbip-2:~$ sudo usbip attach -r 192.168.1.172 -d 3-1
usbip: error: Attach Request for 3-1 failed - Device busy (exported)

Typically, occurs when client is already ported in device from server.

Windows Version

I found a windows version today. I have not tried it, but I will. I think I want to resurrect this process for my current home assistant. So, this would be a good time to test this out. I will follow up with more info in the near future. This is my next Home Assistant improvement! I am sick of having it running on one specific proxmox server. This is defeating my proxmox setup as I cannot move HA (Home Assistant) where I want it. So, I will try windows as a server in the effort to test usbip out!

Leave a Reply

Your email address will not be published. Required fields are marked *