Skip to content

fix: gate Intercom on server-side hasCommand instead of microphone/speaker props#25

Open
retrography wants to merge 1 commit into
caplaz:mainfrom
retrography:fix/intercom-gating-via-hascommand
Open

fix: gate Intercom on server-side hasCommand instead of microphone/speaker props#25
retrography wants to merge 1 commit into
caplaz:mainfrom
retrography:fix/intercom-gating-via-hascommand

Conversation

@retrography
Copy link
Copy Markdown

@retrography retrography commented May 22, 2026

Summary

Some doorbells that support two-way talk — notably Video Doorbell S220 (BATTERY_DOORBELL_2) — do not expose microphone or speaker boolean properties on the underlying eufy-security device. The current gate in createDeviceManifest (device-utils.ts:288-293) requires both properties to be present, so for these models the Intercom interface is never added and HomeKit / Scrypted hide the talk button.

Replace the property-presence check with a server-side api.hasCommand("deviceStartTalkback") call, which consults the authoritative DeviceCommands table in eufy-security-client. This is the same source of truth the server uses when actually executing talkback, so the manifest now matches what the device will accept at runtime.

Repro

  • Device: Eufy Video Doorbell S220 (T8210, BATTERY_DOORBELL_2)
  • Connected via eufy-security-ws to caplaz/eufy-security-scrypted, exported to HomeKit
  • Live video works, motion + doorbell press fire correctly
  • Talk button absent in HomeKit; device.interfaces in the Scrypted REPL does not include Intercom

getProperties for the S220 returns a payload that does not include microphone or speaker (confirmed against the upstream property table for BATTERY_DOORBELL_2), so the properties.microphone !== undefined && properties.speaker !== undefined gate evaluates false and Intercom is skipped — even though the upstream DeviceCommands table for this model does include CommandName.DeviceStartTalkback.

Fix

// The argument is the upstream CommandName enum value (camelCase), not the
// snake_case WS protocol command name.
const { exists: hasTalkback } = await api.hasCommand("deviceStartTalkback");
if (hasTalkback) {
  interfaces.push(ScryptedInterface.Intercom);
}

Note on the string: api.hasCommand proxies to Device.hasCommand upstream, which checks the value against the CommandName enum — those values are camelCase ("deviceStartTalkback"), not the snake-case WS protocol command name ("device.start_talkback" from DEVICE_COMMANDS.START_TALKBACK). It would be nice to export the CommandName enum from @caplaz/eufy-security-client so callers don't have to hard-code the string, but that's out of scope for this fix.

Tests

Updated tests/unit/device-utils.test.ts:

  • ✅ Intercom added when device supports deviceStartTalkback
  • ✅ Intercom added when talkback is supported but microphone/speaker properties are absent (the S220 case)
  • ✅ Intercom NOT added when device does not support deviceStartTalkback, even if microphone + speaker properties are present

All 11 tests in device-utils.test.ts pass.

Test plan

  • npm test -- device-utils.test.ts passes locally
  • Lint + format pass (pre-commit hook)
  • Verified on hardware: device.interfaces now includes Intercom for an S220, and the HomeKit talk button works

…eaker props

Some doorbells that support two-way talk (notably BATTERY_DOORBELL_2 / S220)
do not expose `microphone` or `speaker` boolean properties on the eufy-security
device, so the previous gate in `createDeviceManifest` skipped the Intercom
interface and HomeKit / Scrypted hid the talk button.

Replace the property-presence check with `api.hasCommand(DEVICE_COMMANDS.START_TALKBACK)`,
which consults the authoritative DeviceCommands table in eufy-security-client.
This keeps existing behavior for cameras that report the boolean properties
while correctly enabling Intercom for devices that support talkback but omit
those flags.

Tests updated to cover the supported, unsupported, and S220-style
"talkback-supported-but-no-property-flags" cases.
@retrography retrography force-pushed the fix/intercom-gating-via-hascommand branch from 0d164ed to 823ce71 Compare May 22, 2026 19:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant