home-assistant-components
home-assistant-components copied to clipboard
Remote IR switch
Wanted to share my work, ir switch with template or ping. I use it mainly for TV.
import asyncio
from functools import partial
import logging
import time
import datetime
import voluptuous as vol
from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA)
from homeassistant.components.binary_sensor.ping import (PingData)
from homeassistant.components.remote import (
ATTR_COMMAND, DOMAIN, SERVICE_SEND_COMMAND)
from homeassistant.const import (
ATTR_ENTITY_ID, CONF_HOST, CONF_NAME, CONF_TOKEN, STATE_OFF, STATE_ON)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.util import Throttle
from homeassistant.helpers.event import async_track_state_change
from homeassistant.core import callback
from homeassistant.exceptions import TemplateError
DEPENDENCIES = ['remote']
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = 'IR Switch'
CONF_REMOTE = 'remote'
CONF_PING = 'ping'
CONF_POWER_TEMPLATE = 'power_template'
CONF_COMMANDS = 'commands'
COMMAND_TURN_OFF = 'turn_off'
COMMAND_TURN_ON = 'turn_on'
COMMANDS_SCHEMA = vol.Schema({
vol.Required(COMMAND_TURN_OFF): cv.string,
vol.Required(COMMAND_TURN_ON): cv.string,
}, extra=vol.ALLOW_EXTRA)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_REMOTE): cv.entity_id,
vol.Optional(CONF_PING): cv.string,
vol.Optional(CONF_POWER_TEMPLATE): cv.template,
vol.Required(CONF_COMMANDS): COMMANDS_SCHEMA
})
MIN_TIME_BETWEEN_UPDATES = datetime.timedelta(seconds=10)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the xiaomi remote climate platform."""
name = config.get(CONF_NAME)
remote_entity_id = config.get(CONF_REMOTE)
ping = config.get(CONF_PING)
power_template = config.get(CONF_POWER_TEMPLATE)
commands = config.get(CONF_COMMANDS)
if ping:
async_add_entities([
RemoteSwitch(hass, name, remote_entity_id, commands, power_template, PingData(ping, 1))
])
else:
async_add_entities([
RemoteSwitch(hass, name, remote_entity_id, commands, power_template, ping)
])
class RemoteSwitch(SwitchDevice, RestoreEntity):
def __init__(self, hass, name, remote_entity_id, commands, power_template, ping):
self.hass = hass
self._name = name
self._remote_entity_id = remote_entity_id
self._commands = commands
self._state = None
self._skip_update = False
self._power_template = power_template
if power_template:
self._power_template.hass = hass
self._ping = ping
# if power_template:
# power_template.hass = hass
# power_entity_ids = power_template.extract_entities()
# async_track_state_change(hass, power_entity_ids, self._async_power_changed)
@property
def name(self):
"""Return the name of the climate device."""
return self._name
@property
def is_on(self):
if self._ping:
return self._ping.available
else:
return self._state
@property
def available(self) -> bool:
return True
def _send_command(self, command_name):
if command_name in self._commands:
command = self._commands[command_name]
if command is not None:
self.hass.services.call(DOMAIN, SERVICE_SEND_COMMAND, {
ATTR_COMMAND: 'raw:' + command,
ATTR_ENTITY_ID: self._remote_entity_id
})
def turn_on(self):
if not self.is_on:
self._send_command('turn_on')
self._state = True
if self._ping:
self._ping.available = True
self._skip_update = True
self.schedule_update_ha_state()
def turn_off(self):
if self.is_on:
self._send_command('turn_off')
self._state = False
if self._ping:
self._ping.available = False
self._skip_update = True
self.schedule_update_ha_state()
@callback
def _async_update_power(self):
try:
if self._power_template.async_render().lower() not in ('true', 'on', '1'):
self._state = False
else:
self._state = True
except TemplateError as ex:
_LOGGER.warning('Unable to update power from template: %s', ex)
@Throttle(MIN_TIME_BETWEEN_UPDATES)
async def async_update(self):
if self._skip_update:
self._skip_update = False
return
if self._ping:
self._ping.update()
elif self._power_template:
self._async_update_power()
Here you can find ir codes example: https://www.dropbox.com/s/texllwcvx3sxnqe/ir_remote_codes.rar?dl=0&file_subpath=%2Fir_remote_codes%2Fswitch
@CooleRnax do you think you would be able to create a media_player custom component here? Would like to have those for some devices.