node-zwave-js/docs/usage/tcp-connection.md

4.9 KiB

Remote serial port over TCP

Instead of using a local serial port, the driver can connect to a serial port hosted on a remote server via TCP, for example using ser2net. Removing the requirement to have a Z-Wave controller physically connected to the host running Z-Wave JS can have a few benefits, depending on the use case.

Examples include:

  1. Being able to place the Z-Wave controller in another location, away from the Z-Wave JS host.
    Ethernet is much more flexible when it comes to bridging distances than USB or serial interfaces.

  2. Allowing for live migration of Z-Wave JS running in a virtual machine to another host in a cluster.
    Passing through a physical USB or serial device ties a virtual machine to the host that has the hardware connected to it. This is especially true for Z-Wave controllers, as parts of the configuration reside in the hardware.

[!NOTE] Proxying serial connections over TCP/IP networks introduces an additional point of failure. Latency, jitter and packet loss can all negatively affect the performance and functioning of a Z-Wave network. As such it is recommended to limit the use of this feature to local and preferably wired networks.
Considering these effects when troubleshooting connectivity issues and mentioning the use of a remote serial port when reporting bugs is another good measure to take.

[!ATTENTION] Currently Z-Wave JS does not support authenticated or encrypted remote ports. If you are using Z-Wave JS to control security relevant devices ensure that the network the port is shared over is trusted, secure and protected.

Configuration in Z-Wave JS

To use a remote serial port, enter tcp://<hostname-or-ip>:<port> as the connection string in the "Serial Port" field of the Z-Wave JS configuration, where

  • <hostname-or-ip> is the hostname or IP address of the remote server
  • and <port> is the port number under which the serial port is accessible.

The serial port must be configured with the following settings:

  • raw, no timeout
  • baudrate: 115200
  • data bits: 8
  • parity: none
  • stop bits: 1

Configuring ser2net

[!NOTE] This uses the new YAML configuration format for ser2net and as such requires a ser2net version 4.0 or newer. If you have been using the old line-based configuration format make sure that you save the sample below using a .yaml suffix and point ser2net to that file.

The following ser2net.yaml configuration will expose a local serial port via TCP using ser2net:

connection: &my-zwave
    accepter: tcp,<port>
    enable: on
    options:
        kickolduser: true
    connector: serialdev,<path-to-serial>,115200N81,nobreak,local

where <path-to-serial> is the path to the serial port on the remote server and <port> is the port number used in the connection string. The serial port configuration mentioned earlier is found encoded in the string 115200N81. The string &my-zwave defines an alias for this connection. ser2net requires an alias to be set and it can be used to reference a connection in more complex configurations but in this simple configuration it serves no further purpose.

Enabling mDNS Service Discovery

Service Discovery via mDNS allows Z-Wave JS to automatically detect remote Z-Wave controllers shared through a TCP serial port on the network.

Z-Wave JS expects a remote serial port to be advertised within your domain (.local by default) using a service type of _zwave._tcp.

Analogous to the above configuration we can use ser2net to enable this feature:

connection: &my-zwave
    accepter: tcp,<port>
    enable: on
    options:
        kickolduser: true
        mdns: true
        mdns-sysattrs: true
        mdns-type: "_zwave._tcp"
    connector: serialdev,<path-to-serial>,115200N81,nobreak,local

In this case, the alias my-zwave will be used as the service instance name. This name can be customized to distinguish different instances. In this example the resulting PTR record value will be my-zwave._zwave._tcp.local.

For Service Discovery to fully function a few things are required:

  1. The gensio library underlying ser2net was built with mDNS support enabled. ser2net will fail to start with the above configuration if this is not the case. ser2net first started supporting mDNS in version 4.3.0.
  2. The host running ser2net has a functioning implementation of mDNS / DNS-SD. For most Linux distributions it is sufficient if the avahi daemon is enabled and running.
  3. On the Z-Wave JS side it is necessary that the embedded mDNS implementation can participate in multicast communication on the local network. When running Z-Wave JS in a container this requires the container network to share the host network namespace, which in Docker can be achieved by passing --network host to the docker run command.