Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Add support for the Unitymedia Horizon HD Recorder #14275

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jun 10, 2018
Merged

Add support for the Unitymedia Horizon HD Recorder #14275

merged 12 commits into from
Jun 10, 2018

Conversation

benleb
Copy link
Contributor

@benleb benleb commented May 3, 2018

Description:

A new platform for the Unitymedia Horizon HD Recorder sold by Unitymedia in Germany. The channel list is hardcoded currently but I already reached out to Unitymedia to get a parseable list. As this list doesn't change often, I think that's not a problem. Also working on an async version of this but as this involves the underlying library (einder), this takes some time.

Related issue (if applicable): -

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

Example entry for configuration.yaml (if applicable):

media_player:
  - platform: horizon
    host: 192.168.0.127

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox. Your PR cannot be merged unless tests pass

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

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

  • 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.

If the code does not interact with devices:

  • Tests have been added to verify that the new code works.

@fabaff fabaff changed the title added new platform for the Unitymedia Horizon HD Recorder Add support for the Unitymedia Horizon HD Recorder May 10, 2018
from einder import Client, keys
from einder.exceptions import AuthenticationError

host = config.get(CONF_HOST)
Copy link
Member

Choose a reason for hiding this comment

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

Please access the config (host, name, port) directly (config[CONF_HOST]) if it's safe.

client = Client(host, port=port)
except (AuthenticationError, OSError) as msg:
_LOGGER.error("Connection to %s at %s failed: %s", name, host, msg)
return False
Copy link
Member

Choose a reason for hiding this comment

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

You could raise a PlatformNotReady exception if there is a chance (OSError?) for recovery. The AuthenticationError should return False.

Copy link
Member

Choose a reason for hiding this comment

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

Nothing is checking this return value. Either just return or raise PlatformNotReady as recommended above.

self._name = name
self._state = False
self._keys = keys
self._source_list = {1: 'Das Erste HD', 2: 'ZDF HD', 3: 'RTL HD',
Copy link
Member

Choose a reason for hiding this comment

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

I'm not happy about using the source_list as channel list. I've seen this multiple times now. This is just my personal feeling.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think this dictionary of channels belongs in home assistant code. Why do we need it? Looks like we send the channel ID and not the channel name anyway. This could be moved to the documentation, and instead of using source select to select channel, just use play media service.

syssi
syssi previously approved these changes May 22, 2018
self._name = name
self._state = False
self._keys = keys
self._source_list = {1: 'Das Erste HD', 2: 'ZDF HD', 3: 'RTL HD',
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this dictionary of channels belongs in home assistant code. Why do we need it? Looks like we send the channel ID and not the channel name anyway. This could be moved to the documentation, and instead of using source select to select channel, just use play media service.


def play_media(self, media_type, media_id, **kwargs):
"""Play media / switch to channel."""
if MEDIA_TYPE_CHANNEL == media_type and isinstance(int(media_id), int):
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need the type check after the copy to integer?

in self._source_list.items()
if v == source]

if digits is not None:
Copy link
Member

Choose a reason for hiding this comment

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

When can this happen?

def _select_channel(self, channel):
"""Select a channel (taken from einder library, thx)."""
for i in str(channel):
key = int(i) + 0xe300
Copy link
Member

Choose a reason for hiding this comment

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

This looks like too much protocol specific code. It should probably be part of the interface library.

self._client.authorize()
except (AuthenticationError, OSError) as msg:
_LOGGER.error("Connection to %s failed: %s", self._name, msg)
return False
Copy link
Member

Choose a reason for hiding this comment

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

Nothing is checking this return value.

client = Client(host, port=port)
except (AuthenticationError, OSError) as msg:
_LOGGER.error("Connection to %s at %s failed: %s", name, host, msg)
return False
Copy link
Member

Choose a reason for hiding this comment

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

Nothing is checking this return value. Either just return or raise PlatformNotReady as recommended above.

return self._name

@property
def client(self):
Copy link
Member

Choose a reason for hiding this comment

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

Remove this. It's not needed and not used.

return self._state

@property
def keys(self):
Copy link
Member

Choose a reason for hiding this comment

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

Same as above.

@syssi syssi dismissed their stale review May 26, 2018 21:29

Requested changes by Martin

@benleb
Copy link
Contributor Author

benleb commented Jun 2, 2018

I will look at this in the next 1-2 weekends :) Thanks for the comments/tips!

@benleb
Copy link
Contributor Author

benleb commented Jun 9, 2018

@syssi & @MartinHjelmare thanks for your reviews, all mentioned things should be fixed now.

})


# pylint: disable=unused-argument
Copy link
Member

Choose a reason for hiding this comment

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

This is already globally disabled.

"""Initialize the remote."""
self._client = client
self._name = name
self._state = False
Copy link
Member

Choose a reason for hiding this comment

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

Initialize unknown state as None.

except OSError as msg:
# occurs if horizon box is offline
_LOGGER.error("Reconnect to %s failed: %s", self._name, msg)
raise PlatformNotReady
Copy link
Member

Choose a reason for hiding this comment

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

We're not inside setup_platform anymore here, so raising PlatformNotReady doesn't work. Probably just return.

@benleb
Copy link
Contributor Author

benleb commented Jun 10, 2018

thanks for your reviews and your help @MartinHjelmare!! Wont make these mistakes again in my next PR ;)

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

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

Nice!

@MartinHjelmare
Copy link
Member

Can be merged when build passes.

@syssi syssi merged commit 1da3003 into home-assistant:dev Jun 10, 2018
@ghost ghost removed the in progress label Jun 10, 2018
@benleb benleb deleted the add-horizon-platform branch June 10, 2018 13:45
@balloob balloob mentioned this pull request Jun 22, 2018
@home-assistant home-assistant locked and limited conversation to collaborators Dec 10, 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.

4 participants