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

Assuming you use socat the way I use usbip, yes, correct.
Fortunately I don’t lose wifi connection to my PI ever so I don’t need to do this.
Unfortunately the windows 10 hyper-v host I have Homeassistant on force restarts itself every so often.

So for the last few months I’ve been successfully running home-assistant on x86 machine that was remotely connecting to a z-wave usb stick on a RPi, orchestrated on Kubernetes. (however, if you just want the socat commands, you can just extract it from the kubernetes manifests below)

The new ozw-zwave-mqtt support that’s being added will obsolete this (and I’m so excited about that!), but this recipe may still have use for folks who may want to do this for zigbee or any type of other serial interface on a remote machine.

My configuration:

  • Kubernetes cluster (I’m using k3s+metallb and nfs server for persistent storage).
  • VMs on ESXi running as my normal x86 workers (home-assistant will get scheduled on this)
  • RPi node (with node taints --node-taint rpi=true:NoSchedule --node-taint rpi=true:NoExecute)
  • Aeotec Z-Stick 5 attached to the RPi node

I have three kubernetes deployments

  • zwave-server (this will expose the Z-Stick as a tcp service)
  • zwave-client(this will connect to zwave-server and expose it as a pts device on the k8s node)
  • home-assistant(this will mount the /dev/pts so it can access to the client device)

I’m using nodeSelector to place zwave-server on the RPi, and then colocate zwave-client and home-assistant on the same node. (The reason the zwave-client and home-assistant are two deployments is so that I can run the zwave-client in priviledged mode, and keep home-assistant locked down)

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: hass
  name: zwave-server
spec:
  selector:
    matchLabels:
      app: zwave-server
  replicas: 1
  template:
    metadata:
      labels:
        app: zwave-server
    spec:
      containers:
        - image: paullj1/socat_static:1.7.3.3
          name: socat
          args: 
            #- -dddd
            - -dd
            - tcp-l:8080,reuseaddr,keepalive,nodelay
            - file:$(DEVICE),nonblock,rawer
          env:
            - name: DEVICE
              value: "/dev/ttyACM0"
          ports:
            - containerPort: 8080
          securityContext:
            privileged: true # Implied /dev access
      tolerations:
        - key: "rpi"
          operator: Equal
          value: "true"
      nodeSelector:
        kubernetes.io/hostname: "k3s-agent-rpi3.home"

---
apiVersion: v1
kind: Service
metadata:
  namespace: hass
  name: zwave-server
spec:
  ports:
  - port: 8080
  selector:
    app: zwave-server
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: hass
  name: zwave-client
spec:
  selector:
    matchLabels:
      app: zwave-client
  replicas: 1
  template:
    metadata:
      labels:
        app: zwave-client
    spec:
      containers:
        - image: paullj1/socat_static:1.7.3.3
          name: socat
          args: 
            #- -dddd
            - -dd
            - pty,link=/var/run/zwave/dev,ignoreof,rawer
            - tcp:zwave-server:8080,forever
          securityContext:
            privileged: true # Implied /dev access
          volumeMounts:
            - name: dev-pts
              mountPath: /dev/pts
            - name: zwave-dir
              mountPath: /var/run/zwave
          resources: {}
      volumes:
        - name: dev-pts
          hostPath:
            path: /dev/pts
            type: Directory
        - name: zwave-dir
          hostPath:
            path: /var/run/zwave
            type: DirectoryOrCreate
      nodeSelector:
        kubernetes.io/hostname: "k3s-agent-1.home"
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: hass
  name: hass
spec:
  selector:
    matchLabels:
      app: hass
  replicas: 1
  template:
    metadata:
      labels:
        app: hass
    spec:
      containers:
        - name: hass
          image: homeassistant/home-assistant:0.109.0
          env:
            - name: ZWAVE_DEVICE
              value: /var/run/zwave/dev
          ports:
            - containerPort: 8123
              name: http
              protocol: TCP
          volumeMounts:
            - name: config-nas-volume
              mountPath: /config
            - name: dev-pts
              mountPath: /dev/pts
            - name: zwave-dir
              mountPath: /var/run/zwave
          livenessProbe:
            initialDelaySeconds: 60
            timeoutSeconds: 10
            httpGet:
              path: /api/
              port: http
              httpHeaders:
                - name: Content-Type
                  value: application/json
                - name: Authorization
                  value: Bearer XXXXXXXXXX
          resources: {}
      volumes:
        - name: config-nas-volume
          nfs:
            server: nas.home
            path: /mnt/tank/kubernetes/hass
        - name: zwave-dir
          hostPath:
            path: /var/run/zwave
            type: Directory
        - name: dev-pts
          hostPath:
            path: /dev/pts
            type: Directory
      nodeSelector:
        kubernetes.io/hostname: "k3s-agent-1.home"
