Skip to content

Releases: k-the-hidden-hero/bticino_intercom

Release v2.0.0

20 Jun 13:31

Choose a tag to compare

v2.0.0 — WebRTC live video & two-way audio

After 12 release candidates and over two months of beta, v2.0 is stable.

What's new since v1.9.x

🎥 WebRTC live video (multi-camera)

One camera entity per external unit (BNEU). Live video on demand from the
HA dashboard, with two-way audio when paired with the custom Lovelace card
from bticino_ha_extras. Chrome/Chromium only — see Firefox investigation.

📞 Answer mode

Pick up an incoming call straight from HA: the device's SDP offer (sent
via push WebSocket) is answered with an SDP from the browser.

🗂️ Call history with persistent snapshots

Snapshots and vignettes are downloaded to disk the moment the call arrives,
so they remain viewable after the Azure SAS URLs expire. Browse via HA
Media Source or a dedicated authenticated HTTP view. Configurable retention
(default 30 days / 500 events).

🔔 Doorbell event entity (HA standard)

Adds event.<intercom>_doorbell using DoorbellEventType.RING — works
with HA's generic doorbell.rang trigger. The existing binary_sensor
stays (dual-entity pattern, same approach UniFi uses).

🏠 Call Home camera

Voice-only intercoms (no camera) get a "Call Home" camera entity with
a SEELE-style poster so the answer-mode UI still works.

📦 Blueprints

  • actionable_doorbell_notification — Answer / Open / Reject buttons
  • incoming_call_notification — with ringtone

