You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
Highlights
"View outside" right after hanging up works again on local UDP (#41, #44, @m4r1k): the view waits for the panel to settle and retries an unanswered call within the time a person waits. Field test on a 40507: 31/32 views with video.
Card on iPhone and voice (#53, #54, #64, @Apeiv): no more smearing between keyframes on iOS, and the visitor's voice no longer crackles (reordered on the server over the cloud relay, resampled continuously in the card).
Card fixes (#64): the popup opens for a call already in progress (#35), history photos reload after their signed link expires, a new idle_picture option.
Security (#46, #52, #64, #65): an mDNS announcement can no longer move the intercom's address without your confirmation, linear-time log redaction, away message entities admin-only, card shortcut names escaped, /av's SDP in a private temp file.
HomeKit (#45, #48, #56): views open faster, no more port collisions between ffmpegs, re-encoder frame delay down from ~340 to ~70 ms on a Pi 5.
find_sga reports a cloud relay 202 Accepted as queued, not as an answer (#14, #62).
Added
Card idle_picture option (also in the visual editor): last_ring (default) keeps the last
ring's photo in the scene and the compact photo button at rest; standby shows the doorbell icon
there instead. The photos stay in the history drawer.
Fixed
/av's input SDP is written to a private temporary file (mode 0600, an unpredictable name) instead
of a fixed, guessable path in the temp directory, and removed when ffmpeg is stopped.
Card history photos and clips no longer stay broken behind an expired signed path: a photo or
clip the browser fetches again after the ~30 s signature has expired (HA logged "Login attempt or
request with invalid authentication" for /api/vimar_intercom/rings/*.jpg) is signed again once
and reloaded.
Card voice playback no longer clicks 50 times a second: the 8 kHz voice is resampled to the
audio context's rate continuously across packets and low-passed at 3.6 kHz, and the playout
buffer starts 120 ms ahead and grows by 40 ms at every underrun, up to 300 ms (#53).
The visitor's voice clicked on the cloud relay: audio never looked at the RTP sequence number, so a
packet lost or reordered on the way was skipped or played out of place. Audio is now put back in
order like the video, duplicates are dropped, and a lost packet is filled with the previous 20 ms at
half volume, and a source that restarts its sequence numbers is followed. The server keeps at most
1 s of voice waiting instead of 4 s (#53).
Card live video on iPhone no longer smears between keyframes: the WebCodecs decoder is fed
AVC (an avcC description built from SPS/PPS, length-prefixed NAL units) instead of Annex B, is
reconfigured only when SPS/PPS change, and runs with optimizeForLatency off on iOS (#53).
Away message text and audio file can be changed by administrators only. The two entities
were writable by any user who could call the service; a call with no user (automations) still works.
Card shortcut buttons no longer inject markup: the friendly_name and icon of a button.*
entity are escaped, and an icon not shaped like prefix:name falls back to the default.
Card popup layout: the popup now opens when the card first sees a call already in progress
(notification "Answer", app reopened after the ring), not only on ringing or with the anchor in
the URL. A period that starts with calling (a tap on the card, HomeKit, Alexa) still needs the
anchor (#35).
"View outside" opened right after hanging up no longer fails after 25 s on local UDP (#41). The
view waits for the panel to answer our BYE (at most 6 s) before calling it again. A call to the
video panel (a view's, the card's "view outside", the call buttons) that the panel leaves
unanswered is cancelled and tried again, within 21 s of the first try and 24 s of the tap
(inside /av's 25 s): after 3 s when the panel's proxy said 100
Trying and the panel never rang, else after 6 s. Every try waits until 5 s after the last call
on the line (or our own cancelled try) ended: a 2-wire panel ignores an INVITE that comes
sooner. Calls to a flat or the switchboard, and cloud plants, are unchanged. The 487 that ends our own cancelled INVITE is
logged at DEBUG, and /av's "call not established" says how long it really waited.
The card's Fill/Fit button (#42). It is hidden while the video and its box have the same shape
(a 4:3 panel in the default 4:3 box), where filling and fitting draw the same picture and the
button seemed to do nothing. When the card falls back to Home Assistant's picture card (no
WebCodecs, or the card's player failed), the choice now reaches it as fit_mode.
In cloud mode, finding the local IP resolved the proxy's name on the event loop, at setup and at
every reconnect: with the network down (Home Assistant starting before the router) that DNS
lookup froze every integration for seconds. It runs in the executor now.
HomeKit: two ffmpegs starting together (the re-encoder and a view) could be handed overlapping
loopback ports, and one logged "bind failed: Address in use". Every ffmpeg RTP input now gets an
even port with the next one free (RTCP), and a pair handed out is not handed out again for 10 s.
Changed
SRTP costs a quarter less per packet (28 µs instead of 38 µs for a video packet on a Raspberry
Pi 5): the IV is one integer XOR, the AES-CTR cipher is set up without a Counter object, and the
HMAC is copied from one keyed once. The bytes on the wire are the same (known-answer tests).
The voice to the panel (the card's microphone, HomeKit's Talk, the away message) is μ-law encoded
through a lookup table: 13 µs instead of 113 µs per 20 ms packet on a Raspberry Pi 5, the same
bytes, on the event loop that also carries the call's video.
HomeKit views open faster. The view's audio no longer waits for the video path (re-encoder and
keyframe included), and with Smoother video on, the re-encoder starts while the view's call is
still connecting instead of after its video arrives.
find_sga reports a 202 Accepted as queued instead of exists: the cloud relay accepted the
probe but no device took it, so nothing at that address can answer over the cloud (#14). The
service's sip_timeout now goes up to 30 s, because over the relay that 202 can take ~15 s.
Security
One crafted SIP datagram could stall Home Assistant for seconds: the Authorization pattern in log_redact was quadratic on a run of bare line feeds, and every received message goes through it
on the event loop. The pattern now matches only spaces and tabs around the header name, and a log
line longer than 16 KB is cut once it has been redacted (#46).
A device on the local network could change the intercom's address in Home Assistant by announcing
the Tab's MAC (which the Tab publishes) over mDNS with another address: REGISTER, door commands
and calls then went there. A new address is now offered only when it is a private IPv4 address that
the record announces as its own, and applied only after you confirm it under Discovered (#46).