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:
- Turn cellar lighting ON
- Capture and rectify a camera snapshot
- Crop individual shelf bins
- Run bottle-end detection using ONNX
- Compare detection results with database inventory
- Turn lighting OFF
- 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:
- Attempt to turn light OFF
- Record pipeline finish time
- Compute total runtime
- 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.