Initial release v0.1.0
Home Assistant custom integration for NVIDIA Shield TV that composes the Android TV Remote, Jellyfin, smart plug, and receiver entities into a single unified media player with ADB-based now-playing from any app. Part of the Media Zone ecosystem. Entities: - media_player: power (with smart plug fallback), transport, input, volume routed to receiver, rich stream info overlay when Jellyfin is active - sensor: DAG attributes and stream info - button: Pair ADB Config: - Two-step flow: basic setup + optional ADB pairing on the Shield - Configurable ADB port (default 5555) - Pick an existing Jellyfin media_player entity — stream info is read from the HA Jellyfin integration's own DataUpdateCoordinator, so no server URL / API key / extra config needed here - Privacy mode (adb_store_app_info=False) suppresses non-Jellyfin media details, showing only the app name Ecosystem: - Exposes media_dag_* attributes for ha-media-zone orchestration - Exposes media_dag_running_apps and async_bring_to_foreground for the Media Zone card's app switcher Shared ADB code lives in ltomes/ha-adb-common and is vendored at custom_components/nvidia_shield/ha_adb_common/ for HACS installs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
0ad51879ae
24 files changed
+2538
No files matched your search
@@ -0,0 +1,56 @@
|
||||
"""ADB key management — generation and migration."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ensure_adb_key(
|
||||
hass_config_dir: str,
|
||||
domain: str,
|
||||
legacy_paths: list[str] | None = None,
|
||||
) -> str:
|
||||
"""Ensure an ADB key pair exists. Migrate from legacy paths or generate if missing.
|
||||
|
||||
Args:
|
||||
hass_config_dir: Home Assistant config directory.
|
||||
domain: Integration domain name (e.g. "nvidia_shield", "hisense_tv").
|
||||
Used to namespace the key storage.
|
||||
legacy_paths: Optional list of legacy key paths to check for migration,
|
||||
in priority order. Avoids forcing device re-pairing.
|
||||
|
||||
Returns:
|
||||
Path to the private key file.
|
||||
"""
|
||||
key_dir = os.path.join(hass_config_dir, ".storage", domain)
|
||||
os.makedirs(key_dir, exist_ok=True)
|
||||
key_path = os.path.join(key_dir, "adbkey")
|
||||
|
||||
if os.path.exists(key_path):
|
||||
return key_path
|
||||
|
||||
# Try migrating from legacy locations
|
||||
all_legacy = list(legacy_paths or [])
|
||||
# Always check the generic location as a last resort
|
||||
generic = os.path.join(hass_config_dir, ".storage", "adbkey")
|
||||
if generic not in all_legacy:
|
||||
all_legacy.append(generic)
|
||||
|
||||
for legacy_key in all_legacy:
|
||||
if os.path.exists(legacy_key):
|
||||
shutil.copy2(legacy_key, key_path)
|
||||
pub = legacy_key + ".pub"
|
||||
if os.path.exists(pub):
|
||||
shutil.copy2(pub, key_path + ".pub")
|
||||
_LOGGER.info("Migrated ADB key from %s to %s", legacy_key, key_path)
|
||||
return key_path
|
||||
|
||||
# Generate new key
|
||||
from adb_shell.auth.keygen import keygen
|
||||
|
||||
keygen(key_path)
|
||||
_LOGGER.info("Generated new ADB key at %s", key_path)
|
||||
|
||||
return key_path
|
||||
Reference in new issue
Block a user