Skip to content

stock_runtime.py — Vision Pipeline Runtime Orchestrator

Overview

stock_runtime.py is the main runtime orchestrator of the automated wine inventory vision pipeline in the Wine Platform project.

It executes the full end-to-end stock detection workflow:

  1. Turn cellar lighting ON
  2. Capture and rectify a camera snapshot
  3. Crop individual shelf bins
  4. Run bottle-end detection using ONNX
  5. Compare detection results with database inventory
  6. Turn lighting OFF
  7. Write a structured JSON execution summary

The pipeline is designed for fully autonomous execution and is typically triggered by a scheduled cron job.

Key properties:

  • headless execution
  • deterministic pipeline order
  • structured step logging
  • non-fatal hardware control
  • always writes run summary
  • exit codes compatible with cron/systemd

Role in Wine Platform Architecture

stock_runtime.py belongs to the Vision Workers lane of the Wine Platform system.

The Wine Platform consists of two main operational lanes:

Lane Purpose
Manual Lane Qt kiosk UI for manual cellar management
Vision Lane automated stock detection pipeline

System Architecture

flowchart LR

subgraph VisionWorkers["Vision Workers - wine_inventory"]
SR["stock_runtime.py"]
SNAP["take_clean_snapshot.py"]
CROP["crop_with_json.py"]
ONNX["onnx_batch.py"]
DBC["DB_compare.py"]
end

subgraph Hardware
CAM["Tapo Camera (RTSP)"]
LIGHT["Tapo Smart Plug<br>Cellar Light"]
end

subgraph Storage
DB[(MariaDB Inventory)]
OUT["Detection Output Folder"]
end

SR --> SNAP
SNAP --> CROP
CROP --> ONNX
ONNX --> DBC

CAM --> SNAP
SR --> LIGHT

DBC <--> DB
SR --> OUT

Pipeline Execution Flow

The runtime executes a strict sequence of steps.

flowchart TD

START["Pipeline Start"]

LON["tapo_turn_on_and_settle"]
SNAP["take_clean_snapshot"]
CROP["crop_with_json"]
ONNX["onnx_batch"]
DBC["DB_compare"]
LOFF["tapo_turn_off"]

SUMMARY["Write Summary JSON"]

START --> LON
LON --> SNAP
SNAP --> CROP
CROP --> ONNX
ONNX --> DBC
DBC --> LOFF
LOFF --> SUMMARY

Configuration

Configuration is loaded from:

CONF_DIR/pince_shelf.ini

via:

load_pince_config()

The configuration file contains:

Section Purpose
camera RTSP camera settings
paths output directories
crop geometry shelf bin coordinates
model paths ONNX detection model
lighting Tapo plug settings

Runtime Constants

INI_FILENAME = "pince_shelf.ini"
DEFAULT_CAM = 0
DEFAULT_INIT_TEMPLATES = False

DEFAULT_CAM

Camera index used for snapshot acquisition.

DEFAULT_INIT_TEMPLATES

Controls whether corner templates should be re-initialized.

Normally:

False

Template initialization is only used during manual recalibration.


Lighting Control

Function

_turn_light_on_and_settle(cfg)

Purpose:

  • request light ON
  • wait for illumination stabilization

Dependencies:

switch_light_on(cfg)
get_light_stabilize_seconds(cfg)

Example result:

{
 "requested": "on",
 "ok": true,
 "stabilized": true,
 "slept_seconds": 2.0
}

Lighting control is non-fatal.

If the light fails to turn on:

  • pipeline continues
  • error recorded in summary

Pipeline Steps

Step 1 — Snapshot Acquisition

Module:

take_clean_snapshot.run()

Responsibilities:

  • capture camera frame
  • detect shelf corner markers
  • rectify perspective
  • produce aligned shelf image

Outputs:

rectified snapshot
debug overlays
snapshot images

Step 2 — Shelf Bin Cropping

Module:

crop_with_json.run()

Purpose:

  • load shelf geometry
  • crop each diamond-shaped bin
  • generate individual bin images

Outputs:

cropped bin images

Step 3 — Bottle-End Detection

Module:

onnx_batch.run()

Purpose:

  • run ONNX inference on each bin
  • detect bottle ends
  • compute bottle counts

Outputs:

detection JSON files
per-bin counts

Step 4 — Database Comparison

Module:

DB_compare.run()

Purpose:

  • compare detected counts
  • validate against stored inventory

Outputs:

  • discrepancy reports
  • inventory validation

Pipeline Control Functions

Two helper functions manage pipeline execution.


_step()

Used for critical steps.

Behavior:

  • executes step
  • measures runtime
  • records result
  • raises exceptions if failure occurs

Recorded data:

{
  name
  ok
  seconds
  result
}

_step_nonfatal()

Used for non-critical steps.

Behavior:

  • catches exceptions
  • logs failure
  • pipeline continues

Recorded data:

{
  name
  ok
  seconds
  error
}

JSON Execution Summary

A run summary is always written to:

<det_out>/stock_runtime_summary.json

Example:

{
 "pipeline": "stock_runtime",
 "started_at": "2026-03-10 05:00:00",
 "steps": [
   {
     "name": "take_clean_snapshot",
     "ok": true,
     "seconds": 1.24
   }
 ],
 "ok": true,
 "seconds_total": 12.6
}

Purpose:

  • monitoring
  • debugging
  • operational tracking

Logging System

Logging is initialized via:

_init_logging()

Log directory:

/home/pi/wine_platform/shared/logs

Log file:

pipeline_runtime.log

Log format:

timestamp [LEVEL] module - message

Logging outputs:

Destination Purpose
file persistent logs
console runtime debugging

Error Handling Strategy

Design principle:

The pipeline must never crash silently.

Scenario Behavior
light control fails continue
snapshot fails pipeline fails
cropping fails pipeline fails
detection fails pipeline fails
DB comparison fails pipeline fails

Regardless of failures:

  • summary JSON is written
  • light OFF attempt is executed

Finalization Logic

Inside the finally block:

  1. Attempt to turn light OFF
  2. Record pipeline finish time
  3. Compute total runtime
  4. Write summary JSON

Even if the pipeline fails.


Runtime Sequence

sequenceDiagram

participant Cron
participant Runtime
participant Light
participant Camera
participant Vision
participant Database

Cron->>Runtime: start stock_runtime.py

Runtime->>Light: switch_light_on()
Light-->>Runtime: confirmation

Runtime->>Camera: capture snapshot
Camera-->>Runtime: frame

Runtime->>Vision: crop bins
Vision-->>Runtime: bin images

Runtime->>Vision: run ONNX detection
Vision-->>Runtime: bottle counts

Runtime->>Database: compare inventory
Database-->>Runtime: validation result

Runtime->>Light: switch_light_off()

Runtime->>Runtime: write JSON summary

Dependencies

Python Standard Library

json
logging
time
pathlib
typing

Project Modules

pince_shelf.config.settings
pince_shelf.utils.paths
pince_shelf.utils.tapo_manager

pince_shelf.vision.take_clean_snapshot
pince_shelf.vision.crop_with_json
pince_shelf.vision.onnx_batch
pince_shelf.vision.DB_compare

External Systems

System Role
Tapo camera image source
Tapo smart plug cellar lighting
ONNX runtime bottle detection
MariaDB inventory database

Scheduling

The script is typically executed by cron.

Example:

0 3 * * * python stock_runtime.py

Meaning:

Run the full stock detection pipeline daily at 03:00.


Reliability Features

The pipeline includes several mechanisms to ensure stable operation:

  • deterministic execution order
  • hardware control isolation
  • step timing metrics
  • structured summary output
  • robust exception handling
  • guaranteed light shutdown

Summary

stock_runtime.py is the central orchestrator of the Wine Platform vision system.

Responsibilities include:

  • controlling illumination
  • executing the vision pipeline
  • comparing results with database state
  • producing structured execution logs

The design allows the wine cellar inventory system to operate fully autonomously, while maintaining traceability, observability, and reliability.