Skip to content

v1.29.6

Choose a tag to compare

@github-actions github-actions released this 30 May 23:02
· 139 commits to main since this release

🚀 VibeNVR v1.29.6

📝 Summary

This release delivers a set of focused but impactful improvements to the reliability and clarity of the live monitoring experience. The motion detection pipeline has been hardened against stale state bugs, the UI now communicates the full recording lifecycle with precision, and timezone handling has been made universally correct across all services.

🛠️ What's Changed

🕐 Timezone Consistency — All Docker Services

Previously, the backend and engine services had a hardcoded TZ=Europe/Rome environment variable, silently ignoring any custom timezone set via .env. This caused frame overlays, timeline event entries, and recording filenames to be stamped in the wrong local time for any user outside Italy.

Fix: All four Docker services (backend, engine, frontend, db) now use the dynamic form TZ=${TZ:-Europe/Rome}, which respects the value in .env while keeping Europe/Rome as the safe default. Existing setups are unaffected.


🛡️ Motion Badge Reliability — No More Stuck Badges

A stale-state bug caused the AI: PERSON or MOTION badge on the live camera card to persist indefinitely after disabling and re-enabling a camera while a motion event was still active. The root cause was entries being added to the backend's in-memory LIVE_MOTION dict on motion_on events but never cleaned up on camera stop.

Three independent fixes have been applied to make the system resilient at every layer:

  • TTL Guard (Backend — routers/events.py): Every motion_on event now stores a _updated_at timestamp. The /events/status route checks this on every poll and automatically evicts any LIVE_MOTION entry older than 60 seconds. This acts as a safety net if the motion_end event is ever missed (e.g., due to a container crash).

  • Instant Cleanup on Camera Stop (Backend — motion_service.py): The stop_camera() function now immediately removes the camera's entry from LIVE_MOTION after sending the stop signal to the engine. The badge disappears the instant you toggle the camera off, with no delay.

  • Engine State Reset on Detection Switch (Engine — camera_thread.py): When the active detection engine is changed at runtime (e.g., switching from OpenCV to AI Engine in camera settings), if a motion event was already in progress, the engine now fires a synthetic motion_end event before handing off to the new engine. This prevents the new engine from inheriting stale motion state and ensures a clean transition.


🎨 Live View — Three-State Recording Badge

The live camera tile previously used a single red pulsing badge for all active states. This made it impossible to distinguish between an active detection event and the post-capture recording cooldown (where the motion has ended but the video file is still being written to disk).

The UI now exposes three distinct visual states:

State Visual Badge Text Meaning
Active Motion (OpenCV) 🔴 Pulsing red border + badge MOTION Background subtraction has detected movement
Active Motion (AI Engine) 🔴 Pulsing red border + badge AI: PERSON (or detected label) YOLO model has identified an object
Finalizing Recording 🟠 Solid orange border + badge SAVING REC Motion ended, post-capture buffer writing to disk
Continuous Mode 🔵 Solid blue border + badge CONTINUOUS Always-on recording, no motion trigger required

The transition is now: AI: PERSON → (you leave frame) → SAVING REC → (file finalized) → badge disappears.


🌍 Localization

The new SAVING REC badge string has been fully localized. The extract_t.py and auto_translate.py scripts were run to propagate the translation key timeline.saving_rec to all 10 supported locale files:

EN · IT · FR · DE · ES · PT · ZH · JA · UK · RU


🙌 Contributors

A big thank you to the following community contributors whose work is included in this release:

  • @Lion-killer (Yuriy Bilous)
    • PR #34 — Fixed a runtime crash caused by a missing t() translation wrapper in LogSettingsModal, which would cause the Logs settings panel to fail to render in non-English locales. @Lion-killer in #34
    • PR #29 — Contributed the complete Ukrainian (uk) locale translation, adding full language support for Ukrainian-speaking users. @Lion-killer in #29

⬆️ Upgrade Notes

No database migrations or configuration changes are required for this release.

If you have set a custom TZ value in your .env file, it will now be correctly applied to all services automatically after the next rebuild.

docker compose down && docker compose up -d --build (only for dev environment)

## New Contributors
* @Lion-killer made their first contribution in https://github.com/spupuz/VibeNVR/pull/29

**Full Changelog**: https://github.com/spupuz/VibeNVR/compare/v1.29.5...v1.29.6