--- author: email: mail@petermolnar.net image: https://petermolnar.net/favicon.jpg name: Peter Molnar url: https://petermolnar.net lang: en published: '2024-09-26T21:30:00+01:00' summary: My current, FreeBSD based server for self-hosting and home automation - now with a touchscreen! tags: title: FreeBSD "kiosk" for home automation dashboard --- ## Background For quite a few years now I have been looking for a small touchscreen, because I wanted a local (no network involved) interface for my home automation server. I tried the following which didn't work: - A Raspberry Pi (3b) with the official touchscreen. The official screen is 800*600, which is sad in 2024 _(it was sad in the early 2000s already)_, and I ended up with severe realibility issues due to the horrors of the Pi's USB architecture and the Sonoff Zigbee adapter I'm using. - Cheap, Chinese, HDMI display: 1024*600, without any decent feature of a display, like power management: it just kept telling me there's no signal without going to sleep. - Mimo displays - driver horrors on linux, I haven't had that for decades. They are not useful as a general displays at all becase they need the OS to boot first, so no picture until the OS boots. - ELO POS terminal (1215L) which, apart from being way too large and heavy, also needs it's own, picky, horribly drivers for the touch part to work. It's also ancient, with a foil based touch solution, that feels rather horrible. I nearly gave up: the machine I choose, the Lenovo M600 tiny (I have an unneeded on I'm currently selling, if anyone wants a fanless mini pc[^4]) only has 2 DisplayPort connectors, and DP -> HDMI adapters are not great. Then suddenly, I found the HP L7010t 10.1-inch Retail Touch Monitor[^2]: Displayport + touch, no special drivers, and even FreeBSD's kernel can use the touch features out of the box. ## Minimal X to run a single browser session on FreeBSD On FreeBSD 14.1, the base system needed the following: ```sh pkg install xorg xorg-server drm-kmod xf86-video-intel gsed epiphany openbox ``` `xf86-video-intel` is not in the official documentation, but it's needed[^1]. Tried `twm`, `tinywm`: they had issues with window size. Tried `dwm` but the menubar is annoying. Settled with `openbox`. Tried `midori`, but wasn't working smooth, `firefox-esr`, but it consumed too much CPU and touch scrolling wasn't working fine, `chromium` which worked perfectly but had too much Google in it for this scenario, `surf-browser` which didn't work at all. settled with `epiphany`. These are needed to enable graphics and auto-power off the screen: ```bash sysrc kld_list+=i915kms sysrc blanktime=300 ``` Create a user that will be logged in automaticaly: ```bash pw adduser -n kioskuser -d /home/kioskuser -s /bin/sh ``` Set up auto login for this user: ```bash cp /etc/gettytab /etc/gettytab.backup gsed -ri 's/root/kioskuser/g' /etc/gettytab ``` In `/etc/ttys` change ```apache ttyv0 "/usr/libexec/getty Pc" xterm onifexists secure ``` to ```apache ttyv0 "/usr/libexec/getty autologin" xterm onifexists secure ``` Then create: `/home/kioskuser/.profile` ```bash ENV=$HOME/.shrc; export ENV if [ "$PWD" != "$HOME" ] && [ "$PWD" -ef "$HOME" ] ; then cd ; fi XPID=`pgrep xinit` if [ -z "$XPID" ] && [ `tty` == "/dev/ttyv0" ]; then startx fi ``` And: `/home/kioskuser/.xinitrc` ```bash #!/bin/sh userresources=$HOME/.Xresources usermodmap=$HOME/.Xmodmap sysresources=/usr/local/etc/X11/xinit/.Xresources sysmodmap=/usr/local/etc/X11/xinit/.Xmodmap # merge in defaults and keymaps if [ -f $sysresources ]; then xrdb -merge $sysresources fi if [ -f $sysmodmap ]; then xmodmap $sysmodmap fi if [ -f "$userresources" ]; then xrdb -merge "$userresources" fi if [ -f "$usermodmap" ]; then xmodmap "$usermodmap" fi xset +dpms xset s on xset s blank openbox & exec /usr/local/bin/epiphany ``` Which should auto-start X with `epiphany`. **Note: this is not hardened, if the browser is closed, the user will be in the shell, X and epiphany will not auto-restart.** ## Extra: home automation jail on `lo0` with PF firewall routing I moved my services onto a single machine which now runs 3 jail: one for web and exposed to the world services, one for home automation, and one for minidlna. The first two listen on an extra 127.0.0.x on `lo0`, while the last has it's own IP. This also makes it quite simple to create a backup of them: I found zrepl[^5] and I can sync the jails onto a virtual machine on my laptop. Backup problem solved without needing to run yet another computer at home. I ended up with this setup because my router - a FRITZ!Box 7530 AX - is surprisingly dumb, and can't comprehend the idea of multiple IPs on the same node, so to overcome any possible routing issue I decided to use a single IP initially and route everything with `pf` locally. I mostly works, except for DLNA. I can't make the DLNA broascast packets work with this setup, so that jail is the exception, but I won't get into details with that now. Zigbee2MQTT needs access to raw sockets, so that has to be reflected in the jail setup: `/etc/jail.conf` ```apache domoticz { exec.start = "/bin/sh /etc/rc"; exec.poststart = "/bin/sh /usr/local/jails/domoticz/usr/local/etc/jail_dev_symlinks.sh"; exec.poststart += "/usr/sbin/service pf reload"; exec.stop = "/bin/sh /etc/rc.shutdown"; exec.consolelog = "/var/log/jail_console_${name}.log"; # PERMISSIONS allow.raw_sockets; allow.read_msgbuf; exec.clean; mount.devfs; devfs_ruleset = 3; allow.reserved_ports; # HOSTNAME/PATH host.hostname = "${name}"; path = "/usr/local/jails/${name}"; # NETWORK ip4.addr = 127.0.0.2; interface = lo0; } ``` And to avoid issues with tty namings, I run a script to create the symlinks. I tried doing this properly with devd, but it's virtually impossible inside the jails to do it right. `/usr/local/jails/domoticz/usr/local/etc/jail_dev_symlinks.sh` ```bash #!/bin/sh rootdir="/usr/local/jails/domoticz" vendor="0x10c4" product="0xea60" ttyname=`sysctl dev.uslcom | grep "vendor=$vendor product=$product" | sed -r 's/.*ttyname=([^\s]+) .*/\1/'` chgrp dialer $rootdir/dev/tty$ttyname chown zigbee2mqtt $rootdir/dev/tty$ttyname chmod g+rw $rootdir/dev/tty$ttyname /bin/ln -s /dev/tty$ttyname $rootdir/dev/ttyUzigbee ``` As I mentioned, the two main jails listen on `lo0` so they don't have issues of not having 127.0.0.1 resolved and so only what PF allows will be exposed this way. `/usr/local/etc/pf.conf` ```apache # vim: set ft=pf # /usr/local/etc/pf.conf lan="re0" lo="lo0" localnet = $lan:network jail_domoticz="127.0.0.2" local_ip="192.168.1.2" # 8800: node-red # 8880: zigbee2mqtt # 8088: domoticz # 1883: mqtt rdr on $lan inet proto {tcp, udp} from any to $lan port {8800, 8880, 8088, 1883} -> $jail_domoticz nat on $lan from { $jail_domoticz } to any -> $local_ip block in all block return pass inet proto icmp icmp-type echoreq pass quick proto pfsync pass proto carp # for jail pass proto tcp from any to $jail_domoticz port { 8800, 8880, 8088, 1883 } keep state # ssh - you probably want this pass proto tcp from any to $lan port { 22 } keep state pass from {$lan, $lo} to any keep state pass out all keep state ``` ## Thoughts on Home Assistant I gave Home Assistant yet another go. Every once in a while I try it out to see if it got simpler, but no: it's not even slowly becoming a bloated monster. It started as heaviweight, but it's just ridiculous now. First and foremost their idea of supporting the last 2 versions of Python is already not true: I wasn't able to install the current version on 3.11, which FreeBSD 14.1 comes with. Not supporting stable Debian Python[^3] is a shitty decision. In the end I wasn't able to install it at all. It's one thing that pip install needs to compile half the universe because it's not actually Python but C or Rust and it's not distributed for FreeBSD, but once it all looked good and I started `hass` is started to install **even more** Python modules. This thing is badly designed, going entirely against ideas of simplicity and robustness, and I'm genuinely losing my belief in anything Python these days. So many projects out there will tell you "just use docker" thinking you want one more layer of complexity, or that it's available for you at all. Dated or not, Domoticz is staying true to it's simle philosophy of it just works, and I'm going to stay loyal to it in the foreseable future. ## Other notes Don't try to run anything DLNA, like `minidlna` behind a firewall. It doesn't work. [^1]: https://forums.freebsd.org/threads/unable-to-start-anything-x.95048/#post-672721 [^3]: https://wiki.debian.org/DebianBookworm [^2]: https://www.ebay.co.uk/itm/155788268323 [^4]: https://www.ebay.co.uk/itm/186603942366 [^5]: https://zrepl.github.io/