Skip to content

Add Songpal ("Sony Audio Control API") platform#12143

Merged
balloob merged 16 commits intohome-assistant:devfrom
rytilahti:add_sony_audio
Feb 27, 2018
Merged

Add Songpal ("Sony Audio Control API") platform#12143
balloob merged 16 commits intohome-assistant:devfrom
rytilahti:add_sony_audio

Conversation

@rytilahti
Copy link
Copy Markdown
Member

@rytilahti rytilahti commented Feb 3, 2018

Description:

This adds support for a variety of Sony soundbars and potentially
many more devices using the same API with the help of python-songpal: https://github.com/rytilahti/python-songpal

This device is automatically discovered by netdisco and added into homeassistant accordingly, so no manual configuration is required wherever it is working.

Official API from Sony: https://developer.sony.com/develop/audio-control-api/
Officially supported devices by Sony: HT-ST5000, HT-MT500, HT-CT800, SRS-ZR5, STR-DN1080 - however, see http://vssupport.sony.net/en_ww/device.html for list of (potentially) supported devices.

Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#4570

Example entry for configuration.yaml (if applicable):

media_player:
  - platform: songpal
    name: my soundbar
    endpoint: http://192.168.1.1:10000/sony

Checklist:

  • The code change is tested and works locally.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (98 > 79 characters)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (84 > 79 characters)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'typing.List' imported but unused

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

false positive, this is used in async_setup_platform.

@rytilahti rytilahti changed the title WIP: Add Songpal ("Sony Audio Control API") platform Add Songpal ("Sony Audio Control API") platform Feb 3, 2018
@rytilahti rytilahti changed the title Add Songpal ("Sony Audio Control API") platform WIP: Add Songpal ("Sony Audio Control API") platform Feb 4, 2018
@rytilahti
Copy link
Copy Markdown
Member Author

rytilahti commented Feb 4, 2018

Added WIP back as this depends on python >3.5 due due to async def usage. Can be merged after python 3.5 becomes a requirement, which can take some time.

In the meantime, it would be nice to get more people who have such a device to test the tool and the integration :-)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (85 > 79 characters)

@rytilahti rytilahti changed the title WIP: Add Songpal ("Sony Audio Control API") platform Add Songpal ("Sony Audio Control API") platform Feb 23, 2018
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove default=None. It's unnecessary for Optional to work and it also won't work since we upgraded voluptuous. The upgraded voluptuous will validate all values passed via default with the validator. None is not valid for cv.string

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to know, thanks!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work. devices is not shared between 2 configured entities. It would also mean that you are registering the service twice.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, no idea where I came up with that idea. Converted it to store devices in hass.data.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this to a constant.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by moving this to a constant? Which part of it precisely?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole thing.

SET_SOUND_SCHEMA = vol.Schema(…)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, moved it on top of the file.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? Why not just assign it to self.dev in the constructor?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, changed that.

except SongpalException as ex:
# if we were available, print out the exception
if self._available:
_LOGGER.error("Got an exception %s", ex, exc_info=True)
Copy link
Copy Markdown
Member

@balloob balloob Feb 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use _LOGGER.exception(""), it will log the exception.

Does this also mean that whenever the device goes offline, we log a whole stack trace? That seems undesirable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That it will do indeed. I thought it'd be a good idea to have something visible in case some of the above calls fail, but I can remove it and just print out the exception.

from songpal import SongpalException
try:
volumes = await self.dev.get_volume_information()
if not volumes:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move all code that will not raise out of the try…except

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that all the method calls may result in such an exception. One solution would be to do the fetching inside one block and then access the properties outside of it, I just kept it like this to keep the assignments & their usage nearby. I would not really like to have three separate try-except-blocks for this.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the rest of the issues (plus one extra I spotted in wrong handling of multiple volume controls) except this one. If you really prefer to have those fetches in one block, I could simply return in case of failure and set the state variables outside the try-catch block.

try:
volumes = await self.dev.get_volume_information()
if not volumes:
_LOGGER.error("Got no volume controls, bailing out")
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this set available to False?

Copy link
Copy Markdown
Member Author

@rytilahti rytilahti Feb 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should never get that far I suppose, but I can add a safe-guard for it.
edit: done.

.coveragerc Outdated
homeassistant/components/media_player/roku.py
homeassistant/components/media_player/russound_rio.py
homeassistant/components/media_player/russound_rnet.py
homeassistant/components/media_player/songpal.py
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔡

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

* Fix coveragerc ordering
* Do not print out the whole exception trace when failing to update
* Do not bail out when receiving more than one volume control
* Set to unavailable when no volume controls are available
@balloob balloob merged commit 39cee98 into home-assistant:dev Feb 27, 2018
@rytilahti rytilahti deleted the add_sony_audio branch February 28, 2018 00:27
"""Set volume level."""
volume = int(volume * self._volume_max)
_LOGGER.debug("Setting volume to %s", volume)
return await self._volume_control.set_volume(volume)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why return here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is indeed unnecessary here, but it should not cause any side effects so I will fix that with the same PR where this will be converted non-polling, if that's okay.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@balloob balloob mentioned this pull request Mar 9, 2018
@home-assistant home-assistant locked and limited conversation to collaborators Jul 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants