Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
203 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
""" | ||
Support for the Roku remote. | ||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/remote.roku/ | ||
""" | ||
import requests.exceptions | ||
|
||
from homeassistant.components import remote | ||
from homeassistant.const import (CONF_HOST) | ||
|
||
|
||
DEPENDENCIES = ['roku'] | ||
|
||
|
||
async def async_setup_platform(hass, config, async_add_entities, | ||
discovery_info=None): | ||
"""Set up the Roku remote platform.""" | ||
if not discovery_info: | ||
return | ||
|
||
host = discovery_info[CONF_HOST] | ||
async_add_entities([RokuRemote(host)], True) | ||
|
||
|
||
class RokuRemote(remote.RemoteDevice): | ||
"""Device that sends commands to an Roku.""" | ||
|
||
def __init__(self, host): | ||
"""Initialize the Roku device.""" | ||
from roku import Roku | ||
|
||
self.roku = Roku(host) | ||
self._device_info = {} | ||
|
||
def update(self): | ||
"""Retrieve latest state.""" | ||
try: | ||
self._device_info = self.roku.device_info | ||
except (requests.exceptions.ConnectionError, | ||
requests.exceptions.ReadTimeout): | ||
pass | ||
|
||
@property | ||
def name(self): | ||
"""Return the name of the device.""" | ||
if self._device_info.userdevicename: | ||
return self._device_info.userdevicename | ||
return "Roku {}".format(self._device_info.sernum) | ||
|
||
@property | ||
def unique_id(self): | ||
"""Return a unique ID.""" | ||
return self._device_info.sernum | ||
|
||
@property | ||
def is_on(self): | ||
"""Return true if device is on.""" | ||
return True | ||
|
||
@property | ||
def should_poll(self): | ||
"""No polling needed for Roku.""" | ||
return False | ||
|
||
def send_command(self, command, **kwargs): | ||
"""Send a command to one device.""" | ||
for single_command in command: | ||
if not hasattr(self.roku, single_command): | ||
continue | ||
|
||
getattr(self.roku, single_command)() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
""" | ||
Support for Roku platform. | ||
For more details about this platform, please refer to the documentation at | ||
https://home-assistant.io/components/roku/ | ||
""" | ||
import logging | ||
|
||
import voluptuous as vol | ||
|
||
from homeassistant.components.discovery import SERVICE_ROKU | ||
from homeassistant.const import CONF_HOST | ||
from homeassistant.helpers import discovery | ||
import homeassistant.helpers.config_validation as cv | ||
|
||
REQUIREMENTS = ['python-roku==3.1.5'] | ||
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
DOMAIN = 'roku' | ||
|
||
SERVICE_SCAN = 'roku_scan' | ||
|
||
ATTR_ROKU = 'roku' | ||
|
||
DATA_ROKU = 'data_roku' | ||
|
||
NOTIFICATION_ID = 'roku_notification' | ||
NOTIFICATION_TITLE = 'Roku Setup' | ||
NOTIFICATION_SCAN_ID = 'roku_scan_notification' | ||
NOTIFICATION_SCAN_TITLE = 'Roku Scan' | ||
|
||
|
||
CONFIG_SCHEMA = vol.Schema({ | ||
DOMAIN: vol.All(cv.ensure_list, [vol.Schema({ | ||
vol.Required(CONF_HOST): cv.string | ||
})]) | ||
}, extra=vol.ALLOW_EXTRA) | ||
|
||
# Currently no attributes but it might change later | ||
ROKU_SCAN_SCHEMA = vol.Schema({}) | ||
|
||
|
||
def setup(hass, config): | ||
"""Set up the Roku component.""" | ||
hass.data[DATA_ROKU] = {} | ||
|
||
def service_handler(service): | ||
"""Handle service calls.""" | ||
if service.service == SERVICE_SCAN: | ||
scan_for_rokus(hass) | ||
|
||
def roku_discovered(service, info): | ||
"""Set up an Roku that was auto discovered.""" | ||
_setup_roku(hass, config, { | ||
CONF_HOST: info['host'] | ||
}) | ||
|
||
discovery.listen(hass, SERVICE_ROKU, roku_discovered) | ||
|
||
for conf in config.get(DOMAIN, []): | ||
_setup_roku(hass, config, conf) | ||
|
||
hass.services.register( | ||
DOMAIN, SERVICE_SCAN, service_handler, | ||
schema=ROKU_SCAN_SCHEMA) | ||
|
||
return True | ||
|
||
|
||
def scan_for_rokus(hass): | ||
"""Scan for devices and present a notification of the ones found.""" | ||
from roku import Roku, RokuException | ||
rokus = Roku.discover() | ||
|
||
devices = [] | ||
for roku in rokus: | ||
try: | ||
r_info = roku.device_info | ||
except RokuException: # skip non-roku device | ||
continue | ||
devices.append('Name: {0}<br />Host: {1}<br />'.format( | ||
r_info.userdevicename if r_info.userdevicename | ||
else "{} {}".format(r_info.modelname, r_info.sernum), | ||
roku.host)) | ||
if not devices: | ||
devices = ['No device(s) found'] | ||
|
||
hass.components.persistent_notification.create( | ||
'The following devices were found:<br /><br />' + | ||
'<br /><br />'.join(devices), | ||
title=NOTIFICATION_SCAN_TITLE, | ||
notification_id=NOTIFICATION_SCAN_ID) | ||
|
||
|
||
def _setup_roku(hass, hass_config, roku_config): | ||
"""Set up a Roku.""" | ||
from roku import Roku | ||
host = roku_config[CONF_HOST] | ||
|
||
if host in hass.data[DATA_ROKU]: | ||
return | ||
|
||
roku = Roku(host) | ||
r_info = roku.device_info | ||
|
||
hass.data[DATA_ROKU][host] = { | ||
ATTR_ROKU: r_info.sernum | ||
} | ||
|
||
discovery.load_platform( | ||
hass, 'media_player', DOMAIN, roku_config, hass_config) | ||
|
||
discovery.load_platform( | ||
hass, 'remote', DOMAIN, roku_config, hass_config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters