by Łukasz Jakóbiec
Z eibd na knxd: migracja, której nie było
Jedenaście lat po postawieniu eibd na Raspberry Pi wymieniłem go. Wystarczył jeden apt install, nie zmienił się ani wiersz kodu i nie ma o tym żadnego commita. Oto działająca konfiguracja, do czego służy każda flaga i dlaczego kompatybilny protokół bywa drogim prezentem.
W 2014 roku pisałem o postawieniu eibd na Raspberry Pi, żeby coś innego niż włącznik na ścianie mogło rozmawiać z moją magistralą KNX. Zadziałało, a potem po prostu działało dalej, i na tym właśnie polega problem z infrastrukturą: przestaje przypominać o swoim istnieniu.
To Raspberry wciąż jest w sieci. Zalogowałem się na nie, pisząc ten tekst. Binarki eibd mają datę z marca 2015, knxtool i groupswrite nadal leżą obok, a w /etc/init.d nadal siedzi skrypt startowy. Nie prowadzą do niego żadne dowiązania, nie ma unitu systemd, więc od lat nic go nie uruchamia. Nikt go nie wyłączył. Po prostu przestałem go o cokolwiek pytać i tak stoi do dziś, z zapalonymi diodami.
Magistralę obsługuje teraz knxd na porządnym serwerze. Tak wyglądała ta zmiana, i wyszedł z tego krótszy artykuł, niż się spodziewałem.
Po co w ogóle się przesiadać
eibd się skończył. Wersja 0.0.5 to koniec drogi, upstream nie ruszył się od ponad dekady, a w repozytoriach żadnej aktualnej dystrybucji go nie ma, dlatego mój był w ogóle kompilowany ze źródeł. knxd to jego utrzymywany fork, autorstwa Michaela Bittnera i Matthiasa Urlichsa, a praktyczna różnica jest taka, że można wpisać apt install knxd.
To mniejszy powód, niż brzmi, i jednocześnie jedyny, który się liczy. Demon kompilowany ze źródeł to demon, którego za cztery lata będziesz przebudowywał o północy, na dystrybucji z nowszym kompilatorem, żeby naprawić coś zupełnie niezwiązanego. Bycie spakowanym to funkcja, a nie szczegół. Dostajesz unit systemd, aktywację po sokecie, dedykowanego użytkownika i czyjąś cudzą odpowiedzialność za następną łatkę bezpieczeństwa.
Cała zmiana
Jedna instalacja pakietu, w listopadzie 2025, i jeden plik konfiguracyjny. Oto on w całości, bo to jest dokładnie ta rzecz, którą sam chciałem wtedy znaleźć:
# /etc/knxd.conf
KNXD_OPTS="-e 0.0.1 -E 1.1.240:8 -u /tmp/eib -b ipt:<gateway>"
# previously -E had 0.0.2:8 which means tunneling clients got
# different sender addresses in a range.
Cztery flagi. Warto przejść je po kolei, bo razem stanowią całą konfigurację tego programu.
-b ipt:<gateway>to backend i jedyna linijka, która mówi cokolwiek o świecie fizycznym.ipt:to tunelowanie KNX/IP: połączenie punkt-punkt z jedną bramką, a nie routingip:, który jest multicastem i osobnym zestawem problemów. Za tym adresem stoi bramka KNX/IP Siemensa, a za nią skrętka. Jeśli przesiadasz się z Raspberry z nakładką TPUART, to właśnie ta flaga się zmienia: demon nie musi już być nigdzie blisko magistrali.-e 0.0.1to własny adres indywidualny demona na magistrali. Każde urządzenie KNX taki ma. knxd też potrzebuje, bo teraz jest urządzeniem.-E 1.1.240:8to pula ośmiu kolejnych adresów, rozdawanych klientom tunelującym. To ta flaga, na której ludzie się przewracają, i to nad nią wisi jedyny odręczny komentarz w moim pliku.-u /tmp/eibtworzy socket uniksowy dokładnie w tej ścieżce. Ta ścieżka nie jest konwencją knxd. Tam socket kładł eibd, i to pierwsza wskazówka, o czym naprawdę jest ten artykuł.
Jedyna rzecz, nad którą musiałem pomyśleć
Kiedy program łączy się z knxd przez tunelowanie i wysyła telegram, ten telegram potrzebuje adresu nadawcy, i nie może to być własny adres knxd, bo wtedy dwa programy mówiące naraz podają się za to samo urządzenie. Więc knxd przydziela każdemu klientowi jeden adres z puli: tutaj 1.1.240 do 1.1.247, osiem sztuk.
Pula powinna leżeć w tym samym obszarze i tej samej linii co reszta instalacji i nie może kolidować z żadnym realnym urządzeniem. 0.0.2 nie spełnia ani jednego, ani drugiego: to poprawny adres, więc nic nie protestuje, ale telegramy przychodzą wtedy z fragmentu przestrzeni adresowej, w którym nic nie powinno istnieć. Wszystko dalej działa, bo komunikacji grupowej jest wszystko jedno, kto wysłał. Gryzie dopiero później, kiedy patrzysz w monitor magistrali i próbujesz ustalić, które urządzenie coś zrobiło, albo kiedy sprzęgacz filtruje po linii i po cichu cię odcina.
Wybierz zakres we własnej linii, zostaw zapas nad realnymi urządzeniami i daj więcej miejsc, niż wydaje ci się potrzebne. Są za darmo.
Dlaczego nie zmienił się ani wiersz kodu
Do tego wracam najczęściej. Oprogramowanie nad tą magistralą to spory system, jakieś 69 000 linii Pythona i dwadzieścia dziewięć procesów, opisany szerzej osobno, a wymiana demona pod spodem wymagała zmiany w nim zera. Ani jednej linijki.
Odpowiadają za to dwie decyzje projektowe w knxd i obie są czyimś wyborem kompatybilności zamiast czystości, sprzed lat:
- Zachował protokół klienta eibd, na porcie eibd, 6720.
-upozwala położyć socket uniksowy z powrotem w starej ścieżce.
Więc biblioteka kliencka w moim projekcie, wkopiowany EIBConnection3.py, w którego nagłówku dalej stoi EIBD client library, Copyright 2005-2010 Martin Koegler, połączyła się z demonem wydanym piętnaście lat po jej napisaniu i niczego nie zauważyła.
Connection string to nadal ip:<host> bez portu, bo 6720 jest domyślny i zawsze był. Ustawienie w mojej konfiguracji nadal nazywa się EIBD_SOCKET_URL. Całą robotę robią dwie funkcje i obie mają oryginalne nazwy:
EIBOpenVBusmonitorText()do słuchania. Otwiera tekstowy busmonitor, który podaje każdą ramkę na magistrali, adresowaną do ciebie albo i nie, jako linię tekstu rozbieraną potem wyrażeniem regularnym. Nie jest to eleganckie i ani razu nie zawiodło.EIBOpen_GroupSocket(False)do wysyłania. Otwiera to dokładnie jeden proces w domu i tylko on potrafi sprawić, żeby cokolwiek fizycznie się ruszyło.
Co daje pakiet
Unit jest aktywowany po sokecie i warto o tym wiedzieć, bo to zmienia miejsce, w które się patrzy, kiedy coś nie gra. knxd.socket trzyma sokety nasłuchujące i uruchamia knxd.service na żądanie; sam serwis jest Type=notify, czyta argumenty z /etc/knxd.conf przez EnvironmentFile i chodzi na własnym, nieuprzywilejowanym użytkowniku.
Konsekwencje, w kolejności, w jakiej mnie zaskoczyły:
- Edycja
/etc/knxd.confwymaga restartu serwisu. To plik środowiskowy, a nie konfiguracja, którą demon obserwuje. - Jeśli zmieniasz to, na czym nasłuchuje, trzeba zrestartować też unit sokietowy, a restart samego serwisu będzie wyglądał, jakby nic nie zrobił.
- W systemie leży
/etc/default/knxd, który pod systemd jest martwy. Został po starym skrypcie startowym. Edytowanie go nie daje żadnego błędu ani żadnego efektu, czyli najgorszą możliwą kombinację. - Demon chodzi jako
knxd, więc socket w/tmp/eibnależy do tego użytkownika i twój klient musi mieć prawo go odczytać.
Sprawdzenie, czy naprawdę działa
Pierwszej rzeczy, po którą sięgnąłem, nie było. Pakiet Ubuntu nie dostarcza knxtool, więc groupswrite i spółka są niedostępne, a razem z nimi oczywisty test dymny.
Sprawdzam zamiast tego tak:
systemctl status knxd knxd.socket
# the sockets it should have created
ls -l /tmp/eib /run/knx
ss -lntp | grep 6720
# and the real test: watch the bus and press a light switch
journalctl -u knxd -f
Jeśli sockety istnieją i port nasłuchuje, knxd stoi. To jeszcze nie znaczy, że rozmawia z bramką. Prawdziwy test to otworzyć busmonitor, podejść do ściany, nacisnąć włącznik i zobaczyć, że telegram przyszedł. Nic mniejszego nie odróżnia zdrowego demona od takiego, który radośnie obsługuje pustą magistralę.
Contact me
Questions, ideas, or spotted a bug? Send me a note.