Does ZWaveJS2MQTT Work on Raspian?

I’m using the project documentation to try to get ZWaveJS2MQTT up and running on a Pi 3B. I’ve also tried this on a Pi 4 and neither works.

If you’ve got Z2M working on a Pi, please tell me how you did it. (I had it working on a Debian system, but the Z-Stick had rotten results when plugged in to that - it wouldn’t communicate with a Z-Wave device about 20’ away on the other side of a clear room!)

I’m using the Getting Started section, under “Other Methods.” I’ve tried using the first described method to use curl, then wget to download the Z2M archive. When I do, and unzip it, I get:

pi@radagast:~/zwavejs2mqtt-simple $ ./zwavejs2mqtt
-bash: ./zwavejs2mqtt: cannot execute binary file: Exec format error

When I try the 2nd method in that section, using yarn, I get an error because there is no file named “install”:

pi@radagast:~/zwavejs2mqtt-scratch/zwavejs2mqtt $ yarn install
00h00m00s 0/0: : ERROR: [Errno 2] No such file or directory: ‘install’
pi@radagast:~/zwavejs2mqtt-scratch/zwavejs2mqtt $ yarn
00h00m00s 0/0: : ERROR: There are no scenarios; must have at least one.

I haven’t installed Docker on this Pi yet. Looks like it’s not something I can install with apt. But if the executable for Z2M doesn’t work this way, will it work if I use Docker?

The current package version of zwavejs2mqtt is for the amd64 platform.

As for the yarn command, sounds like you didn’t install the correct program. See zwave-js - Z-Wave driver written entirely in JavaScript/TypeScript

Docker is the easiest way to install zwavejs2mqtt, IMO, if you can get it installed. I use it on my Pi3 and Pi4, and with zwavejs2mqtt.

I have ZWaveJS2MQTT running on a Pi3 in Docker. It’s been stable for over a year.

When I look, I see a package named ‘docker’, but it’s apparently something other than the container system. Do I install Docker from apt or in another way?

Ah! One of those things that’s important, but not where I was looking! I’ll look into this, but also look into Docker.

One reason I was trying to do it with yarn is because I was considering putting it on a MacMini, which is already in my remote building and I figured if I could build it on the Pi, I could build it on the Mac (most likely) with help of brew to add what I needed. But now it’s more about just getting it working AND talking to all my Z-Wave devices in that building. (When a Z-stick won’t talk to a device that’s about 20’ away on the other side of an open room, there’s something wrong - my guess is interference from the other Linux system I had it on.)

I have installed it with yarn on Windows, it works fine. I think it will take a long time to install on an RPi though, because it has to build some packages from source code, but it works. After all, that’s how the Docker image is built.

sudo apt-get remove docker docker-engine docker.io containerd runc
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
exit
(You can’t run the docker command until you have logged out and back in)

That’s Docker installed.

mkdir /home/pi/zwave

docker run -v /home/pi/zwave:/usr/src/app/store --device /dev/serial/by-id/your-stick-id:/dev/zwave -p 8091:8091 -p 3000:3000 --restart=always zwavejs/zwavejs2mqtt:latest

That should get the container running.

Find your stick ID for the /dev/serial/by-id/ bit by running ls -l /dev/serial/by-id/

Okay, that makes sense, since I had found a package named “docker” that apparently had nothing to do with the program we’re talking about.

Thank you!

Important addition:

After installing Docker, add this:

sudo usermod -aG docker pi

That adds pi as a user to the group docker. Without that, there will only be error message when trying to install Z2M.

I looked this over and, to me, part of the command line to start Z2M through Docker specified things like when to restart, the port and device. But it’s still running as a command in my ssh shell (I do a lot of the work from my main desktop, so I use VNC and ssh to connect to my Pi systems quite a bit.)

When it rebooted, I tried ps aux to see if the program was running and it didn’t show up. When I use a browser to read the port for configuration, though, I the config pages there.

How is that working? It’s not a service. Is Docker handling it through a daemon?

And it seems that even though I copied my device path (/dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_ac0656ead0e5ea11bfc18dd5994a5d01-if00-port0) by copy and paste, so there were no typos, that it’s unable to read it.

I’m running zwavejs2mqtt on Raspbian (well, RPi OS now) using yarn without issues. Personally I consider Docker to be total overkill for these kind of uses, only increasing complexity and use eating up resources for no benefit. On an embedded system with limited resources, the more bare to the metal you can go, the better. Building the packages took a while indeed (especially on an SD card), but nothing too bad either. Once built, the driver starts within a couple of seconds and seems very reliable so far.

But - it depends on how often it needs to be rebuilt? Right now they update monthly, and to fix bugs for existing devices and add support for new devices, I need to update every few months too. With Docker it takes 5-8 minutes to pull the latest build and have it back up and running. How long does it to take to re-build on bare metal?

