From 6efcad9cdf00229d1e96afa425f95407742b9ee6 Mon Sep 17 00:00:00 2001 From: Bora Date: Thu, 1 Jan 2026 11:39:26 +0100 Subject: [PATCH] 5: readme --- app.py | 2 +- readme.md | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 readme.md diff --git a/app.py b/app.py index 749ff82..4295cd9 100644 --- a/app.py +++ b/app.py @@ -29,7 +29,7 @@ DETECTION_INTERVAL = 10 # - Low values (1-5) allow darker/low-contrast images (good for night). # - High values (20-40) filter out gray/blank screens but might skip valid dark images. # - Set to 0 to disable this check entirely. -FRAME_STD_THRESHOLD = 5.0 +FRAME_STD_THRESHOLD = 1.0 # ------------------------------------------------------------------------------ diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..56e8648 --- /dev/null +++ b/readme.md @@ -0,0 +1,63 @@ +# RTSPCamDigitDetection Backend + +This service reads frames from one or more RTSP cameras, crops user-defined ROIs (Regions of Interest) containing 7‑segment digits, runs a TensorFlow Lite digit classifier, and publishes the assembled numeric value to MQTT (e.g., for Home Assistant) [code_file:9][code_file:11]. + +It also exposes a Flask web UI/API for live video previews, snapshots, and ROI configuration [code_file:9]. + +## High-Level Architecture + +* **`app.py` (Main Service):** Runs the Flask web server and the main processing loop. It drains results from the inference worker, handles MQTT publishing, and manages the rate-limiting logic per camera [code_file:9]. +* **`inference.py` (Worker):** A background thread that performs the heavy lifting. It accepts frames, crops the ROIs, runs the TFLite model, and validates results against confidence thresholds and numeric ranges [code_file:11]. +* **`manager.py` & `camera.py`:** Handles the RTSP connections, frame buffering, and camera configuration management. + +## Configuration + +Configuration variables are defined directly at the top of the scripts for simplicity. + +### 1. Main Settings (`app.py`) +Edit the top section of `app.py` to change these [code_file:9]: + +* **`DEBUG_LOG`** *(bool)*: + * `True`: Enables verbose logging (heartbeats every 5s, per-task timing, detailed skip reasons). + * `False`: Quiet mode. Only prints crucial info (MQTT publishes, connection errors). Warnings about skipped frames are rate-limited to once per minute to prevent log flooding. +* **`DETECTION_INTERVAL`** *(int)*: + * How often (in seconds) to attempt a detection for each camera (Default: `10`). +* **`FRAME_STD_THRESHOLD`** *(float)*: + * Standard Deviation threshold to filter out "bad" frames before inference. + * Frames with contrast lower than this value are skipped. + * *Recommendation:* Set to `0` or `1` if your valid digits are low-contrast. Set higher (e.g., `25`) only if you need to filter out specific gray/green encoding artifacts. + +### 2. Inference Settings (`inference.py`) +Edit the top section of `inference.py` to tune the AI [code_file:11]: + +* **`CONFIDENCE_THRESHOLD`** *(0.0 - 1.0)*: + * Minimum confidence required for a digit to be accepted. + * *Recommendation:* `0.85` is a good balance to prevent false positives like "1010" while accepting valid digits. +* **`MIN_VALUE` / `MAX_VALUE`** *(int)*: + * Sanity check range. Decoded numbers outside this range (e.g., `1010`) are discarded. + +## How It Works (Logic & Logging) + +### The "10s vs 60s" Behavior +You might notice that successful detections are logged every **10 seconds**, but errors (like "Value out of range") appear only every **60 seconds**. +* **Success:** The app attempts detection every `DETECTION_INTERVAL` (10s). Every success is logged immediately as INFO. +* **Failure:** If the camera feed is bad or the value is out of range, the error technically occurs every 10s. However, when `DEBUG_LOG = False`, these repetitive warnings are suppressed and only printed **once per minute** to keep the CLI readable [code_file:9]. + +### MQTT Behavior +* **Topic:** `homeassistant/sensor/RTSPCamDigitDetection/state/` +* **Payload:** `{"value": 42, "confidence": 0.98}` +* **Trigger:** Published only on **successful** detection and validation. Errors are not published to this topic to avoid messing up sensor history. + +## API Endpoints + +The app runs on port `5000` by default [code_file:9]. + +| Method | Endpoint | Description | +| :--- | :--- | :--- | +| `GET` | `/` | Web UI Entry point. | +| `GET` | `/video/` | MJPEG stream for live preview. | +| `GET` | `/snapshot/` | Capture a single JPEG snapshot. | +| `GET` | `/cameras` | List configured cameras. | +| `GET` | `/rois/` | Get current ROI definitions. | +| `POST` | `/save_rois` | Save new ROI definitions to disk. | +| `POST` | `/detect_digits` | Manual trigger: runs inference immediately and returns full debug details (JSON). |