Kategorie: Home Automation

Home Assistant schön(er) gemacht

Bei mir läuft Home Assi­stant in einem Docker-Con­tai­ner auf einem Raspber­ry Pi 4, schon sehr lan­ge. Anfangs als nati­ve Instal­la­ti­on, da wur­de dann aber die Update­rei bald ner­vig, des­halb Docker, da geht das Updaten (und Down­gra­den) deut­lich schmerz­frei­er — mitt­ler­wei­le küm­mert sich watch­tower dar­um, das geht alles voll­au­to­ma­tisch, sehr schick.
Dann kam irgend­wann der Wunsch auf, die Instal­la­ti­on auch aus dem Inter­net zugäng­lich zu machen. Der nächst­lie­gen­de Gedan­ke war, auf dem Rou­ter ein­fach ein Port­for­war­ding zu schal­ten: Router:TCP/443 -> Pi:TCP/443. Das hat aber min­des­tens zwei Probleme:

  • DNS-Name. Ich habe zwar die Domain sokoll.com, aber die IP des Rou­ters ändert sich zwar sel­ten, aber eben doch ab und an. Dann müß­te das DNS nach­ge­zo­gen wer­den. Unter der Vor­aus­set­zung, daß man den Wech­sel der IP über­haupt bemerkt hat.
  • TLS-Zer­ti­fi­kat für den Web­ser­ver. Natür­lich will ich nichts selbst­si­gnier­tes, Let’s Encrypt soll es schon sein. Dann geht aber die HTTP chal­len­ge nicht. DNS chal­len­ge gin­ge, mache ich ohne­hin, aber dann müß­te ich wild mit cron­jobs ham­peln und das Zer­ti­fi­kat von mei­nem Net­cup-Ser­ver holen.

Alles nicht so fein. Also muß­te eine ande­re Lösung her: der DNS-Name zeigt auf mei­nen Ser­ver bei Net­cup, dort läuft ein Apa­che als rever­se proxy:

<VirtualHost 185.207.105.125:443 [2a03:4000:1e:181::1]:443>
  Protocols h2 http/1.1
  ServerName hass.sokoll.com
  ServerAlias home.sokoll.com
  ServerAdmin webmaster@sokoll.com
  ErrorLog ${APACHE_LOG_DIR}/hass.sokoll.com-error.log
  CustomLog ${APACHE_LOG_DIR}/hass.sokoll.com-access.log combined
  SSLCertificateFile /etc/dehydrated/certs/wildcard_sokoll.com/fullchain.pem
  SSLCertificateKeyFile /etc/dehydrated/certs/wildcard_sokoll.com/privkey.pem
  ProxyRequests off
  ProxyPreserveHost On
  ProxyPass /api/websocket wss://91.66.45.77/api/websocket
  ProxyPassReverse /api/websocket wss://91.66.45.77/api/websocket
  ProxyPass / https://91.66.45.77/
  ProxyPassReverse / https://91.66.45.77/
  SSLProxyEngine on
  SSLProxyCheckPeerCN off
  SSLProxyCheckPeerExpire off
  SSLProxyCheckPeerName off
</VirtualHost>

(die IP ist schon lan­ge nicht mehr gültig)
Das heißt: Der Request kommt bei Net­cup an, und der Apa­che dort schubst ihn dann wei­ter zu mei­nem Rou­ter, dort gibt es ein Port­for­war­ding auf den Pi. Nicht son­der­lich ele­gant, funk­tio­niert aber.

Nun änder­te sich kürz­lich die IP wie­der, und ich muß­te die Web­ser­ver-Kon­fi­gu­ra­ti­on ändern, hat­te mich ver­tippt, ging nicht, Feh­ler suchen und fin­den und behe­ben, bis zum nächs­ten IP-Wech­sel, das ist doch alles Mist.
Auf dem Ser­ver läuft ein #Wire­guard, das ver­sorgt ein Tele­fon und einen Lap­top mit #Piho­le, das könn­te doch auch den Pi bedie­nen? Wenn dann der Pi den Tun­nel auf­baut, hät­te ich immer die­sel­ben IPs und könn­te mir das gan­ze Geham­pel mit Port­for­war­ding auf dem Rou­ter sparen.
Wire­guard ist sim­pel. Auf dem Server:

