diff --git a/deconz/CHANGELOG.md b/deconz/CHANGELOG.md index 1527f98..bd435f9 100644 --- a/deconz/CHANGELOG.md +++ b/deconz/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 4.0 + +- Bump deCONZ to 2.05.72 +- Add support for Hass.io Ingress +- Improve auto discovery handling +- Remove support for UPnP + ## 3.9 - Adds support for enabling UPnP diff --git a/deconz/Dockerfile b/deconz/Dockerfile index a58239c..0c15e57 100644 --- a/deconz/Dockerfile +++ b/deconz/Dockerfile @@ -22,6 +22,7 @@ RUN apt-get update \ libqt5widgets5 \ lsof \ netcat \ + nginx \ sqlite3 \ tigervnc-common \ tigervnc-standalone-server \ @@ -54,7 +55,8 @@ RUN if [ "${BUILD_ARCH}" = "armhf" ]; \ && chown root:root /usr/bin/deCONZ* \ && sed -i 's/\/root/\/data/' /etc/passwd -COPY data/run.sh data/discovery.sh / COPY data/ika-otau-dl.sh /bin/ +COPY data/nginx.conf /etc/nginx/nginx.conf +COPY data/run.sh data/discovery.sh / CMD ["/run.sh"] diff --git a/deconz/README.md b/deconz/README.md index 514de6a..84d0f93 100644 --- a/deconz/README.md +++ b/deconz/README.md @@ -37,7 +37,8 @@ If you're using Hass.io you may find the correct value for this on the 1. Replace `null` in the `device` option in the add-on configuration and specify the device name in quotes: (e.g. `"/dev/ttyUSB0"`, `"/dev/ttyAMA0"`, or `"/dev/ttyACM0"`). 2. Click on "SAVE" to save the add-on configuration. -3. Start the add-on. +3. Toggle the "Show in sidebar" to add it to your Home Assistant side bar. +4. Start the add-on. After installing and starting this add-on, access the deCONZ WebUI ("Phoscon") with "WEB UI" button. @@ -122,25 +123,6 @@ Example add-on config with `dbg_aps` enabled on log level 1: } ``` -## Enabling UPnP - -The add-on, by default, disables the native UPnP functionality of deCONZ. -This is because the add-on uses an alternative discovery mechanism that allows -for an improved integration experience. - -Nevertheless, the add-on allows you to enable UPnP again, in case you want -deCONZ to be discovered by other applications (that are not Home Assistant). - -Add the `upnp` add-on option, and set it to `true` to enable UPnP: - -```json -{ - "device": "/dev/ttyUSB0", - "vnc_password": "", - "upnp": true -} -``` - ## Configuration Add-on configuration: @@ -168,6 +150,7 @@ In most cases this is one of the following: - Use at least 2.5A power supply for your Raspberry Pi! This avoids strange behavior when using this add-on. +- The add-on has no UPnP support. UPnP interferes with Ingress. ## Support diff --git a/deconz/build.json b/deconz/build.json index 7d43027..58a56f0 100644 --- a/deconz/build.json +++ b/deconz/build.json @@ -5,6 +5,6 @@ "armhf": "homeassistant/armhf-base-raspbian:stretch" }, "args": { - "DECONZ_VERSION": "2.05.71" + "DECONZ_VERSION": "2.05.72" } } diff --git a/deconz/config.json b/deconz/config.json index 5f159ec..36c8a8a 100644 --- a/deconz/config.json +++ b/deconz/config.json @@ -1,26 +1,23 @@ { "name": "deCONZ", - "version": "3.9", + "version": "4.0", "slug": "deconz", "description": "Control a ZigBee network with ConBee or RaspBee by Dresden Elektronik", "arch": ["amd64", "armhf", "aarch64"], "url": "https://github.com/home-assistant/hassio-addons/tree/master/deconz", "startup": "system", "boot": "auto", + "ingress": true, + "ingress_entry": "pwa/index.html", + "panel_icon": "mdi:zigbee", "homeassistant": "0.91.2", - "webui": "http://[HOST]:[PORT:80]/pwa/index.html", "discovery": ["deconz"], "ports": { - "80/tcp": 40850, - "5900/tcp": null, - "8080/tcp": 40860 + "5900/tcp": null }, "ports_description": { - "80/tcp": "deCONZ API backend", - "5900/tcp": "deCONZ graphical desktop via VNC", - "8080/tcp": "deCONZ WebSocket Server" + "5900/tcp": "deCONZ graphical desktop via VNC" }, - "host_network": true, "kernel_modules": true, "auto_uart": true, "udev": true, @@ -39,8 +36,7 @@ "dbg_info": "int?", "dbg_otau": "int?", "dbg_zcl": "int?", - "dbg_zdp": "int?", - "upnp": "bool?" + "dbg_zdp": "int?" }, "image": "homeassistant/{arch}-addon-deconz" } diff --git a/deconz/data/discovery.sh b/deconz/data/discovery.sh index 5b4d91c..5126c21 100644 --- a/deconz/data/discovery.sh +++ b/deconz/data/discovery.sh @@ -3,73 +3,66 @@ DATA_STORE="/data/hassio.json" -function _discovery_config() { - local api_key=${1} - local serial=${2} - local config - - config=$(bashio::var.json \ - host "$(bashio::addon.ip_address)" \ - port "^$(bashio::addon.port 80)" \ - api_key "${api_key}" \ - serial "${serial}" \ - ) - - bashio::var.json \ - service deconz \ - config "^${config}" -} - - -function _save_data() { - local api_key=${1} - local serial=${2} - local config - - bashio::var.json api_key "${api_key}" serial "${serial}" > ${DATA_STORE} - bashio::log.debug "Store API information to ${DATA_STORE}" -} - - function _deconz_api() { local api_key local result - local api_port + local serial - api_port=$(bashio::addon.port 80) - while ! nc -z localhost "${api_port}" < /dev/null; do sleep 10; done - - if ! result="$(curl --silent --show-error --request POST -d '{"devicetype": "Home Assistant"}' "http://127.0.0.1:${api_port}/api")"; then + # Register an API key for Home Assistant + if ! result="$(curl --silent --show-error --request POST -d '{"devicetype": "Home Assistant"}' "http://127.0.0.1:8080/api")"; then bashio::log.debug "${result}" bashio::exit.nok "Can't get API key from deCONZ gateway" fi - api_key="$(echo "${result}" | jq --raw-output '.[0].success.username')" + api_key="$(bashio::jq "${result}" '.[0].success.username')" - sleep 15 - if ! result="$(curl --silent --show-error --request GET "http://127.0.0.1:${api_port}/api/${api_key}/config")"; then - bashio::log.debug "${result}" - bashio::exit.nok "Can't get data from deCONZ gateway" - fi - serial="$(echo "${result}" | jq --raw-output '.bridgeid')" + # Try to get the bridge ID/serial, try to avoid using 0000000000000000 + retries=25 + serial="0000000000000000" + while [[ "${serial}" = "0000000000000000" ]]; do + bashio::log.debug "Waiting for bridge ID..." + sleep 10 - _save_data "${api_key}" "${serial}" + # If we tried 25 times, just abort. + if [[ "${retries}" -eq 0 ]]; then + bashio::exit.nok "Failed to get a valid bridge ID. Discovery aborted." + fi + + # Get bridge ID from API + if ! result="$(curl --silent --show-error --request GET "http://127.0.0.1:8080/api/${api_key}/config")"; + then + bashio::log.debug "${result}" + bashio::exit.nok "Can't get data from deCONZ gateway" + fi + serial="$(bashio::jq "${result}" '.bridgeid')" + + ((retries--)) + done + + bashio::var.json api_key "${api_key}" serial "${serial}" > "${DATA_STORE}" + bashio::log.debug "Stored API information to ${DATA_STORE}" } function _send_discovery() { local api_key + local config local result - local payload - api_key="$(jq --raw-output '.api_key' "${DATA_STORE}")" - serial="$(jq --raw-output '.serial' "${DATA_STORE}")" + api_key="$(bashio::jq "${DATA_STORE}" '.api_key')" + serial="$(bashio::jq "${DATA_STORE}" '.serial')" + + config=$(bashio::var.json \ + host "$(hostname)" \ + port "^8080" \ + api_key "${api_key}" \ + serial "${serial}" \ + ) # Send discovery info - payload="$(_discovery_config "${api_key}" "${serial}")" - if bashio::api.hassio "POST" "/discovery" "${payload}"; then - bashio::log.info "Success send discovery information to Home Assistant" + if bashio::discovery "deconz" "${config}" > /dev/null; then + bashio::log.info "Successfully send discovery information to Home Assistant." else - bashio::log.error "Discovery message to Home Assistant fails!" + bashio::log.error "Discovery message to Home Assistant failed!" fi } @@ -77,7 +70,7 @@ function _send_discovery() { function hassio_discovery() { # No API data exists - generate - if [ ! -f "$DATA_STORE" ]; then + if ! bashio::fs.file_exists "${DATA_STORE}"; then bashio::log.info "Create API data for Home Assistant" _deconz_api fi diff --git a/deconz/data/nginx.conf b/deconz/data/nginx.conf new file mode 100644 index 0000000..1b5d507 --- /dev/null +++ b/deconz/data/nginx.conf @@ -0,0 +1,62 @@ +worker_processes 1; +pid /var/run/nginx.pid; +error_log /dev/stdout info; +daemon off; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + proxy_read_timeout 1200; + gzip on; + gzip_disable "msie6"; + resolver 127.0.0.11; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + # Ingress + server { + listen 8099 default_server; + + allow 172.30.32.2; + deny all; + + server_name _; + access_log /dev/stdout combined; + + client_max_body_size 4G; + keepalive_timeout 5; + + root /dev/null; + + # The websocket isn't used yet. This is a stub for the future. + location /api/websocket { + proxy_pass http://localhost:8081; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + + location / { + proxy_redirect off; + proxy_pass http://localhost:8080; + + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_set_header X-NginX-Proxy true; + } + } +} \ No newline at end of file diff --git a/deconz/data/run.sh b/deconz/data/run.sh index 5ecda07..1a6f635 100755 --- a/deconz/data/run.sh +++ b/deconz/data/run.sh @@ -16,14 +16,9 @@ WAIT_PIDS=() # Default QT platform PLATFORM="minimal" -# Load config -DECONZ_DEVICE=$(bashio::config 'device') -API_PORT=$(bashio::addon.port 80) -VNC_PORT=$(bashio::addon.port 5900) -VNC_PASSWORD=$(bashio::config 'vnc_password') -WEBSOCKET_PORT=$(bashio::addon.port 8080) - # Lookup udev link +bashio::log.info "Waiting for device..." +DECONZ_DEVICE=$(bashio::config 'device') if [[ -c "${DECONZ_DEVICE}" ]]; then bashio::log.debug "Specified device points to a character special file, continuing" else @@ -53,32 +48,13 @@ bashio::config.has_value 'dbg_zcl' \ bashio::config.has_value 'dbg_zdp' \ && DBG_ZDP="$(bashio::config 'dbg_zdp')" || DBG_ZDP=0 -# Handle UPNP -bashio::config.true 'upnp' \ - && UPNP=1 || UPNP=0 - -# Check if port is available -if bashio::var.is_empty "${API_PORT}" \ - || bashio::var.is_empty "${WEBSOCKET_PORT}"; -then - bashio::exit.nok "You need set API and Websocket port!" -fi - # Check if VNC is enabled +VNC_PORT="$(bashio::addon.port 5900)" if bashio::var.has_value "${VNC_PORT}"; then - if [[ "${VNC_PORT}" -lt 5900 ]]; then - bashio::exit.nok "VNC requires the port number to be set to 5900 or higher!" - fi - - # Check if configured VNC port is free - if nc -z 127.0.0.1 "${VNC_PORT}"; then - bashio::log.fatal "VNC port ${VNC_PORT} is already in use!" - bashio::exit.nok "Please change the port number" - fi TMP_FOLDER=$(mktemp -d) export XDG_RUNTIME_DIR="${TMP_FOLDER}" - export DISPLAY=":$((VNC_PORT-5900))" + export DISPLAY=":0" PLATFORM="xcb" # Require password when VNC is enabled @@ -87,6 +63,7 @@ if bashio::var.has_value "${VNC_PORT}"; then fi bashio::log.info "Starting VNC server..." + VNC_PASSWORD=$(bashio::config 'vnc_password') echo "${VNC_PASSWORD}" | tigervncpasswd -f > /root/.vncpasswd tigervncserver \ -name "Hass.io - deCONZ" \ @@ -108,19 +85,19 @@ deCONZ \ --dbg-otau="${DBG_OTAU}" \ --dbg-zcl="${DBG_ZCL}" \ --dbg-zdp="${DBG_ZDP}" \ - --http-port="${API_PORT}" \ - --ws-port="${WEBSOCKET_PORT}" \ - --upnp="${UPNP}" \ + --upnp=0 \ + --http-port=8080 \ + --ws-port=8081 \ --dev="${DECONZ_DEVICE}" & WAIT_PIDS+=($!) -# Start OTA updates for deCONZ -bashio::log.info "Running the deCONZ OTA updater..." -deCONZ-otau-dl.sh &> /dev/null & +# Wait for deCONZ to start before continuing +bashio::net.wait_for 8080 -# Start OTA updates for IKEA -bashio::log.info "Running the IKEA OTA updater..." -ika-otau-dl.sh &> /dev/null & +# Start Nginx proxy +bashio::log.info "Starting Nginx..." +nginx & +WAIT_PIDS+=($!) # Register stop function stop_addon() { @@ -134,7 +111,15 @@ trap "stop_addon" SIGTERM SIGHUP # Start Hass.io discovery bashio::log.info "Running Hass.io discovery task..." -hassio_discovery +hassio_discovery & + +# Start OTA updates for deCONZ +bashio::log.info "Running the deCONZ OTA updater..." +deCONZ-otau-dl.sh &> /dev/null & + +# Start OTA updates for IKEA +bashio::log.info "Running the IKEA OTA updater..." +ika-otau-dl.sh &> /dev/null & # Wait until all is done bashio::log.info "deCONZ is set up and running!"