RPi as Z-Wave/ZigBee-over-IP server for Hass

I get this error.

Job for usbip.service failed because the control process exited with error code. See "systemctl status usbip.service" and "journalctl -xe" for details.



Last login: Sun Mar 24 00:17:19 2019 from 10.0.24.7
flemmingss@Home-Assistant:~$ systemctl status usbip.service
● usbip.service - usbip client
   Loaded: loaded (/lib/systemd/system/usbip.service; enabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sun 2019-03-24 00:42:29 CET; 18h ago
  Process: 1278 ExecStart=/bin/sh -c /usr/lib/linux-tools/$(uname -r)/usbip attach -r 10.0.24.11 -b $(/usr/lib/linux-tools/$(una
 Main PID: 1278 (code=exited, status=127)

Mar 24 00:42:29 Home-Assistant systemd[1]: Starting usbip client...
Mar 24 00:42:29 Home-Assistant sh[1278]: /bin/sh: 1: /usr/lib/linux-tools/4.4.0-31-generic/usbip: not found
Mar 24 00:42:29 Home-Assistant sh[1278]: /bin/sh: 1: /usr/lib/linux-tools/4.4.0-31-generic/usbip: not found
Mar 24 00:42:29 Home-Assistant systemd[1]: usbip.service: Main process exited, code=exited, status=127/n/a
Mar 24 00:42:29 Home-Assistant systemd[1]: Failed to start usbip client.
Mar 24 00:42:29 Home-Assistant systemd[1]: usbip.service: Unit entered failed state.
Mar 24 00:42:29 Home-Assistant systemd[1]: usbip.service: Failed with result 'exit-code'.

Is my configuration wrong?
Devices:

Bus 001 Device 011: ID 0403:6001 Future Technology Devices International, Ltd FT232 USB-Serial (UART) IC #RFXTRX433E
Bus 001 Device 009: ID 0403:6015 Future Technology Devices International, Ltd Bridge(I2C/SPI/UART/FIFO) #Deconz
Bus 001 Device 010: ID 0658:0200 Sigma Designs, Inc. #UZB1

/lib/systemd/system/usbipd.service

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

[Service]
Type=forking
ExecStart=/usr/sbin/usbipd -D
ExecStartPost=/bin/sh -c "/usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0403:6001#' | cut '-d#' -f1)" #RFXTRX433E
ExecStartPost=/bin/sh -c "/usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0403:6015#' | cut '-d#' -f1)" #ConBee
ExecStartPost=/bin/sh -c "/usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0658:0200#' | cut '-d#' -f1)" #UZB1
ExecStop=/bin/sh -c "/usr/sbin/usbip unbind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0403:6001#' | cut '-d#' -f1`); killall usbipd" #RFXTRX433E
ExecStop=/bin/sh -c "/usr/sbin/usbip unbind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0403:6015#' | cut '-d#' -f1`); killall usbipd" #ConBee
ExecStop=/bin/sh -c "/usr/sbin/usbip unbind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0658:0200#' | cut '-d#' -f1`); killall usbipd" #UZB1

[Install]
WantedBy=multi-user.target

/lib/systemd/system/usbip.service

[Unit]
Description=usbip client
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c "/usr/lib/linux-tools/$(uname -r)/usbip attach -r 10.0.24.11 -b $(/usr/lib/linux-tools/$(uname -r)/usbip list -r 10.0.24.11 | grep '0403:6001' | cut -d: -f1)" #RFXTRX433E
ExecStart=/bin/sh -c "/usr/lib/linux-tools/$(uname -r)/usbip attach -r 10.0.24.11 -b $(/usr/lib/linux-tools/$(uname -r)/usbip list -r 10.0.24.11 | grep '0403:6015' | cut -d: -f1)" #ConBee
ExecStart=/bin/sh -c "/usr/lib/linux-tools/$(uname -r)/usbip attach -r 10.0.24.11 -b $(/usr/lib/linux-tools/$(uname -r)/usbip list -r 10.0.24.11 | grep '0658:0200' | cut -d: -f1)" #UZB1
ExecStop=/bin/sh -c "/usr/lib/linux-tools/$(uname -r)/usbip detach --port=$(/usr/lib/linux-tools/$(uname -r)/usbip port | grep '<Port in Use>' | sed -E 's/^Port ([0-9][0-9]).*/\\1/')"

[Install]
WantedBy=multi-user.target

btw, 10.0.24.4 is HA, 10.0.24.11 is the Pi

The service from pie, looks god?

root@raspberrypi:~# sudo systemctl status usbipd.service
● usbipd.service - usbip host daemon
   Loaded: loaded (/lib/systemd/system/usbipd.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2019-03-24 00:19:24 CET; 19h ago
  Process: 517 ExecStartPost=/bin/sh -c /usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0658:0200#' | cut '-d
  Process: 510 ExecStartPost=/bin/sh -c /usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0403:6015#' | cut '-d
  Process: 495 ExecStartPost=/bin/sh -c /usr/sbin/usbip bind --$(/usr/sbin/usbip list -p -l | grep '#usbid=0403:6001#' | cut '-d
  Process: 487 ExecStart=/usr/sbin/usbipd -D (code=exited, status=0/SUCCESS)
 Main PID: 493 (usbipd)
   CGroup: /system.slice/usbipd.service
           └─493 /usr/sbin/usbipd -D

Mar 24 00:19:22 raspberrypi systemd[1]: Starting usbip host daemon...
Mar 24 00:19:22 raspberrypi usbipd[493]: usbipd: info: starting usbipd (usbip-utils 2.0)
Mar 24 00:19:22 raspberrypi usbipd[493]: usbipd: info: listening on 0.0.0.0:3240
Mar 24 00:19:22 raspberrypi usbipd[493]: usbipd: info: listening on :::3240
Mar 24 00:19:22 raspberrypi sh[495]: usbip: info: bind device on busid 1-1.4: complete
Mar 24 00:19:23 raspberrypi sh[510]: usbip: info: bind device on busid 1-1.3: complete
Mar 24 00:19:24 raspberrypi sh[517]: usbip: info: bind device on busid 1-1.2: complete
Mar 24 00:19:24 raspberrypi systemd[1]: Started usbip host daemon.
1 Like

Use this post as a starting point: RPi as Z-Wave/ZigBee-over-IP server for Hass

I made some tweaks to the service files posted there. I’ve included mine in a gist here: https://gist.github.com/shbatm/1526174a9d285c342eb05c9efa35c02d

1 Like

@flemmingss I would try what was suggested above and split the devices into multiple service files. Also, I would suggest updating the service to use After=network-online.target so the service comes up after you have a network connection (vs. just an active network stack).

Thanks for your help. You made my life so much easier.

You sir, rock my socks. Thank you for your effort and documentation on this!

1 Like

Just wanted to add that the usbip method works with HASSIO as of ver 0.90.1 I’ve been testing.

My Setup:

  • Zwave Server
    • Pi 3B
    • OS: DietPi
    • Aeotec Z-wave Stick - 0658:0200
    • Ethernet instead of WiFi
  • HA Server - Zwave client
    • Host: 2c/8gb ram VM running on ESXi 6.7
    • OS: DietPi vmware
    • HASSIO installed following this method
# Ensure that `/dev/ttyACM0` shows on the host and inside the hassio container
$ docker exec -it $(docker ps -f name=homeassistant -q) stat /dev/ttyACM0 | head -n1
  File: /dev/ttyACM0

Other notes:

Removed a ` in the usbip.service file.

From:

ExecStop=/bin/sh -c "/usr/sbin/usbip unbind --$(/usr/sbin/usbip list -p -l | grep '#usbid=10c4:8a2a#' | cut '-d#' -f1`); killall usbipd"

To:

ExecStop=/bin/sh -c "/usr/sbin/usbip unbind --$(/usr/sbin/usbip list -p -l | grep '#usbid=10c4:8a2a#' | cut '-d#' -f1); killall usbipd"
1 Like

Im getting the same error like @flemmingss had. Already using @shbatm 's config file with the network online target and just one device. Has someone an idead what I’m doing wrong?

-- Unit usbip.service has begun starting up.
Apr 13 17:24:43 server-landerer sh[18437]: /bin/sh: 1: /usr/local/sbin/usbip: not found
Apr 13 17:24:43 server-landerer sh[18437]: /bin/sh: 1: /usr/local/sbin/usbip: not found
Apr 13 17:24:43 server-landerer systemd[1]: usbip.service: Main process exited, code=exited, status=127/n/a
Apr 13 17:24:43 server-landerer systemd[1]: usbip.service: Failed with result 'exit-code'.
Apr 13 17:24:43 server-landerer systemd[1]: Failed to start usbip client.
-- Subject: Unit usbip.service has failed
-- Defined-By: systemd
-- Support: http://www.ubuntu.com/support
-- 
-- Unit usbip.service has failed.
-- 
-- The result is RESULT.

Make sure you have enabled the kernel module and then try running the usbip command from the command line. There should be an option to list connected ports and list available ports on a remote host.

Sorry I don’t have the exact steps (out of town). But the kernel module should be in the link above, the commands can be found with usbip --help

I already loaded thekernel module and checked if they are loaded:

When I’m trying to use usbip, I’m always getting the same error:

Am I missig a symlink?

@Niklas - I get this error when the host is offline or unreachable (the device with the physical USB device). Check that the service is up and running on the host, that it’s exporting the correct devices, and that it’s reachable from your client.

Sorry that I’m still bothering you :smiley:
From the client I can ping the host, usbipd ist listening on port 3240 on the host so that should be fine…

I just noticed the double slash in the path (/hwdata//usb.ids, last screenshot). Could that be the reason?

Your usbip list command from the client should look like:

usbip list -r 192.168.178.31

If that works, then at least your usbip server with your zwave stick is working.
In your client’s system service script, you can either modify the path for where your usbip command lives, or create a symlink.

To modify: get the path with where usbip, and use that path in your /lib/systemd/system/usbip.service

To symlink: ln -s $(which usbip) /usr/local/sbin/usbip
In my case, my usbip was in /usr/sbin/usbip

I have spent the last several days exercising this approach extensively, with usbip as a service on an rPi and hass.io running in a Hyper-V VM. I like the result a lot (thank you), and it appears stable in use, but not on any kind of restart.

Rebooting the client (Hyper-V VM) from the outer ubuntu OS works OK, rebooting it from the hass.io docker causes the rPi server to think the connection is still in use and it will not then reconnect when the hass.io side restarts. Rebooting or restarting the service on the rPi, the starting the service on the Hyper-V client, THEN restarting the HA service from the HA configuration page will restore it.

Rebooting the server (or restarting the usbip service on the rPi server) will break the connection but not cause the service on Hyper-V to fail, so it does not restart, so it just never works again until you restart it (and then restart HA again).

This is workable but awkward – any time I am rebooting either side requires care and checking to see that everything is functional. I can’t find any kind of watchdog or heartbeat setting that might automate this. Since in the rPi reboot case both ends have the service running but not functional, it is hard to script something to notice (the only clue I have is that a HA restart gives an error on the zwave integration startup).

Those using this – have you found a way to make the client/server reliably survive reboots?

Linwood

So I was having problems with this as well. I run hass.io in Docker on a RockPi in my network room, and the physical z-wave stick runs on a Raspberry Pi MagicMirror2 by the front door. Your comment inspired me to finally implement my plan for a more robust restart connection (especially after it died from a power outage yesterday).

I’ve updated my gist here: https://gist.github.com/shbatm/1526174a9d285c342eb05c9efa35c02d

This now has a “usbipManager.sh” (basically an expanded init script) script which does a few extra things:

  1. Before connecting: Ping the host and see if it’s available. If not, wait and retry using an exponential delay (1s, 2s, 4s, 16s, etc. to 256s). This gives time after, for example, a whole home power outage, where everything comes back at the same time, but you have to wait for the other server to come up first.
  2. After confirming the host is there, check if the USB-IP service is available. If it isn’t, try to restart the service on the remote machine using SSH. FOR THIS TO WORK you must have Public Key Authorization set up both directions on the 2 machines. This will “fail” the script on the client, but the server will “call back” on service restart and restart the client.
  3. If everything is good, mount the device.
  4. After mounting the device, restart the homeassistant docker, if it’s already running.

On the USBIP server side:
The server’s .service file actually includes a line to call the client (via SSH) and attempt to restart the client’s service when the server’s service is available. It will continue on if it fails, but if it succeeds, this will cascade to re-mount the port on the client and restart Home Assistant. This is useful if I have to restart the MagicMirror for any reason… when I do, it will call the Hass.io server and tell it to reconnect and restart.

2 Likes

Thank you @shbatm. I had vague ideas of doing something similar but your code will save me a lot of time. I had gotten distracted with a related issue however, and wonder if you have seen it.

When I restart the service on the client, sometimes but not always, it changes the device names. On the server I have /dev/ttyUSB0 and /dev/ttyUSB1 for a Nortec stick. At first they match exactly on the client. When I just do a sysctrl restart usbip on the client side they move to /dev/ttyUSB2 and /dev/ttyUSB3. If I restart again they do not advance again, though as I write this I realize I also never change HA’s config to use the new devices, so maybe the issue is some kind of in-use condition not allowing the old device names to be reused?

I was experimenting with udev rules to force the naming of the client side usbip devices, with zero luck. It is almost as though udev is not involved in their creation. Now that I have thought of the in-use issue, maybe I can change the stop condition to always restart HA’s container and see if that releases it.

But have you seen this issue and have any insight?

So far my only solution has been a reboot of the client’s containing VM, and I am loath to script that in the service for fear some condition will just get it stuck in a boot loop. Of udev would work, even if it failed to create the device because of a name collision, my thought was the restart would fail and I could do something – dealing with a new device name is much more of a pain in terms of scripting, I would need to change the configuration.yaml script inside the docker container.

Postscript: I see you have a udev rule in there also, I’ll try yours (I was using subsystem usb as that’s how it showed).

Further to the issue of device names, it appears (e.g. the first answer here) and docker (how I’m running hass.io) does not allow symlinks (discussion here, apparently no plans to allow). So as best I can tell I need to find out why I am having shifting names.

I take it you are not using docker for hass.io? As you are using a symlink (which I can get working).

This is what I’m dealing with. I thought perhaps it was caused by the docker containers remaining active and holding a reference to the device but apparently not.

root@ha:~# service hassio-supervisor stop
root@ha:~# docker stop homeassistant
homeassistant
root@ha:~# ls -lat /dev/ttyU*
crw-rw---- 1 root dialout 188, 1 May  3 15:14 /dev/ttyUSB1
crw-rw---- 1 root dialout 188, 0 May  3 15:14 /dev/ttyUSB0
root@ha:~# systemctl stop usbip
root@ha:~# ls -lat /dev/ttyU*
ls: cannot access '/dev/ttyU*': No such file or directory
root@ha:~# systemctl start usbip
root@ha:~# ls -lat /dev/ttyU*
crw-rw---- 1 root dialout 188, 2 May  3 15:43 /dev/ttyUSB2
crw-rw---- 1 root dialout 188, 3 May  3 15:43 /dev/ttyUSB3

I cannot figure out why a service restart is, seemingly every time, changing the names of the devices. Forcing with udev to a symlink does not help as they need to be visible inside docker and it doesn’t do symlinks. I’ve done this stopping all docker containers and even docker itself in between and no difference, every time I restart I get 2 and 3. Restart again and still 2 and 3 (though I have yet to actually try using them as 2 and 3).

Postscript: To fill this out a bit, the devices do not appear “real” in some way inside docker. If I leave docker (and HA/Hassio) running, and restart usbip, then try to list the devices from inside docker they are not quite there.

root@ha:~# docker exec homeassistant ls -la /dev/ttyU*
ls: /dev/ttyUSB2: No such file or directory
ls: /dev/ttyUSB3: No such file or directory
root@ha:~# docker exec homeassistant ls -la /dev
<long list filtered for here> 
crw-rw----    1 root     dialout   188,   0 May  3 12:35 ttyUSB0
crw-rw----    1 root     dialout   188,   1 May  3 12:35 ttyUSB1

I have no idea what it means to be able to list them in the folder, but not with a wildcard, but must be a clue. Before the restart you can list them with a wildcard.

Postscript #2: If I restart usbip (to get ttyUSB2), then change configuration.yaml to reference ttyUSB2 then HA works. If at that point I restart usbip I get ttyUSB4. So it definitely appears to be some kind of in-use thing that is forcing the creation of new names.

Last Postscript: I have tried all sorts of combinations, restarting the server and client’s service, restarting docker, etc., and I cannot avoid the change to USB0->USB2 with anything I do, and cannot figure out a way to fix it short of a reboot. A Symlink won’t work inside the docker container, which is the only workaround I can find.

See my post on the other thread:

I do use a udev rule for the client host for convenience, but inside Hass.io I use the by-id serial device, which is persistent.

I do use a udev rule for the client host for convenience, but inside Hass.io I use the by-id serial device, which is persistent.

I didn’t even know that existed, but it does seem to work. It requires a restart of the docker homeassistant container for a new version to be visible (after a restart of usbip) but that was kind of expected.

Thank you. I was going around in circles trying to fix the USBx name difference, and did not even know this existed.

Does beg the question what kind of dangling in-use condition is causing it to increment, but it does not seem to do any harm.

Thank you!!

Glad it’s working. I pulled my hair our for a few days when I was trying to get it set up (even rolling my own Docker image with socat/usbip inside) until I stumbled on the by-id tag by dumb luck.