Great work, @ondyn - though, after reviewing your code changes, I came to an “ugly” but interesting alternitve: what if we just replace uv with a wrapper script - hehe? So I asked ChatGPT to build one - well, it took longer than expected - stupid A.I., but here it is and it works great. I also had IPv6 issues on zeroconf with failing weather service and others, too…
precedence ::ffff:0:0/96 100
in /etc/gai.conf
didn’t work either, so I patched lib/python3.13/site-packages/zeroconf/_utils/net.py in ip6_addresses_to_indexes to swallow wired, failing adapters from
for iface in interfaces:
if isinstance(iface, int):
result.append((interface_index_to_ip6_address(adapters, iface), iface)) # type: ignore[arg-type]
elif isinstance(iface, str) and ipaddress.ip_address(iface).version == 6:
result.append(ip6_to_address_and_index(adapters, iface)) # type: ignore[arg-type]
to
for iface in interfaces:
try:
if isinstance(iface, int):
result.append((interface_index_to_ip6_address(adapters, iface), iface)) # type: ignore[arg-type]
elif isinstance(iface, str) and ipaddress.ip_address(iface).version == 6:
result.append(ip6_to_address_and_index(adapters, iface)) # type: ignore[arg-type]
except:
pass
Anyway, latest, untouched HA-Core is now running fine, when I install homeassistant and before first launch call this vu_wrapper.sh to direct all uv pip things to pip when HA is trying to install things on first launch 
uv_wrapper.sh:
#!/bin/sh
#
# A single POSIX-compatible script that:
# 1) On "install": replaces the system uv with this wrapper
# 2) On "uninstall": restores the original uv
# 3) Otherwise acts as the uv wrapper itself
# Current script path
MANAGER_SCRIPT="$0"
# Try to find the "real" uv in PATH
SYSTEM_UV="$(command -v uv 2>/dev/null || true)"
show_usage() {
echo "Usage:"
echo " uv install → replace the system uv with this wrapper"
echo " uv uninstall → restore the original uv"
echo " uv pip [...] → call pip"
echo " uv venv [...] → call python3 -m venv"
echo " uv install ... → same as pip install ..."
echo " uv uninstall ... → same as pip uninstall ..."
echo " uv [other] → forward to original uv_disabled"
exit 0
}
# ----------------------------
# 1) Handle "install"
# ----------------------------
if [ "$1" = "install" ]; then
# Check if the wrapper is already installed (presence of uv_disabled indicates an active wrapper)
if [ -n "$SYSTEM_UV" ] && [ -f "${SYSTEM_UV}_disabled" ]; then
echo "⚠️ It appears the wrapper is already installed at $SYSTEM_UV"
echo " Original binary: ${SYSTEM_UV}_disabled"
exit 1
fi
if [ -z "$SYSTEM_UV" ]; then
echo "❌ Error: No 'uv' found in PATH. Cannot install wrapper."
exit 1
fi
# If the discovered uv equals this script, we're already running as uv.
# Possibly the user manually placed this script at /usr/local/bin/uv, etc.
# => If so, either it's already installed or we can't reinstall
if [ "$SYSTEM_UV" = "$MANAGER_SCRIPT" ]; then
echo "⚠️ This script is already located at $SYSTEM_UV."
echo " If you intended to install, place it elsewhere and run './uv_manager.sh install'."
exit 1
fi
# Optional check: if uv is a symlink
if [ -L "$SYSTEM_UV" ]; then
echo "⚠️ Refusing to overwrite a symlink: $SYSTEM_UV."
echo " Please replace the real binary manually if needed."
exit 1
fi
# Rename the discovered uv to uv_disabled
echo "🔧 Installing wrapper: renaming $SYSTEM_UV → ${SYSTEM_UV}_disabled"
mv "$SYSTEM_UV" "${SYSTEM_UV}_disabled" 2>/dev/null || {
echo "❌ Could not rename $SYSTEM_UV. Try running with sudo?"
exit 1
}
echo "🔧 Copying this script to $SYSTEM_UV..."
cp "$MANAGER_SCRIPT" "$SYSTEM_UV" || {
echo "❌ Could not copy wrapper to $SYSTEM_UV. Check permissions."
mv "${SYSTEM_UV}_disabled" "$SYSTEM_UV" 2>/dev/null || true
exit 1
}
chmod +x "$SYSTEM_UV"
echo "✅ Wrapper installed successfully!"
echo " Original uv binary saved as: ${SYSTEM_UV}_disabled"
exit 0
fi
# ----------------------------
# 2) Handle "uninstall"
# ----------------------------
if [ "$1" = "uninstall" ]; then
if [ -z "$SYSTEM_UV" ] || [ ! -f "${SYSTEM_UV}_disabled" ]; then
echo "⚠️ The wrapper does not seem to be installed (no uv_disabled found)."
exit 1
fi
# Check if we really are the wrapper script
if [ "$SYSTEM_UV" != "$MANAGER_SCRIPT" ]; then
echo "⚠️ The uv in PATH ($SYSTEM_UV) is not the same as this script ($MANAGER_SCRIPT)."
echo " Possibly the wrapper is installed elsewhere, or the system is inconsistent."
exit 1
fi
echo "🔁 Restoring original uv from ${SYSTEM_UV}_disabled → $SYSTEM_UV"
rm -f "$SYSTEM_UV" || {
echo "❌ Could not remove wrapper at $SYSTEM_UV."
exit 1
}
mv "${SYSTEM_UV}_disabled" "$SYSTEM_UV" || {
echo "❌ Could not restore original uv."
exit 1
}
chmod +x "$SYSTEM_UV"
echo "✅ Original uv restored."
exit 0
fi
# ----------------------------
# 3) On any other call with arguments,
# we assume we're running in "wrapper mode"
# ----------------------------
# If user calls "uv" with no arguments → show usage
if [ $# -eq 0 ]; then
show_usage
fi
UV_DISABLED="${MANAGER_SCRIPT}_disabled"
# (a) uv pip ...
if [ "$1" = "pip" ]; then
shift
ARGS=""
SKIP_NEXT=0
for arg in "$@"; do
if [ "$SKIP_NEXT" -eq 1 ]; then
SKIP_NEXT=0
continue
fi
if [ "$arg" = "--index-strategy" ]; then
SKIP_NEXT=1
continue
fi
ARGS="$ARGS \"$arg\""
done
# shellcheck disable=SC2086
eval exec pip $ARGS
# (b) uv venv ...
elif [ "$1" = "venv" ]; then
shift
if [ -z "$1" ]; then
exec python3 -m venv .venv
else
exec python3 -m venv "$@"
fi
# (c) uv install => pip install ...
elif [ "$1" = "install" ]; then
shift
exec pip install "$@"
# (d) uv uninstall => pip uninstall ...
elif [ "$1" = "uninstall" ]; then
shift
exec pip uninstall "$@"
# (e) All other commands => forward to uv_disabled
else
if [ -x "$UV_DISABLED" ]; then
exec "$UV_DISABLED" "$@"
else
echo "❌ Original uv not found at: $UV_DISABLED"
echo " Possibly it's already uninstalled or the system is inconsistent."
exit 1
fi
fi
My final installation steps on an old Asus ZenFone 4 (ZE554KL) with stock un-rooted Android 8 is:
- Install F-Droid from homepage
- In F-Droid install Termux and Termux:Boot
- Launch Termux:Boot and then Termux and enter commands:
pkg update
pkg upgrade -y
pkg install openssh -y
passwd
sshd
# continue in ssh
pkg install proot-distro -y
proot-distro install debian
proot-distro login debian
apt update && apt upgrade -y
# follow https://github.com/pascallj/python3.13-backport to install python 3.13
apt install wget -y && wget -qO- https://pascalroeleven.nl/deb-pascalroeleven.gpg > /etc/apt/keyrings/deb-pascalroeleven.gpg
cat <<EOF | tee /etc/apt/sources.list.d/pascalroeleven.sources
Types: deb
URIs: http://deb.pascalroeleven.nl/python3.13
Suites: bookworm-backports
Components: main
Signed-By: /etc/apt/keyrings/deb-pascalroeleven.gpg
EOF
apt update && apt install python3.13 python3.13-dev python3.13-venv build-essential ffmpeg libisal-dev libturbojpeg0 libpcap0.8 -y
# install HA-Core
python3.13 -m venv hass
source hass/bin/activate
pip install --upgrade pip wheel
pip install homeassistant
# patch lib/python3.13/site-packages/zeroconf/_utils/net.py in ip6_addresses_to_indexes to fix USB, DHPC and zeroconf errors
python -c "import zeroconf._utils.net as m; p=m.__file__; o=open(p).read(); old=(' for iface in interfaces:\\n if isinstance(iface, int):\\n result.append((interface_index_to_ip6_address(adapters, iface), iface)) # type: ignore[arg-type]\\n elif isinstance(iface, str) and ipaddress.ip_address(iface).version == 6:\\n result.append(ip6_to_address_and_index(adapters, iface)) # type: ignore[arg-type]'); new=(' for iface in interfaces:\\n try:\\n if isinstance(iface, int):\\n result.append((interface_index_to_ip6_address(adapters, iface), iface)) # type: ignore[arg-type]\\n elif isinstance(iface, str) and ipaddress.ip_address(iface).version == 6:\\n result.append(ip6_to_address_and_index(adapters, iface)) # type: ignore[arg-type]\\n except:\\n pass'); patched=o.replace(old,new); import sys; open(p,'w').write(patched); print('No changes made. Possibly already patched or code differs:', p) if patched==o else print('Successfully patched:', p)"
# run HA
hass -v
# wired thing was, now I didn't need the vu_wrapper.sh script anymore, updates to packages or the installation order might have fixed it - haha :-)
# Finally, create boot scripts
apt install daemonize -y
mkdir -p ~/.termux/boot
echo '#!/data/data/com.termux/files/usr/bin/bash
termux-wake-lock
sshd
' > ~/.termux/boot/01-sshd.sh && chmod +x ~/.termux/boot/01-sshd.sh
echo '#!/data/data/com.termux/files/usr/bin/bash
daemonize $(which proot-distro) login debian -- bash -c "
cd ~
source hass/bin/activate
while true; do
hass
done
"' > ~/.termux/boot/02-hass.sh && chmod +x ~/.termux/boot/02-hass.sh