# pantry-vision configuration template.
#
# Copy this to the container host as (for example)
# /opt/smart-home/pantry-vision/pantry-vision.env, fill in real values, and chmod 600
# it. Same never-commit handling as admin-canvas.env / digest-engine.env.

# ---------------------------------------------------------------------------
# Auth — required. pantry-vision fails closed (rejects every request) while this is
# empty. Unlike admin-canvas's token (which only ever needs to be known by Home
# Assistant), this one also has to be baked into the kitchen-display kiosk's own
# build config (hosts/kitchen-display/scripts/build-kitchen-display-iso.sh), since
# the kiosk's frontend calls this API directly, not through HA. Generate one with:
#   openssl rand -hex 32
# ---------------------------------------------------------------------------
PANTRY_VISION_TOKEN=

# ---------------------------------------------------------------------------
# Vision LLM (Ollama, the same LLM host as digest-engine/Assist)
# ---------------------------------------------------------------------------
OLLAMA_HOST=http://llm-host:11434
# MUST be a vision-capable model, and MUST already be pulled on the LLM host
# (`ollama pull llava`, or whatever you pick) — plain text models like the
# qwen2.5:14b-instruct used elsewhere in this project cannot see images at all.
# Not verified against a real pull/run — see README.md.
OLLAMA_VISION_MODEL=llava
OLLAMA_TIMEOUT=120

# ---------------------------------------------------------------------------
# Grocy — already running as the always-on `grocy` container from
# hosts/container-host/scripts/setup-container-host.sh, reachable on the compose
# network at this internal name/port regardless of ENABLE_PANTRY_VISION.
# ---------------------------------------------------------------------------
GROCY_URL=http://grocy:80
# Settings -> Manage API keys, inside Grocy's own UI. Required for every write
# (/confirm, /consume, /adjust); the reads use the same key.
GROCY_API_KEY=
# VERIFY against your own Grocy instance (Settings -> Locations / Quantity units) —
# these are fresh-install defaults ("Default" location, "Piece" unit), not guaranteed
# to match a Grocy that's already been customised. GROCY_DEFAULT_QU_ID is the unit
# stock is counted in, and pantry-vision counts INDIVIDUAL ITEMS, never packages: a
# twelve-pack of eggs is booked in as twelve. Point this at a "Piece"-like unit, not
# at "Pack".
GROCY_DEFAULT_LOCATION_ID=1
GROCY_DEFAULT_QU_ID=2

# ---------------------------------------------------------------------------
# Where things get put away. The confirm screen's fridge/freezer/cupboard/counter
# choice is resolved to a Grocy location BY NAME, creating it if it doesn't exist —
# so if your Grocy already calls them something else ("Kühlschrank", "Vorratskammer"),
# put those names here. A mismatch doesn't error, it quietly creates a second,
# duplicate location, which is the kind of thing you only notice a month later.
#
# With more than one cold appliance, name them apart here ("Fridge (kitchen)") and
# list every one of them in PANTRY_DOOR_APPLIANCES below — see
# docs/fridge-item-location.md.
# ---------------------------------------------------------------------------
PANTRY_LOCATION_FRIDGE=Fridge
PANTRY_LOCATION_FREEZER=Freezer
PANTRY_LOCATION_CUPBOARD=Cupboard
PANTRY_LOCATION_COUNTER=Counter

# ---------------------------------------------------------------------------
# Door-sensor-triggered appliance cameras (optional; off while unset).
#
# Format:  id:Grocy location name:frigate_camera , ...
# The camera is optional — an appliance with only a door sensor still records that
# it was opened, which is the half of this feature that pays for itself.
#
# A Zigbee contact sensor on each door drives an HA automation that POSTs
# {"appliance": "<id>", "state": "opened"} to this service's /doorway-event. The
# service then pulls a short burst from that camera and records what it recognised
# as a HINT — with a timestamp and a confidence, in its own SQLite file, NEVER into
# Grocy stock. A camera at a door cannot tell in from out, misses two-items-at-once,
# and sees nothing behind an arm; read docs/fridge-item-location.md before treating
# any of it as authoritative. Moving stock between appliances is /transfer, which a
# person taps.
# ---------------------------------------------------------------------------
PANTRY_DOOR_APPLIANCES=
# Example:
# PANTRY_DOOR_APPLIANCES=fridge-kitchen:Fridge (kitchen):cam_fridge_kitchen,freezer-loggia:Freezer (loggia):cam_freezer_loggia

# The same Frigate this project's `chores` already pulls snapshots from. Unset means
# door events are still recorded, just without a picture.
FRIGATE_URL=
FRIGATE_TIMEOUT=15
# Frames per door event, and the gap between them. An item crosses a doorway in about
# a second: one frame is a coin toss, ten is a queue at the vision model. The burst
# stops early on the first frame that identifies something.
PANTRY_DOORWAY_BURST=3
PANTRY_DOORWAY_BURST_INTERVAL=0.7
# Hints are worthless once stale, and are pruned on write.
PANTRY_HINT_RETENTION_DAYS=30
PANTRY_HINTS_DB_PATH=/data/pantry-hints.db

# ---------------------------------------------------------------------------
# Run behaviour
# ---------------------------------------------------------------------------
PANTRY_VISION_PORT=8095
PANTRY_VISION_MAX_IMAGE_MB=15
# Upper bound on the vision model's claimed pack size, since that number gets
# multiplied into stock. It is editable on screen before anything is written; this is
# only the guard against a model that answers "units_per_package": 100000.
PANTRY_MAX_UNITS_PER_PACKAGE=240
LOG_LEVEL=INFO
