Skip to content

Troubleshooting

Chris Brightly edited this page Oct 18, 2026 · 25 revisions

Troubleshooting

Quick fixes for the most common problems. See also Known limitations and the FAQ.

Setup fails on Home Assistant 2026.7: "Requirements for aidot not found"

If the log shows:

Setup failed for custom integration 'aidot': Requirements for aidot not found:
['python-aidot-cameras[webrtc]>=...'].

this is fixed as of python-aidot-cameras 0.10.3. Update the AiDot integration and restart Home Assistant.

Background: HA 2026.7 pins PyAV to av==17, while stock aiortc (the WebRTC engine) capped av<17, so the streaming dependency was unsatisfiable and HA reported it as "not found." As of library 0.10.3, aiortc is vendored with the PyAV ceiling widened - aiortc runs unchanged on av 17 - so the integration installs normally on HA 2026.7. No HA downgrade needed.

If you still see it: update the AiDot integration in HACS and restart Home Assistant. If HACS shows no update, the fix rides the library floor (currently >=1.0.0rc54 from integration 2.37.12); restarting HA re-resolves the requirement and pulls it. Confirm your HA version under Settings -> About.

Camera stream won't load in the browser

go2rtc must be running. Go to Settings -> Add-ons -> go2rtc and confirm it is started. On Home Assistant OS and Container it ships pre-installed; if you run Core or Supervised you may need to install it separately.

Camera connects but the picture stays blank (no video)

Mains (A000088 / M3 Pro) cameras: a bug fixed in 2.9.14 (library 0.12.14) made every DTLS camera go dark whenever a positive warm-hold window was configured - the serve was torn down and respawned forever. If a mains camera shows a blank picture, update to 2.9.14 or later first.

SDES cameras (battery L2 models and the PTZ / A001064): update to 2.10.0 first. Before that release these cameras could fail every live view, and the cause was a bug in the integration rather than your network. Opening a view re-registered the camera with go2rtc, and that call silently dropped the very stream the camera was publishing - so go2rtc had nothing to serve and the view went blank. The related "press play once, fail, press again, works" behaviour on a cold camera is fixed in the same release.

A camera whose picture is black while everything else looks right: update to 2.11.0. This one was easy to mistake for a dead camera, because nothing else was wrong - the camera connected, the stream ran at around 2 Mbps, and eleven megabytes arrived during a viewing that showed nothing at all. The decoder was being set up from a description of the video remembered from an earlier session, and one camera model changes that description between sessions, so the decoder was told to expect a stream that no longer matched and could not decode a single frame. A camera that does this is now recognised and the stale description is neither kept nor used for it again.

Worth knowing when diagnosing this yourself: bytes arriving is not evidence the picture should be appearing. "Is media arriving" and "is media decodable" are different questions, and only the second one explains a black picture.

If it still happens on 2.10.0 or later: this is NO_MEDIA - the camera's encrypted media can't get back to Home Assistant, usually because the camera can't reach HA directly and its media isn't traversing the cloud relay. That is common when the camera sits on a separate VLAN or behind AP/client isolation.

  • If the camera shares the Home Assistant LAN, set Connection mode to LAN only (fastest, same-network only) (Settings -> Devices & Services -> AiDot Cameras -> Configure -> Live view and connection) to bypass the relay.
  • If it can't share the LAN, this is a camera/network limitation rather than an integration bug - the relay path simply isn't carrying the media.

The repeated ffmpeg SDES stderr warnings this wrote to the log on every retry are quieted as of 2.8.9 (they now log at debug); a genuine ffmpeg error still warns.

A camera worked, then stopped - and only restarting Home Assistant fixes it

Fixed in 2.9.23 (library 0.14.0). Update and restart.

Two faults produced this, and they compounded.