~$ ssh -l root big wg
interface: wg0
  public key: RzZAu5Js3c8/5yQBPlhKg2b0jkOlxHT6vLreiC1BCgo=
  private key: (hidden)
  listening port: 51820

peer: yS2cSLvEovdsLLT8ne/lixoiU87o821TgBkzrVHRFS4=
  endpoint: 91.66.61.253:35710
  allowed ips: 192.168.3.6/32
  latest handshake: 1 minute, 21 seconds ago
  transfer: 16.10 MiB received, 1.83 MiB sent

peer: RF22N9Kb6AO0N+jqZvSIdPxtZj3CxgasdgwuW6ktGys=
  endpoint: 91.66.61.253:58623
  allowed ips: 192.168.3.5/32
  latest handshake: 1 minute, 45 seconds ago
  transfer: 50.42 MiB received, 715.71 MiB sent

peer: OAbhrovugDdR8he1UIzy67Szh798C4lxWelSwrd3Z3o=
  endpoint: 91.66.61.253:1024
  allowed ips: 192.168.3.4/32
  latest handshake: 1 minute, 49 seconds ago
  transfer: 19.73 MiB received, 77.50 MiB sent
~$

Auf dem Pi:

~$ ssh -l root r4 wg
interface: wg0
  public key: yS2cSLvEovdsLLT8ne/lixoiU87o821TgBkzrVHRFS4=
  private key: (hidden)
  listening port: 35710

peer: RzZAu5Js3c8/5yQBPlhKg2b0jkOlxHT6vLreiC1BCgo=
  endpoint: 185.207.105.125:51820
  allowed ips: 192.168.3.1/32
  latest handshake: 15 seconds ago
  transfer: 1.03 MiB received, 8.97 MiB sent
  persistent keepalive: every 25 seconds
~$

In der Apa­che-Kon­fi­gu­ra­ti­on oben noch die VPN-Adres­se des Pi ein­tra­gen und Apa­che reloaden.
Fertsch. Funk­tio­niert traumhaft.
Gut. Ein Pro­blem hat­te ich: Der Tun­nel wird von innen auf­ge­baut, solan­ge da kei­ne Pake­te lau­fen, ist der Tun­nel unten, und das gan­ze schö­ne Kon­strukt funk­tio­niert nicht. Man könn­te einen Dau­er-ping im Hin­ter­grund lau­fen las­sen, aber das wäre nun wirk­lich uncool. Und dann ent­deck­te ich eben persistent keepalive, was das Pro­blem ele­gant löst.

Wire­guard rockt da house!

Home Assistant auf Docker umgestellt

Ich hat­te bis­lang Home Assi­stant in einem Python vir­tu­al envi­ron­ment zu lau­fen — war­um? Nun, es gibt wohl ein Image auf SD-Kar­te: Ein­schie­ben, boo­ten, HA läuft. Aller­dings ist ein Pi viel zu potent, als daß man ihn mit einer ein­zi­gen Auf­ga­be belei­di­gend unter­for­dern wollte.
Da kam die venv-Vari­an­te gera­de recht: Man kann rum­schwei­nen, Python-Packa­ges nach­in­stal­lie­ren nach Gus­to, ohne das sys­tem-Python anfas­sen zu müs­sen. Mit einer Ein­schrän­kung: Man ist an das System-Python(3) gebun­den, und das ist bei einem aktu­el­len Raspbi­an 3.7.3 — und HA mault das seit Mona­ten als depre­ca­ted an.
Ein neue­res Python gibt es aber nicht als Paket (jeden­falls habe ich nichts gefun­den). Also ich bin ja ein uber­he­ro, habe vie­le vie­le Jah­re send­mail aus den Quel­len über­setzt und mei­ne aller­ers­te sendmail.cf tat­säch­lich sel­ber geschrie­ben (und danach m4 ent­deckt), also so ein pop­li­ges Python sel­ber bau­en, ist ja wohl kei­ne Her­aus­fo­de­rung! Stellt sich raus: In der Tat, ist es nicht, geht ganz smooth. Also schnell noch Alia­se gesetzt und los: python-venv gestar­tet, HA gestartet.

