deCONZ ingress & discovery (#561)

* Migrate deconz to ingress/discovery

* update chmod

* Add discovery

* Fix lint

* Fix typo

* Bump versio 0.91.2

* Fix discovery

* Cleanup config

* Fix discovery

* Fix url

* Fix port

* Fix script

* Support new host config

* Use new network feature

* add notes

* Fix shell

* simplify v1

* Cleanup

* Fix api port access

* Remove waiting

* Use more modern version

* Fix lint

* Add a note to ingress phoscon app

* fix format

* Fix ingress

* Fix ingress

* Fix output

* Change flow

* Fix wait port

* Fix config

* Add tiemout

* Cleanup
This commit is contained in:
Pascal Vizeli
2019-04-11 14:49:36 +02:00
committed by GitHub
parent 1bbe315d3e
commit 9aa2ad8c87
10 changed files with 287 additions and 86 deletions

View File

@@ -1,19 +1,31 @@
# Changelog
## 2.0
- Add support for Home Assistant Add-on integration
- Add Ingress support
**WARNING:** This version change the network modus to host network that it works with mobile apps from deCONZ. That mean you need remove the old integration and connect it again. 2min after first Startup, the Add-on provide a own Discovery details to Home Assistant.
## 1.4
- Bump deCONZ to 2.05.59
- Remove the fake aarch64 version in favor of new arch selector
## 1.3
- Bump deCONZ to 2.05.58
- Support now Firmware updates over the Phoscon UI
## 1.2
- Bump deCONZ to 2.05.57
## 1.1
- Bump deCONZ to 2.05.55
## 1.0
- Initial release as Home Assistant core Add-on
- Bump deCONZ to 2.05.54

View File

@@ -5,10 +5,12 @@ FROM $BUILD_FROM
ARG BUILD_ARCH
RUN apt-get update \
&& apt-get install -y \
nginx \
curl \
kmod \
lsof \
tzdata \
netcat \
libcap2-bin \
libqt5core5a \
libqt5gui5 \
@@ -40,7 +42,8 @@ RUN if [ "${BUILD_ARCH}" = "armhf" ] || [ "${BUILD_ARCH}" = "aarch64" ]; \
&& chown root:root /usr/bin/deCONZ* \
&& sed -i 's/\/root/\/data/' /etc/passwd
COPY run.sh /
COPY ika-otau-dl.sh /bin/
COPY data/run.sh data/discovery.sh /
COPY data/ika-otau-dl.sh /bin/
COPY data/nginx.conf /etc/nginx/ingress.conf
CMD ["/run.sh"]

View File

@@ -2,6 +2,8 @@
Add-on to allow Home Assistant to control a ZigBee network with Conbee or RaspBee hardware by Dresden Elektronik.
**Note:** The Ingress support allow to load the Phoscon APP external of the Network, but they discovery only device inside same Network. That is a limitation of Phoscon APP and not Ingress itself.
## First Steps
If using RaspBee, you may need to edit `config.txt` on the root of your SD card for your RaspBee to be recognized and assigned a device name. Add folling information to `config.txt`:

View File

@@ -1,9 +1,9 @@
{
"build_from": {
"amd64": "homeassistant/amd64-base-ubuntu:18.04",
"armhf": "homeassistant/armhf-base-raspbian:stretch"
},
"args": {
"DECONZ_VERSION": "2.05.59"
}
"build_from": {
"amd64": "homeassistant/amd64-base-ubuntu:18.04",
"armhf": "homeassistant/armhf-base-raspbian:stretch"
},
"args": {
"DECONZ_VERSION": "2.05.59"
}
}

View File

@@ -1,34 +1,44 @@
{
"name": "deCONZ",
"version": "1.4",
"slug": "deconz",
"description": "Control a ZigBee network with Conbee or RaspBee by Dresden Elektronik",
"arch": ["amd64", "armhf"],
"url": "https://home-assistant.io/addons/deconz",
"startup": "system",
"boot": "auto",
"webui": "http://[HOST]:[PORT:80]",
"ports": {
"80/tcp": 9880,
"8080/tcp": 9881
},
"kernel_modules": true,
"auto_uart": true,
"gpio": true,
"apparmor": false,
"privileged": [
"SYS_MODULE",
"SYS_RAWIO"
],
"devices": [
"/dev/bus/usb:/dev/bus/usb:rwm",
"/dev/mem:/dev/mem:rw"
],
"options": {
"device": null
},
"schema": {
"device": "str"
},
"image": "homeassistant/{arch}-addon-deconz"
"name": "deCONZ",
"version": "2.0",
"slug": "deconz",
"description": "Control a ZigBee network with Conbee or RaspBee by Dresden Elektronik",
"arch": ["amd64", "armhf"],
"url": "https://home-assistant.io/addons/deconz",
"startup": "system",
"boot": "auto",
"homeassistant": "0.91.2",
"webui": "http://[HOST]:[PORT:80]/pwa",
"ingress": true,
"ingress_port": 0,
"ingress_entry": "pwa/index.html",
"discovery": ["deconz"],
"ports": {
"80/tcp": 40850,
"8080/tcp": 40860
},
"ports_description": {
"80/tcp": "deCONZ API backend",
"8080/tcp": "deCONZ WebSocket Server"
},
"host_network": true,
"kernel_modules": true,
"auto_uart": true,
"gpio": true,
"apparmor": false,
"privileged": [
"SYS_MODULE",
"SYS_RAWIO"
],
"devices": [
"/dev/bus/usb:/dev/bus/usb:rwm",
"/dev/mem:/dev/mem:rw"
],
"options": {
"device": null
},
"schema": {
"device": "str"
},
"image": "homeassistant/{arch}-addon-deconz"
}

86
deconz/data/discovery.sh Normal file
View File

@@ -0,0 +1,86 @@
#!/usr/bin/env bashio
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
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
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')"
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')"
_save_data "${api_key}" "${serial}"
}
function _send_discovery() {
local api_key
local result
local payload
api_key="$(jq --raw-output '.api_key' "${DATA_STORE}")"
serial="$(jq --raw-output '.serial' "${DATA_STORE}")"
# 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"
else
bashio::log.error "Discovery message to Home Assistant fails!"
fi
}
function hassio_discovery() {
# No API data exists - generate
if [ ! -f "$DATA_STORE" ]; then
bashio::log.info "Create API data for Home Assistant"
_deconz_api
fi
_send_discovery
}

