Skip to content

About

Overlay to be put over a camera feed to add information on top of a camera feed. Simple HTML layer on top.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

 

History

675 Commits

Folders and files

Repository files navigation

status-badge

Virtual Camera Overlay

A Vue.js-based overlay for displaying fitness tracking data from Home Assistant on your webcam during video meetings.

Overview

This application connects to a Home Assistant instance via WebSockets and displays real-time fitness metrics (steps, speed, distance, heart rate) as a transparent overlay. It's designed to be used with OBS Studio's virtual camera feature in video conferencing apps (Zoom, Teams, Meet, etc.) so you can work out on a treadmill or exercise bike during meetings while showing colleagues you're actively engaged.

Features

  • Real-time Data: Connects to Home Assistant via WebSockets for instant fitness metrics
  • Meeting-Appropriate: Visible enough to show activity, subtle enough not to distract
  • Widget System: Modular display of steps, speed, distance, heart rate with color-coded zones
  • Virtual Camera Ready: Designed to work as a browser source in OBS Studio's virtual camera
  • Transparent Background: Renders only the overlay elements, no camera feed (use OBS to composite)
  • Configurable: Easily customize connection settings via environment variables

Setup

Prerequisites

  • Node.js 18+ and pnpm
  • Home Assistant instance with long-lived access token
  • OBS Studio (for virtual camera functionality)
  • Video conferencing app (Zoom, Teams, Meet, etc.)

Installation

  1. Clone this repository:

    git clone https://github.com/yourusername/fitness-tracker-overlay.git
    cd fitness-tracker-overlay
  2. Install dependencies:

    pnpm install
  3. Configure environment variables:

    • Copy the example environment file:
      cp .env.example .env
    • Edit .env and add your Home Assistant access token and other configuration:
      VITE_HA_TOKEN=your_long_lived_access_token_here
      VITE_HA_DEV_HOST=192.168.0.13
      VITE_HA_DEV_PORT=8123
      
  4. Start the development server:

    pnpm dev
  5. Build for production:

    pnpm build

OBS Studio Virtual Camera Setup

This overlay is designed to be composited with your webcam feed in OBS, then output as a virtual camera to your video conferencing app.

  1. Add your webcam as a "Video Capture Device" source in OBS
  2. Add the overlay as a "Browser" source above your webcam:
    • For local development: use http://localhost:5174/ (Vite dev server)
    • For production: host the built files on a web server or use "Local File" pointing to dist/index.html
  3. Set the Browser source width and height to match your OBS canvas size (e.g., 1920x1080)
  4. Important: Check "Enable transparency" in the Browser Source properties
  5. Start Virtual Camera in OBS (Tools → Start Virtual Camera)
  6. In your video conferencing app (Zoom/Teams/Meet), select "OBS Virtual Camera" as your camera source

Tip: If the overlay background isn't transparent, add this in the Browser source Custom CSS field:

body {
  background-color: rgba(0, 0, 0, 0) !important;
  margin: 0px auto;
  overflow: hidden;
}

Configuration

Environment Variables

Variable Description Default
VITE_HA_TOKEN Home Assistant long-lived access token -
VITE_HA_DEV_HOST Host IP/domain for development 192.168.0.13
VITE_HA_DEV_PORT Dev server websocket port 8123

Runtime token configuration

For production builds the overlay now reads app-config.json at runtime. Create public/app-config.json (or copy public/app-config.example.json) with:

{
  "haToken": "your_long_lived_access_token_here"
}

When deploying via Woodpecker the pipeline writes this file automatically using the HA_TOKEN secret. If the file is missing, the overlay falls back to the compile-time VITE_HA_TOKEN env variable (useful for local dev).

Development Mode

When in development mode (pnpm dev), a Development Panel appears (press u to toggle). It allows you to:

  • Mock step and heart rate data without a real Home Assistant connection
  • Manually control connection state
  • Toggle special overlays (Be Right Back, Heart Rate visualization, Compact steps mode)
  • Monitor current metric values

This makes it easy to test and develop the overlay without needing a running treadmill or Home Assistant instance.

Customizing Entities and Widgets

Which Home Assistant entities feed the overlay, and which widgets appear where, is declared in public/overlay-config.json — a committed file deployed alongside the build (fetched relative to the current page, so it keeps working under Home Assistant's /local/). No entity ID or widget layout is hard-coded in src/.

{
  "maxHeartRate": 185,
  "heartRate": {
    "anchor": "top-left",
    "offset": { "x": 20, "y": 20 }
  },
  "entities": {
    "steps": "sensor.ksmb_v1_7aed_current_step_count",
    "distance": "sensor.ksmb_v1_7aed_current_distance",
    "speed": "number.ksmb_v1_7aed_speed_level",
    "heartRate": "sensor.galaxy_watch5_rrry_heart_rate",
    "brbToggle": "input_boolean.janis_vco_brb",
    "heartToggle": "input_boolean.janis_vco_heart",
    "compactToggle": "input_boolean.janis_vco_compact"
  },
  "widgets": [
    {
      "id": "steps-display",
      "type": "steps",
      "anchor": "bottom-right",
      "offset": { "x": 30, "y": 30 },
      "size": { "width": 240, "height": 190 }
    }
  ]
}
  • entities maps every Home Assistant entity the overlay reads to its entity ID. Point the overlay at a different treadmill or watch by editing these values.
  • widgets is a list of widgets to render. Each entry has an id, a type (steps, temperature, or sensor), an anchor (top-left, top-right, bottom-left, or bottom-right), an offset from that corner, a size, and type-specific props (entityId, unit, displayName — not needed for steps, which reads from the entities above). Add a temperature or sensor entry to light up those widgets; no code change is required. A steps entry may also set compactSize ({width, height}), used instead of the built-in 600×72 default while compact mode is on; omit it to keep that default.
  • maxHeartRate configures the heart-rate zone thresholds (see DESIGN.md).
  • heartRate controls where the BPM display and its pulse-wave animation render — an anchor and offset, same shape as a widget's. They always move together, anchored to the same corner. The full-screen pulsing screen border is unaffected and always stays inset to the viewport. If heartRate is missing or fails validation, the overlay still renders, HeartRate falls back to top-left, {x: 20, y: 20}, and one warning is logged to the console — unlike entities/ widgets, an invalid heartRate doesn't take down the rest of the overlay.

If the file is missing, isn't valid JSON, or is missing/mistypes a required entities or widgets field (including a malformed compactSize), the overlay renders nothing and logs one error to the console rather than running with partial or stale configuration. See docs/adr/0001-overlay-config-file.md and docs/adr/0002-heart-rate-position-and-steps-compact-size.md for the full rationale.

Home Assistant Toggles

These input_boolean helpers can be flipped live from Home Assistant to control the overlay without a redeploy:

Entity Effect
input_boolean.janis_vco_brb Shows the "Be Right Back" overlay
input_boolean.janis_vco_heart Enables the heart-rate pulse visualization
input_boolean.janis_vco_compact Collapses the steps widget into a compact, header-less row

If a helper doesn't exist in Home Assistant, its toggle simply has no effect; the overlay behaves as if it were off.

Troubleshooting

  • Connection Issues: Check that your Home Assistant instance is accessible and that your token is valid.
  • No Data Showing: Verify that the entity IDs in public/overlay-config.json match your Home Assistant entity IDs.
  • Virtual Camera Not Appearing: Make sure OBS Virtual Camera is started (Tools → Start Virtual Camera).
  • Overlay Not Transparent in OBS: Verify "Enable transparency" is checked in Browser source properties.
  • Video App Can't See OBS Camera: Some apps require you to restart them after OBS Virtual Camera is started.

License

MIT License - See LICENSE file for details.

Credits

About

Overlay to be put over a camera feed to add information on top of a camera feed. Simple HTML layer on top.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Used by

Contributors

Languages