Wel­co­me tot the depen­den­ci­es hell!¹

Ach was da alles nicht ver­füg­bar ist! xz,sqlite3 — danach habe ich aufgegeben.

Die Lösung?

systemctl stop home-assistant@homeassistant.service
systemctl disable home-assistant@homeassistant.service
docker run --init -d --name="home-assistant" -e "TZ=Europe/Berlin" -v /home/homeassistant/.homeassistant:/config/ --net=host --restart=always homeassistant/raspberrypi4-homeassistant:stable

Löppt. So ein­fach kann es sein!

root@r4:~# python3 --version
Python 3.7.3
root@r4:~# docker exec -ti home-assistant python3 --version
Python 3.8.7
root@r4:~#

Dann will man natür­lich gleich Watch­tower haben. Das meckert zwar beim Star­ten, läuft dann aber wohl doch:

root@r4:~# docker run -d --name watchtower --restart always -v /var/run/docker.sock:/var/run/docker.sock containrrr/watchtower
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm/v7) and no specific platform was requested
33f87b78d1ba24793b0272db247f7f4fc9315e0e4aee335128e1049db6fe3aa3
root@r4:~# docker ps
CONTAINER ID   IMAGE                                             COMMAND         CREATED          STATUS          PORTS      NAMES
33f87b78d1ba   containrrr/watchtower                             "/watchtower"   13 seconds ago   Up 11 seconds   8080/tcp   watchtower
bfebd671b8fd   homeassistant/raspberrypi4-homeassistant:stable   "/init"         43 minutes ago   Up 43 minutes              home-assistant
root@r4:~#

Wun­der­bar! War­um habe ich das nicht seit lan­gem so???


¹ OK, wer schon mal Ruby Depen­den­ci­es hin­be­kom­men hat, der wird das­sel­be bei Python noch voll­trun­ken hinbekommen.

Elektriker hier?

Von Strom weiß ich soviel, daß zuviel davon viel Aua macht.
Im Haus habe ich Außen­ja­lou­sien, die wer­den mit einem nor­ma­len Unter­putz-Schal­ter geschaltet:

Das schreit natür­lich danach, der Haus­au­to­ma­ti­sie­rung vor­ge­wor­fen zu wer­den, dabei muß es aber immer mög­lich blei­ben, die Jalou­sien wei­ter­hin mit klas­si­schen Schal­tern zu schalten.

Da bin ich auf Shel­ly gesto­ßen, das von HA unter­stützt wird.

Könn­te das was werden?

Zigbee: Reichweite?

Mein #HomeAs­si­stant redet nur über Ethernet/WLAN mit den Gerä­ten. Die­se sind fast alle IKEA Tråd­fri und wer­den von HomeAs­si­stant dann via IKEA-Bridge  ange­spro­chen, die­ses kom­mu­ni­ziert dann mit den Gerä­ten (Lam­pen, Fern­be­die­nun­gen, Schal­ter, Steck­do­sen) via #Zig­bee. Das funk­tio­niert wie es soll.
Nun ist es aber so, daß die Tråd­fri-Fern­be­die­nun­gen schon schick sind — nur lei­der las­sen sie sich von HomeAs­si­stant aus nicht anspre­chen, wahr­schein­lich gibt die Bridge das nicht her. Aber könn­te man sie aus­le­sen, dann lie­ße sich alles mög­li­che damit anstel­len — mein Schwa­ger ist schon ganz scharf darauf 😉
Also ist die Idee, die Fern­be­die­nun­gen direkt via Zig­bee anzu­spre­chen — dazu muß HomeAs­si­stant aber erst­mal Zig­bee spre­chen. Das läuft auf einem Raspi 4, und ich lieb­äug­le mit RaspBee II, schon weil der Preis über­schau­bar ist, so daß ein Fehl­kauf nicht schlimm wird.

