work in progress. This how-to is meant to be as a hand-book for experienced user. Backup your router before playing with this. Unexpected things might happen.
Guys from deconz did great job when tuning their official raspberry Pi image - that's not the case with this manual. At least so far. If deConz is the only way to control your bathroom lights, ensure you have headlamps for your family members before you'll start with following experimental-graded procedure.
Using internal flash storage is not recommended by Turris Omnia makers!
Configure external (USB, msata) storage as described here. External storage should be mounted in /srv
mountpoint.
opkg install kmod-usb-acm
opkg install usbutils
in forris GUI:
→ “updater” and in “Package lists” check “LXC utilities”.
Click on “Save and update” and wait for installation.
Plug in the Conbee II USB stick and reboot omnia to let luci load relevant plugin and load new kernel module. After reboot, we should see the device (VendorID: Dresden Elektronik ) with the proper driver (cdc_acm) loaded:
root@turris:/dev# lsusb ... Bus 002 Device 081: ID 1cf1:0030 Dresden Elektronik ... root@turris:/dev#
root@turris:/dev# lsusb --tree /: Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 5000M |__ Port 1: Dev 2, If 0, Class=Mass Storage, Driver=usb-storage, 5000M /: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 480M /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 5000M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci-hcd/1p, 480M |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M |__ Port 1: Dev 81, If 0, Class=Communications, Driver=cdc_acm, 12M |__ Port 1: Dev 81, If 1, Class=CDC Data, Driver=cdc_acm, 12M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=orion-ehci/1p, 480M root@turris:/dev#
There is watchdog inside a device, so if deCONZ is not talking to USB stick, device will reset itself after some time. Don't be surprised to see such reconnects in dmesg. (and related increasing DevID)
If USB device is not recognized by Turris Omnia OS, try to plug it into USB2 hub connected to USB3 Omnia port. As there is new Turris OS release in preparations, I don't want to spent time by debugging this.
Vendor expects current raspbian, which is based on Debian Buster 3) of armv7l architecture. So let's create ABI-compatible LXC container:
root@turris:/srv/lxc# lxc-create -t download -n lxc_deconz Setting up the GPG keyring Downloading the image index --- DIST RELEASE ARCH VARIANT BUILD --- #.. additional OSs removed... Debian Stretch aarch64 default 2019-09-18 Debian Buster armv7l default 2019-09-18 Debian Buster aarch64 default 2019-09-18 Gentoo stable armv7l default 2019-09-18 #.. additional OSs removed... --- Distribution: Debian Release: Buster Architecture: armv7l Downloading the image index Downloading the rootfs Downloading the metadata The image cache is now ready Unpacking the rootfs --- Distribution Debian version Buster was just installed as a container. Content of the tarballs is provided by third party, thus there is no warranty of any kind nor support from Turris team. Do not use containers on internal flash, they can wear it down really fast!!! root@turris:/srv/lxc#
get the container CLI:
root@turris:/srv/lxc# lxc-ls lxc_deconz root@turris:/srv/lxc# lxc-attach -n lxc_deconz root@LXCNAME:/#
set some descriptive hostname:
root@LXCNAME:/# hostnamectl set-hostname lxc-deconz root@LXCNAME:/#
“restart” container by clickin on “stop” and “start” in Luci gui. (Services → LXC Containers)
BUG: For unknown reason, in current Turris omnia OS, lxc_stop
CLI command is hanging. Use Luci GUI instead.
attach back to the container and install dependencies and nice-to-have tools:
root@turris:/srv/lxc# lxc-attach -n lxc_deconz root@lxc-deconz:/# apt install procps iputils-ping less wget curl gnupg lsb-release libatomic1 usbutils strace tree
download and install wiringpi
- it is not directly needed, but it is dependency of deconz deb package. There is plan to remove this dependency from deconz. 4)
root@lxc-deconz:/# wget https://project-downloads.drogon.net/wiringpi-latest.deb root@lxc-deconz:/# apt install ./wiringpi-latest.deb
get deconz repo key:
curl http://phoscon.de/apt/deconz.pub.key | apt-key add -
add deconz repository to the system:
sh -c "echo 'deb http://phoscon.de/apt/deconz \ $(lsb_release -cs) main' > \ /etc/apt/sources.list.d/deconz.list"
install deconz package:
apt update apt install deconz
USB stick driver creates /dev/ttyACM0
block device there on host. We need to pass this device into LXC container.
In turris(host) shell, get the major cgroup number of /dev/ttyACM0
:
root@turris:/srv/lxc# ls -la /dev/ttyACM0 crw-r--r-- 1 root root 166, 0 Sep 21 22:22 /dev/ttyACM0 root@turris:/srv/lxc#
it's 166 - we'll need this number later.
Open containers config and configure /dev/ttyACM0
passthru with the path and number we found above:
append to /srv/lxc/lxc_deconz/config
:
.. # usb devices: lxc.cgroup.devices.allow = c 166:* rwm lxc.mount.entry = /dev/ttyACM0 dev/ttyACM0 none bind,optional,create=file 0 0
stop & start container and check if device is present:
root@lxc-deconz:/# ls -lah /dev/ttyACM0 crw-r--r-- 1 root root 166, 0 Sep 21 20:22 /dev/ttyACM0 root@lxc-deconz:/#
Now, try the vendors' utility if we can see the USB stick:
root@lxc-deconz:~# GCFFlasher_internal -l GCFFlasher V3_06 (c) dresden elektronik ingenieurtechnik gmbh Path | Vendor | Product | Serial | Type -----------------+--------+---------+------------+------- root@lxc-deconz:~#
no - it's missing, because deCONZ is internally calling function from libqt5serial
, trying to use udev database in /run/udev/data/
, usually created by systemd-udevd
. That's not case in containerized OS from obvious reasons but we can steal the proper file from raspberryPi running systemd and having USB dongle plugged.. :)
so first, in container, create the right dir:
mkdir -p /run/udev/data/
and fill it with the required data:
cd /run/udev/data/ echo "E:ID_VENDOR_ID=1cf1 E:ID_MODEL_ID=0030" > c166\:0
now the USB stick should be recognized:
root@lxc-deconz:/run/udev/data# GCFFlasher_internal -l GCFFlasher V3_06 (c) dresden elektronik ingenieurtechnik gmbh Path | Vendor | Product | Serial | Type -----------------+--------+---------+------------+------- /dev/ttyACM0 | 0x1CF1 | 0x0030 | | ConBee II root@lxc-deconz:/run/udev/data#
root@lxc-deconz:/run/udev/data# deCONZ -platform minimal
Apparently, in the deconz deb package, cap_sys_time
and cap_sys_boot
are set in postinst for /usr/bin/deCONZ
. Both caps are forbidden in lxc configuration (see /usr/share/lxc/config/common.conf
):
root@lxc-deconz:/# getcap /usr/bin/deCONZ /usr/bin/deCONZ = cap_net_bind_service,cap_sys_boot,cap_sys_time+ep root@lxc-deconz:/#
both caps can be removed with:
root@lxc-deconz:/# /sbin/setcap cap_net_bind_service+ep /usr/bin/deCONZ
file caps now looks like:
root@lxc-deconz:/# getcap /usr/bin/deCONZ /usr/bin/deCONZ = cap_net_bind_service+ep root@lxc-deconz:/#
Indeed, we'll fix that permanently in the systemd unit file, to be sure that package update will not break our setup.
deconz will start, listen on default port (8080) and USB firmware version should be visible in webGUI:
If USB firmware version is not visible, check if USB device is visible inside of container (lsusb
, etc.)
add regular user to run the service:
useradd deconz-user
make home dir and change the ownership:
mkdir /home/deconz-user chown -R deconz-user:deconz-user /home/deconz-user
Add deconz-user
into dialout group:
usermod -a -G dialout deconz-user
copy reference unit file into /etc/systemd/system:
root@lxc-deconz:~# cp /lib/systemd/system/deconz.service /etc/systemd/system/
..and tweak it to our needs:
[Unit] Description=deCONZ: ZigBee gateway -- REST API Wants=deconz-init.service deconz-update.service StartLimitIntervalSec=0 [Service] User=deconz-user PermissionsStartOnly=true ExecStartPre=/bin/chown root:dialout /dev/ttyACM0 ExecStartPre=/bin/chmod 664 /dev/ttyACM0 ExecStartPre=/bin/mkdir -p /run/udev/data ExecStartPre=/sbin/setcap cap_net_bind_service+ep /usr/bin/deCONZ ExecStartPre=/bin/bash -c "/bin/echo -e 'E:ID_VENDOR_ID=1cf1\nE:ID_MODEL_ID=0030' > /run/udev/data/c166:0" ExecStart=/usr/bin/deCONZ -platform minimal --http-port=80 Restart=on-failure StartLimitInterval=60 #AmbientCapabilities=CAP_NET_BIND_SERVICE CAP_KILL CAP_SYS_BOOT CAP_SYS_TIME [Install] WantedBy=multi-user.target
explanation
User
.. the regular user we created so deconz-user
in our casePermissionsStartOnly
.. will execute ExecStartPre
commands as root, but the service itself as deconz-user
ExecStartPre
commands .. fixing permisions on /dev/ttyACM0
and tweaking the udev dir, also limiting the capabilities of the deconz binary.
as described in how-to, edit /etc/config/lxc-auto
at Turris to automatically start our container:
root@turris:~# cat /etc/config/lxc-auto ... config container option name lxc_deconz option timeout 30 ... root@turris:~#
deCONZ can be started directly from cli with several debug options5), e.g:
deCONZ -platform minimal --dbg-info=2 --dbg-zdp=2 --dbg-zcl=2 --db-aps=2 --dbg-http=2
root@raspberrypi:/home/pi# lsb_release -a No LSB modules are available. Distributor ID: Raspbian Description: Raspbian GNU/Linux 10 (buster) Release: 10 Codename: buster root@raspberrypi:/home/pi#