Files
Microscope-Display/install.sh
Microscope Camera 34cd247dca Microscope camera kiosk
Touchscreen kiosk for the Raspberry Pi HQ camera (IMX477) used as a
microscope: live preview from boot, raw frame recording, full-resolution
stills, and automatic capture-SSD mounting.

- app.py: GTK3 fullscreen UI over cage — preview, REC/STOP, PHOTO,
  90-degree rotate button, tap-to-open exposure/gain/settings sliders,
  and an "SSD NOT MOUNTED" badge
- camera.py: picamera2 wrapper with separate video (ISP preview + packed
  12-bit raw) and still (4056x3040) configurations
- recorder.py: writer thread turning the raw stream into one Bayer frame
  per file plus index.jsonl/session.json, with dropped/missed accounting
- photos.py: still capture to DNG + JPEG, and a background worker that
  renders a viewable 16-bit sRGB TIFF from the 12-bit Bayer frame
- storage.py: SSD mount state and the date/time/format session layout
- tools/unpack_raw.py: desktop-side unpacker/demosaicer
- system/ + install.sh: systemd units, udev rule, mount helper, sudoers

Note: raw frames are written byte-for-byte as the sensor produced them, so
they stay decodeable regardless of how the stills pipeline evolves.
2026-10-31 00:44:46 -04:00

81 lines
2.9 KiB
Bash
Executable File

#!/bin/bash
# Install the microscope camera kiosk and its storage plumbing onto this machine.
#
# This is the scripted form of what was originally set up by hand; running it on
# a fresh Raspberry Pi OS install should reproduce the whole system:
#
# sudo ./install.sh
#
# Everything it writes is listed in the README under "System integration".
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PREFIX="${PREFIX:-/opt/microscope-camera}"
MOUNT_POINT="${MOUNT_POINT:-/mnt/microscope}"
if [[ $EUID -ne 0 ]]; then
echo "run me with sudo" >&2
exit 1
fi
echo "==> packages"
apt-get update
apt-get install -y --no-install-recommends \
cage python3-gi python3-gi-cairo gir1.2-gtk-3.0 python3-cairo \
python3-picamera2 python3-pidng python3-simplejpeg python3-tifffile \
python3-pil python3-numpy grim
echo "==> application -> $PREFIX"
mkdir -p "$PREFIX"
install -m 0644 "$HERE/app.py" "$HERE/camera.py" "$HERE/config.py" \
"$HERE/photos.py" "$HERE/recorder.py" "$HERE/storage.py" \
"$HERE/README.md" "$PREFIX/"
if [[ ! -f "$PREFIX/config.json" ]]; then
install -m 0644 "$HERE/config.json" "$PREFIX/"
fi
mkdir -p "$PREFIX/tools"
install -m 0755 "$HERE/tools/unpack_raw.py" "$PREFIX/tools/"
chown -R tyler:tyler "$PREFIX"
echo "==> SSD mount helper"
install -m 0755 "$HERE/system/microscope-ssd" /usr/local/sbin/microscope-ssd
install -m 0755 "$HERE/system/microscope-boot-check" /usr/local/sbin/microscope-boot-check
echo "==> sudoers"
install -m 0440 -o root -g root "$HERE/system/sudoers-microscope-ssd" \
/etc/sudoers.d/microscope-ssd
echo "==> udev rule"
install -m 0644 "$HERE/system/99-microscope-ssd.rules" \
/etc/udev/rules.d/99-microscope-ssd.rules
echo "==> systemd units"
install -m 0644 "$HERE/system/microscope-camera.service" \
"$HERE/system/microscope-ssd-mount.service" \
"$HERE/system/microscope-boot-check.service" \
/etc/systemd/system/
echo "==> fstab (mount the capture SSD at boot when present)"
if ! grep -q "$MOUNT_POINT" /etc/fstab; then
mkdir -p "$MOUNT_POINT"
UUID="$(blkid -s UUID -o value "$(lsblk -no PATH,LABEL | awk '$2=="MICROSCOPE"{print $1; exit}')" 2>/dev/null || true)"
if [[ -n "${UUID:-}" ]]; then
printf '\n# Microscope capture SSD - mounts automatically when plugged in\n'
printf 'UUID=%s %s ext4 nofail,noatime,errors=remount-ro,x-systemd.device-timeout=5 0 2\n' \
"$UUID" "$MOUNT_POINT" >> /etc/fstab
else
echo " no MICROSCOPE-labelled partition found; add the fstab line by hand" >&2
fi
fi
echo "==> enable services"
systemctl daemon-reload
udevadm control --reload-rules
systemctl enable microscope-camera.service microscope-boot-check.service
systemctl restart microscope-camera.service
echo
echo "done. The kiosk should now be on the display."
echo " systemctl status microscope-camera.service"
echo " journalctl -u microscope-camera.service -f"