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 pc1) only has 2 DisplayPort connectors, and DP -> HDMI adapters are not great. Then suddenly, I found the HP L7010t 10.1-inch Retail Touch Monitor2: Displayport + touch, no special drivers, and even FreeBSD's kernel can use the touch features out of the box.
Update: well, nothing is perfect. The HP's mounting space is about 2mm smaller, than the standard stands, so I ended up making a DIY stand by drilling a 10cm by 10cm square in the four corners into a steel bookend and bending it backwards.
Minimal X to run a single browser session on FreeBSD
On FreeBSD 14.1, the base system needed the following:
pkg install xorg xorg-server drm-kmod xf86-video-intel gsed surf-browser openbox
xf86-video-intel
is not in the official documentation,
but it's needed3.
Update: on FreeBSD 14.2, as long as 14.1 is
supported, drm-kmod
is broken4
because it's still built for 14.1 Instead use
drm-515-kmod
:
pkg install xorg xorg-server drm-515-kmod xf86-video-intel gsed surf-browser openbox
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,
. Update: I realized I wasn't starting
surf-browser
which didn't work at all. settled with
epiphany
surf-browser
5 they way I should have, and it's
much lighter, then epiphany
, so surf it is. Note: it's not
NetSurf6 - I'd love to use NetSurf, but it
lacks the JavaScript support needed for Domoticz and Zigbee2MQTT.
These are needed to enable graphics and auto-power off the screen:
sysrc kld_list+=i915kms
sysrc blanktime=300
Create a user that will be logged in automaticaly:
pw adduser -n kioskuser -d /home/kioskuser -s /bin/sh
Set up auto login for this user:
cp /etc/gettytab /etc/gettytab.backup
gsed -ri 's/root/kioskuser/g' /etc/gettytab
In /etc/ttys
change
ttyv0 "/usr/libexec/getty Pc" xterm onifexists secure
to
ttyv0 "/usr/libexec/getty autologin" xterm onifexists secure
Then create:
/home/kioskuser/.profile
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
#!/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 zrepl7 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
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
#!/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
# 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 Python8 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.
(Oh, by the way: this entry was written by Peter Molnar, and originally posted on petermolnar dot net.)