The user's remote displayed but offered no app picker, and the protocol transport was never actually switched on. Both halves are fixed here. REMOTE PARITY. The entity declares RemoteEntityFeature.ACTIVITY — exactly what core's androidtv_remote declares — and publishes activity_list, which is what makes the frontend render an activity picker at all. The list is the app directory (the user's apps map, else the curated table as a floor) in map order, then the apps ADB discovery found and something can name, in the one name chain (user map > device label > curated > package id). Nothing nameless is listed as a bare package id, and current_activity is None until something is known: no activity is invented. remote.turn_on honours activity= by waking the device when it reports itself off and then launching through the existing launch path; a listed name resolves case-insensitively, a package id or a detail link passes through, and anything else raises unknown_activity naming the value instead of silently doing nothing. An empty/absent activity keeps the previous behaviour exactly, async_turn_off is untouched, and a configured command script still owns the sequence. WHY THE TRANSPORT WAS DEAD, MEASURED. androidtvremote2's keep_reconnecting only starts _async_reconnect, whose whole body is `while self._remote_message_protocol:` — false on the first check with nothing connected, so the task returned immediately: no connect attempt, no retry, and the auth callback was never reachable. HA core connects FIRST and only then keeps it alive. Our _start_protocol called keep_reconnecting after generating a certificate and never called async_connect anywhere, so every send_key_command/send_launch_app_command raised ConnectionClosed internally, the helpers swallowed it into `return False` plus a debug line, and no push (is_available/is_on/current_app/volume_info) ever arrived. The fix is a background connect loop: async_connect under a bounded timeout, network failures retried with the ADB watchdog's jitter and backoff, InvalidAuth routed into the EXISTING reauth callback (entry.async_start_reauth), and keep_reconnecting only after a session is up. Setup never blocks on a transport. A send that cannot run is no longer silent: it is counted, its error recorded verbatim, and logged at WARNING with the transport state, and the remote publishes protocol_state / protocol_connected / protocol_ever_authenticated / protocol_last_error / protocol_failures / protocol_certificate plus sticky per-push *_seen flags — so "sent" and "never switched on" can never look alike again. CASE (b) IS FIXED, NOT DOCUMENTED: switching the transport on in the options flow for an entry that never paired now routes into the real async_step_protocol_pair, and "continue without pairing" persists the transport OFF. One marker carries the pairing (CONF_PROTOCOL_PAIRED), written by the setup pairing step, the reauth finisher and the reconfigure finisher, so no entry can sit enabled-but-unpaired. The certificate from the first pairing is reused by design, so a paired entry is asked for no new PIN — which is also why the marker, not certificate material, is the source of truth. ADB STAYS THE PRIMARY STATE SOURCE. Arming the protocol introduces pushes that were never live before, so the reading now names its tier: manager.foreground_source drives the media player's app_source and the remote's activity_source, and the new tests prove a full protocol push set leaves the media state, the now-playing reading and every ADB store field untouched, while an ADB-only entry still serves media player, sensors, apps, scripts and receiver with only the protocol surface degraded. Copy: unknown_activity, activity_launch_failed and protocol_unavailable in BOTH strings.json and translations/en.json, pinned by a test; the README documents the picker, activity resolution, how to read the transport-state attributes, the script bypass (a script-routed press is never evidence of pairing), the connect-then-keep-alive lifecycle and cert reuse versus the other integration's own pairing. Evidence: 6 new real-HA FlowManager tests in tests/test_config_flow_real_ha.py (unpaired -> pairs, PIN -> marker, skip -> off, paired -> not asked again, and the setup flow's marker on success and on skip), a real-HA entity contract test in tests/test_ha_api_drift.py (exact supported_features equality with core, activity_list/current_activity reaching the state machine, live _attr_ updates) and new suites in tests/test_protocol_transport.py (connect-first, keep_reconnecting alone is a no-op, retry, auth rejection, honest send failures, ADB-primary precedence) and tests/test_command_routing.py (the activity contract, turn_on(activity=), script ownership, the transport attribute states). No device and no browser exist here: device behaviour is inferred from the library and core source, and every UI-facing claim is proven at the entity/registry/metadata level under real Home Assistant. Verify: suites 719/4 and 720/3; real-HA glob (tests/test_adb_command_real_ha.py + tests/test_config_flow_real_ha.py) 56 passed, 0 skipped; ruff clean; drift exit 0 (25 modules, 76 imports, 206 relative imports, 1322 statement blocks, 57 call arguments) with the floors raised 40->70, 100->195, 500->1300 and 52->55.
413 lines
25 KiB
JSON
413 lines
25 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."
|
|
}
|
|
},
|
|
"menu": {
|
|
"title": "Finish setup",
|
|
"description": "Pair the transports and check anything else before the entry is created. {pairing}.",
|
|
"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."
|
|
},
|
|
"menu_options": {
|
|
"receiver": "Receiver",
|
|
"connection": "Connection",
|
|
"adb_pair": "Set up ADB",
|
|
"protocol_pair": "Pair the remote protocol",
|
|
"finish": "Create the entry"
|
|
}
|
|
},
|
|
"receiver": {
|
|
"title": "Receiver",
|
|
"description": "The receiver or soundbar this Shield plays through — a media_player, or a plain switch. Playback turns a switch receiver on when it is 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."
|
|
}
|
|
},
|
|
"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."
|
|
}
|
|
},
|
|
"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."
|
|
}
|
|
},
|
|
"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.",
|
|
"invalid_app_row": "A row needs a package id with no spaces and a non-empty name — for example ar.tvplayer.tv=TiviMate. An icon, if given, cannot contain spaces.",
|
|
"unknown_app_row": "That app is no longer in the list. Pick one of the rows offered, or add it again."
|
|
},
|
|
"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}.",
|
|
"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 — a media_player, or a plain switch that playback turns on when it is off.",
|
|
"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."
|
|
},
|
|
"menu_options": {
|
|
"connection": "Main setup",
|
|
"receiver": "Receiver",
|
|
"apps": "Apps",
|
|
"discover": "Discover installed apps",
|
|
"scripts": "Scripts",
|
|
"finish": "Save and close"
|
|
}
|
|
},
|
|
"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",
|
|
"screen_capture_enabled": "Add a screen capture image entity",
|
|
"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.",
|
|
"screen_capture_enabled": "Adds an image entity showing the Shield's screen on demand. Off by default: a capture is a full-resolution screen grab, it is a manual/diagnostic surface, and it never drives state.",
|
|
"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. Playback turns a switch receiver on when it is off, so no receiver volume scripts are needed for that.",
|
|
"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": "The apps this Shield offers: they fill the media player's source list and name the apps in automations. Add, edit or remove ONE app with the rows below, or paste the whole list as text. The list carries the apps discovery found as well as the rows you saved — a detected app is marked, and picking it lets you give it a name. Currently: {apps}",
|
|
"menu_options": {
|
|
"apps_text": "Edit the whole list as text",
|
|
"apps_add": "Add an app",
|
|
"apps_edit": "Edit an app",
|
|
"apps_remove": "Remove an app",
|
|
"menu_again": "Back to the main menu"
|
|
}
|
|
},
|
|
"apps_text": {
|
|
"title": "Apps as text",
|
|
"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. Icons the device reported: {icons} — the icon column itself takes a picture URL or a camera entity.",
|
|
"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."
|
|
}
|
|
},
|
|
"apps_add": {
|
|
"title": "Add an app",
|
|
"description": "Adds ONE row. The package id is what the Shield launches, the name is what the card, the sensor and the source list show.",
|
|
"data": {
|
|
"app_package": "Package id",
|
|
"app_name": "Name to show",
|
|
"app_icon": "Icon (optional)"
|
|
},
|
|
"data_description": {
|
|
"app_package": "The Android package id, for example ar.tvplayer.tv or com.netflix.ninja. No spaces.",
|
|
"app_name": "What the source list, the Current App sensor and the media player show for this app.",
|
|
"app_icon": "Optional: a picture URL or a camera entity id. Leave blank to show no picture."
|
|
}
|
|
},
|
|
"apps_edit": {
|
|
"title": "Edit an app",
|
|
"description": "Pick the app to edit: the rows you saved plus the apps discovery found (marked 'detected'). The next step edits the name and the icon, and saving a detected app stores it as one of your own rows.",
|
|
"data": {
|
|
"app_package": "App"
|
|
},
|
|
"data_description": {
|
|
"app_package": "Every app you can act on. '(no name yet)' means the device reported no label for it — pick it and type one. To change a package id itself, remove the row and add it again, or edit the whole list as text."
|
|
}
|
|
},
|
|
"apps_edit_form": {
|
|
"title": "Edit an app",
|
|
"description": "Editing {app}. The package id identifies the row and is not changed here.",
|
|
"data": {
|
|
"app_name": "Name to show",
|
|
"app_icon": "Icon (optional)"
|
|
},
|
|
"data_description": {
|
|
"app_name": "What the source list, the Current App sensor and the media player show for this app.",
|
|
"app_icon": "A picture URL or a camera entity id. Clear it to drop the picture."
|
|
}
|
|
},
|
|
"apps_remove": {
|
|
"title": "Remove an app",
|
|
"description": "Pick the app to remove. Nothing is removed until you confirm on the next step.",
|
|
"data": {
|
|
"app_package": "App"
|
|
},
|
|
"data_description": {
|
|
"app_package": "The rows saved so far. The confirmation is next."
|
|
}
|
|
},
|
|
"apps_remove_confirm": {
|
|
"title": "Remove an app",
|
|
"description": "Remove {app} from the list? It leaves the source list when you save, and the app itself stays installed on the Shield.",
|
|
"menu_options": {
|
|
"apps_remove_yes": "Remove it",
|
|
"apps_remove_no": "Keep it"
|
|
}
|
|
},
|
|
"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 Shield to run it on: its media_player entity. Select it in the target picker above, or pass entity_id (or the Shield's device_id) in YAML."
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"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}"
|
|
},
|
|
"no_target": {
|
|
"title": "No Shield selected",
|
|
"message": "Select the Shield to run this on: the target picker's entity (or pass entity_id / device_id in YAML). {service} sends nothing without a target."
|
|
},
|
|
"ambiguous_target": {
|
|
"title": "More than one Shield selected",
|
|
"message": "{entity_id} covers more than one adb_command target — select exactly one Shield (one media_player entity) — command not sent."
|
|
},
|
|
"unknown_activity": {
|
|
"title": "Unknown activity",
|
|
"message": "'{activity}' is not one of this Shield's activities. Use a name from the remote's activity list (the Apps map names, or the built-in list when no map is set), or pass an app's package id / a detail link."
|
|
},
|
|
"activity_launch_failed": {
|
|
"title": "Activity could not launch",
|
|
"message": "'{activity}' was not launched: the remote protocol could not run the command. Check the remote entity's protocol_* attributes (protocol_state says whether the transport is connected) — nothing was sent."
|
|
},
|
|
"protocol_unavailable": {
|
|
"title": "Remote-protocol transport unavailable",
|
|
"message": "'{activity}' was not launched: this entry has no remote-protocol transport (the option is off, or the androidtvremote2 library is missing). Turn the transport on and pair it, then try again."
|
|
}
|
|
},
|
|
"entity": {
|
|
"sensor": {
|
|
"current_app": {
|
|
"name": "Current app"
|
|
},
|
|
"now_playing": {
|
|
"name": "Now playing"
|
|
},
|
|
"installed_apps": {
|
|
"name": "Installed apps"
|
|
}
|
|
},
|
|
"image": {
|
|
"screen_capture": {
|
|
"name": "Screen capture"
|
|
}
|
|
}
|
|
}
|
|
}
|