View File

@@ -2,7 +2,8 @@
URL_IKEA="http://fw.ota.homesmart.ikea.net/feed/version_info.json"
while true; do
while true
do
# fetch data
if ! IKEA_DATA="$(curl -sL ${URL_IKEA})"; then

60
deconz/data/nginx.conf Normal file
View File

@@ -0,0 +1,60 @@
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;
upstream backend {
ip_hash;
server 127.0.0.1:%%PORT%%;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Ingress
server {
listen %%INGRESS_INTERFACE%%:%%INGRESS_PORT%% 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;
location / {
proxy_redirect off;
proxy_pass http://backend;
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;
}
}
}

71
deconz/data/run.sh Executable file
View File

@@ -0,0 +1,71 @@
#!/usr/bin/env bashio
set -e
. /discovery.sh
WAIT_PIDS=()
# Load config
DECONZ_DEVICE=$(bashio::config 'device')
API_PORT=$(bashio::addon.port 80)
WEBSOCKET_PORT=$(bashio::addon.port 8080)
INGRESS_PORT=$(bashio::addon.ingress_port)
INGRESS_INTERFACE=$(bashio::addon.ip_address)
# Check if port is available
if [ -z "${API_PORT}" ] || [ -z "${WEBSOCKET_PORT}" ]; then
bashio::exit.nok "You need set API/Websocket port!"
fi
# Start Gateway
bashio::log.info "Start deCONZ gateway"
deCONZ \
-platform minimal \
--auto-connect=1 \
--dbg-info=1 \
--dbg-aps=0 \
--dbg-zcl=0 \
--dbg-zdp=0 \
--dbg-otau=0 \
--http-port=${API_PORT} \
--ws-port=${WEBSOCKET_PORT} \
--upnp=0 \
--dev="${DECONZ_DEVICE}" &
WAIT_PIDS+=($!)
# Start OTA updates for deCONZ
bashio::log.info "Run deCONZ OTA updater"
deCONZ-otau-dl.sh &> /dev/null &
WAIT_PIDS+=($!)
# Start OTA updates for IKEA
bashio::log.info "Run IKEA OTA updater"
ika-otau-dl.sh &> /dev/null &
WAIT_PIDS+=($!)
# Start Ingress handler
bashio::log.info "Start Ingress handler"
sed -i "s/%%PORT%%/${API_PORT}/g" /etc/nginx/ingress.conf
sed -i "s/%%INGRESS_PORT%%/${INGRESS_PORT}/g" /etc/nginx/ingress.conf
sed -i "s/%%INGRESS_INTERFACE%%/${INGRESS_INTERFACE}/g" /etc/nginx/ingress.conf
nginx -c /etc/nginx/ingress.conf &
WAIT_PIDS+=($!)
# Register stop
function stop_addon() {
bashio::log.debug "Kill Processes..."
kill -15 "${WAIT_PIDS[@]}"
wait "${WAIT_PIDS[@]}"
bashio::log.debug "Done."
}
trap "stop_addon" SIGTERM SIGHUP
# Start Hass.io discovery
bashio::log.info "Run Hass.io discovery task"
hassio_discovery
# Wait until all is done
bashio::log.info "deCONZ is setup and running"
wait "${WAIT_PIDS[@]}"

View File

@@ -1,44 +0,0 @@
#!/bin/bash
set -e
CONFIG_PATH=/data/options.json
DECONZ_DEVICE="$(jq --raw-output '.device' $CONFIG_PATH)"
WAIT_PIDS=()
# List all devices
GCFFlasher_internal -l
# Start Gateway
deCONZ \
-platform minimal \
--auto-connect=1 \
--dbg-info=1 \
--dbg-aps=0 \
--dbg-zcl=0 \
--dbg-zdp=0 \
--dbg-otau=0 \
--http-port=80 \
--ws-port=8080 \
--upnp=0 \
--dev="${DECONZ_DEVICE}" &
WAIT_PIDS+=($!)
# Start OTA updates for deCONZ
deCONZ-otau-dl.sh &
WAIT_PIDS+=($!)
# Start OTA updates for IKEA
ika-otau-dl.sh &
WAIT_PIDS+=($!)
# Register stop
function stop_addon() {
echo "Kill Processes..."
kill -15 "${WAIT_PIDS[@]}"
wait "${WAIT_PIDS[@]}"
echo "Done."
}
trap "stop_addon" SIGTERM SIGHUP
# Wait until all is done
wait "${WAIT_PIDS[@]}"