SURFACES
- The Configure menu gains a **Discover installed apps** row. A row rather
than a form step, because a menu choice is dispatched with no user input:
it awaits the manager's bounded sweep and returns to the menu with a line
saying what was found. Discovery is therefore always explicit — never a
per-poll cost — and a failed sweep still renders the menu.
- The Apps table opens on the REAL app list: the stored rows first (kept
position, name and icon untouched) and then every discovered app, named
by its device label or its package id when the label fetch did not answer.
The user's entry for a package always wins over the device label.
- `sensor.<name>_installed_apps` (ADB-enabled entries only): state = app
count, `installed_apps` attribute = the same table, `discovery` attribute
= ok / pending / not_connected / adb_disabled. It polls through the
manager's TTL cache, so a poll on a fresh table issues no shell, and the
standard `homeassistant.update_entity` action refreshes it.
The discovered icon is deliberately NOT written into the icon column: that
column is documented as a picture URL or a `camera.*` entity feeding
`entity_picture`, and an `mdi:` name there would be a value the media
player cannot use. The icons are offered in the installed-apps attribute,
and the table's description names them.
strings.json + translations/en.json: the `installed_apps` entity name, the
Discover row label, and the menu description now carries {discovery}, so the
page says how many apps were found (or why none were).
README: an "App discovery" section documenting both commands, how system
and launcher entries are treated, the label/caching semantics, the icon
rule and its limits, the sensor surface and the fallback behaviour — and
that the source-list fallback stays the user's map, not the discovery.
319 lines
19 KiB
JSON
319 lines
19 KiB
JSON
{
|
|
"config": {
|
|
"step": {
|
|
"user": {
|
|
"title": "NVIDIA Shield",
|
|
"description": "{discovery_note}Set up your NVIDIA Shield. Everything here is optional except one state source — the Nvidia Remote Protocol or ADB. Link the devices and services you want to use.",
|
|
"data": {
|
|
"name": "Name",
|
|
"jellyfin_entity": "Jellyfin media player",
|
|
"receiver_entity": "Receiver",
|
|
"receiver_input": "Receiver input",
|
|
"power_entity": "Power switch",
|
|
"adb_enabled": "Read state over ADB",
|
|
"adb_store_app_info": "Show title and artist",
|
|
"host": "The Shield's IP address",
|
|
"adb_port": "ADB port",
|
|
"protocol_enabled": "Add the Nvidia Remote Protocol"
|
|
},
|
|
"data_description": {
|
|
"jellyfin_entity": "The Jellyfin media_player for this Shield. Leave blank to detect it automatically.",
|
|
"receiver_entity": "The receiver, soundbar or speaker switch this Shield plays through. Leave blank if there is none.",
|
|
"receiver_input": "The receiver input the Shield uses, for example 'Shield'. Leave blank if you are not sure.",
|
|
"power_entity": "A smart plug switch, if you want reliable on/off detection.",
|
|
"adb_enabled": "Reads now-playing information over ADB from any app. Requires Developer options > Network debugging on the Shield.",
|
|
"adb_store_app_info": "Shows the title and artist from non-Jellyfin apps. Turn off to show only the app name (privacy mode).",
|
|
"host": "The Shield's IP address. Pre-filled when the Shield was discovered — change it only if you need a different address.",
|
|
"adb_port": "The ADB port. The standard value is 5555 — change it only if ADB uses a custom port on your network.",
|
|
"protocol_enabled": "Adds the all-in-one remote-protocol transport (power, availability, app push and volume readout). It needs a one-time PIN pairing right after this step."
|
|
}
|
|
},
|
|
"adb_pair": {
|
|
"title": "Allow ADB access",
|
|
"description": "On the Shield, open Settings > System > Developer options and turn on Network debugging (it may be called ADB debugging). Then select Submit — the Shield shows an Allow prompt; approve it. Nothing happened? Check the address below and select Submit again. Not now? Turn on 'Continue without ADB pairing' and select Submit.",
|
|
"data": {
|
|
"host": "The Shield's IP address",
|
|
"adb_port": "ADB port",
|
|
"skip_pairing": "Continue without ADB pairing"
|
|
},
|
|
"data_description": {
|
|
"host": "The Shield's IP address. Pre-filled when the Shield was discovered — change it only if the Shield moved or you gave it a different address.",
|
|
"adb_port": "The standard ADB port is 5555.",
|
|
"skip_pairing": "Finishes setup now and leaves ADB unpaired. The Pair ADB button stays available on the device page, so you can pair later."
|
|
}
|
|
},
|
|
"protocol_pair": {
|
|
"title": "Pair the remote protocol",
|
|
"description": "While this step is open the Shield shows a pairing code. Type it below and select Submit. If no code appears on the Shield, check the IP address below and select Submit again — pairing restarts and the Shield shows a new code. To set up without the remote protocol, turn on 'Continue without protocol pairing'.",
|
|
"data": {
|
|
"pairing_code": "Pairing code shown on the Shield",
|
|
"host": "The Shield's IP address",
|
|
"skip_pairing": "Continue without protocol pairing"
|
|
},
|
|
"data_description": {
|
|
"pairing_code": "The code the Shield displays while this step is open.",
|
|
"host": "The Shield's IP address. Pre-filled when the Shield was discovered — change it if the Shield moved.",
|
|
"skip_pairing": "Finishes setup with the remote protocol off — it stays off until you pair it. Pair later from this integration's entry menu: choose Reconfigure."
|
|
}
|
|
},
|
|
"reauth_confirm": {
|
|
"title": "Re-pair Nvidia Shield",
|
|
"description": "The Shield no longer trusts the saved pairing certificate, usually after a factory reset. Select Submit to pair again — the Shield then shows a code."
|
|
},
|
|
"menu": {
|
|
"title": "Finish setup",
|
|
"description": "Pair the transports and check anything else before the entry is created.",
|
|
"menu": {
|
|
"receiver": "Receiver",
|
|
"connection": "Connection",
|
|
"adb": "Set up ADB",
|
|
"protocol": "Pair the remote protocol",
|
|
"finish": "Create the entry"
|
|
},
|
|
"data": {
|
|
"host": "The Shield's IP address",
|
|
"adb_port": "ADB port",
|
|
"adb_enabled": "Read state over ADB",
|
|
"protocol_enabled": "Add the Nvidia Remote Protocol"
|
|
},
|
|
"data_description": {
|
|
"host": "The Shield's IP address. Pre-filled when the Shield was discovered — change it only if you need a different address.",
|
|
"adb_port": "The ADB port. The standard value is 5555 — change it only if ADB uses a custom port on your network.",
|
|
"adb_enabled": "Reads now-playing information over ADB from any app. Requires Developer options > Network debugging on the Shield.",
|
|
"protocol_enabled": "Adds the all-in-one remote-protocol transport (power, availability, app push and volume readout). It needs a one-time PIN pairing right after this step."
|
|
}
|
|
},
|
|
"setup_connection": {
|
|
"title": "Connection",
|
|
"description": "The Shield's address, the ADB port and which transports this entry uses.",
|
|
"data": {
|
|
"host": "The Shield's IP address",
|
|
"adb_port": "ADB port",
|
|
"adb_enabled": "Read state over ADB",
|
|
"protocol_enabled": "Add the Nvidia Remote Protocol"
|
|
},
|
|
"data_description": {
|
|
"host": "The Shield's IP address. Pre-filled when the Shield was discovered — change it only if you need a different address.",
|
|
"adb_port": "The ADB port. The standard value is 5555 — change it only if ADB uses a custom port on your network.",
|
|
"adb_enabled": "Reads now-playing information over ADB from any app. Requires Developer options > Network debugging on the Shield.",
|
|
"protocol_enabled": "Adds the all-in-one remote-protocol transport (power, availability, app push and volume readout). It needs a one-time PIN pairing right after this step."
|
|
}
|
|
},
|
|
"setup_receiver": {
|
|
"title": "Receiver",
|
|
"description": "The receiver or soundbar this Shield plays through — a media_player, or a plain switch.",
|
|
"data": {
|
|
"receiver_entity": "Receiver",
|
|
"receiver_input": "Receiver input"
|
|
},
|
|
"data_description": {
|
|
"receiver_entity": "The receiver, soundbar or speaker switch this Shield plays through. Leave blank if there is none.",
|
|
"receiver_input": "The receiver input the Shield uses, for example 'Shield'. Leave blank if you are not sure."
|
|
}
|
|
}
|
|
},
|
|
"error": {
|
|
"adb_failed": "The Shield did not accept the ADB connection. Make sure Network debugging is on, approve the Allow prompt on the Shield, then select Submit to try again.",
|
|
"adb_no_host": "No IP address for the Shield yet. Fill in the host field above (a discovered Shield is pre-filled automatically).",
|
|
"protocol_no_host": "No IP address for the Shield yet. Fill in the host field above (a discovered Shield is pre-filled automatically).",
|
|
"protocol_pair_failed": "The Shield rejected that pairing code. Check the code on the Shield and select Submit to try again.",
|
|
"protocol_unavailable": "The androidtvremote2 library is not installed, so the remote protocol cannot pair. Install it and restart Home Assistant, or turn on 'Continue without protocol pairing' to finish setup anyway.",
|
|
"protocol_unreachable": "The Shield did not answer at that address. Check the address above and that the Shield is awake, then select Submit to try again — or turn on 'Continue without protocol pairing' to finish setup without it.",
|
|
"no_state_source": "No state source selected. Choose at least one: 'Add the Nvidia Remote Protocol' or 'Read state over ADB'.",
|
|
"invalid_app_map": "Each line must be package=name with a non-empty package (no spaces) and a non-empty name — for example ar.tvplayer.tv=TiviMate.",
|
|
"invalid_digit_delay": "The digit delay must be between 0.05 and 1.0 seconds."
|
|
},
|
|
"abort": {
|
|
"already_configured": "This Shield is already set up.",
|
|
"reauth_successful": "Re-paired successfully.",
|
|
"reauth_skipped": "Pairing skipped. The saved certificate is still not trusted, so the remote protocol stays unavailable until you pair again.",
|
|
"reauth_entry_missing": "This entry no longer exists.",
|
|
"reconfigure_skipped": "Nothing changed — the remote protocol stays off until you pair it. Choose Reconfigure from this integration's entry menu when you are ready.",
|
|
"reconfigure_entry_missing": "This entry no longer exists, so there is nothing to reconfigure.",
|
|
"zeroconf_no_host": "The discovery event carried no usable address.",
|
|
"yaml_seed_only": {},
|
|
"yaml_seed": {
|
|
"title": "YAML succeeded earlier",
|
|
"message": "The configuration.yaml nvidia_shield block is seed-only: it starts the standard interactive flow. Removing the YAML block creates or deletes nothing."
|
|
}
|
|
}
|
|
},
|
|
"options": {
|
|
"step": {
|
|
"init": {
|
|
"title": "NVIDIA Shield settings",
|
|
"description": "Settings for this Shield. Saving reloads the integration so the change takes effect. {discovery}.",
|
|
"menu": {
|
|
"connection": "Main setup",
|
|
"receiver": "Receiver",
|
|
"apps": "Apps",
|
|
"discover": "Discover installed apps",
|
|
"scripts": "Scripts",
|
|
"finish": "Save and close"
|
|
},
|
|
"data": {
|
|
"jellyfin_entity": "Jellyfin media player",
|
|
"receiver_entity": "Receiver",
|
|
"receiver_input": "Receiver input",
|
|
"power_entity": "Power switch",
|
|
"adb_enabled": "Read state over ADB",
|
|
"protocol_enabled": "Add the Nvidia Remote Protocol",
|
|
"adb_store_app_info": "Show title and artist",
|
|
"host": "The Shield's IP address",
|
|
"adb_port": "ADB port",
|
|
"app_name_map": "App names and icons",
|
|
"adb_command_enabled": "Enable the adb_command service",
|
|
"channel_digit_delay": "Channel digit delay (seconds)",
|
|
"channel_send_enter": "Send ENTER after channel digits",
|
|
"script_turn_on": "Turn on script",
|
|
"script_turn_off": "Turn off script",
|
|
"script_volume_up": "Volume up script",
|
|
"script_volume_down": "Volume down script",
|
|
"script_volume_set": "Volume set script",
|
|
"script_volume_mute": "Mute script",
|
|
"script_select_source": "Select source script",
|
|
"logcat_events": "Instant app detection (logcat stream)",
|
|
"remote_command_script": "Remote command script"
|
|
},
|
|
"data_description": {
|
|
"jellyfin_entity": "The Jellyfin media_player for this Shield. Stream details come from the HA Jellyfin integration — no extra setup needed.",
|
|
"receiver_entity": "The receiver or soundbar this Shield plays through.",
|
|
"receiver_input": "The receiver input the Shield uses, for example 'Shield'.",
|
|
"power_entity": "A smart plug switch, if you want reliable on/off detection.",
|
|
"adb_enabled": "Reads now-playing information over ADB from any app. Requires Developer options > Network debugging on the Shield.",
|
|
"adb_store_app_info": "Shows the title and artist from non-Jellyfin apps. Turn off to show only the app name (privacy mode).",
|
|
"host": "The Shield's IP address. Change it only if the Shield moved or you gave it a different address.",
|
|
"protocol_enabled": "Adds the all-in-one remote-protocol transport (power, availability, app push and volume readout). Turning it on needs a one-time PIN pairing — use Reconfigure on the entry to pair.",
|
|
"adb_port": "The ADB port. The standard value is 5555.",
|
|
"app_name_map": "One entry per line, package=name (for example ar.tvplayer.tv=TiviMate), with an optional |icon after the name. Leave blank to clear.",
|
|
"adb_command_enabled": "Adds the nvidia_shield.adb_command service (a raw ADB shell command over the persistent connection). Security-relevant: leave it off unless you need it — the same opt-in posture as the core androidtv integration.",
|
|
"channel_digit_delay": "Pause between the channel digits entered via play_media(channel) — 0.05 to 1.0 seconds (default 0.1, the tested value).",
|
|
"channel_send_enter": "Presses ENTER after the last digit (protocol key first, then the ADB keyevent fallback). Off by default, matching TiviMate's tested behavior.",
|
|
"logcat_events": "Detects app changes instantly through a dedicated logcat stream (AdbDevice.streaming_shell). Off by default — polling keeps the state correct either way, and the integration falls back to polling if the stream keeps failing.",
|
|
"remote_command_script": "One script for remote.send_command. It replaces the key path when set and receives the call's own parameters as variables: command (the list of key commands), num_repeats, delay_secs and hold_secs."
|
|
}
|
|
},
|
|
"connection": {
|
|
"title": "Main setup",
|
|
"description": "The Shield's address, the transports it is read over, and the devices this entry links to. Changes here are kept when you save.",
|
|
"data": {
|
|
"host": "The Shield's IP address",
|
|
"adb_port": "ADB port",
|
|
"adb_enabled": "Read state over ADB",
|
|
"adb_store_app_info": "Show title and artist",
|
|
"protocol_enabled": "Add the Nvidia Remote Protocol",
|
|
"logcat_events": "Watch app launches over logcat",
|
|
"adb_command_enabled": "Allow the adb_command action",
|
|
"jellyfin_entity": "Jellyfin media player",
|
|
"power_entity": "Power switch"
|
|
},
|
|
"data_description": {
|
|
"host": "The Shield's IP address. Change it only if the Shield moved.",
|
|
"adb_port": "The ADB port. The standard value is 5555 — change it only if ADB uses a custom port on your network.",
|
|
"adb_enabled": "Reads now-playing information over ADB from any app. Requires Developer options > Network debugging on the Shield.",
|
|
"adb_store_app_info": "Shows the title and artist from non-Jellyfin apps. Turn off to show only the app name (privacy mode).",
|
|
"protocol_enabled": "The all-in-one remote-protocol transport (power, availability, app push and volume readout). It needs the one-time PIN pairing from setup.",
|
|
"logcat_events": "Uses a second ADB stream to notice app launches the moment they happen. Leave off unless you want the faster app switch.",
|
|
"adb_command_enabled": "Exposes the adb_command action for this entry's media player. Off by default; it runs arbitrary shell commands on the Shield.",
|
|
"jellyfin_entity": "The Jellyfin media_player for this Shield. Leave blank to detect it automatically.",
|
|
"power_entity": "A smart plug switch, if you want reliable on/off detection."
|
|
}
|
|
},
|
|
"receiver": {
|
|
"title": "Receiver",
|
|
"description": "The receiver or soundbar this Shield plays through — a media_player, or a plain switch for a soundbar that only turns on and off.",
|
|
"data": {
|
|
"receiver_entity": "Receiver",
|
|
"receiver_input": "Receiver input"
|
|
},
|
|
"data_description": {
|
|
"receiver_entity": "The receiver, soundbar or speaker switch this Shield plays through. Leave blank if there is none.",
|
|
"receiver_input": "The receiver input the Shield uses, for example 'Shield'. Leave blank if you are not sure."
|
|
}
|
|
},
|
|
"apps": {
|
|
"title": "Apps",
|
|
"description": "One app per line: the package id, an equals sign, the name to show, and optionally a pipe and an icon (a picture URL or a camera entity id). Blank uses the built-in list.",
|
|
"data": {
|
|
"app_name_map": "App names and icons"
|
|
},
|
|
"data_description": {
|
|
"app_name_map": "One row per app, for example ar.tvplayer.tv=TiviMate|http://192.168.1.10/tivi.png. The name is what the source list, the Current App sensor and the media player show."
|
|
}
|
|
},
|
|
"scripts": {
|
|
"title": "Scripts",
|
|
"description": "Optional: run a Home Assistant script instead of the built-in command, per command. Clear a row to go back to the built-in path.",
|
|
"data": {
|
|
"remote_command_script": "Script for remote.send_command",
|
|
"script_turn_on": "turn_on script",
|
|
"script_turn_off": "turn_off script",
|
|
"script_volume_up": "volume_up script",
|
|
"script_volume_down": "volume_down script",
|
|
"script_volume_set": "volume_set script",
|
|
"script_volume_mute": "volume_mute script",
|
|
"script_select_source": "select_source script",
|
|
"channel_digit_delay": "Delay between channel digits (seconds)",
|
|
"channel_send_enter": "Send ENTER after channel digits"
|
|
},
|
|
"data_description": {
|
|
"remote_command_script": "Replaces the whole remote.send_command path for this Shield. Leave blank to use the built-in key presses.",
|
|
"channel_digit_delay": "The gap between the digits of a channel number, 0.05 to 1.0 seconds. Default 0.1.",
|
|
"channel_send_enter": "Turn on if your channel app needs ENTER after the digits."
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"services": {
|
|
"adb_command": {
|
|
"name": "ADB command",
|
|
"description": "Send a raw ADB shell command to the persistent connection of an Nvidia Shield entry (option-gated use).",
|
|
"fields": {
|
|
"command": {
|
|
"name": "Command",
|
|
"description": "The shell command to run on the device."
|
|
},
|
|
"entity_id": {
|
|
"name": "Entity",
|
|
"description": "The Nvidia Shield media player to target."
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"exceptions": {
|
|
"invalid_command": {
|
|
"title": "Empty command",
|
|
"message": "The command field is empty — nothing was sent."
|
|
},
|
|
"unsupported_target": {
|
|
"title": "Unsupported entity for adb_command",
|
|
"message": "{entity_id} is not an adb_command participant (its entry must enable the adb_command_enabled option) — command not sent."
|
|
},
|
|
"adb_unavailable": {
|
|
"title": "ADB unavailable",
|
|
"message": "The ADB connection of {entity_id} is down — command not sent."
|
|
},
|
|
"unknown_source": {
|
|
"title": "Unknown source",
|
|
"message": "'{source}' is not one of this Shield's apps. Use a name from the source list — the app names from the Apps map, or the built-in list when no map is set."
|
|
},
|
|
"command_script_failed": {
|
|
"title": "Command script failed",
|
|
"message": "The script configured for {action} ({script}) failed: {error}"
|
|
}
|
|
},
|
|
"entity": {
|
|
"sensor": {
|
|
"current_app": {
|
|
"name": "Current app"
|
|
},
|
|
"now_playing": {
|
|
"name": "Now playing"
|
|
},
|
|
"installed_apps": {
|
|
"name": "Installed apps"
|
|
}
|
|
}
|
|
}
|
|
}
|