-
-
Save jbeck22/e022385b71aa20620c903815f32004c9 to your computer and use it in GitHub Desktop.
Home Assistant Roku Remote (requires HA 0.62)
This file contains hidden or 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
homeassistant: | |
customize: | |
script.roku_button: | |
# using https://github.com/c727/home-assistant-tiles | |
custom_ui_state_card: state-card-tiles | |
config: | |
columns: 3 | |
column_width: 75px | |
row_height: 75px | |
entities: | |
- entity: script.roku_button | |
icon: mdi:power | |
column_span: 3 | |
data: { button: power } | |
- entity: script.roku_button | |
icon: mdi:backburger | |
data: { button: back } | |
- entity: script.roku_button | |
icon: mdi:home-outline | |
column: 3 | |
data: { button: home } | |
- entity: script.roku_button | |
icon: mdi:arrow-up-thick | |
column: 2 | |
data: { button: up } | |
- entity: script.roku_button | |
icon: mdi:arrow-left-thick | |
column: 1 | |
data: { button: left} | |
- entity: script.roku_button | |
label: "OK" | |
column: 2 | |
data: { button: select } | |
- entity: script.roku_button | |
icon: mdi:arrow-right-thick | |
column: 3 | |
data: { button: right } | |
- entity: script.roku_button | |
icon: mdi:arrow-down-thick | |
column: 2 | |
data: { button: down } | |
- entity: script.roku_button | |
icon: mdi:replay | |
column: 1 | |
data: { button: replay } | |
- entity: script.roku_button | |
icon: mdi:information-outline | |
column: 3 | |
data: { button: info } | |
- entity: script.roku_button | |
icon: mdi:rewind | |
column: 1 | |
data: { button: reverse } | |
- entity: script.roku_button | |
icon: mdi:play-pause | |
column: 2 | |
data: { button: play } | |
- entity: script.roku_button | |
icon: mdi:fast-forward | |
column: 3 | |
data: { button: forward } | |
- entity: script.roku_button | |
icon: mdi:volume-plus | |
column: 4 | |
column_span: 1 | |
row: 1 | |
row_span: 2 | |
data: { button: volume_up } | |
- entity: script.roku_button | |
icon: mdi:volume-minus | |
column: 4 | |
column_span: 1 | |
row: 3 | |
row_span: 2 | |
data: { button: volume_down } | |
- entity: script.roku_button | |
icon: mdi:volume-mute | |
column: 4 | |
column_span: 1 | |
row: 5 | |
data: { button: volume_mute } | |
frontend: | |
extra_html_url: | |
- /local/custom_ui/state-card-tiles.html | |
extra_html_url_es5: | |
- /local/custom_ui/state-card-tiles.html | |
group: | |
Living Room TV: | |
entities: | |
- script.roku_button | |
script: | |
roku_button: | |
sequence: | |
service: roku_remote.press_button | |
data_template: | |
button: "{{ button }}" | |
python_script: | |
input_text: | |
roku_remote_ip: | |
name: Roku Remote IP | |
roku_remote: |
This file contains hidden or 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 must be placed in | |
# {config-dir}/custom_components | |
# requires python-roku v3.1.5 which will be released with HA 0.62 | |
DOMAIN = 'roku_remote' | |
LAST_BUTTON_TOPIC = 'last_button' | |
from roku import Roku | |
import logging | |
def setup(hass, config): | |
roku = None | |
last_ip_state_name = 'input_text.roku_remote_ip' | |
def find_roku(): | |
logging.info('[roku_remote] looking for devices') | |
devices = Roku.discover(timeout=5) | |
logging.info('[roku_remote] found: ') | |
logging.info(devices) | |
found = None; | |
for d in devices: | |
if d.port == 8060: found = d | |
if found != None: break | |
if found != None: | |
roku = found | |
hass.states.set(last_ip_state_name, roku.host) | |
logging.info('[roku_remote] selected:') | |
logging.info(roku) | |
else: | |
logging.error('[roku_remote] no roku found') | |
return found | |
find_roku() | |
if roku == None: | |
roku = Roku(hass.states.get(last_ip_state_name).state) | |
def button_press(call): | |
button_name = call.data.get('button', '') | |
hass.states.set("{0}.{1}".format(DOMAIN, LAST_BUTTON_TOPIC), button_name) | |
try: | |
getattr(roku, button_name)() | |
except Exception as e: | |
if find_roku() != None: getattr(roku, button_name)() | |
hass.services.async_register(DOMAIN, 'press_button', button_press) | |
return True |
This file contains hidden or 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 must be placed in | |
# {config-dir}/python_scripts | |
# | |
# Some extra fun, since there is no api for setting tv volume, instead we can turn it down a whole bunch | |
# and then go up for the number of times specificed in service call. | |
for x in range(0, 50): | |
hass.services.call('roku_remote', 'press_button', service_data={ 'button': "volume_down" }, blocking=True) | |
level = data.get('level', 15) | |
for x in range(0, level): | |
hass.services.call('roku_remote', 'press_button', service_data={ 'button': "volume_up" }, blocking=True) |
This file contains hidden or 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 must be placed in | |
{config-dir}/www/custom_ui/ | |
Created by @c727 | |
https://github.com/c727/home-assistant-tiles | |
--> | |
<dom-module id="state-card-tiles"> | |
<template> | |
<style> | |
.grid { | |
display: grid; | |
grid-template-columns: repeat(var(--tiles-columns), var(--tiles-column-width)); | |
grid-auto-rows: var(--tiles-row-height); | |
grid-gap: var(--tiles-gap); | |
width: 100%; | |
} | |
paper-button { | |
box-shadow: none !important; | |
margin: 0 !important; | |
background-color: var(--tiles-color); | |
color: #fff; | |
} | |
paper-button.on { | |
background-color: var(--tiles-color-on); | |
} | |
paper-button.off { | |
background-color: var(--tiles-color-off); | |
} | |
</style> | |
<paper-button-group class="grid" on-tap="stopPropagation"> | |
<template is="dom-repeat" items="[[config.entities]]" as="entity"> | |
<paper-button raised class$="[[computeTileClass(hass, entity)]]" style$="[[computeTileStyle(entity)]]" | |
on-tap="callService" > | |
<template is="dom-if" if="[[entity.icon]]"> | |
<iron-icon icon="[[entity.icon]]"></iron-icon> | |
</template> | |
[[entity.label]] | |
</paper-button> | |
</template> | |
</paper-button-group> | |
</template> | |
</dom-module> | |
<script> | |
const VERSION = '2017113'; | |
var timeout = 0; | |
Polymer({ | |
is: 'state-card-tiles', | |
properties: { | |
hass: { | |
type: Object, | |
}, | |
stateObj: { | |
type: Object, | |
}, | |
config: { | |
type: Object, | |
computed: 'computeConfig(stateObj)', | |
}, | |
}, | |
computeConfig: function (stateObj) { | |
return stateObj.attributes.config; | |
}, | |
ready: function () { | |
var config = this.config; | |
this.updateStyles({ | |
'--tiles-columns': config.columns ? config.columns : '3', | |
'--tiles-column-width': config.column_width ? config.column_width : '100px', | |
'--tiles-row-height': config.row_height ? config.row_height : '100px', | |
'--tiles-gap': config.gap ? config.gap : '4px', | |
'--tiles-color': config.color ? config.color : 'var(--primary-color)', | |
'--tiles-color-on': config.color_on ? config.color_on : 'var(--google-green-500)', | |
'--tiles-color-off': config.color_off ? config.color_off : 'var(--google-red-500)', | |
}); | |
}, | |
computeTileClass: function (hass, entity) { | |
var domain = entity.entity.split('.')[0]; | |
if (domain === 'script') return ''; | |
return (hass.states[entity.entity].state === 'on') ? 'on' : 'off'; | |
}, | |
computeTileStyle: function (entity) { | |
var c = entity.column ? entity.column : 'auto'; | |
var cs = entity.column_span ? entity.column_span : 1; | |
var r = entity.row ? entity.row : 'auto'; | |
var rs = entity.row_span ? entity.row_span : 1; | |
var img = entity.image ? ' background-image: url("' + entity.image + '");' : ''; | |
return 'grid-column: ' + c + ' / span ' + cs + '; grid-row: ' + r + ' / span ' + rs + ';' + img; | |
}, | |
callService: function (e) { | |
var entity = e.model.entity.entity; | |
var domain = entity.split('.')[0]; | |
if (domain === 'script') { | |
var service = entity.split('.')[1]; | |
var data = e.model.entity.data ? (e.model.entity.data) : {}; | |
} else { | |
var service = 'toggle'; | |
var data = { 'entity_id': entity }; | |
} | |
this.hass.callService(domain, service, data); | |
}, | |
stopPropagation: function (e) { | |
e.stopPropagation(); | |
}, | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment