-
-
Notifications
You must be signed in to change notification settings - Fork 13
Camera
Ava streams live camera video and snapshots directly to Home Assistant via the native ESPHome protocol. No intermediate server, no HTTP bridge, no browser rendering — just a direct binary stream from the Android camera to HA.
Compatible with Android 5-16.
WallPanel is a popular Android kiosk app that also streams camera to Home Assistant. But users consistently report lag, stuttering, and frame accumulation on WallPanel. Here is why Ava does not have these problems:
WallPanel and similar apps stream camera frames over HTTP. This approach has a fundamental flaw:
- HTTP buffering — Each frame is sent as an HTTP response. Both the server and HA's client buffer the data. When the network is slow, frames queue up in multiple buffers
- No backpressure — The camera produces frames at a fixed rate. If the network cannot keep up, frames accumulate in memory. The stream falls further and further behind real-time
- Multiple layers of latency — The frame passes through HTTP, TCP, HA's HTTP client, HA's camera component, and the browser canvas. Each step adds delay
- Result — After a few minutes, the "live" stream is showing frames from 10-30 seconds ago. The only fix is to restart the stream
Ava uses a fundamentally different streaming architecture:
| Aspect | WallPanel (HTTP) | Ava (Native ESPHome) |
|---|---|---|
| Transport | HTTP multipart stream | Native ESPHome protocol |
| Buffering | Server + client buffers | No intermediate buffer |
| Backpressure | None — frames queue in memory | Smart frame dropping — old frames are discarded |
| Frame dropping | No — every frame is queued | Yes — only the latest frame is kept |
| Lag accumulation | Yes — buffers grow over time | No — the stream always shows current frames |
The key difference: Ava never lets frames accumulate. If the network is slow, the frame rate drops gracefully, but the frames you see are always current — never seconds behind. The stream self-corrects automatically. There is no growing delay, no need to restart.
Capture single photos on demand from Home Assistant.
- Configurable image size (Original, 500px, 720px, 1080px square crop)
- Auto rotation correction based on device orientation
- Manual orientation override (Portrait, Portrait Flipped, Landscape, Landscape Flipped)
- Front or back camera selection
- Works on old devices with legacy camera hardware
Live video streaming via native ESPHome protocol.
- Frame rate: 1-15 FPS (configurable)
- Resolution: 240p-720p (configurable)
- Smart frame dropping — never accumulates lag
- Automatic orientation handling with manual override
- Video recording state persists across app restarts
On-device face detection. No cloud, no external API — all processing happens locally on the Android device.
- Draws bounding boxes around detected faces on the video stream
- Reports person detected as a binary sensor to HA
- Smoothing algorithm for stable detection (no flickering)
On-device gender classification for each detected face.
- Counts male and female faces separately
- Reports as separate sensors to HA
- Smoothing to prevent flickering
- Only runs when face detection is enabled
Go to Settings -> Advanced
| Setting | Description | Default |
|---|---|---|
| Remote Camera | Allow HA to control camera remotely | Off |
| Camera Mode | Snapshot or Video mode | Snapshot |
| Camera Selection | Front or back camera | Front |
| Video FPS | Video stream frame rate (1-15) | 2 fps |
| Video Resolution | Video stream resolution (240-720) | 240p |
| Image Orientation | Auto, Portrait, Portrait Flipped, Landscape, Landscape Flipped | Auto |
| Image Size | Original, 500px, 720px, 1080px | 500px |
| Face Detection | Detect faces in video stream | Off |
| Show Face Box | Draw bounding box around detected faces | Off |
| Mode | Description |
|---|---|
| Snapshot Mode | HA triggers a snapshot on demand via button press |
| Video Mode | HA toggles recording on/off via switch; live stream while recording |
| Camera | Description |
|---|---|
| Back Camera | Rear-facing camera |
| Front Camera | Front-facing camera (default — better for kiosk/dashboard use) |
| Frame Rate | Use Case | Bandwidth |
|---|---|---|
| 1 fps | Static monitoring, lowest bandwidth | ~30 KB/s |
| 2 fps | Default, general monitoring | ~60 KB/s |
| 5 fps | General surveillance | ~150 KB/s |
| 10 fps | Motion monitoring | ~300 KB/s |
| 15 fps | Maximum smoothness | ~450 KB/s |
Actual bandwidth depends on resolution, scene complexity, and JPEG compression. These are estimates for 480p.
| Resolution | Pixels | Bandwidth | Use Case |
|---|---|---|---|
| Smooth | 320x240 | Lowest | Low-bandwidth, battery saving |
| SD | 480x360 | Low | General monitoring |
| HD | 640x480 | Medium | Clear image, good balance |
| FHD | 960x720 | High | Maximum detail |
| Orientation | Description |
|---|---|
| Auto | Use device sensor to determine rotation |
| Portrait | Force 0° rotation |
| Portrait Flipped | Force 180° rotation |
| Landscape | Force 90° rotation |
| Landscape Flipped | Force 270° rotation |
| Size | Description |
|---|---|
| Original | No crop, full sensor image |
| 500px | Center square crop, 500x500 |
| 720px | Center square crop, 720x720 |
| 1080px | Center square crop, 1080x1080 |
Ava's camera works across a wide range of Android devices, from modern flagships to decade-old tablets.
Full CameraX support with hardware-accelerated JPEG encoding. Works on:
- Google Pixel (all generations)
- Samsung Galaxy (all generations)
- Xiaomi / Redmi / Poco
- OnePlus / Oppo / Vivo
- Most modern Android devices
Devices with older camera hardware are automatically detected and handled with special care:
- Retry logic for camera initialization failures
- Automatic fallback to closest available resolution
Tested on:
- Samsung Galaxy Tab S2
- Samsung Galaxy Tab A (2016)
- Amazon Fire Tablet (5th gen+)
- Various Android 5-6 era tablets
Some kiosk devices block background camera access. Ava automatically handles these restrictions:
- Meta Portal (all models)
- Other kiosk devices with similar camera restrictions
- Automatically detected — no manual configuration needed
Ava auto-detects camera availability. If no camera is present, camera entities are not created in HA.
| Entity | Description | Mode |
|---|---|---|
camera.your_device_name_camera_snapshot |
Snapshot camera | Snapshot |
camera.your_device_name_video_camera |
Video stream camera | Video |
button.your_device_name_take_snapshot |
Trigger snapshot | Snapshot |
switch.your_device_name_video_recording |
Toggle video recording | Video |
| Entity | Description |
|---|---|
binary_sensor.your_device_name_face_detected |
Person detected (occupancy class) |
sensor.your_device_name_male_count |
Number of male faces detected |
sensor.your_device_name_female_count |
Number of female faces detected |
type: picture-entity
entity: camera.your_device_name_video_camera
camera_view: live
show_name: false
show_state: falsetype: picture-glance
entity: camera.your_device_name_video_camera
camera_view: live
entities:
- entity: switch.your_device_name_video_recording
name: Recording
- entity: binary_sensor.your_device_name_face_detected
name: Personservice: camera.snapshot
target:
entity_id: camera.your_device_name_camera_snapshot
data:
filename: /config/www/snapshots/front_door_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpgCombine video stream + face detection + notifications for a complete security camera:
automation:
- alias: "Person Detected - Send Snapshot"
trigger:
- platform: state
entity_id: binary_sensor.ava_face_detected
to: "on"
action:
- service: camera.snapshot
target:
entity_id: camera.ava_camera_snapshot
data:
filename: /config/www/snapshots/detection_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg
- service: notify.mobile_app
data:
message: "Person detected"
data:
image: /api/snapshot_proxy/camera.ava_camera_snapshotTurn on lights when a person is detected on camera, turn off when no one is there:
automation:
- alias: "Camera Occupancy - Lights On"
trigger:
- platform: state
entity_id: binary_sensor.ava_face_detected
to: "on"
action:
- service: light.turn_on
target:
entity_id: light.living_room
- service: input_boolean.turn_on
target:
entity_id: input_boolean.room_occupied
- alias: "Camera Occupancy - Lights Off"
trigger:
- platform: state
entity_id: binary_sensor.ava_face_detected
to: "off"
for:
minutes: 5
action:
- service: light.turn_off
target:
entity_id: light.living_room
- service: input_boolean.turn_off
target:
entity_id: input_boolean.room_occupiedUse a physical button or HA dashboard button to simulate a doorbell — capture a snapshot and send it to your phone:
automation:
- alias: "Doorbell Press"
trigger:
- platform: state
entity_id: button.ava_take_snapshot
to: "unavailable"
action:
- delay: 2
- service: camera.snapshot
target:
entity_id: camera.ava_camera_snapshot
data:
filename: /config/www/doorbell.jpg
- service: notify.mobile_app
data:
title: "Doorbell"
message: "Someone is at the door"
data:
image: /local/doorbell.jpgStart recording when motion is detected by a separate PIR sensor, stop after 5 minutes of no motion:
automation:
- alias: "Motion - Start Recording"
trigger:
- platform: state
entity_id: binary_sensor.hallway_pir
to: "on"
action:
- service: switch.turn_on
target:
entity_id: switch.ava_video_recording
- alias: "No Motion - Stop Recording"
trigger:
- platform: state
entity_id: binary_sensor.hallway_pir
to: "off"
for:
minutes: 5
action:
- service: switch.turn_off
target:
entity_id: switch.ava_video_recordingTake a snapshot every hour and store it for time-lapse:
automation:
- alias: "Hourly Snapshot"
trigger:
- platform: time_pattern
hours: "/1"
action:
- service: camera.snapshot
target:
entity_id: camera.ava_camera_snapshot
data:
filename: /config/www/timelapse/{{ now().strftime('%Y%m%d_%H') }}.jpgWhen someone approaches (proximity), turn on the display and start the camera. When they leave, turn everything off:
automation:
- alias: "Approach - Smart Display On"
trigger:
- platform: state
entity_id: binary_sensor.ava_proximity
to: "on"
action:
- service: switch.turn_on
target:
entity_id: switch.ava_display
- service: switch.turn_on
target:
entity_id: switch.ava_video_recording
- alias: "Leave - Smart Display Off"
trigger:
- platform: state
entity_id: binary_sensor.ava_proximity
to: "off"
for:
minutes: 2
action:
- service: switch.turn_off
target:
entity_id: switch.ava_video_recording
- service: switch.turn_off
target:
entity_id: switch.ava_displayWhen Ava detects a wake word, capture a snapshot to see who is talking:
automation:
- alias: "Wake Word Snapshot"
trigger:
- platform: state
entity_id: assist_satellite.ava
to: "listening"
action:
- service: camera.snapshot
target:
entity_id: camera.ava_camera_snapshot
data:
filename: /config/www/wake_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpgIf Bluetooth presence shows a family member is home, suppress the person detection alert. If no one is home, treat it as an intruder:
automation:
- alias: "Intruder Alert"
trigger:
- platform: state
entity_id: binary_sensor.ava_face_detected
to: "on"
condition:
- condition: state
entity_id: binary_sensor.ava_bluetooth_presence
state: "off"
action:
- service: camera.snapshot
target:
entity_id: camera.ava_camera_snapshot
data:
filename: /config/www/intruder_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg
- service: notify.mobile_app
data:
title: "Intruder Alert"
message: "Person detected but no family member is home"
data:
image: /local/intruder_latest.jpg
priority: highWhen an audio event (glass breaking, alarm, baby crying) is detected, capture a snapshot to see what happened:
automation:
- alias: "Audio Event - Capture Camera"
trigger:
- platform: state
entity_id: sensor.ava_audio_event
to: "glass_breaking"
action:
- service: camera.snapshot
target:
entity_id: camera.ava_camera_snapshot
data:
filename: /config/www/audio_event_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg
- service: notify.mobile_app
data:
title: "Glass Breaking Detected"
message: "Audio event triggered camera capture"
data:
image: /local/audio_event_latest.jpgCount people by gender for analytics or adjust behavior:
automation:
- alias: "Log Visitor Count"
trigger:
- platform: state
entity_id: sensor.ava_male_count
action:
- service: input_number.set_value
target:
entity_id: input_number.male_visitors_today
data:
value: "{{ states('input_number.male_visitors_today') | int + 1 }}"Place multiple Ava devices in different rooms and view all cameras on one dashboard:
type: grid
columns: 2
cards:
- type: picture-entity
entity: camera.living_room_ava_video_camera
camera_view: live
- type: picture-entity
entity: camera.kitchen_ava_video_camera
camera_view: live
- type: picture-entity
entity: camera.bedroom_ava_video_camera
camera_view: live
- type: picture-entity
entity: camera.garage_ava_video_camera
camera_view: live- Use 5G WiFi if available
- Keep device close to router
- Start with 480p, increase if stable
- Use 5 FPS for smooth motion, 2 FPS for static scenes
- Keep the device plugged in — video streaming is CPU-intensive
- Use 1-2 FPS frame rate
- Use 240p resolution
- Use snapshot mode instead of video stream
- Only enable video recording when needed (use switch entity)
- Use snapshot mode — camera only activates on demand
- Lower FPS to 1-2
- Lower resolution to 240p
- Turn off face detection when not needed
- Use proximity or Bluetooth presence to trigger recording only when someone is present
- Check if camera permission is granted
- Check if Remote Camera is enabled in Settings -> Advanced
- Confirm Home Assistant is connected
- Check if the device has a camera (Ava auto-detects)
- For kiosk devices, ensure overlay permission is granted
Ava's stream should not accumulate lag. If you experience lag:
- Lower frame rate (try 1-2 fps)
- Lower resolution (try 240p)
- Check WiFi signal strength
- Check if another app is using the camera
- Restart the Ava service — the stream will resume fresh
The video recording switch is off. Turn it on via:
- HA:
switch.turn_onon thevideo_recordingentity - Ava app: Settings -> Advanced -> Camera Mode -> Video
- Enable Face Detection in Settings -> Advanced
- Ensure camera mode is Video (face detection only works on video stream)
- Check lighting conditions — the TFLite model needs reasonable light
- Ensure the face is clearly visible and not too small in the frame
- Face detection runs on-device — no internet needed
Gender detection uses a 5-frame median smoothing window. If it still flickers:
- Increase FPS to 5+ for more samples
- Ensure good lighting
- Faces at extreme angles may confuse the model
- Ava has legacy HAL support with retry logic — it should work on Android 5-6 devices
- If the camera still fails, try switching to the front camera
- Some very old devices may not support CameraX — try Snapshot mode instead of Video
- Check if another app has exclusive camera access
- This is normal on devices without auto-exposure in ImageAnalysis mode
- Try a different camera (front vs back)
- Ensure the scene is well-lit
- Some devices limit exposure in background camera mode
Yes. Camera streaming and voice satellite run independently. The camera uses ImageAnalysis which does not conflict with audio recording.
On most devices, yes. Camera and Bluetooth audio use different hardware paths. On some very low-end devices, heavy camera usage may cause Bluetooth audio stuttering.
Back to Home