Nun aller­dings ist der Raspi im Kel­ler, das nächs­te Zig­bee-Gerät (eine Tråd­fri-Lam­pe) ist ca. 6 Meter ent­fernt, getrennt durch eine Kel­ler­de­cke (Stahl­be­ton) und eine Mau­er (Hohl­zie­gel). Da Zig­bee ja ein Mesh-Netz­werk ist, soll­te ich nur einen Zugang benö­ti­gen, eben die­se Lam­pe. Hat jemand prak­ti­sche Erfah­run­gen mit Zig­bee durch Stahlbeton?

Und jährlich grüßt das Pythontier

Mein HomeAs­si­stant auf dem Raspi 4 beschwert sich. Der Raspi hat ein aktu­el­les Raspian:

pi@r4:~ $ python3 --version
Python 3.7.3
pi@r4:~ $ lsb_release  -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster
pi@r4:~ $

Beim Sohn auf einem Odroid N2:

root@ULU:~# python3 --version
Python 3.8.5
root@ULU:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.1 LTS
Release:	20.04
Codename:	focal
root@ULU:~#

Ich hab’ echt kei­nen Bock auf das Geham­pel mit selbst übersetzen 🙁

SD-Karten halten auch nicht ewig

und mei­ne in dem einen Pi natür­lich bis Sonn­abend, 3. 10., Fei­er­tag, kein Laden mit SD-Kar­ten hat offen.

Sym­ptom: Das Time­Ma­chi­ne-Back­up eines Mac hing. netatalk restar­tet, hing. Reboot ging. Danach ging/geht bis auf ping gar nichts mehr. Moni­tor krie­ge ich nicht dran, ich habe kein Kabel mit Micro-HDMI.
Es ist eine 32-GB-Kar­te. Woll­te mir die Kar­te als Image sichern — dd bricht nach ca. 8 GB mit Lese­feh­lern ab.
Wer­de ver­su­chen, die Kar­te neu zu bespie­len, so daß sie wenigs­tens bis nächs­te Woche noch funk­tio­niert. Betrof­fen sind die Back­ups der Macs und Home Assi­stant und die loka­le Musik­bi­blio­thek (wobei wir fast nur Spo­ti­fy hören, das fällt also kaum ins Gewicht)

Unschön.

PS:
dd:

root@odroidc2:~# dd if=/dev/sdb of=/usbplatte-1/sd-karte.r4.iso bs=100M status=progress
8182317056 bytes (8.2 GB, 7.6 GiB) copied, 490.146 s, 16.7 MB/s
dd: error reading '/dev/sdb': Input/output error
78+1 records in
78+1 records out
8182317056 bytes (8.2 GB, 7.6 GiB) copied, 527.358 s, 15.5 MB/s
root@odroidc2:~#

rsync:

root@odroidc2:~# rsync -avhHP --partial /mnt/ /usbplatte-1/sd-karte.r4/root/
sending incremental file list
var/log.old/syslog.1
        104.67M 100%    1.40MB/s    0:01:11 (xfr#1, to-chk=258/122668)
rsync: read errors mapping "/mnt/var/log.old/syslog.1": Input/output error (5)
WARNING: var/log.old/syslog.1 failed verification -- update discarded (will try again).
var/log.old/syslog.1
        104.67M 100%    2.69MB/s    0:00:37 (xfr#2, to-chk=258/122668)
rsync: read errors mapping "/mnt/var/log.old/syslog.1": Input/output error (5)
ERROR: var/log.old/syslog.1 failed verification -- update discarded.

sent 212.76M bytes  received 16.41K bytes  1.55M bytes/sec
total size is 18.28G  speedup is 85.89
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1196) [sender=3.1.2]
root@odroidc2:~#