Ok - So I was finally able to get it working. Pretty sure I tried the same thing last time, so not sure what I did different this time.
Step 1:
Got all the files for the Apple TV Component and put them in the custom_component folder. So I wouldn’t have to change the original one. core/homeassistant/components/apple_tv at dev · home-assistant/core · GitHub
Step 2:
Change the manifest, I just changed the name and added a version:
{
"domain": "apple_tv",
"name": "Eple TV",
"version": "1.0.0",
"codeowners": ["@postlund"],
"config_flow": true,
"dependencies": ["zeroconf"],
"documentation": "https://www.home-assistant.io/integrations/apple_tv",
"iot_class": "local_push",
"loggers": ["pyatv", "srptools"],
"requirements": ["pyatv==0.15.1"],
"zeroconf": [
"_mediaremotetv._tcp.local.",
"_companion-link._tcp.local.",
"_airport._tcp.local.",
"_sleep-proxy._udp.local.",
"_touch-able._tcp.local.",
"_appletv-v2._tcp.local.",
"_hscp._tcp.local.",
{
"type": "_airplay._tcp.local.",
"properties": {
"model": "appletv*"
}
},
{
"type": "_airplay._tcp.local.",
"properties": {
"model": "audioaccessory*"
}
},
{
"type": "_airplay._tcp.local.",
"properties": {
"am": "airport*"
}
},
{
"type": "_raop._tcp.local.",
"properties": {
"am": "appletv*"
}
},
{
"type": "_raop._tcp.local.",
"properties": {
"am": "audioaccessory*"
}
},
{
"type": "_raop._tcp.local.",
"properties": {
"am": "airport*"
}
}
]
}
Step 3:
Change the remote.py to this:
"""Remote control support for Apple TV."""
import asyncio
from collections.abc import Iterable
import logging
from typing import Any
from pyatv.const import InputAction
from homeassistant.components.remote import (
ATTR_DELAY_SECS,
ATTR_HOLD_SECS,
ATTR_NUM_REPEATS,
DEFAULT_DELAY_SECS,
DEFAULT_HOLD_SECS,
RemoteEntity,
)
from homeassistant.const import CONF_NAME
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AppleTvConfigEntry
from .entity import AppleTVEntity
_LOGGER = logging.getLogger(__name__)
PARALLEL_UPDATES = 0
COMMAND_TO_ATTRIBUTE = {
"wakeup": ("power", "turn_on"),
"suspend": ("power", "turn_off"),
"turn_on": ("power", "turn_on"),
"turn_off": ("power", "turn_off"),
"volume_up": ("audio", "volume_up"),
"volume_down": ("audio", "volume_down"),
}
async def async_setup_entry(
hass: HomeAssistant,
config_entry: AppleTvConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Load Apple TV remote based on a config entry."""
name: str = config_entry.data[CONF_NAME]
# apple_tv config entries always have a unique id
assert config_entry.unique_id is not None
manager = config_entry.runtime_data
async_add_entities([AppleTVRemote(name, config_entry.unique_id, manager)])
class AppleTVRemote(AppleTVEntity, RemoteEntity):
"""Device that sends commands to an Apple TV."""
@property
def is_on(self) -> bool:
"""Return true if device is on."""
return self.atv is not None
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the device on."""
await self.manager.connect()
async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the device off."""
await self.manager.disconnect()
async def async_send_command(self, command: Iterable[str], **kwargs: Any) -> None:
"""Send a command to one device."""
num_repeats = kwargs[ATTR_NUM_REPEATS]
delay = kwargs.get(ATTR_DELAY_SECS, DEFAULT_DELAY_SECS)
if not self.is_on:
_LOGGER.error("Unable to send commands, not connected to %s", self.name)
return
for _ in range(num_repeats):
for single_command in command:
split = single_command.split(' ')
command_name = split[0]
if '.' in command_name:
attr_value = self.atv
for command_path in command_name.split('.'):
attr_value = getattr(attr_value, command_path, None)
else:
attr_value = getattr(self.atv.remote_control, single_command, None)
if not attr_value:
raise ValueError("Command not found. Exiting sequence!!!")
_LOGGER.info("Sending command %s", single_command)
arg = ' '.join(split[1:])
args = []
if arg:
args.append(arg)
await attr_value(*args)
await asyncio.sleep(delay)
Step 4
Restart Home Assistant - You should then see in your integration that the Apple TV Component has changed to the new name, in my case it changed from Apple TV to Eple TV (Apple in Norwegian for lack of imagination)
Step 5:
You should now be able to call an action like this:
action: remote.send_command
target:
entity_id: remote.living_room
data:
command:
- 'keyboard.text_set "Lord of the Rings"'
Note: For it to work you would have to have the search open on the Apple TV, so you could put it as part of a script.
alias: Nytt skript
sequence:
- action: media_player.select_source
target:
entity_id: media_player.living_room
data:
source: Søk
- action: remote.send_command
target:
entity_id: remote.living_room
data:
command:
- keyboard.text_set "Lord of the Rings"