Once a stream session had started, the integration treated it as live for good. When the publisher died underneath it, every later view reused that dead session and handed go2rtc a stream nobody was publishing to - so the live view failed with nothing in the log to explain it, and stayed that way until Home Assistant restarted. Opening a view now asks go2rtc whether a publisher is actually attached, and restarts the session when it is not. (If go2rtc cannot be reached the session is left alone, so an unreachable go2rtc can't tear down a working stream.)

Battery cameras were hit hardest and could show no video at all: they are deliberately excluded from the startup warm-up, so nothing else ever gave them a session. Mains cameras mostly masked the problem, because the startup warm-up leaves them running.

Underneath that, the stream handed to ffmpeg advertises both video codecs and has to be narrowed to the one the camera actually sends. When a session's media started late there was nothing to narrow on, so the wrong decoder was bound and go2rtc rejected the published stream outright - no video, for anyone. The codec is now taken from the camera's own negotiated answer in that case.

Every device shows as disconnected / offline

Fixed in 2.9.19 (library floor >=0.13.0). Update and restart.

The LAN-session check compared a private attribute against an enum that exists in only one version of the underlying device library. On the newer version - the one Home Assistant core's own AiDot integration requires - neither is present, so the check answered "not connected" forever and every device looked permanently offline. Nothing raised an error, which is why there was nothing in the log to go on.

Battery camera drains fast, and its first live view fails until you refresh

Fixed in 2.9.21 (library 0.13.1). Update and restart.

A battery camera used to be kept in a permanent keepalive: the integration could not tell whether anyone was actually watching, and "unknown" never released. So the camera was renewed around the clock against a live view nobody had open - draining it, and leaving it parked in a permanently-retrying state, which is why the first view would land on a session that never delivered a frame. Hitting refresh appeared to fix it only because a retry happened to be mid-flight with media.

Mains camera re-views are slow again (they used to be instant)

Fixed in 2.9.22 (library 0.13.2). Update and restart.

Mains cameras were being misread as battery-powered, because the cloud reports the same batteryMode flag on mains cameras with none of the corroborating battery telemetry. A camera on that path is given the battery idle window instead of the mains warm-hold, so every re-view paid a full cold start - exactly what the warm-hold exists to avoid.

Note the floor is a hard >=0.13.2: Home Assistant only installs a requirement it does not already satisfy, so an older library stays in place - and the fix stays inert - until the floor moves.

The log is flooded with AiDot chatter (and contains device credentials)

Fixed in 2.9.20. Update and restart - no configuration needed.

The underlying device library logs routine traffic at WARNING - every ping, frame, command and connect - and dumps each device's raw record, including its password and AES key, when the device client is constructed. The integration now filters that by message: the noise and the credential dump are dropped at every level (including debug), while real failures are untouched.

Do not add a logger: override for aidot.device_client to silence this. It looks like the fix and is a trap. Home Assistant drops the record before the filter can see it, so setting aidot.device_client: error throws away connect device error - the one message that tells you a device failed to connect. You get a quiet log and a silent failure. If you added such an override, remove it.

To see the protocol chatter deliberately, set aidot.device_client: debug, which the filter honours. Credentials stay dropped even then.

Home Assistant says a module "is logging too frequently"

Fixed in 2.20.3 (library 1.0.0rc12). Update and restart - no configuration needed.

The warning looks like this, and Home Assistant raises it itself:

Module aidot_cameras.camera.webrtc_open is logging too frequently.
200 messages since last count

This is a different problem from the device-library chatter above, and the fix for that one does not touch it. The camera library reports a session's progress through a channel built for its command-line tool: when something is showing those messages on a screen they are logged quietly, and when nothing is, the log itself becomes the channel and they are logged at INFO. Running inside Home Assistant nothing ever shows them, so per-packet diagnostics ended up at the same level as the handful of lines that describe a session starting.

There is now a second channel for the steady-state messages, logging at debug whether or not anything is listening. Measured over 11.7 hours on an eight-camera install, INFO lines from the library fall from 39584 to 437 - roughly 3400 an hour to 37. The lines that describe a session are deliberately kept, so the log still shows a camera waking, offering, connecting and serving.

If you turned this integration's logging down to warning to escape the noise, you can put it back to the default and get those session lines again.

The same release stopped one diagnostic writing a camera's decrypted audio to the log as hex. That dump was at INFO, so it reached ordinary log files; it is now truncated to a short prefix. If you keep old log files or have shared one for support, they may contain it.

Reading the health line

From integration 2.37.9 (library 1.0.0rc51; 2.37.10 is the first public release that carries it) every live session logs one INFO line a minute under aidot_cameras.camera.health:

camera <id>: health 20s: packets=1686 (84.1/s) lost=0 (0.0%) stall=0.0s path=direct viewers=present
  • The link is lossy: lost climbs (DTLS models; the SDES models recover loss with retransmission and report bytes instead).
  • The picture froze: stall climbs while lost stays at 0 - the camera stopped sending. A DTLS session with no video for 30 s is re-opened on its own.
  • Nobody was watching: viewers=absent beyond the idle window, after which the session is released. unknown means the go2rtc the camera publishes into could not be asked.

path=relay means the media rides the vendor's relay rather than your LAN - normal for a camera on another subnet. The counts are the library's own view of the stream, before go2rtc. The interval is AIDOT_HEALTH_LINE_S; 0 turns the line off.

A device you removed in the AiDot app still shows in Home Assistant

Expected. A device the vendor cloud no longer serves goes unavailable here automatically, but its entities stay registered until you delete the device yourself in Settings -> Devices & Services -> AiDot Cameras, then pick the device and Delete. Home Assistant never removes devices on its own.

A leftover entity for a control that was removed

Some controls were removed once the cameras were shown to acknowledge the command and then ignore it - a switch that did nothing and reported nothing. Home Assistant keeps the entity until you delete it.

Entity Removed in Use instead
switch.<camera>_auto_tracking on a camera that cannot pan or tilt 2.17.3 nothing - the camera ignored it
switch.<camera>_ir_light 2.15.0 select.<camera>_night_vision, which does switch the IR cut filter
select.<camera>_resolution 2.11.9 (entity cleared in 2.12.0) nothing - see Resolution

Delete the stale entity if it lingers after updating.

Live view plays in slow motion (about a tenth of real speed)

Fixed in integration 2.30.4 - update. This is a different fault from the buffering one below, even though both read as "slow".

The Picture / Picture Glance card opens Home Assistant's built-in HLS dialog, which only accepts AAC audio. The integration used to register an ffmpeg:<stream>#audio=aac source with go2rtc so that dialog had sound. Some go2rtc builds stamp that transcode's timestamps on a 90 kHz clock while advertising MPEG4-GENERIC/8000, so the audio arrived stretched about elevenfold - and because players sync video to audio, the video crawled to match. It affected every camera and every model, and nothing was logged as an error.

To confirm it on a version before 2.30.4, capture the same stream twice over the same wall-clock window and compare how long each result claims to be:

ffmpeg -rtsp_transport tcp -i "rtsp://<host>:8554/aidot_<id>?audio=pcma" -c copy pcma.mkv   # ~15 s for 15 s
ffmpeg -rtsp_transport tcp -i "rtsp://<host>:8554/aidot_<id>?audio=aac"  -c copy aac.mkv    # ~163 s for 15 s

From 2.30.4 that go2rtc AAC source is no longer offered, so the dialog plays at the right speed; 2.30.4 to 2.30.7 left it silent. From 2.30.8 the dialog has sound by default through the Audio in HLS and recordings option (Configure -> Audio and recordings): the camera library publishes its own AAC track, encoded in-process with timestamps that follow the camera's own audio clock, and only the HLS path asks go2rtc for it. Turn the option off and the dialog is silent, at the right speed. WebRTC cards (Dashboard cards) carry the camera's own audio untouched either way. Moving to a different card does not fix the speed on an older version, because a downstream go2rtc prefers the same AAC source and relays the bad timestamps unchanged.

Stream is slow / buffers like HLS instead of WebRTC

Live view is served over go2rtc WebRTC (low-latency) whenever go2rtc is reachable: each camera publishes its video and audio straight into go2rtc (Direct publish into go2rtc, on by default since 2.35.0) and the integration hands Home Assistant the go2rtc RTSP URL. A standard (DTLS) camera is served on a local port and registered with go2rtc only when the integration cannot reach go2rtc directly, as with Home Assistant's bundled go2rtc. If go2rtc is unavailable it falls back to Home Assistant's HLS pipeline (higher latency) - so confirm go2rtc is running (above).

Note: the first view of an idle camera always has the handshake delay (see Cameras) before WebRTC takes over.

To force the HLS fallback (e.g. for debugging), set AIDOT_GO2RTC=0 in the Home Assistant process environment. AIDOT_GO2RTC_API overrides the go2rtc REST base URL (default http://127.0.0.1:1984).

"Camera must be streaming" error on PTZ or aidot.talk

PTZ rides the active stream session: open the live camera card in the Home Assistant UI to establish it, then retry. aidot.talk does not need a live view - it reuses the live session when one is open and otherwise opens its own temporary session and closes it afterwards - so if it reports this error the camera could not be reached at all (asleep, off the network, or held by the AiDot app's live view); the error's wording predates that behaviour.

Every live view has dropped to HLS at once; the log shows go2rtc: add stream 'aidot_...' failed http=400 for every camera

go2rtc's own configuration file (go2rtc.yaml, the WebRTC add-on's or integration's) holds a stream listed twice, which makes that go2rtc (1.9.9) reject every registration until the duplicate is removed by hand. go2rtc saves each registration by reading the file, patching it and writing it back, with nothing guarding that cycle, so two registrations landing at once could leave a stream listed twice. From 2.34.3 this integration never writes two registrations at once, which is what tore the file (2.30.6 had only kept one camera's own registrations apart), and from 2.34.4 a repair issue in Settings names the condition and goes away once a registration succeeds.

To fix an existing file: stop go2rtc, delete the second copy of the duplicated aidot_...: block in go2rtc.yaml (the key line and its - rtsp://... line below it), start go2rtc. The warning's text from library 1.0.0rc41 on quotes go2rtc's reason (mapping key ... already defined).

The PTZ camera's HLS view or recording is blank with "In-sync audio for recordings" on, while the live view works

The camera answered in H.265 despite the H.264 pin (it does so in roughly one open in seven), and only an H.264 session can feed the in-sync stream. From library 1.0.0rc42 (integration 2.33 and later) such a session is abandoned and re-opened, up to twice; the log line is sent video payload type 97 against an offer pinned to 96 ... re-opening. If it still happens, the camera insisted three times in a row and the session was served as it came; the next one is normally fine.

A recording or HLS view started just after a camera went idle produced nothing

Fixed in 2.30.6. Update and restart.

Home Assistant resolves a camera's stream source only when it creates a stream, and otherwise reuses the one it cached - even a stopped one. A battery camera's session was then released 120 s after its last viewer, so a camera.record (or the Picture cards' HLS dialog) started in the next few seconds got the old stream, which pointed at a source no longer being published: it answered 404, never re-opened the camera, and the recording never wrote a file. The integration now replaces a cached stream whose session has ended at the moment Home Assistant is about to reuse it, so the camera is opened again. A stream over a live session is reused exactly as before.

A notification's clip starts a few seconds in, after the motion

Fixed in 2.34.2. Update; clips cached by an older version are made again.

Reading the cloud's clip, the integration threw away everything it had read while working out the clip's format - the whole first part of the clip, about 3 s, often with the motion that triggered the notification. 2.34.1 hid the blank picture this left at the start; from 2.34.2 nothing is lost (a 12 s clip is its full 15 s again).

Clips in the Media Browser show blank or won't play

Recorded clips require an active AiDot cloud storage subscription. Check the AiDot mobile app to confirm the camera's cloud plan is active. See Cloud recordings.

Motion events are not firing

  1. Check that switch.motion_detection is on for the camera.
  2. Motion is cloud-polled (~30 s), not pushed, so a new event can take up to ~30 s to appear - this is normal.
  3. Update to 2.8.5 or later. Earlier versions reloaded the integration on every account-token refresh, which re-primed the motion poll and dropped any event that landed just after - so motion (and occupancy) could look stuck.
  4. If events consistently never arrive, reload the integration: the Reload button on the AiDot device, the entry's ... menu, or Settings -> Devices & Services -> AiDot Cameras.
  5. Check whose account Home Assistant is signed in with. Motion events come from the camera's cloud event list, and that list is only populated for the account that owns the home - a member the home is shared to reads an empty list and so gets no motion events, no notifications, and no cloud recordings, even though the owner's phone in the AiDot app shows all three. This is an account-role limit on AiDot's side, not a fault in the integration. If motion never fires but the app shows events, sign Home Assistant in with the home-owner account (the one the cameras were added under). See also Cloud recordings.

Authentication error / integration keeps reloading

As of 2.8.5 the integration no longer reloads itself on every account-token refresh - that self-reload was the usual cause of "keeps reloading" and of motion/occupancy dropping out, so update to the latest first.

If it still reloads, your AiDot credentials have likely expired or changed: go to Settings -> Devices & Services -> AiDot Cameras -> Reconfigure and re-enter them. To reload on demand, use the Reload button on the AiDot device or the entry's ... menu.

LAN control is not attaching to cameras

Enable Local camera control in the integration options (Settings -> Devices & Services -> AiDot Cameras -> Configure). This only works for mains-powered cameras; battery cameras are excluded by design. Changes take effect after restarting Home Assistant. If cameras still don't attach, confirm they are on the same subnet as the Home Assistant host.

A camera in the AiDot app blocks Home Assistant (or vice versa)

Each camera serves one live session at a time. Close the live view in the AiDot mobile app before streaming in Home Assistant. Snapshots and recorded clips are unaffected.

Clone this wiki locally