Files
nixos/docs/superpowers/specs/2026-07-29-alexa-media-player-design.md
finn.markwitz 7bfbf4de9a docs(home-assistant): design for alexa_media_player integration
Spec for packaging the Alexa Media Player HACS component declaratively
on jupiter (HA -> Echo: TTS/announce, media, sensors). Requires bumping
alexapy 1.29.22 -> 1.29.25 and packaging dictor 0.1.12 (absent from
nixpkgs) to satisfy the manifest's exact requirement pins. Alexa -> HA
voice control is explicitly deferred.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RCn8YgGQMGpauatdeTdQYf
2026-07-29 17:01:41 +02:00

6.7 KiB

Amazon Alexa integration for Home Assistant (jupiter) — design

Date: 2026-07-29 Machine: jupiter Status: approved, ready for implementation plan

Goal

Let Home Assistant control and read the household Amazon Echo devices via the unofficial alexa_media_player integration: text-to-speech / announcements, media control, and per-device sensors (last-called device, next alarm/timer, DND state, etc.).

This uses the user's Amazon account through an unofficial API. It is a config-flow integration: after the rebuild it is added through the HA UI, not via YAML.

Non-goals (deferred)

Alexa → HA voice control ("Alexa, turn on the light") is out of scope. It would need either emulated_hue bound to port 80 on the LAN, or a public HTTPS endpoint plus the AWS-Lambda Smart Home Skill. The user chose to decide on that later. Nothing in this change touches the firewall, port 80, systemd unit capabilities, or network exposure.

Approach

Package the integration declaratively, following the existing ha-sourdough pattern in modules/environments/home-assistant/default.nix (a buildHomeAssistantComponent entry in services.home-assistant.customComponents). No HACS runtime.

Unlike sourdough, alexa_media_player has real Python dependencies. Its manifest.json (v5.15.7) declares:

alexapy==1.29.25
packaging>=20.3
wrapt>=1.14.0
dictor>=0.1.12,<0.2

buildHomeAssistantComponent runs manifestCheckPhase at build time (check_manifest.py): every requirement must resolve to an installed distribution whose version satisfies the specifier, or the build fails. Home Assistant repeats this check at runtime. Therefore each requirement must be satisfied exactly — the exact ==1.29.25 pin in particular.

Dependency status in the pinned nixpkgs (nixos-25.11):

Requirement nixpkgs today Action
alexapy==1.29.25 1.29.22 Bump to 1.29.25 via override
dictor>=0.1.12,<0.2 absent Package dictor 0.1.12 (new)
wrapt>=1.14.0 1.17.2 none — already satisfied
packaging>=20.3 26.1 none — already satisfied

authcaptureproxy (in nixpkgs at 1.3.7) is a transitive dependency of alexapy, not listed in the manifest, so it needs no direct handling.

Components

All changes live in modules/environments/home-assistant/default.nix (plus the hashes below). Three small pieces, wired together in the module's let block:

1. dictor package (new)

Not in nixpkgs. Pure-Python, no runtime dependencies (requires_dist: null), ships a setup.py. A minimal pkgs.python3Packages.buildPythonPackage:

  • pname dictor, version 0.1.12
  • src = fetchPypi { pname = "dictor"; version = "0.1.12"; hash = "sha256-bbSDda4eU9ye2EToWzj04/v79qTmC+yjd1Fa0URTuRs="; }
  • setuptools format (legacy setup.py); build-system = [ setuptools ]
  • doCheck = false (no meaningful test suite); pythonImportsCheck = [ "dictor" ]

Build against the HA Python set so the version lands in HA's venv — i.e. use config.services.home-assistant.package.python.pkgs (the same interpreter the component check and HA runtime use), not the top-level pkgs.python3Packages.

2. alexapy 1.29.25 (override)

nixpkgs alexapy is fetched from GitLab (keatontaylor/alexapy, tag v<version>), not PyPI. Override just the version + src via overridePythonAttrs, reusing the existing build-system and dependency list:

  • version = "1.29.25"
  • src = fetchFromGitLab { owner = "keatontaylor"; repo = "alexapy"; tag = "v1.29.25"; hash = "sha256-P/hvgqZVaBJF5dbmHrDjQMC+pwV3EEhKyFIS5KmhgD4="; }

This is a patch bump (1.29.22 → 1.29.25); the dependency set is expected to be unchanged. Override the HA-Python-set alexapy so it shares the interpreter with dictor and the component.

3. alexa_media_player component (new customComponents entry)

buildHomeAssistantComponent {
  owner = "Alandtse";
  domain = "alexa_media";
  version = "5.15.7";
  src = fetchFromGitHub {
    owner = "Alandtse";
    repo  = "alexa_media_player";
    rev   = "v5.15.7";
    hash  = "sha256-1rcZVSX1xA1Lc4qSu39MOitVEciZFhoPQy2y5+PpoAI=";
  };
  dependencies = [ alexapy' dictor' wrapt packaging ];  # HA-python-set packages
}

dependencies must make every manifest requirement importable at the required version for manifestCheckPhase to pass. Include all four (the two custom ones plus wrapt and packaging from the HA Python set) to be explicit.

Data flow

  1. nixos-rebuild switch builds the component; manifestCheckPhase validates the four requirements against the provided dependencies.
  2. HA starts; the custom component is present but not configured.
  3. User adds Alexa Media Player in Settings → Devices & Services, signs in with the Amazon account (email/password; 2FA or app-password handled in the UI flow at runtime).
  4. HA creates media_player entities and per-device sensors; TTS/announce services become available for automations.

Error handling / risks

  • Version-pin drift. If a future alexa_media_player bump changes the alexapy== pin, alexapy must be re-bumped in lockstep, or the build fails loudly at manifestCheckPhase (fail-safe, not silent).
  • Amazon login fragility. The unofficial API can break on Amazon's side (captcha/2FA changes). This is a runtime concern, independent of packaging; not addressed here.
  • dictor upper bound <0.2. 0.1.12 is the current release and satisfies it. If nixpkgs later gains a dictor ≥ 0.2, prefer our pinned 0.1.12 for this component.

Verification

  • nix build '.#nixosConfigurations.jupiter.config.system.build.toplevel' succeeds — this exercises the build-time manifest-requirements check for all three new/overridden derivations.
  • nixfmt-rfc-style clean on the edited module.
  • Post-deploy (manual, by the user): the integration appears under Add Integration, and a TTS/announce call reaches an Echo.

Pinned artifacts

Artifact Source Ref / version Hash
alexa_media_player GitHub v5.15.7 sha256-1rcZVSX1xA1Lc4qSu39MOitVEciZFhoPQy2y5+PpoAI=
alexapy GitLab v1.29.25 sha256-P/hvgqZVaBJF5dbmHrDjQMC+pwV3EEhKyFIS5KmhgD4=
dictor PyPI sdist 0.1.12 sha256-bbSDda4eU9ye2EToWzj04/v79qTmC+yjd1Fa0URTuRs=