🛡️ Stability

  • 429 rate-limit prevention: terminate/rescind RTC retransmits are now
    deduplicated by session_id (fix for #56)
  • Lock open no longer returns HTTP 500: lock entities that advertise the
    OPEN feature now implement async_open (fix for #57)
  • Proactive WebSocket re-subscribe + resilient coordinator
  • Smart retry backoff at boot

Upgrade requirements

  • Home Assistant ≥ 2026.5.0
  • pybticino >=1.8.2
  • For two-way audio: bticino_ha_extras custom card (Chrome only)

For HA < 2026.5: stay on v1.9.x.

Breaking changes

None for users on v1.9.x with default config. The event entity is new
(additive). DoorbellEventType is wire-compatible (still emits "ring").

Thanks to the beta testers

This release exists because these people ran 12 RCs against real
intercoms in their homes and filed actionable bug reports:

  • @marcob79 — the most prolific reporter (#41, #46, #50, #51, #56);
    caught the Android Companion WebRTC quirk and the 429 cascade that
    ships fixed here
  • @hamanolo — found the iOS Sound Only crash (#48)
  • @tamet83 — blueprint UX feedback and the silent-urgent notification
    spec (#52, #53)
  • @Doudy — Home + Security user management edge cases (#49)
  • @filou01 — Classe 300X bridge detection (#54)

Grazie a tutti — sul serio.

Open issues

  • ⚠️ #50 — HA Companion Android WebRTC still under investigation
  • 🔓 #57 — door open from HA on some installs: the HTTP 500 crash is fixed,
    but physically opening the entrance is setup-specific and still under
    investigation
  • 🆕 #55 — BNC3 DND / Professional Studio controls (queued)

What's next

  • v1.9.x stable line continues for users on HA < 2026.5
  • Reverse call (call the intercom from HA) is on the roadmap

Release v2.0.0-rc13

26 May 12:38

Choose a tag to compare

Release v2.0.0-rc13 Pre-release
Pre-release

Summary

Thirteenth and final release candidate of v2.0. One change on top of v2.0.0-rc12:

🛡️ 429 rate-limit cascade fix (#56)

Netatmo's push WebSocket broadcasts the same RTC `terminate`/`rescind` event to every device registered for push notifications (each with a unique `_id` but the same `session_id`). The coordinator previously processed every duplicate as a fresh event, calling `async_request_refresh()` each time → 3 HTTP calls per duplicate. With 6 receivers + a normal call, that's ~18 API calls in 2s, tripping the 429 rate limit (see attached log on issue #56).

Fix: track session_ids closed within the last 60s in a small in-memory dict. Terminate/rescind events whose session_id is in that set are skipped (no refresh, no duplicate logbook entries, no duplicate "end" event). Test coverage: 6 duplicate terminates → 1 refresh, same for rescind.

This also collapses the cosmetic noise where `bticino_intercom_terminated` logbook events fired ~10 times per call.

Soak

This is the final RC. Once we confirm a few days without 429 in the wild, v2.0.0 stable follows.

Upgrade requirements

Same as v2.0.0-rc12: Home Assistant ≥ 2026.5.0, pybticino `>=1.8.2`.

CI note

GitHub Actions was experiencing partial degradation when this tag was pushed (HACS validation hit a GitHub API rate limit). This release was created manually with the same packaging logic the CI workflow uses; the artifact below is bit-identical to what the workflow would produce. HACS validation will be rerun once GitHub recovers.

Full Changelog: v2.0.0-rc12...v2.0.0-rc13

Release v2.0.0-rc12

20 May 19:37

Choose a tag to compare

Release v2.0.0-rc12 Pre-release
Pre-release

Summary

Twelfth release candidate of v2.0. Two changes on top of v2.0.0-rc11:

  1. Classe 300X bridge detection fix (bumps pybticino requirement to >=1.8.2) — same fix as stable v1.9.7.
  2. DoorbellEventType.RING enum adoption + minimum HA bumped to 2026.5.0.

What's new

Classe 300X support (#54)

pybticino no longer sends the hardcoded DEFAULT_DEVICE_TYPES filter by default, so the API returns all module types including BNC3 (Classe 300X bridge). Verified end-to-end against the live Netatmo API: zero regression on Classe 100X.

DoorbellEventType.RING

HA 2026.5 (released 2026-05-06) standardized the doorbell event type under homeassistant.components.event.DoorbellEventType. The integration now uses the official enum instead of the raw "ring" string:

  • ✅ Official pattern, will be enforced by HA 2027.4
  • ✅ Enables HA's generic doorbell.rang trigger across integrations
  • ✅ Wire-compatible — the enum value is still "ring", so existing automations triggered on event_type: "ring" keep working

hacs.json now pins minimum HA to 2026.5.0 so HACS surfaces an explicit incompatibility warning instead of an ImportError at integration load.

Upgrade requirements

  • Home Assistant ≥ 2026.5.0 (was unset before — practically required 2025.x+ for the event entity)
  • pybticino >=1.8.2

If you are on a pre-2026.5 HA, stay on v2.0.0-rc11 (or upgrade HA first). Stable line (v1.9.x) does NOT require HA 2026.5 and remains the right pick if you can't upgrade HA right now.

Stable vs beta

Track Latest Use if
Stable v1.9.7 You want locks/sensors/snapshots, no WebRTC live video
Beta (this) v2.0.0-rc12 You want WebRTC live video and two-way audio (Chrome/Chromium only — see Firefox investigation)

Open issues handled this round

  • #54 (Classe 300X bridge detection) — fixed
  • #48 (iOS Sound Only crash) — fixed in rc11, closed
  • #49 (Home + Security user management) — answered, closed
  • ⚠️ #50 (HA Companion Android WebRTC) — investigation continues; please attach the requested webrtc-internals dumps from both Chrome Android and Companion if affected
  • 🎁 #53 (Blueprint feature: silent urgent notification) — shipped in bticino_ha_extras c60683b; re-import the blueprint to get it

Release v1.9.7

20 May 19:37

Choose a tag to compare

Summary

Stable patch release that unblocks BTicino Classe 300X users. The previous stable (v1.9.6) failed setup with No bridge module found in the system (MAC address ID check failed) on Classe 300X devices because of a hardcoded device-type filter inside pybticino. v1.9.7 picks up pybticino 1.8.2 which removes that filter.

What's fixed

  • #54 — Classe 300X "No bridge module found" (Christoph Aichhorn @filou01, reproduced by @Engel-der-Nacht)
    • Root cause: pybticino.account.DEFAULT_DEVICE_TYPES omitted BNC3 (Classe 300X bridge) and was sent as a filter to /api/homesdata, so the API returned a home with zero modules.
    • Fix: pybticino now skips the filter by default. Classe 100X (BNC1) users are unaffected — verified end-to-end against the live Netatmo API with no module-count regression.

Upgrade

HACS will pick up the new pybticino version automatically on the next HA restart after upgrading to v1.9.7. No config changes required.

Compatibility

  • HA: any supported version (no minimum bump on this stable line — v1.9.x stays backward compatible)
  • pybticino: >=1.8.2

Beta track

The v2.0.0 beta line (WebRTC live video, two-way audio, blueprints, idle card redesign) continues separately. The next pre-release v2.0.0-rc12 ships alongside this stable and includes the same Classe 300X fix.

Release v2.0.0-rc11

12 May 20:18

Choose a tag to compare

Release v2.0.0-rc11 Pre-release
Pre-release

v2.0.0-rc11

🐛 Fix

  • Real snapshot no longer blocked by SOUND ONLY placeholder (#48)
    Race in EventHistoryStore.async_record_call: the RTC offer push records the call before the incoming_call push delivers the real snapshot URL. From rc8, the SEELE placeholder was generated immediately on that first record, setting snapshot_file. The subsequent download of the real Azure snapshot was then short-circuited by the loop's existing-file check, leaving users stuck with the placeholder forever.
    Fix: defer placeholder generation to async_close_call. The placeholder represents "call ended without a snapshot ever being delivered" — that determination can only be made at call end. Voice-only intercoms still get the placeholder; cameras with real snapshots now show the real image.

🧪 Tests

  • 4 new regression tests in tests/test_history.py covering:
    • No eager placeholder on offer-only record
    • Real snapshot replaces eager record (the exact race)
    • Voice-only call gets placeholder at close
    • Real snapshot is never overwritten by placeholder

📞 Looking for testers

If you opened or commented on these issues, please update to rc11 and report whether the snapshot now shows correctly:

  • #48 — "Sound Only" snapshot regression
  • #52 — Snapshot/vignette never updates

Open issues NOT addressed in rc11

These need more diagnostic data from users — please reply on the issue thread:

  • #50 — Call from HA Android Companion: signaling works server-side, likely card/client-side or carrier NAT issue
  • #52.4 — "Home Assistant authentication failed" from card (card-side bug, not integration)
  • #53 — Spook ghost entity: hardcoded state_attr('camera.bticino_intercom_<home>_last_event_snapshot', 'image url') is a custom modification, not from our blueprints. Multi-lock action is already supported via doorbell_actionable_notification.yaml.

Full Changelog: v2.0.0-rc10...v2.0.0-rc11

Release v2.0.0-rc9

24 Apr 19:06

Choose a tag to compare

Release v2.0.0-rc9 Pre-release
Pre-release

v2.0.0-rc9

🔧 Fixes

  • Answer mode m-line order fix (#47) — When answering an incoming call via the bticino_ha_extras card, the browser rejected the device's SDP with "The order of m-lines in answer doesn't match order in offer". The device sends (video, audio) but the browser may expect (audio, video). The SDP m-sections are now reordered to match the browser's offer before being sent as the answer (RFC 8829).

Changes since rc6

  • Snapshot/vignette images no longer expire (#44) — Images are downloaded locally before events fire. Automations and notifications always have images available immediately. No more Azure SAS URL 403 errors.
  • ensure_connected AttributeError resolved (#46) — pybticino ≥ 1.8.1 required.
  • TURN/STUN servers now work — Correct endpoint discovered by decompiling the Android app (app-turn.netatmo.net/api/getcredentials). WebRTC works behind NAT.
  • SEELE-style "SOUND ONLY" placeholder — Voice-only intercoms show a generated placeholder instead of reusing snapshots from other modules.
  • Actionable Doorbell Notification blueprint — Snapshot preview + configurable lock buttons. Uses Android alarm_stream (rings even on silent). Import blueprint
  • Light timezone warning fixedset_module_state now includes timezone.

🧪 We need beta testers!

We're getting close to a stable v2.0.0 release, and we need your help to make sure everything works across different setups. If you have a BTicino Classe 100X/300X intercom, please:

  1. Install this RC via HACS (enable "Show beta versions" → update to v2.0.0-rc9)
  2. Test these scenarios:
    • Ring the doorbell → check that the snapshot appears immediately and stays visible after 5+ minutes
    • Try the new actionable notification blueprint (with lock buttons)
    • If you have multiple intercoms (with/without camera), verify each shows the correct image
    • Try answering a call via the bticino_ha_extras card
  3. Report any issues at GitHub Issues

Every test report — even "it works!" — helps us ship a solid v2.0.0. Thank you! 🙏

Release v2.0.0-rc8

24 Apr 18:56

Choose a tag to compare

Release v2.0.0-rc8 Pre-release
Pre-release

v2.0.0-rc8

🔧 Fixes

  • TURN/STUN servers now work — The TURN endpoint URL was wrong (/turn on app.netatmo.net → actually app-turn.netatmo.net/api/getcredentials). Found by decompiling the Android app's string resources. WebRTC now works behind NAT with Twilio TURN servers provided by Netatmo. Requires pybticino ≥ 1.8.1.
  • Light timezone warning fixedset_module_state calls in the light platform now include the timezone parameter, eliminating the Calling setstate without timezone warning on every staircase light toggle.

✨ New

  • SEELE-style "SOUND ONLY" placeholder — When a call arrives from a voice-only intercom (no camera), the snapshot entity now shows a generated placeholder with the module name in white and "SOUND ONLY" in red on a black background, instead of misleadingly reusing the last snapshot from a different intercom. Inspired by the SEELE monoliths from Neon Genesis Evangelion.

⚙️ Internal

  • Snapshot camera no longer falls back to stale API event history when an active call has no images — prevents showing old snapshots from different modules.
  • Placeholder images are cached per module name (generated once, reused forever).

🧪 We need beta testers!

This is a release candidate — please help us test before v2.0.0. Install via HACS (enable "Show beta versions" → update) and report issues.

Release v2.0.0-rc7

24 Apr 14:44

Choose a tag to compare

Release v2.0.0-rc7 Pre-release
Pre-release

v2.0.0-rc7

🔧 Fixes

  • Snapshot/vignette images no longer expire (#44) — Camera entities now read from locally persisted images instead of Azure SAS URLs. Previously, snapshot images would return a 403 error ~5 minutes after a doorbell ring because the cloud URLs expired. Images are now downloaded to disk before events are fired, so automations and notifications always have images available immediately.
  • ensure_connected AttributeError resolved (#46) — Bumped pybticino requirement to >=1.8.0, which includes ensure_connected() and resubscribe() for the signaling client. This fixes the error when answering calls via the bticino_ha_extras card.

✨ New

  • Actionable Doorbell Notification blueprint — New blueprint with snapshot preview and up to 3 configurable door-unlock buttons. Uses Android's alarm_stream channel so the notification rings even when the phone is on silent/mute. Button labels are automatically derived from lock entity names — no manual configuration needed. Import blueprint

⚙️ Internal

  • WebSocket event processing is now fully async — _process_websocket_event, _process_rtc_event, _process_status_event, and _close_history_event are all awaited inline instead of using background tasks. This ensures images are on disk before any event fires.
  • _update_last_event no longer reuses stale subevents from previous API polls (which contained expired Azure URLs).

🧪 We need beta testers!

This is a release candidate — we'd love your help testing it before the stable v2.0.0 release. If you have a BTicino Classe 100X/300X intercom, please:

  1. Install this RC via HACS (enable "Show beta versions" → update to v2.0.0-rc7)
  2. Ring your doorbell and check that:
    • The snapshot camera entity shows the image immediately and keeps showing it after 5+ minutes (no more 403 errors)
    • The new blueprint notification works with your locks
  3. Report any issues at GitHub Issues

Your feedback helps us ship a solid v2.0.0. Thank you! 🙏

Release v2.0.0-rc10

24 Apr 20:23

Choose a tag to compare

Release v2.0.0-rc10 Pre-release
Pre-release

v2.0.0-rc10

🔧 Fixes (from final code review)

  • Timezone-aware timestamps in media browser — Event times now respect the HA timezone configuration instead of using the server's local time
  • Call dedup now checks session_id — A second genuine call from the same module is no longer silently swallowed as a retransmission; the old session is closed and a new one starts
  • Config flow saves history options — History enabled/retention/max events settings from the initial setup form are now actually persisted (were silently dropped before)
  • reject_call fails visibly — When the signaling terminate fails, the rejection is no longer reported as successful; the error propagates so the user knows the call wasn't actually rejected
  • URL-encoded event IDs in media browser — Prevents broken URLs if event IDs contain special characters
  • Binary sensor initialization_turn_off_canceller properly initialized in __init__ instead of relying on hasattr

✨ Also in this release (since rc6)

  • Local image persistence (#44) — No more Azure SAS URL 403 errors
  • TURN/STUN servers — Correct endpoint, WebRTC works behind NAT
  • SEELE "SOUND ONLY" placeholder — Voice-only intercoms get a generated placeholder saved to history
  • All calls recorded in history — Not just those with images
  • Answer mode m-line fix (#47) — SDP m-line order matched to browser offer
  • Actionable doorbell notification blueprint — Alarm stream, multi-lock buttons
  • Light timezone fix — No more setstate without timezone warnings

📝 Blueprint improvements

  • Incoming call blueprint now uses English defaults (was hardcoded Italian)
  • Doorbell notification blueprint: simplified image path template

🧪 We need beta testers!

This is the final RC before v2.0.0 stable. If you have a BTicino Classe 100X/300X intercom, please:

  1. Install via HACS (enable "Show beta versions" → update to v2.0.0-rc10)
  2. Test these scenarios:
    • Ring the doorbell → snapshot appears immediately and persists
    • Try the actionable notification blueprint (alarm_stream, lock buttons)
    • Answer a call via the bticino_ha_extras card
    • Check the media browser for call history
    • If you have multiple intercoms, verify each shows the correct image
  3. Report any issues at GitHub Issues

Every test report helps us ship a solid v2.0.0. Thank you! 🙏

Release v1.9.6

24 Apr 13:19

Choose a tag to compare

What's Changed

Full Changelog: v1.9.5...v1.9.6