From 85d31f62372de6c9f740d7e88fe352e5fdffb04b Mon Sep 17 00:00:00 2001 From: Pascal Vizeli Date: Tue, 15 Jan 2019 15:21:36 +0100 Subject: [PATCH] deCONZ (#502) * Migrate deCONZ addon to core repo * Update add-on * Update run.sh * Update Dockerfile * Update Dockerfile * Update Dockerfile * Update Dockerfile * Update Dockerfile * Update Dockerfile * Update build.json * Update Dockerfile * Update Dockerfile * Use our raspbian * Update config.json * Update build.json * Update config.json * Update build.json * Update config.json * Update config.json * Update run.sh * Update config.json * Update config.json * Delete firmware.sh * Update Dockerfile * Update Dockerfile * Update run.sh * Update config.json * Update run.sh * Update Dockerfile * Create ika-otau-dl.sh * Update run.sh * Fix rights * Update ika-otau-dl.sh * Update ika-otau-dl.sh * Update ika-otau-dl.sh * Update ika-otau-dl.sh * Update README.md * Update Dockerfile --- deconz/CHANGELOG.md | 5 +++++ deconz/Dockerfile | 47 ++++++++++++++++++++++++++++++++++++++++++ deconz/README.md | 30 +++++++++++++++++++++++++++ deconz/build.json | 10 +++++++++ deconz/config.json | 34 ++++++++++++++++++++++++++++++ deconz/ika-otau-dl.sh | 31 ++++++++++++++++++++++++++++ deconz/logo.png | Bin 0 -> 10330 bytes deconz/run.sh | 44 +++++++++++++++++++++++++++++++++++++++ snips/build.json | 2 +- 9 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 deconz/CHANGELOG.md create mode 100644 deconz/Dockerfile create mode 100644 deconz/README.md create mode 100644 deconz/build.json create mode 100644 deconz/config.json create mode 100755 deconz/ika-otau-dl.sh create mode 100644 deconz/logo.png create mode 100755 deconz/run.sh diff --git a/deconz/CHANGELOG.md b/deconz/CHANGELOG.md new file mode 100644 index 0000000..6554f03 --- /dev/null +++ b/deconz/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +## 1.0 +- Initial release as Home Assistant core Add-on +- Bump deCONZ to 2.05.54 diff --git a/deconz/Dockerfile b/deconz/Dockerfile new file mode 100644 index 0000000..cf8f015 --- /dev/null +++ b/deconz/Dockerfile @@ -0,0 +1,47 @@ +ARG BUILD_FROM +FROM $BUILD_FROM + +ARG BUILD_ARCH +ARG DECONZ_VERSION + +# Install deCONZ dependencies +RUN apt-get update \ + && apt-get install -y \ + curl \ + kmod \ + lsof \ + tzdata \ + libcap2-bin \ + libqt5core5a \ + libqt5gui5 \ + libqt5network5 \ + libqt5serialport5 \ + libqt5sql5 \ + libqt5websockets5 \ + libqt5widgets5 \ + sqlite3 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && if [ "${BUILD_ARCH}" = "armhf" ] || [ "${BUILD_ARCH}" = "aarch64" ]; \ + then \ + curl -q -L -o /wiringpi.deb https://unicorn.drogon.net/wiringpi-2.46-1.deb \ + && dpkg -i /wiringpi.deb \ + && rm -rf /wiringpi.deb; \ + fi + +# Install deCONZ +RUN if [ "${BUILD_ARCH}" = "armhf" ] || [ "${BUILD_ARCH}" = "aarch64" ]; \ + then \ + curl -q -L -o /deconz.deb https://www.dresden-elektronik.de/rpi/deconz/beta/deconz-${DECONZ_VERSION}-qt5.deb; \ + else \ + curl -q -L -o /deconz.deb https://www.dresden-elektronik.de/deconz/ubuntu/beta/deconz-${DECONZ_VERSION}-qt5.deb; \ + fi \ + && dpkg -i /deconz.deb \ + && rm -f /deconz.deb \ + && chown root:root /usr/bin/deCONZ* \ + && sed -i 's/\/root/\/data/' /etc/passwd + +COPY run.sh / +COPY ika-otau-dl.sh /bin/ + +CMD ["/run.sh"] diff --git a/deconz/README.md b/deconz/README.md new file mode 100644 index 0000000..385c9c8 --- /dev/null +++ b/deconz/README.md @@ -0,0 +1,30 @@ +# deCONZ + +Add-on to allow Home Assistant to control a ZigBee network with Conbee or RaspBee hardware by Dresden Elektronik. + +## 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`: + +``` +enable_uart=1 +dtoverlay=pi3-miniuart-bt +``` + +Before starting the add-on for the first time after installing, in the add-on config you must specify the device name that has been assigned to your RaspBee/Conbee as the `device`. Replace **null** and specify the device name in quotes (e.g. "/dev/ttyUSB0" or "/dev/ttyAMA0"). The other config options have sensible defaults that should not need to be changed unless you are debugging. + +Use a 2.5A power supply for your Raspberry Pi 3! Strange behaviour with this Add-on may otherwise result. + +## Adding ZigBee Devices + +After installing and starting this addon in Hass.io, access the deCONZ WebUI ("Phoscon") with WebUI button. + +## Configuring the Home Assistant deCONZ Component + +If `discovery:` is enabled in configuration.yaml, navigate to the Configuration - Integrations page after starting this Add-on to configure the deCONZ component. + +If `discovery:` is not enabled, follow these instructions to configure the deCONZ component: https://home-assistant.io/components/deconz/. + +## Migrating to this Add-on + +To migrate deCONZ to Hass.io and this Add-on (or before uninstalling/reinstalling this Add-on), backup your deCONZ config via the Phoscon WebUI, then restore that config after installing/reinstalling. _You must perform these steps or your Light and Group names and other data will be lost!_ (However, your ZigBee devices will remain paired to your Conbee or RaspBee hardware.) diff --git a/deconz/build.json b/deconz/build.json new file mode 100644 index 0000000..4585e38 --- /dev/null +++ b/deconz/build.json @@ -0,0 +1,10 @@ +{ + "build_from": { + "aarch64": "homeassistant/armhf-base-raspbian:stretch", + "amd64": "homeassistant/amd64-base-ubuntu:18.04", + "armhf": "homeassistant/armhf-base-raspbian:stretch" + }, + "args": { + "DECONZ_VERSION": "2.05.54" + } + } diff --git a/deconz/config.json b/deconz/config.json new file mode 100644 index 0000000..aab2e7b --- /dev/null +++ b/deconz/config.json @@ -0,0 +1,34 @@ +{ + "name": "deCONZ", + "version": "1.0", + "slug": "deconz", + "description": "Control a ZigBee network with Conbee or RaspBee by Dresden Elektronik", + "arch": ["aarch64","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" +} diff --git a/deconz/ika-otau-dl.sh b/deconz/ika-otau-dl.sh new file mode 100755 index 0000000..8a4a00f --- /dev/null +++ b/deconz/ika-otau-dl.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +URL_IKEA="http://fw.ota.homesmart.ikea.net/feed/version_info.json" + +while true; do + + # fetch data + if ! IKEA_DATA="$(curl -sL ${URL_IKEA})"; then + echo "[Info] Can't fetch data from ikea!" + sleep 18000 + continue + fi + + IKEA_DATA_SIZE="$(echo "${IKEA_DATA}" | jq --raw-output '. | length')" + for (( i=0; i < "${IKEA_DATA_SIZE}"; i++ )); do + OTAU_URL=$(echo "${IKEA_DATA}" | jq --raw-output ".[$i].fw_binary_url // empty") + + if [ -z "${OTAU_URL}" ]; then + continue + fi + + OTAU_FILE="/data/otau/${OTAU_URL##*/}" + if [ -f "${OTAU_FILE}" ]; then + continue + fi + + curl -s -L -o "${OTAU_FILE}" "${OTAU_URL}" + done + + sleep 259200 +done diff --git a/deconz/logo.png b/deconz/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1031e7bb5c792231cd34f0782af1ebb38bef99a8 GIT binary patch literal 10330 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