# 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": "", "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