Yes, Docker handles it all.

You may need to add the docker user to the dialout group?

pi@zigbee:~ $ id
uid=1000(pi) gid=1000(pi) groups=1000(pi),4(adm),20(dialout),24(cdrom),27(sudo),29(audio),44(video),46(plugdev),60(games),100(users),105(input),109(netdev),995(docker),997(gpio),998(i2c),999(spi)

EDIT: Just to check - you are trying to access it at /dev/zwave when you configure it through the web interface? That’s what the docker command was doing mapping the physical stick (by it’s ID) to the virtual device /dev/zwave

Not necessarily. Updates to the device database do not need anything to be rebuilt, they can be installed from the web UI in seconds. Only actual modifications to the source packages would need a partial rebuild. Not a full mind you, only the modified packages or dependencies will be rebuilt. So I wouldn’t expect this to take long at all, maybe a few minutes. Not that I plan to update this very often, once it works with my devices (and right now it does), it’s gonna stay at this version.

I honestly don’t remember. I launched the process and left for groceries. When I got back, it was done. This was a full build though, downloading and building the entire dependency tree. A simple change to the zwavejs package wouldn’t need that.

Good luck with that!
Every major home assistant update (the first one of each month) wants the server updated to the latest version, or it will complain that it cannot connect because the API schema is too low. This month I have already had to update twice, I have a script that automatically updates on the 2nd of the month anyway - which it did, but I had to update it AGAIN to get it talk to the .1 release of Home Assistant this month.

I’m not using the HA zwaveJS integration (mainly due to the constant update hell with HA). It’s all over MQTT, so HA updates will not affect the zwave driver at all (and vice-versa).

I added it to the dialout group (the same way I added pi to the docker group), with no change.

So I did what worked on the system that didn’t behave (the non-Pi computer) and did

sudo chmod a+rw /dev/serial/by-id/mydevice
sudo chmod a+rw /dev/ttyUSB0

(The one in by-id links to the 2nd one.) It doesn’t help here.

EDIT: Just to check - you are trying to access it at /dev/zwave when you configure it through the web interface? That’s what the docker command was doing mapping the physical stick (by it’s ID) to the virtual device /dev/zwave

There is no /dev/zwave there - before or after I run it with Docker.

EDIT: I have logging set to “Silly.” All I get for the issue of not reading the device node is:

2021-10-11 19:23:17.479 INFO ZWAVE: Connecting to /dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_ac0656ead0e5ea11bfc18dd5994a5d01-if00-port0
2021-10-11 19:23:17.503 WARN ZWAVE: Retry connection in 3 seconds...

Is there any way to get more information than that? I’d like to find out what kind of error message it’s getting so I can try to address it directly.

More info on the inability to read the device. I went back to the control panel in my browser and saw this:

Note the message at top:

Driver: Error: No such file or directory, cannot open /dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_ac0656ead0e5ea11bfc18dd5994a5d01-if00-port0

Even though I’ve used copy-and-paste whenever I need this device node (to avoid typos), I copied that entire path (from /def to port0) and pasted as part of the command:

ls -l /dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_ac0656ead0e5ea11bfc18dd5994a5d01-if00-port0

It’s there. I verified it exists.

Does this have something to do with Docker and how it references files outside of its own container?

Summary time - in other words, it’s working and I’d like to spell out everything in one place, so anyone searching for help on this will find it clearly written out.

First, do what @mobile.andrew.jones has said to install Docker - with one added command:

sudo apt-get remove docker docker-engine docker.io containerd runc
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker pi
exit

I’ve added the 2nd to last command line - I couldn’t run Docker as a normal user without it. And be sure to exit your shell. Then just log back in. Docker won’t work unless you do that.

Then, once Docker is installed, let’s deal with the Z-stick. I’ve had problems (and it’s a known issue) with USB Z-sticks and Raspberry Pis. So use a hub or a USB extension cable to keep the Z-stick 1’ or more away from your Pi. (I suspect this is also an issue with Insteon sticks - go for a bigger PLM on Insteon that can do dual mode, RF and through power lines. I wish I had not gone with a USB stick for Insteon!) Also, I’ve had problems with Z-Sticks in powered USB hubs. Unpowered hubs are fine, but I can’t get them to work with powered hubs.

Okay, Docker is in, the Z-Stick is hooked up, but not directly in the Pi. Next, let’s get the program itself, ZWaveJS2MQTT working. Again, thanks to @mobile.andrew.jones for most of this:

Enter the command ls -l /dev/serial/by-id/*. Read the devices that show up in the output. It shouldn’t take much to figure out which one is the Z-Stick. (Mine is /dev/serial/by-id/usb-Silicon_Labs_CP2102N_USB_to_UART_Bridge_Controller_ac0656ead0e5ea11bfc18dd5994a5d01-if00-port0). You’ll be copying and pasting that in a minute or two.

Here’s the two commands you need for setting this up, now that Docker is installed:

mkdir /home/pi/zwave
docker run -v /home/pi/zwave:/usr/src/app/store --device /dev/serial/by-id/your-stick-id:/dev/zwave -p 8091:8091 -p 3000:3000 --restart=always zwavejs/zwavejs2mqtt:latest

Note this includes --restart=always. If you want this to act as a service or daemon, be sure that’s in there. Where it says your-stick-id needs to be replaced with the id of your Z-stick device. Run this and it should work.

A note on command line options: If you use the Z2M wiki, which is quite useful, the command line it gives does NOT include the restart option, so if you use that, the program will die and won’t restart again unless you run it. If that’s your preference, that’s okay. But if you want it to restart each time you boot, like a Linux service, be sure the restart option is in there.

Once it’s started, you can point your browser at:

http://<hostaddress>:8091

Of course will have to be replaced by the IP address of your Pi or localhost if you’re working on your Pi.

That’ll bring up the web control panel. Here’s good starting settings:

General
Auth - turn on. Simple username (admin) and password (zwave) - it even tells you that. You don’t need this, but it protects it from being messed with by accident.
Log Level - depends on what you want. While I’m setting up, I set to Silly, then change to Debug. You can leave it as is.
Log Enabled - Turn on if you want logs. If you want help on this or any other forum, you’ll want logs because they give people info.
Log to File In this case, if you’ve followed the directions on this topic, turning this on will log to the ~/zwave/ directory. The log file name starts with zwavejs2mqtt and has the date appended to the name.

Z-Wave
Serial Port - /dev/zwave - This can be tricky. Be SURE, in the command line, you specify the path to your device in /dev/serial/by-id/ as shown in the command line above. The “–device” option in that docker command tells Docker to use that as the real device, but maps it to /dev/zwave within the Docker environment. (This confused the heck out of me and took me hours to get!)

The rest of the Z-Wave settings are up to you. If you leave Statistics enabled, it helps he developers.

Disable MQTT Gateway
If you’re new to all this, yes, disable it. Click this to on. It’s FAR easier to just use the Home Assistant setup where HA will discover this automatically. If you want to use the MQTT gateway later (or now), you can set it up, but it’s just extra stuff for most people.

Home Assistant
WS Server All you need to do in this section is click to enable the WS (Web Socket) server. Then HA should be able to find this on its own.

You can do more with the settings, I’m just trying to include what it takes to get up and running.

1 Like

I’m so sorry, I could probably have explained that better.
For everyone still reading along - whenever there is a docker command along the lines of /some/path:/another/path whatever is on the left side ( /some/path ) of the colon is the REAL path on your host, the part on the right ( /another/path ) is INSIDE the docker container. Additionally you can use the -v command multiple times, to map multiple paths. Without the -v command, the container will still run, but it will store the data inside the container and it will be erased when the container is rebuilt. The --device command is more like passthrough, it gives the container permission to access a REAL device on your host ( the left side of the colon ) and makes it available INSIDE the container at the path on the right side of the colon.

Additionally, when Home Assistant updates at the start of each month, if it complains that it cannot connect to the ZWaveJS server because the API schema is too low, the container needs to be updated to the latest image. I run this command to automatically update the container and start it running again without having to enter all the details again:

docker run --rm -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower --run-once --cleanup --include-stopped

This will run watchtower ONCE, it will check for updates for any docker containers you have on the host , if there is an update it will stop the container, pull the latest image and create a new container with all the same details you originally created it with, remove the old container from the host (freeing up space), and then start the new container. When it has finished - it will delete itself.

Don’t worry about it - you’ve been a major help here, on this thread, and on others and you contribute a lot. I was so focused on Z2M that I did not widen my research to include Docker. Once I did, it made sense.

I noticed that when I was using the HTML interface, I got a notice of an upgrade. I clicked it, saw the “Installation started” message, but never saw anything about it being completed and the “1” badge on the icon at the top of the page didn’t go away.

Seeing this is good - so now I know how to handle the upgrade when I need to do it, since the other way of upgrading doesn’t seem to work.

Thanks!

Although it is advised against, I have the command in a shell script file, and I run it every month automatically with Cron on the 2nd of the month and the 9th of the month. I never upgrade to HomeAssistant .0 releases if I can help it anyway, I usually update to the .1 release which means by the time I update Home Assistant - the server has automatically been upgraded to the latest release without me doing anything :wink:

The update IN the server, as far as I understand it, is just new config files - for existing and new devices I believe, they will be pulled in anyway when docker pulls the next version.

1 Like