diff --git a/README.md b/README.md index 92d75da..82cb799 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ systems that have installed Home Assistant. TellStick and TellStick Duo service. -- **[OpenZwave](/zwave/README.md)** +- **[OpenZWave](/zwave/README.md)** Allow Home Assistant to talk to a Z-Wave Network via a USB Controller. diff --git a/zwave/CHANGELOG.md b/zwave/CHANGELOG.md index 0e28ed8..503aa61 100644 --- a/zwave/CHANGELOG.md +++ b/zwave/CHANGELOG.md @@ -1,9 +1,25 @@ # Changelog +## 0.4.0 + +- Add OZW instance ID configuration option +- Fix persistent storage of OpenZWave +- Fix permissions on discovery script +- Fix OZW database location +- Improve build speed by using all available cores +- Add built-in ozw-admin +- Add VNC access to add-on to access ozw-admin +- Add Ingress support to add-on to access ozw-admin +- Documentation improvements +- Update OpenZWave (and database) to d2de699 +- Update ozwdaemon to 337e488 +- Add logo and icon +- Detect use of example network key from documentation + ## 0.3.0 - Add port to allow ozw-admin to connect -- Enable discovery again +- Enable discovery again - Set network key default to empty ## 0.2.1 diff --git a/zwave/DOCS.md b/zwave/DOCS.md index effd07f..aaee288 100644 --- a/zwave/DOCS.md +++ b/zwave/DOCS.md @@ -1,40 +1,163 @@ -# Home Assistant Add-on: OpenZwave +# Home Assistant Add-on: OpenZWave ## Installation Follow these steps to get the add-on installed on your system: 1. Navigate in your Home Assistant frontend to **Supervisor** -> **Add-on Store**. -2. Find the "OpenZwave" add-on and click it. +2. Find the "OpenZWave" add-on and click it. 3. Click on the "INSTALL" button. +4. This add-on currently requires to have the Mosquitto add-on installed. + Please make sure to install and set up that add-on before continuing. ## How to use +The add-on needs to know where your Z-Wave stick can be found, and therefore, +you'll need to configure the add-on to point to the right device. + +If you're using Home Assistant you may find the correct value for this on the +`Supervisor -> System -> Host system -> Hardware` page. It is recommended +to use a "by-id" path to the device if one exists, as it is not subject to +change if other devices are added to the system. + +1. Replace `null` in the `device` option in the add-on configuration and specify + the device name in quotes: e.g., something like + `"/dev/serial/by-id/usb-0658_0200-if00"`, + `"/dev/ttyUSB0"`, `"/dev/ttyAMA0"`, or `"/dev/ttyACM0"`. +2. Set your 16-byte network key in the form `0x01, 0x02...` used in order to + connect securely to compatible devices. It is recommended that a network key + is configured as security enabled devices may not function correctly if they + are not added securely. +3. Click on "SAVE" to save the add-on configuration. +4. Start the add-on. +5. Add the OpenZWave integration to Home Assistant, see documentation: + + +After installing and starting this add-on, access the ozw-admin interface using +the "OPEN WEBUI" button. + ## Configuration Add-on configuration: ```yaml device: /dev/ttyUSB0 -network_key: +network_key: 0x2e, 0xcc, 0xab, 0x1c, 0xa3, 0x7f, 0x0e, 0xb5, 0x70, 0x71, 0x2d, 0x98, 0x25, 0x43, 0xee, 0x0c instance: 1 ``` ### Option `device` +The device address of your Z-Wave controller. + +If you're using Home Assistant you may find the correct value for this on the +`Supervisor -> System -> Host system -> Hardware` page. It is recommended +to use a "by-id" path to the device if one exists, as it is not subject to +change if other devices are added to the system. + +In most cases this looks like one of the following: + +- `"/dev/serial/by-id/usb-0658_0200-if00"` +- `"/dev/ttyUSB0"` +- `"/dev/ttyAMA0"` +- `"/dev/ttyACM0"` ### Option `network_key` +Security Z-Wave devices require a network key before being added to the network. +You must set the `network_key` configuration option to use a network key before +adding these devices. -### Option `instance` +To generate a network key, you can use the following script in, e.g., the SSH +add-on: -Zwave instance number as reported to MQTT. This corresponds with the +```bash +cat /dev/urandom | tr -dc '0-9A-F' | fold -w 32 | head -n 1 | sed -e 's/\(..\)/0x\1, /g' -e 's/, $//' +``` + +You can also use sites like this one to generate the required data, +just remember to put `0x` before each pair of characters: + + + +Ensure you keep a backup of this key. If you have to rebuild your system and +don't have a backup of this key, you won't be able to reconnect to any security +devices. This may mean you have to do a factory reset on those devices, and your +controller, before rebuilding your Z-Wave network. + +### Option `instance` (optional) + +Z-Wave instance number as reported to MQTT. This corresponds with the `instance_id` attribute of `ozw` services in Home Assistant. +The instance ID defaults to `1`, which is generally fine to keep and use. +Only change this in case you are using multiple instances on the same MQTT +server. + +## Accessing the ozw-admin application + +The add-on allows you to access the underlying ozw-admin application running +in this add-on. This allows you to view, configure and control your Z-Wave +network and its devices. + +### Accessing the ozw-admin application via Ingress + +You can access the built-in ozw-admin application directly via Home Assistant +Ingress. Click on the "OPEN WEBUI" button to access it. + +If it does not auto connect to your Z-Wave network automatically: +Click on the "Open" button in the menu bar of the application and click on +the start button in the **"Remote OZWDaemon"** section. + +If you need to access the application more often, it can be added to the +Home Assistant sidebar by toggling the "Show in sidebar" switch on the +add-on page. + +### Accessing the ozw-admin application via VNC + +You can access the built-in ozw-admin application via a VNC viewer. + +Please note, you can access the same interface using the "OPEN WEBUI" button, +described above. + +To enable it: + +- Set a port number for VNC in the "Network" configuration section of the + add-on and hit "SAVE". Advised is to use port 5900, but any other port above + 5900 works as well. +- Restart the add-on. + +To access it, you need a [VNC Viewer][vnc-viewer] application. If you are using +macOS, you are in luck, since VNC is built-in. Open the spotlight search and +enter the VNC service URL. + +The VNC service URL looks like [vnc://homeassistant.local:5900](vnc-service-url). +Adjust port and possibly hostname if you've changed it in Home Assistant host system +settings. + +### Connecting remotely using a local ozw-admin application + +Alternatively, the ozw-admin application can be downloaded and installed on a +remote machine, like your desktop computer. To connect your remote machine: + +- Set a port number for the ozw-admin in the "Network" configuration section of + the add-on and hit "SAVE". Advised is to use port 1983, as this is the default. +- Restart the add-on. + +To access your Z-Wave network with the ozw-admin, you need to first download the ozw-admin application. The latest +version can be found here: + + + +After you've installed and started the ozw-admin application, click "Open" +and set the remote host and port in the "Remote OZWDaemon" section. +For example, host: `homeassistant.local`, with port `1983` in the second field. + +Next, click on "Start" to connect. ## Known issues and limitations -- You hardware need to be compatible with OpenZwave library +- Your hardware needs to be compatible with OpenZWave library ## Support @@ -48,9 +171,9 @@ You have several options to get them answered: In case you've found a bug, please [open an issue on our GitHub][issue]. - - [discord]: https://discord.gg/c5DvZ4e [forum]: https://community.home-assistant.io [issue]: https://github.com/home-assistant/hassio-addons/issues [reddit]: https://reddit.com/r/homeassistant +[vnc-service-url]: vnc://homeassistant.local:5900 +[vnc-viewer]: https://bintray.com/tigervnc/stable/tigervnc/ diff --git a/zwave/Dockerfile b/zwave/Dockerfile index 99dd816..e5de41d 100644 --- a/zwave/Dockerfile +++ b/zwave/Dockerfile @@ -1,67 +1,90 @@ ARG BUILD_FROM FROM ${BUILD_FROM} -# Install QT Open Z-Wave -WORKDIR /usr/src +ENV QT_ASSUME_STDERR_HAS_CONSOLE=1 + ARG OZW_VERSION -ARG QTOZW_VERSION ARG QTMQTT_VERSION +ARG QTOZW_VERSION +ARG QTOZWADMIN_VERSION ARG QTWEBSOCKETS_VERSION +# Install QT Open Z-Wave +WORKDIR /usr/src RUN \ apk add --no-cache \ eudev-libs \ + fontconfig \ + mosquitto \ + openssl \ + pwgen \ qt5-qtbase \ qt5-qtremoteobjects \ - openssl \ - coreutils \ + qt5-qtsvg \ rapidjson \ - mosquitto \ - libcurl \ - pwgen \ + ttf-freefont \ && apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/main \ libunwind \ libunwind-dev \ + && apk add --no-cache --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing \ + novnc \ + websockify \ && apk add --no-cache --virtual .build-dependencies \ + binutils \ build-base \ cmake \ + coreutils \ + curl-dev \ eudev-dev \ git \ + openssl-dev \ qt5-qtbase-dev \ qt5-qtremoteobjects-dev \ - openssl-dev \ + qt5-qtsvg-dev \ rapidjson-dev \ - curl-dev \ \ && git clone --depth 1 -b \ ${QTWEBSOCKETS_VERSION} https://github.com/qt/qtwebsockets /usr/src/qtwebsockets \ && cd /usr/src/qtwebsockets \ && /usr/lib/qt5/bin/qmake QT_BUILD_PARTS="libs tools" \ - && make \ + && make -j $(( $(nproc) + 1 )) \ && make install \ \ && git clone --depth 1 -b \ ${QTMQTT_VERSION} https://github.com/qt/qtmqtt /usr/src/qtmqtt \ && cd /usr/src/qtmqtt \ - && /usr/lib/qt5/bin/qmake QT_BUILD_PARTS="libs tools" \ - && make \ + && /usr/lib/qt5/bin/qmake CONFIG+=release QT_BUILD_PARTS="libs tools" \ + && make -j $(( $(nproc) + 1 )) \ && make install \ \ && git clone \ https://github.com/OpenZWave/open-zwave /usr/src/ozw \ && cd /usr/src/ozw \ && git checkout ${OZW_VERSION} \ - && make \ + && make -j $(( $(nproc) + 1 )) \ && make install \ \ && git clone \ https://github.com/OpenZWave/qt-openzwave /usr/src/qtozw \ && cd /usr/src/qtozw \ && git checkout ${QTOZW_VERSION} \ - && /usr/lib/qt5/bin/qmake \ - && make \ + && /usr/lib/qt5/bin/qmake -r CONFIG+=release \ + && make -j $(( $(nproc) + 1 )) \ && make install \ \ + && git clone \ + https://github.com/OpenZWave/ozw-admin.git /usr/src/ozw-admin \ + && cd /usr/src/ozw-admin \ + && git checkout ${QTOZWADMIN_VERSION} \ + && /usr/lib/qt5/bin/qmake -r CONFIG+=release \ + && make -j $(( $(nproc) + 1 )) \ + && make install \ + \ + && strip --remove-section=.note.ABI-tag /usr/lib/libQt5Core.so \ + \ + && mkdir -p /usr/share/OpenZWave \ + && mv /usr/share/qt5/qt-openzwavedatabase.rcc /usr/share/OpenZWave/ \ + \ && apk del --no-cache \ .build-dependencies \ libunwind-dev \ diff --git a/zwave/README.md b/zwave/README.md index cea5832..22a7817 100644 --- a/zwave/README.md +++ b/zwave/README.md @@ -1,4 +1,4 @@ -# Home Assistant Add-on: OpenZwave +# Home Assistant Add-on: OpenZWave Allow Home Assistant to talk to a Z-Wave Network via a USB Controller. diff --git a/zwave/build.json b/zwave/build.json index 3db727f..6fb4fb6 100644 --- a/zwave/build.json +++ b/zwave/build.json @@ -7,8 +7,9 @@ "aarch64": "homeassistant/aarch64-base:3.11" }, "args": { - "OZW_VERSION": "1d7f512f3bb9b304fae25fafaf6d3073956b7210", - "QTOZW_VERSION": "41609866979aa3c8da18f4bfb5ffe989675afd8f", + "OZW_VERSION": "d2de6990389888850e936894080e4096c822e379", + "QTOZW_VERSION": "337e48807568e4e7f90d3b8441cc126c9e057cde", + "QTOZWADMIN_VERSION": "18f15f411f9429ba7c5d321329a87f725f22cf7a", "QTMQTT_VERSION": "5.12.8", "QTWEBSOCKETS_VERSION": "5.12.8" } diff --git a/zwave/config.json b/zwave/config.json index 6c13c70..d30d298 100644 --- a/zwave/config.json +++ b/zwave/config.json @@ -1,20 +1,26 @@ { - "name": "OpenZwave", - "version": "0.3.0", + "name": "OpenZWave", + "version": "0.4.0", "slug": "zwave", "description": "Control a ZWave network with Home Assistant", "arch": ["amd64", "i386", "armhf", "armv7", "aarch64"], "url": "https://github.com/home-assistant/hassio-addons/tree/master/zwave", + "ingress": true, + "ingress_entry": "vnc_lite.html", + "panel_icon": "mdi:z-wave", + "panel_title": "OpenZWave", "startup": "services", "boot": "auto", "init": false, "stage": "experimental", "homeassistant": "0.110.0.dev", "ports": { - "1983/tcp": null + "1983/tcp": null, + "5900/tcp": null }, "ports_description": { - "1983/tcp": "ozw-admin port" + "1983/tcp": "ozw-admin port", + "5900/tcp": "VNC port" }, "services": ["mqtt:want"], "discovery": ["ozw"], diff --git a/zwave/icon.png b/zwave/icon.png new file mode 100644 index 0000000..65dfc13 Binary files /dev/null and b/zwave/icon.png differ diff --git a/zwave/logo.png b/zwave/logo.png new file mode 100644 index 0000000..6f55d12 Binary files /dev/null and b/zwave/logo.png differ diff --git a/zwave/rootfs/etc/cont-init.d/network_key.sh b/zwave/rootfs/etc/cont-init.d/network_key.sh new file mode 100644 index 0000000..7a91ab1 --- /dev/null +++ b/zwave/rootfs/etc/cont-init.d/network_key.sh @@ -0,0 +1,9 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Check to see if example network key from documentation is used +# ============================================================================== +readonly DOCS_EXAMPLE_KEY="0x2e, 0xcc, 0xab, 0x1c, 0xa3, 0x7f, 0x0e, 0xb5, 0x70, 0x71, 0x2d, 0x98, 0x25, 0x43, 0xee, 0x0c" + +if [[ "${DOCS_EXAMPLE_KEY}" == "$(bashio::config 'network_key')" ]]; then + bashio::exit.nok "Network key from the example documentation used. Please create an unique one!" +fi diff --git a/zwave/rootfs/etc/cont-init.d/novnc.sh b/zwave/rootfs/etc/cont-init.d/novnc.sh new file mode 100644 index 0000000..bc2fcb7 --- /dev/null +++ b/zwave/rootfs/etc/cont-init.d/novnc.sh @@ -0,0 +1,7 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Setup noVNC +# ============================================================================== +declare ingress_entry +ingress_entry=$(bashio::addon.ingress_entry) +sed -i "s#websockify#${ingress_entry#?}/websockify#g" /usr/share/novnc/vnc_lite.html diff --git a/zwave/rootfs/etc/cont-init.d/structure.sh b/zwave/rootfs/etc/cont-init.d/structure.sh index 210301f..0f1a09d 100644 --- a/zwave/rootfs/etc/cont-init.d/structure.sh +++ b/zwave/rootfs/etc/cont-init.d/structure.sh @@ -2,5 +2,4 @@ # ============================================================================== # Setup folder structure # ============================================================================== - mkdir -p /data/ozw/config diff --git a/zwave/rootfs/etc/services.d/mosquitto/run b/zwave/rootfs/etc/services.d/mosquitto/run index 9b7bd1d..d4e8fbe 100644 --- a/zwave/rootfs/etc/services.d/mosquitto/run +++ b/zwave/rootfs/etc/services.d/mosquitto/run @@ -2,6 +2,6 @@ # ============================================================================== # Start mosquitto service for communication # ============================================================================== -bashio::log.info "Starting internal mqtt broker..." +bashio::log.info "Starting internal MQTT broker..." exec mosquitto -c /etc/mosquitto.conf diff --git a/zwave/rootfs/etc/services.d/ozwadmin/finish b/zwave/rootfs/etc/services.d/ozwadmin/finish new file mode 100644 index 0000000..698a9da --- /dev/null +++ b/zwave/rootfs/etc/services.d/ozwadmin/finish @@ -0,0 +1,8 @@ +#!/usr/bin/execlineb -S1 +# ============================================================================== +# Take down the S6 supervision tree when ozw-admin fails +# ============================================================================== +if { s6-test ${1} -ne 0 } +if { s6-test ${1} -ne 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/zwave/rootfs/etc/services.d/ozwadmin/run b/zwave/rootfs/etc/services.d/ozwadmin/run new file mode 100644 index 0000000..bba39be --- /dev/null +++ b/zwave/rootfs/etc/services.d/ozwadmin/run @@ -0,0 +1,16 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Start ozw-admin +# ============================================================================== +OZW_CONFIG=/data/ozw/config + +# Wait until ozw is up and running +bashio::net.wait_for 1983 +bashio::log.info "Starting ozw-admin..." + +cd /data/ozw || bashio::exit.nok "Could not change to OZW working directory" +exec ozwadmin \ + -platform vnc:size=1024x768:port=5900 \ + —-host "localhost:1983" \ + --config-dir "${OZW_CONFIG}" \ + --user-dir "${OZW_CONFIG}" diff --git a/zwave/rootfs/etc/services.d/websockify/finish b/zwave/rootfs/etc/services.d/websockify/finish new file mode 100644 index 0000000..585d778 --- /dev/null +++ b/zwave/rootfs/etc/services.d/websockify/finish @@ -0,0 +1,8 @@ +#!/usr/bin/execlineb -S1 +# ============================================================================== +# Take down the S6 supervision tree when websockify fails +# ============================================================================== +if { s6-test ${1} -ne 0 } +if { s6-test ${1} -ne 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/zwave/rootfs/etc/services.d/websockify/run b/zwave/rootfs/etc/services.d/websockify/run new file mode 100644 index 0000000..1975096 --- /dev/null +++ b/zwave/rootfs/etc/services.d/websockify/run @@ -0,0 +1,10 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Start ozw-admin +# ============================================================================== + +# Wait until ozwadmin is up and running +bashio::net.wait_for 5900 +bashio::log.info "Starting websockify..." + +exec websockify --web /usr/share/novnc/ 8099 127.0.0.1:5900 diff --git a/zwave/rootfs/etc/services.d/zwave/discovery b/zwave/rootfs/etc/services.d/zwave/discovery old mode 100644 new mode 100755 index 55e278a..f159a8d --- a/zwave/rootfs/etc/services.d/zwave/discovery +++ b/zwave/rootfs/etc/services.d/zwave/discovery @@ -10,7 +10,7 @@ ha_config=$(\ host "$(hostname)" \ port "^1883" \ username "homeassistant" \ - password $(bashio::jq /data/auth.json ".homeassistant_password") \ + password "$(bashio::jq /data/auth.json '.homeassistant_password')" \ ) if bashio::discovery "ozw" "${ha_config}" > /dev/null; then diff --git a/zwave/rootfs/etc/services.d/zwave/finish b/zwave/rootfs/etc/services.d/zwave/finish index 32960a6..20a8bb8 100644 --- a/zwave/rootfs/etc/services.d/zwave/finish +++ b/zwave/rootfs/etc/services.d/zwave/finish @@ -1,6 +1,6 @@ #!/usr/bin/execlineb -S1 # ============================================================================== -# Take down the S6 supervision tree when OpenZwave fails +# Take down the S6 supervision tree when OpenZWave fails # ============================================================================== if { s6-test ${1} -ne 0 } if { s6-test ${1} -ne 256 } diff --git a/zwave/rootfs/etc/services.d/zwave/run b/zwave/rootfs/etc/services.d/zwave/run index 82bccde..b8f42bb 100644 --- a/zwave/rootfs/etc/services.d/zwave/run +++ b/zwave/rootfs/etc/services.d/zwave/run @@ -1,25 +1,30 @@ #!/usr/bin/with-contenv bashio # ============================================================================== -# Start OpenZwave service for zwave radio +# Start OpenZWave service for zwave radio # ============================================================================== -OZW_CONFIG=/data/ozw/config -OZW_NETWORK_KEY=$(bashio::config 'network_key') -OZW_DEVICE=$(bashio::config 'device') -bashio::config.has_value 'instance' \ - && OZW_INSTANCE="$(bashio::config 'instance')" || OZW_INSTANCE=1 +export MQTT_PASSWORD +export OZW_NETWORK_KEY -MQTT_PASSWORD="$(bashio::jq /data/auth.json ".ozw_password")" +MQTT_PASSWORD="$(bashio::jq /data/auth.json '.ozw_password')" +OZW_CONFIG=/data/ozw/config +OZW_DEVICE=$(bashio::config 'device') +OZW_INSTANCE=1 +OZW_NETWORK_KEY=$(bashio::config 'network_key') + +# Set custom instance ID if configured +if bashio::config.has_value 'instance'; then + OZW_INSTANCE=$(bashio::config 'instance') +fi # Wait until mosqitto is up and running -bashio::log.info "Starting OpenZwave..." +bashio::log.info "Starting OpenZWave..." bashio::net.wait_for 1883 # Send out discovery information to Home Assistant ./discovery & # Run daemon -export OZW_NETWORK_KEY -export MQTT_PASSWORD +cd /data/ozw || bashio::exit.nok "Could not change to OZW working directory" exec ozwdaemon \ -s "${OZW_DEVICE}" \ --config-dir "${OZW_CONFIG}" \