---
apiVersion: v1
kind: Service
metadata:
  namespace: hass
  name: hass
spec:
  ports:
  - port: 8123
    targetPort: 8123
    name: hass-8123
  - port: 80
    targetPort: 8123
    name: hass-80
  selector:
    app: hass
  type: LoadBalancer
  loadBalancerIP: XXXXXXXXXXXXX
1 Like

So my situation is the following:
I have Home Assistant running on a Rasberry pi 4B 4GB.
And i have 2 rasberry pi zero. And i want to connect a zwave and a zigbee usb to each.

And then place the 2 pi zero inside the house. And the home assistant is in the garage 30 meter away. Whats the best way to connect these pi zero’s to my main home asisstant. I’ve read this guide but it says it needs to install some apt on the rasberry, but i am running the native iso from home assistant. Can anyone give me some insight?

I would not recommend putting your Z-Wave and ZigBee sticks on a wireless connected device, not reliable enough in my opinion.

Nothing on my HA instance looks like anything here. It doesn’t even have the apt package (or any way to install it from what I can see).

I have been doing linux admin for 30 years and I am literally lost. This home assistant thing looked like a promising replacement for smartthings but it is turning into a nightmare.

All I want is to run Home Assistant on my Hyper-V server and have it run my Zigbee & Zwave network. Is that too much to ask of this product?

Then you installed Home Assistant OS, which doesn’t have this functionality. You can run Home Assistant Container, Home Assistant Supervised on top of Debian or Home Assistant Core in a venv. Here’s a good overview of the different install methods and suggested skill levels.

That’s definitely possible, lots of people do this (including myself). It’s better to open a separate topic with your issues.

That just led me down another rabbit hole that ends up installing Supervised in Docker…which according to this thread doesn’t work.

I don’t know what you are trying to achieve, please open a separate topic for your issue and give some more details about your goal and current setup. You can tag me there if you like to.

Your best bet is zwave2mqtt. Or Ozwdaemon in docker.

I keep getting referred to this post for usbip, but I’m using Debian 10 and it won’t let me install linux-tools-generic – has anyone successfully gotten usbip installed on a debian 10 instance?

1 Like

Yeah, it looks like it’s not a part of the current Debian repository. Looks like there might be a way to install that package by adding a different repo : here, but I’ve just been manually mounting on restarts until I get it sorted:

usbip  list -r xxx.xxx.xxx.xxx

Find the bus id of your target device (ex: 1-1.2)

usbip attach -r xxx.xxx.xxx.xxx -b 1-1.2

this has been working well for meI even have a udev rule reattaching if it gets disconnected, until i added another instance on both client and server for a bluetooth dongle. I noticed that the script as i understand it won’t work with a seconds instance as i understand it on the client the service stop will pick the first port usbip port and detach it regardless which port is actually required to be stopped. IYSWIM…I have also a problem with starting it also where it starts the service ok but just doesn’t work properly…this requires more investigation (starting manually works ok)…

Here’s a blog post I’ve written for the approach I’ve been using USB Support for Home Assistant in Hyper-V – DVLUP

I intensely prefer Hyper V over anything else, it is a superior system over other systems (at least on Windows)

These are both paid versions correct?

Yes, both options are commercial software.

Hi there. Anyone finished a working udev rule for usbip host? Have trouble to get one working on RPi. Second thing is a reconnect script on the client, any ideas?

Did you manage to make it work on Debian 10? I also can’t install linux-generic-tools, and I’m stuck

welp, that was just me that had a firewall rule issue, finally got it work on Debian 10(as the client)

definition on Debian looked a little different for me

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

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c "usbip attach -r 192.168.0.10 -b $(usbip list -r 192.168.0.10 | grep '10c4:8a2a' | cut -d: -f1)"
ExecStop=/bin/sh -c "usbip detach --port=$(usbip port | grep '<Port in Use>' | sed -E 's/^Port ([0-9][0-9]).*/\\1/')"

[Install]
WantedBy=multi-user.target

pretty much the same except for the location of the “usbip” executable

How did you get it to work on Debain and what was the firewall issue? I can’t for the life of me get it to install and the alternative repository seems to be dead.

The firewall issue that I had was my pfSense rule about communicating between devices in the same subnet(I think it just my unique setup)

and if you got HA installed on Debian10, then your configuration on Debian should look like the one I posted