Spaces:
Running
Running
| """ | |
| Manual presence detection test. | |
| Runs for ~1 minute, checking the webcam every 10 seconds. | |
| Prints each result live and logs to the database. | |
| Usage: | |
| uv run python scripts/test_presence_local.py | |
| """ | |
| import logging | |
| import time | |
| from datetime import datetime, timezone | |
| from db.database import get_connection, initialize_database | |
| from db import queries | |
| from core.notifications import send_notification | |
| from core.presence import PresenceDetector | |
| from core.tts import speak | |
| from vital_types.db import PresenceConfig, PresenceLogEntry | |
| CHECK_INTERVAL_SECONDS = 10 | |
| RUN_DURATION_SECONDS = 60 | |
| # After 1 minute of continuous presence, a break reminder fires. | |
| MAX_CONTINUOUS_MINUTES = 1 | |
| logging.basicConfig(level=logging.INFO, format="%(message)s") | |
| def main() -> None: | |
| """Run a short local presence detection session in the foreground.""" | |
| initialize_database() | |
| queries.save_presence_config( | |
| PresenceConfig( | |
| enabled=True, | |
| max_continuous_minutes=MAX_CONTINUOUS_MINUTES, | |
| break_message="Test break — you've been at your desk for 1 minute. Stretch!", | |
| break_duration_minutes=5, | |
| check_interval_seconds=CHECK_INTERVAL_SECONDS, | |
| ) | |
| ) | |
| config = queries.get_presence_config() | |
| assert config is not None | |
| print("Vitál presence test") | |
| print(f"- Check interval: {CHECK_INTERVAL_SECONDS}s") | |
| print(f"- Run duration: {RUN_DURATION_SECONDS}s") | |
| print(f"- Break after: {config.max_continuous_minutes} minute(s) of continuous presence") | |
| print("- Sit in front of your webcam. Press Ctrl+C to stop early.\n") | |
| detector = PresenceDetector(config=config) | |
| deadline = time.time() + RUN_DURATION_SECONDS | |
| check_number = 0 | |
| try: | |
| while time.time() < deadline: | |
| check_number += 1 | |
| present = detector.check_once() | |
| if present: | |
| detector.continuous_seconds += detector.check_interval | |
| else: | |
| detector.continuous_seconds = 0 | |
| status = "PRESENT" if present else "away" | |
| continuous_minutes = detector.continuous_seconds // 60 | |
| print( | |
| f"[check {check_number}] {datetime.now().strftime('%H:%M:%S')} " | |
| f"{status} (continuous ~{continuous_minutes} min)" | |
| ) | |
| queries.insert_presence_log( | |
| PresenceLogEntry( | |
| detected=present, | |
| checked_at=datetime.now(timezone.utc), | |
| continuous_minutes=continuous_minutes, | |
| ) | |
| ) | |
| if present and detector.continuous_seconds >= detector.max_continuous: | |
| print(" -> Break threshold reached. Firing reminder...") | |
| message = detector.break_message | |
| send_notification("Vitál — Time for a Break", message, job_id="presence_break") | |
| speak(message) | |
| detector.continuous_seconds = 0 | |
| time.sleep(CHECK_INTERVAL_SECONDS) | |
| except KeyboardInterrupt: | |
| print("\nStopped early.") | |
| print("\nDone. Last 10 presence_log rows:") | |
| connection = get_connection() | |
| rows = connection.execute( | |
| "SELECT detected, checked_at, continuous_minutes FROM presence_log ORDER BY id DESC LIMIT 10;" | |
| ).fetchall() | |
| for row in reversed(rows): | |
| status = "present" if row["detected"] else "away" | |
| print(f" {row['checked_at']} {status} (continuous ~{row['continuous_minutes']} min)") | |
| if __name__ == "__main__": | |
| main() | |