Closed hermannsblum closed 4 years ago
I'm having the same isuue. How can I control the volume using HomeKit ?
Can you both post the state for the entities you are trying to expose as TV's? In particular, the supported_features
field.
It must have SUPPORT_VOLUME_MUTE
or SUPPORT_VOLUME_STEP
on the HA side to create a TelevisionSpeaker
service in homekit. That should be the case for a denonavr, though.
Hey @Jc2k , thanks for the pointer I guess this could be the problem, this is the relevant part of the state:
supported_features: 85949
If I get your comment right this should rather be a list of strings than an integer?
More exciting than that, its a bitfield. SUPPORT_VOLUME_MUTE
is worth 8 (i.e. its the 4th bit).
>>> 85949 & 8
8
So the SUPPORT_VOLUME_MUTE
bit is set. SUPPORT_VOLUME_SET
is worth 4 and is also set. So i would expect to see a speaker.
Looking at the code again, I think feature_list:
is ignored for TV's. So it might be worth stripping that out in case its having a negative affect. I suspect that is unrelated though.
You said you can select the source. That is only done if you have SUPPORT_SELECT_SOURCE
. Which means when homekit started something was in the supported_features
field. So it's not as likely to be a race where homekit is starting before the media_player has been setup or something. Though it is worth trying to turn off auto_start to see if manually starting homekit helps.
If you are comfortable with a text editor the relevant bit of code is here.
I would be tempted to find this bit:
if CHAR_VOLUME_SELECTOR in self.chars_speaker:
serv_speaker = self.add_preload_service(
SERV_TELEVISION_SPEAKER, self.chars_speaker
)
And make it:
print("Checking for speaker support")
if CHAR_VOLUME_SELECTOR in self.chars_speaker:
print("Configuring speaker")
serv_speaker = self.add_preload_service(
SERV_TELEVISION_SPEAKER, self.chars_speaker
)
Then restart and look at your logs. If you cannot find "Checking for speaker support" in your logs try _LOGGER.warning
instead of print
.
This will tell us whether homekit doesnt think it can support speakers for your media_player
or whether its doing something that iOS can't understand.
Thanks for all the info and support!
I followed your guidance and debugged for all the flags. CHAR_VOLUME_SELECTOR
is there, so it starts configuring a speaker.
I checked for my setup and all the three flags SUPPORT_VOLUME_MUTE
, SUPPORT_VOLUME_STEP
, SUPPORT_VOLUME_SET
are set, so this really cannot be the problem.
I have no idea of homekit in general so the whole magic of how these chars are combined in the piece of code you linked to does not make much sense to me, but I guess this is where it fails?
So that probably means that the entities HA are exposing to the iPhone are invalid in some way. Maybe missing a required field or something. I can think of 2 ways to proceed - both involve getting a JSON file out of the homekit integration so that I can compare it to the 2 real TV's ive seen.
1 - you'll need to unpair HA from your iOS device. you will lose your rooms and scenes. You can then use github.com/jlusiardi/homekit_python/ to pair with it from the command line and get the file i need (though i just remembered that does need a 1 line code fix on the HA side to fix an incompatibility)
2 - where you added the print before you can add print(self.to_HAP())
- this will give me a subset of the data i need but it's probably enough to get started with. Put it right at the end of the function like this:
if self.support_select_source:
... snip ....
_LOGGER.debug("%s: Added source %s.", self.entity_id, source)
print(self.to_HAP())
def set_on_off(self, value):
You might also be able to do self.driver.get_accessories()
which will include the full data.
Let's hope that the second path will work :)
I was able to gather the following:
Comparing the speaker part with a capture from a real TV the only difference I can see is the VolumeControlType. We seem to set it to 1, but on a real TV it is 3. 1 is relative, 3 is absolute.
We can see it gets set to 1
here.
So if the TV supports SET_VOLUME, it gets set to 1
, otherwise it sets it to 2
. This means RELATIVE_WITH_CURRENT
. I have no idea what RELATIVE_WITH_CURRENT
means.
So you should try setting that line to 3 to see if that helps.
The only other difference is that it has a name. So you could also try commenting out this line here.
hmm, I guess that is a dead end then, I tried to remove the name and set SET_VOLUME to
3
, but I still don't have volume control...
OK that was wrong, it worked! The volume control is just super weirdly hidden in homekit apparently, you suddenly I have another remote control access in my control center and there I can control the volume with the volume buttons.
I will check now whether it is the SET_VOLUME or the name...
Hmm, this is not going to help gain insight. After it worked, I reverted all the changes and resetted the component at least 5 times, but the volume control still works. It may be that this is rather a Homekit bug?
I think I might be having a similar problem...
auto_start: False
filter:
include_entities:
[snip]
- media_player.living_room_tv
- media_player.bedroom_tv
entity_config:
media_player.living_room_tv:
feature_list:
- feature: on_off
- feature: play_pause
- feature: play_stop
- feature: toggle_mute
media_player.bedroom_tv:
feature_list:
- feature: on_off
- feature: play_pause
- feature: play_stop
- feature: toggle_mute
For living_room_tv: supported_features: 69004
For bedroom_tv: supported_features: 21389
In both cases only power and input selection seem to work. All features in theory should work. I can control volume/mute for example in lovelace.
They are both using the universal
media_player platform FWIW.
@raccettura
The volume control is just super weirdly hidden in homekit apparently, you suddenly I have another remote control access in my control center and there I can control the volume with the volume buttons.
The volume control is apparently not part of the home app, but showed up for me as a separate entity in control center. Do you see such a remote icon in your control center?
@hermannsblum did you manage to get the arrows working? My TV is working only with play/pause and volume controls.
@raccettura
The volume control is just super weirdly hidden in homekit apparently, you suddenly I have another remote control access in my control center and there I can control the volume with the volume buttons.
The volume control is apparently not part of the home app, but showed up for me as a separate entity in control center. Do you see such a remote icon in your control center?
I’m very interested in understanding if you finally managed to publish your Denon AVR into HomeKit successfully or not. It is not clear to me if you have managed to control the volume. Do you happen to have an Apple Watch? If so, can you control the AVR volume from the watch itself?
@hermannsblum did you manage to get the arrows working? My TV is working only with play/pause and volume controls.
turns out the problem is how the HomeKit integration handles remote control commands. I the way it was written, it supported only Play and Pause, everything else was commented:
MEDIA_PLAYER_KEYS = {
# 0: "Rewind",
# 1: "FastForward",
# 2: "NextTrack",
# 3: "PreviousTrack",
# 4: "ArrowUp",
# 5: "ArrowDown",
# 6: "ArrowLeft",
# 7: "ArrowRight",
# 8: "Select",
# 9: "Back",
# 10: "Exit",
11: SERVICE_MEDIA_PLAY_PAUSE,
# 15: "Information",
}
def set_remote_key(self, value):
"""Send remote key value if call came from HomeKit."""
_LOGGER.debug("%s: Set remote key to %s", self.entity_id, value)
service = MEDIA_PLAYER_KEYS.get(value)
if service:
# Handle Play Pause
if service == SERVICE_MEDIA_PLAY_PAUSE:
state = self.hass.states.get(self.entity_id).state
if state in (STATE_PLAYING, STATE_PAUSED):
service = (
SERVICE_MEDIA_PLAY
if state == STATE_PAUSED
else SERVICE_MEDIA_PAUSE
)
params = {ATTR_ENTITY_ID: self.entity_id}
self.call_service(DOMAIN, service, params)
Since my media_player
entity is an LG TV, I can send remote control commands using the webostv.button
service, so I copied the HomeKit integration to custom_components
and changed the code a little bit:
MEDIA_PLAYER_KEYS = {
2: SERVICE_MEDIA_NEXT_TRACK,
3: SERVICE_MEDIA_PREVIOUS_TRACK,
4: "UP",
5: "DOWN",
6: "LEFT",
7: "RIGHT",
8: "ENTER",
9: "BACK",
10: "EXIT",
11: SERVICE_MEDIA_PLAY_PAUSE,
15: "HOME",
}
def set_remote_key(self, value):
"""Send remote key value if call came from HomeKit."""
_LOGGER.debug("%s: Set remote key to %s", self.entity_id, value)
service = MEDIA_PLAYER_KEYS.get(value)
if service:
# Handle Play/Pause and Next/Previous Track
if service in [SERVICE_MEDIA_PLAY_PAUSE, SERVICE_MEDIA_NEXT_TRACK, SERVICE_MEDIA_PREVIOUS_TRACK]:
if service == SERVICE_MEDIA_PLAY_PAUSE:
state = self.hass.states.get(self.entity_id).state
if state in (STATE_PLAYING, STATE_PAUSED):
service = (
SERVICE_MEDIA_PLAY
if state == STATE_PAUSED
else SERVICE_MEDIA_PAUSE
)
params = {ATTR_ENTITY_ID: self.entity_id}
self.call_service(DOMAIN, service, params)
else:
params = {ATTR_ENTITY_ID: self.entity_id, 'button': service}
self.call_service('webostv', 'button', params)
Now I just need to figure out a way to tell WebOS TVs and non-WebOS TVs apart.
As @marcgarciamarti said above, the volume controls are not in the Home app, but in the Remote app. Once you have the television selected, you use the physical volume controls on the iOS device to change the volume. I've confirmed this is still working on a universal media player in my system. This is documented in the docs here: https://www.home-assistant.io/integrations/homekit/#cant-control-volume-of-your-tv-media-player
@joogps @hermannsblum Additionally, the original PR which added TV support was limited in scope. There is an open PR that will hopefully get merged soon that adds support for physical keys here:
@adrum Great! Actually, I was working on a PR for the HomeKit integration, but I’m currently focusing on the panasonic_viera component. However, I can confirm that the control center remote works flawlessly. The only problem is that the hub can have expose only one TV at a time.
@adrum I think we can close this issue. I updated HA and confirmed on a previously unpaired ios device that the volume control works.
If you can point me to where I can add a PR to the documentation I can also put an info there such that people know that it is not in the homekit app.
@hermannsblum I would recommend adding to/changing the existing FAQ on this page:
https://github.com/home-assistant/home-assistant.io/blob/next/source/_integrations/homekit.markdown
The FAQ title is "Can't control volume of your TV media player?"
@adrum I think we can close this issue. I updated HA and confirmed on a previously unpaired ios device that the volume control works.
If you can point me to where I can add a PR to the documentation I can also put an info there such that people know that it is not in the homekit app.
After reading again all this, I’m not really sure I get what has been described above. @hermannsblum original message referred to controlling a Denon AVR, but at some point it drifted towards TVs. I imagine that it is the way to expose the media_player entity enabling volume control etc., right?
@hermannsblum if I’m right, could you kindly share your final configuration? Do you actually get decent control over it through HomeKit? Do you happen to have an Apple Watch?
Thanks
@marcgarciamarti My config is actually still the exact same as in the issue description. There was no issue in home-assisstant, it is just really hard to find these volume controls 😃
Concerning the TV: Whatever media player you want to connect to homekit (in my case an AVR), you need to enable the „Apple TV Remote“ for your control center and then you will be able to control the volume with the physical volume buttons while the tv remote is open (there is never any indication on the screen that this would work). The TV Remote will also not automatically enable in my experience, it has to be enabled in the device settings. This is very unintuitive, but really not in the power of home-assisstant to change anything there.
@marcgarciamarti My config is actually still the exact same as in the issue description. There was no issue in home-assisstant, it is just really hard to find these volume controls 😃 Concerning the TV: Whatever media player you want to connect to homekit (in my case an AVR), you need to enable the „Apple TV Remote“ for your control center and then you will be able to control the volume with the physical volume buttons while the tv remote is open (there is never any indication on the screen that this would work). The TV Remote will also not automatically enable in my experience, it has to be enabled in the device settings. This is very unintuitive, but really not in the power of home-assisstant to change anything there.
@hermannsblum thanks for the clarification. I do have an apple tv and for me, that application has always been present in Control Center as far as I can recall :) My problem is that I am not successfully managing to expose my AVR -Marantz SR5012- to homekit I guess. I just don't see an AVR there :(
Any tip would be extremely appreciated.
This is what my homekit setup looks like:
homekit:
auto_start: False
filter:
include_domains:
- climate
- sensor
- media_player
- cover
- input_boolean
- switch
- light
exclude_entities:
- input_boolean.zigbee_permit_join
entity_config:
media_player.marantz_sr5012:
feature_list:
- feature: on_off
- feature: play_pause
- feature: play_stop
- feature: toggle_mute
I don't have a manual definition/configuration of media-player in my configuration.yaml file because I use the HEOS front-end integration, and it works just lovely (well, everything does except Homekit)
despite the fact that I don't manually define my AVR, I do end up getting a proper media_player entity:
I decided to manually configure my Marantz AVR like this:
media_player:
- platform: denonavr
host: 192.168.1.12
name: "Marantz SR5012"
show_all_sources: true
timeout: 2
zones:
- zone: Zone2
name: Zone2
and defined this is customize.yaml:
media_player.marantz_sr5012:
device_class: tv
Now I do see a TV like entity in Home.app, but it won't allow me to control the volume.
If I now go to the Remote.app on my iPhone, the AVR is not appearing there as a possible target :(
I’ve tried to understand what the available features number means but I must say that I did not get it. Could you or @Jc2k possibly assist me with that?
New update. I feel dumb. If I go to the Remote.app on my iPhone, the AVR is NOT there. However, if I go to the remote widget in Control Center, it is!! After all this effort, I'm a bit disappointed: I was expecting to be able to turn the volume up and down from my Apple watch once I had managed to get my iPhone to natively control the volume (which is now the case).
@Jc2k or @hermannsblum do you happen to have an apple watch to test this?
@marcgarciamarti I just looked, and there does not seem to be a way to do this with Apple Watch at the moment. I suppose Apple could release this with a future release of watchOS.
It definitely feels like the devices in the Remote.app should match the devices in the Control Center Remote widget. If that were the case, that should allow volume control on watchOS.
@marcgarciamarti I just looked, and there does not seem to be a way to do this with Apple Watch at the moment. I suppose Apple could release this with a future release of watchOS.
It definitely feels like the devices in the Remote.app should match the devices in the Control Center Remote widget. If that were the case, that should allow volume control on watchOS.
thanks for taking the time @adrum ! :) Fully agree, not sure why the two apps won't match in what they show. It is utterly weird. From your answer, I assume that what I see is what you see too... :(
I actually think they should incorporate the remote functionality into the Home app (while keeping the Control Center widget and the Remote app, obviously). It'd be much better to be able to access controls directly from the details page of the TV device. Also, they should really fix the annoying "one TV per bridge" policy.
I agree with all of that. I was working concept on the ability to have multiple bridges in a HomeAssistant install. I need to clean it up and get some feedback on the config changes since it would likely be a breaking change.
Additionally, they use to require cameras to be on their own accessory that was not a bridge, but that changed in recent versions. I don't think it will for televisions since all of the TV manufacturers only have one TV per bridge in practice.
I was thinking about the option of creating multiple bridges too. Actually, I spent the last few days fixing the Panasonic Viera integration and my next goal is to improve the remote handling of the HomeKit component.
It looks like multiple bridges is coming soon! https://github.com/home-assistant/core/pull/34560
This will allow you to overcome the limitation of 1 television per bridge by creating as many bridges as necessary.
Yes, I saw that too! I'm very excited for the new possibilities it will bring.
This will allow you to overcome the limitation of 1 television per bridge by creating as many bridges as necessary.
So does this mean that you can currently only add one TV with home assistant (because it acts as one bridge)? From your conversation above I read that only one TV is possible per bridge. So do I understand correctly that the issue here is that ha acts as one bridge?
What I don't understand is this:
I don't think it will for televisions since all of the TV manufacturers only have one TV per bridge in practice.
Is this because every TV is it's own bridge? What happens if you have two TV's from the same manufacturer with HomeKit support (two bridges)?
Some background to start:
On a homekit device there are, starting at the bottom:
Some devices have multiple accessories on a single device, these are called bridges. But a TV is probably just a single accessory in the HomeKit protocol, so not considered a bridge.
Each device is paired via the HomeKit protocol individually over a HTTP-like encypted protocol. So if you have 3 TV's, thats 3 pairings. Each pairing is unaware of the other pairing, they only talk to the controller (in this case, the iOS device).
So normally there would be 1 TV per pairing.
In HomeKit a bridge is generally an adapter for devices that don't speak the protocol natively, so Hue is a bridge and speaks HomeKit on behalf of all the non-IP Hue devices you have.
Does that help? A TV speaks HomeKit natively, so is not normally on a bridge. Home Assistant acts as a single bridge, so there is a limit on how many devices and of what kind it can export. By pretending to actually be multiple bridges we get around that.
2 TV's from the same manufacturer with HomeKit would be unaware of each other at the HomeKit level.
@Jc2k Yes, it helped to understand it a bit better. Thanks a lot for you explanation and your time!
The volume control is apparently not part of the home app, but showed up for me as a separate entity in control center. Do you see such a remote icon in your control center?
The remote is there, but it only shows the bedroom tv not the living room tv. In neither case can it control play, pause, stop, volume or mute.
The only thing controllable via homekit is on/off and input selection.
For both tv's i'm using the universal media player, so I think that's a likely common denominator.
Is there any way to control the volume step in the widget? I managed to find my receiver in the widget and can increase and decrease the volume using the buttons. However the volume step seems to be 10db - which is quite a lot imho. Is there any place I can customize this?
Home Assistant release with the issue: 0.103
Operating environment (Hass.io/Docker/Windows/etc.): Hass.io
Integration: https://www.home-assistant.io/integrations/homekit
Description of problem: I have a media player based on the Denon integration:
It works perfectly and I can control sources aswell as volume.
I also added it to the homekit integration:
and I specified
device_class: tv
to enable the TV remote.The device shows up in homekit as TV (so far correct), but I can only switch it on/off or select the source. There are no options to change volume or play/pause. The documentation does not say much for this case. How can I debug and fix this problem?