def __init__(self, hass, device_id, friendly_name, state_template, icon_template, entity_picture_template, on_action, off_action, level_action, level_template, entity_ids): """Initialize the light.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._icon_template = icon_template self._entity_picture_template = entity_picture_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._level_script = None if level_action is not None: self._level_script = Script(hass, level_action) self._level_template = level_template self._state = False self._icon = None self._entity_picture = None self._brightness = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._level_template is not None: self._level_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass if self._entity_picture_template is not None: self._entity_picture_template.hass = self.hass
def __init__(self, hass, device_id, friendly_name, state_template, position_template, tilt_template, icon_template, open_action, close_action, stop_action, position_action, tilt_action, entity_ids): """Initialize the Template cover.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._position_template = position_template self._tilt_template = tilt_template self._icon_template = icon_template self._open_script = Script(hass, open_action) self._close_script = Script(hass, close_action) self._stop_script = Script(hass, stop_action) self._position_script = None if position_action is not None: self._position_script = Script(hass, position_action) self._tilt_script = None if tilt_action is not None: self._tilt_script = Script(hass, tilt_action) self._icon = None self._position = None self._tilt_value = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._position_template is not None: self._position_template.hass = self.hass if self._tilt_template is not None: self._tilt_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass
class ScriptEntity(ToggleEntity): """Representation of a script entity.""" def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.object_id = object_id self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_update_ha_state) @property def should_poll(self): """No polling needed.""" return False @property def name(self): """Return the name of the entity.""" return self.script.name @property def state_attributes(self): """Return the state attributes.""" attrs = {} attrs[ATTR_LAST_TRIGGERED] = self.script.last_triggered if self.script.can_cancel: attrs[ATTR_CAN_CANCEL] = self.script.can_cancel if self.script.last_action: attrs[ATTR_LAST_ACTION] = self.script.last_action return attrs @property def is_on(self): """Return true if script is on.""" return self.script.is_running @asyncio.coroutine def async_turn_on(self, **kwargs): """Turn the script on.""" yield from self.script.async_run(kwargs.get(ATTR_VARIABLES)) @asyncio.coroutine def async_turn_off(self, **kwargs): """Turn script off.""" self.script.async_stop() def async_remove(self): """Remove script from HASS. This method must be run in the event loop and returns a coroutine. """ if self.script.is_running: self.script.async_stop() # remove service self.hass.services.async_remove(DOMAIN, self.object_id) return super().async_remove()
class ScriptEntity(ToggleEntity): """Representation of a script entity.""" def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.object_id = object_id self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_update_ha_state) @property def should_poll(self): """No polling needed.""" return False @property def name(self): """Return the name of the entity.""" return self.script.name @property def state_attributes(self): """Return the state attributes.""" attrs = {} attrs[ATTR_LAST_TRIGGERED] = self.script.last_triggered if self.script.can_cancel: attrs[ATTR_CAN_CANCEL] = self.script.can_cancel if self.script.last_action: attrs[ATTR_LAST_ACTION] = self.script.last_action return attrs @property def is_on(self): """Return true if script is on.""" return self.script.is_running async def async_turn_on(self, **kwargs): """Turn the script on.""" context = kwargs.get('context') self.async_set_context(context) self.hass.bus.async_fire(EVENT_SCRIPT_STARTED, { ATTR_NAME: self.script.name, ATTR_ENTITY_ID: self.entity_id, }, context=context) await self.script.async_run( kwargs.get(ATTR_VARIABLES), context) async def async_turn_off(self, **kwargs): """Turn script off.""" self.script.async_stop() async def async_will_remove_from_hass(self): """Stop script and remove service when it will be removed from HASS.""" if self.script.is_running: self.script.async_stop() # remove service self.hass.services.async_remove(DOMAIN, self.object_id)
class WOLSwitch(SwitchDevice): """Representation of a wake on lan switch.""" def __init__(self, hass, name, host, mac_address, off_action, broadcast_address): """Initialize the WOL switch.""" from wakeonlan import wol self._hass = hass self._name = name self._host = host self._mac_address = mac_address self._broadcast_address = broadcast_address self._off_script = Script(hass, off_action) if off_action else None self._state = False self._wol = wol self.update() @property def should_poll(self): """Return the polling state.""" return True @property def is_on(self): """Return true if switch is on.""" return self._state @property def name(self): """Return the name of the switch.""" return self._name def turn_on(self): """Turn the device on.""" if self._broadcast_address: self._wol.send_magic_packet( self._mac_address, ip_address=self._broadcast_address) else: self._wol.send_magic_packet(self._mac_address) def turn_off(self): """Turn the device off if an off action is present.""" if self._off_script is not None: self._off_script.run() def update(self): """Check if device is on and update the state.""" if platform.system().lower() == 'windows': ping_cmd = ['ping', '-n', '1', '-w', str(DEFAULT_PING_TIMEOUT * 1000), str(self._host)] else: ping_cmd = ['ping', '-c', '1', '-W', str(DEFAULT_PING_TIMEOUT), str(self._host)] status = sp.call(ping_cmd, stdout=sp.DEVNULL, stderr=sp.DEVNULL) self._state = not bool(status)
def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self._entities = entity_ids
class WOLSwitch(SwitchDevice): """Representation of a wake on lan switch.""" def __init__(self, hass, name, host, mac_address, off_action): """Initialize the WOL switch.""" from wakeonlan import wol self._hass = hass self._name = name self._host = host self._mac_address = mac_address self._off_script = Script(hass, off_action) if off_action else None self._state = False self._wol = wol self.update() @property def should_poll(self): """Poll for status regularly.""" return True @property def is_on(self): """Return true if switch is on.""" return self._state @property def name(self): """The name of the switch.""" return self._name def turn_on(self): """Turn the device on.""" self._wol.send_magic_packet(self._mac_address) def turn_off(self): """Turn the device off if an off action is present.""" if self._off_script is not None: self._off_script.run() def update(self): """Check if device is on and update the state.""" if platform.system().lower() == "windows": ping_cmd = "ping -n 1 -w {} {}".format(DEFAULT_PING_TIMEOUT * 1000, self._host) else: ping_cmd = "ping -c 1 -W {} {}".format(DEFAULT_PING_TIMEOUT, self._host) status = sp.getstatusoutput(ping_cmd)[0] self._state = not bool(status)
def __init__( self, hass, device_id, friendly_name, state_template, icon_template, entity_picture_template, availability_template, on_action, off_action, level_action, level_template, entity_ids, temperature_action, temperature_template, ): """Initialize the light.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._icon_template = icon_template self._entity_picture_template = entity_picture_template self._availability_template = availability_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._level_script = None if level_action is not None: self._level_script = Script(hass, level_action) self._level_template = level_template self._temperature_script = None if temperature_action is not None: self._temperature_script = Script(hass, temperature_action) self._temperature_template = temperature_template self._state = False self._icon = None self._entity_picture = None self._brightness = None self._temperature = None self._entities = entity_ids self._available = True
def __init__(self, hass, device_id, friendly_name, state_template, icon_template, entity_picture_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self._icon_template = icon_template self._entity_picture_template = entity_picture_template self._icon = None self._entity_picture = None self._entities = entity_ids
async def async_select_source(self, source): """Set the input source.""" if source in self._input_templates: source_script = Script(self.hass, self._input_templates[source], self._name, self._domain) if self._current_source_template is None: self._current_source = source self.async_write_ha_state() await source_script.async_run(context=self._context)
def __init__( self, hass, object_id, config, unique_id, ): """Initialize the Template switch.""" super().__init__(config=config) self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, object_id, hass=hass ) self._name = friendly_name = config.get(ATTR_FRIENDLY_NAME, object_id) self._template = config.get(CONF_VALUE_TEMPLATE) self._on_script = Script(hass, config[ON_ACTION], friendly_name, DOMAIN) self._off_script = Script(hass, config[OFF_ACTION], friendly_name, DOMAIN) self._state = False self._unique_id = unique_id
def __init__( self, hass, name, host, mac_address, off_action, broadcast_address, broadcast_port, ): """Initialize the WOL switch.""" self._hass = hass self._name = name self._host = host self._mac_address = mac_address self._broadcast_address = broadcast_address self._broadcast_port = broadcast_port self._off_script = Script(hass, off_action) if off_action else None self._state = False
def __init__( self, hass, name, value_template, entity_ids, command_lock, command_unlock, optimistic, ): """Initialize the lock.""" self._state = None self._hass = hass self._name = name self._state_template = value_template self._state_entities = entity_ids self._command_lock = Script(hass, command_lock) self._command_unlock = Script(hass, command_unlock) self._optimistic = optimistic
class ScriptEntity(ToggleEntity): """Representation of a script entity.""" def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.object_id = object_id self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_update_ha_state) @property def should_poll(self): """No polling needed.""" return False @property def name(self): """Return the name of the entity.""" return self.script.name @property def state_attributes(self): """Return the state attributes.""" attrs = {} if self.script.can_cancel: attrs[ATTR_CAN_CANCEL] = self.script.can_cancel if self.script.last_action: attrs[ATTR_LAST_ACTION] = self.script.last_action return attrs @property def is_on(self): """Return true if script is on.""" return self.script.is_running @asyncio.coroutine def async_turn_on(self, **kwargs): """Turn the script on.""" yield from self.script.async_run(kwargs.get(ATTR_VARIABLES)) @asyncio.coroutine def async_turn_off(self, **kwargs): """Turn script off.""" self.script.async_stop()
class ScriptEntity(ToggleEntity): """Representation of a script entity.""" def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.object_id = object_id self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_update_ha_state) @property def should_poll(self): """No polling needed.""" return False @property def name(self): """Return the name of the entity.""" return self.script.name @property def state_attributes(self): """Return the state attributes.""" attrs = {} attrs[ATTR_LAST_TRIGGERED] = self.script.last_triggered if self.script.can_cancel: attrs[ATTR_CAN_CANCEL] = self.script.can_cancel if self.script.last_action: attrs[ATTR_LAST_ACTION] = self.script.last_action return attrs @property def is_on(self): """Return true if script is on.""" return self.script.is_running @asyncio.coroutine def async_turn_on(self, **kwargs): """Turn the script on.""" yield from self.script.async_run(kwargs.get(ATTR_VARIABLES)) @asyncio.coroutine def async_turn_off(self, **kwargs): """Turn script off.""" self.script.async_stop()
def __init__( self, hass, object_id, config, unique_id, ): """Initialize the Template switch.""" super().__init__( hass, config=config, fallback_name=object_id, unique_id=unique_id ) self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, object_id, hass=hass ) friendly_name = self._attr_name self._template = config.get(CONF_VALUE_TEMPLATE) self._on_script = Script(hass, config[ON_ACTION], friendly_name, DOMAIN) self._off_script = Script(hass, config[OFF_ACTION], friendly_name, DOMAIN) self._state: bool | None = False
def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self.update() def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" self.update_ha_state(True) track_state_change(hass, entity_ids, template_switch_state_listener)
def __init__(self, host, name, customize, config, timeout, hass, on_action): """Initialize the webos device.""" from pylgtv import WebOsClient self._client = WebOsClient(host, config, timeout) self._on_script = Script(hass, on_action) if on_action else None self._customize = customize self._name = name # Assume that the TV is not muted self._muted = False # Assume that the TV is in Play mode self._playing = True self._volume = 0 self._current_source = None self._current_source_id = None self._state = STATE_UNKNOWN self._source_list = {} self._app_list = {}
async def async_setup_entry(hass, entry, async_add_entities): """Set up the Samsung TV from a config entry.""" bridge = hass.data[DOMAIN][entry.entry_id] host = entry.data[CONF_HOST] on_script = None data = hass.data[DOMAIN] if turn_on_action := data.get(host, {}).get(CONF_ON_ACTION): on_script = Script(hass, turn_on_action, entry.data.get(CONF_NAME, DEFAULT_NAME), DOMAIN)
def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False @callback def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" hass.async_add_job(self.async_update_ha_state, True) async_track_state_change( hass, entity_ids, template_switch_state_listener)
def __init__(self, hass, object_id, name, icon, sequence): """Initialize the script.""" self.object_id = object_id self.icon = icon self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_write_ha_state, logger=_LOGGER)
async def async_setup_entry(hass, config_entry, async_add_entities): """Set up the Samsung TV from a config entry.""" ip_address = config_entry.data[CONF_IP_ADDRESS] on_script = None if (DOMAIN in hass.data and ip_address in hass.data[DOMAIN] and CONF_ON_ACTION in hass.data[DOMAIN][ip_address] and hass.data[DOMAIN][ip_address][CONF_ON_ACTION]): turn_on_action = hass.data[DOMAIN][ip_address][CONF_ON_ACTION] on_script = Script(hass, turn_on_action) async_add_entities([SamsungTVDevice(config_entry, on_script)])
def __init__(self, hass, object_id, cfg): """Initialize the script.""" self.object_id = object_id self.icon = cfg.get(CONF_ICON) self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script( hass, cfg[CONF_SEQUENCE], cfg.get(CONF_ALIAS, object_id), DOMAIN, running_description="script sequence", change_listener=self.async_change_listener, script_mode=cfg[CONF_MODE], max_runs=cfg[CONF_MAX], max_exceeded=cfg[CONF_MAX_EXCEEDED], logger=logging.getLogger(f"{__name__}.{object_id}"), variables=cfg.get(CONF_VARIABLES), ) self._changed = asyncio.Event()
def __init__(self, hass, device_id, friendly_name, state_template, position_template, tilt_template, icon_template, open_action, close_action, stop_action, position_action, tilt_action, entity_ids): """Initialize the Template cover.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._position_template = position_template self._tilt_template = tilt_template self._icon_template = icon_template self._open_script = None if open_action is not None: self._open_script = Script(hass, open_action) self._close_script = None if close_action is not None: self._close_script = Script(hass, close_action) self._stop_script = None if stop_action is not None: self._stop_script = Script(hass, stop_action) self._position_script = None if position_action is not None: self._position_script = Script(hass, position_action) self._tilt_script = None if tilt_action is not None: self._tilt_script = Script(hass, tilt_action) self._icon = None self._position = None self._tilt_value = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._position_template is not None: self._position_template.hass = self.hass if self._tilt_template is not None: self._tilt_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass
async def async_setup_entry(hass, config_entry): """Set up Panasonic Viera from a config entry.""" panasonic_viera_data = hass.data.setdefault(DOMAIN, {}) config = config_entry.data host = config[CONF_HOST] port = config[CONF_PORT] if (on_action := config[CONF_ON_ACTION]) is not None: on_action = Script(hass, on_action, config[CONF_NAME], DOMAIN)
def __init__(self, hass, device, hook, action, counter=1): """Initialize Automation class.""" self.hass = hass self.device = device script_name = "{} turn ON script".format(device.get_name()) self.script = Script(hass, action, script_name) self.action = ActionCallback( hass.data[DATA_KNX].xknx, self.script.async_run, hook=hook, counter=counter ) device.actions.append(self.action)
def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the Philips TV platform.""" name = config.get(CONF_NAME) host = config.get(CONF_HOST) api_version = config.get(CONF_API_VERSION) turn_on_action = config.get(CONF_ON_ACTION) tvapi = PhilipsTV(host, api_version) on_script = Script(hass, turn_on_action) if turn_on_action else None add_entities([PhilipsTVMediaPlayer(tvapi, name, on_script)])
def __init_modes_script(self, config): for mode in MODES: mode_action = config.get(mode, None) if not mode_action: continue if isinstance(mode_action, list): self._modes_script[mode] = Script(self._hass, mode_action, self._unique_id, DOMAIN) else: self._modes_script[mode] = Script(self._hass, [mode_action], self._unique_id, DOMAIN) self._available_modes.append(mode) if len(self._available_modes) > 1: self._supported_features = SUPPORT_MODES else: self._supported_features = 0
def __init__( self, hass, name, value_template, availability_template, command_lock, command_unlock, optimistic, unique_id, ): """Initialize the lock.""" super().__init__(availability_template=availability_template) self._state = None self._name = name self._state_template = value_template self._command_lock = Script(hass, command_lock, name, DOMAIN) self._command_unlock = Script(hass, command_unlock, name, DOMAIN) self._optimistic = optimistic self._unique_id = unique_id
def __init__(self, hass, name, host, mac_address, off_action): """Initialize the WOL switch.""" from wakeonlan import wol self._hass = hass self._name = name self._host = host self._mac_address = mac_address self._off_script = Script(hass, off_action) if off_action else None self._state = False self._wol = wol self.update()
def __init__( self, hass: HomeAssistant, config, unique_id: str | None, ) -> None: """Initialize the button.""" super().__init__(hass, config=config, unique_id=unique_id) self._command_press = Script(hass, config[CONF_PRESS], self._attr_name, DOMAIN) self._attr_device_class = config.get(CONF_DEVICE_CLASS) self._attr_state = None
def __init__( self, hass, device_id, name, state_template, disarm_action, arm_away_action, arm_home_action, arm_night_action, code_arm_required, template_entity_ids, unique_id, ): """Initialize the panel.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass ) self._name = name self._template = state_template self._disarm_script = None self._code_arm_required = code_arm_required if disarm_action is not None: self._disarm_script = Script(hass, disarm_action) self._arm_away_script = None if arm_away_action is not None: self._arm_away_script = Script(hass, arm_away_action) self._arm_home_script = None if arm_home_action is not None: self._arm_home_script = Script(hass, arm_home_action) self._arm_night_script = None if arm_night_action is not None: self._arm_night_script = Script(hass, arm_night_action) self._state = None self._entities = template_entity_ids self._unique_id = unique_id if self._template is not None: self._template.hass = self.hass
def __init__(self, hass, device_id, friendly_name, state_template, speed_template, oscillating_template, on_action, off_action, set_speed_action, set_oscillating_action, speed_list, entity_ids): """Initialize the fan.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._speed_template = speed_template self._oscillating_template = oscillating_template self._supported_features = 0 self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._set_speed_script = None if set_speed_action: self._set_speed_script = Script(hass, set_speed_action) self._set_oscillating_script = None if set_oscillating_action: self._set_oscillating_script = Script(hass, set_oscillating_action) self._state = STATE_OFF self._speed = None self._oscillating = None self._template.hass = self.hass if self._speed_template: self._speed_template.hass = self.hass self._supported_features |= SUPPORT_SET_SPEED if self._oscillating_template: self._oscillating_template.hass = self.hass self._supported_features |= SUPPORT_OSCILLATE self._entities = entity_ids # List of valid speeds self._speed_list = speed_list
class ScriptEntity(ToggleEntity): """Representation of a script entity.""" # pylint: disable=too-many-instance-attributes def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_update_ha_state) @property def should_poll(self): """No polling needed.""" return False @property def name(self): """Return the name of the entity.""" return self.script.name @property def state_attributes(self): """Return the state attributes.""" attrs = {} if self.script.can_cancel: attrs[ATTR_CAN_CANCEL] = self.script.can_cancel if self.script.last_action: attrs[ATTR_LAST_ACTION] = self.script.last_action return attrs @property def is_on(self): """Return true if script is on.""" return self.script.is_running def turn_on(self, **kwargs): """Turn the entity on.""" self.script.run(kwargs.get(ATTR_VARIABLES)) def turn_off(self, **kwargs): """Turn script off.""" self.script.stop()
def setup_platform(hass, config, add_devices, discovery_info=None): """Set up the Philips TV platform.""" import haphilipsjs name = config.get(CONF_NAME) host = config.get(CONF_HOST) turn_on_action = config.get(CONF_ON_ACTION) tvapi = haphilipsjs.PhilipsTV(host) on_script = Script(hass, turn_on_action) if turn_on_action else None add_devices([PhilipsTV(tvapi, name, on_script)])
def setup_platform(hass, config, add_entities, discovery_info=None): """Set up the LG TV platform.""" host = config.get(CONF_HOST) access_token = config.get(CONF_ACCESS_TOKEN) name = config.get(CONF_NAME) on_action = config.get(CONF_ON_ACTION) client = LgNetCastClient(host, access_token) on_action_script = Script(hass, on_action) if on_action else None add_entities([LgTVDevice(client, name, on_action_script)], True)
async def handle_execute_script(hass, connection, msg): """Handle execute script command.""" # Circular dep # pylint: disable=import-outside-toplevel from homeassistant.helpers.script import Script context = connection.context(msg) script_obj = Script(hass, msg["sequence"], f"{const.DOMAIN} script", const.DOMAIN) await script_obj.async_run(msg.get("variables"), context=context) connection.send_message( messages.result_message(msg["id"], {"context": context}))
def __init__(self, hass, name, host, mac_address, off_action, broadcast_address): """Initialize the WOL switch.""" import wakeonlan self._hass = hass self._name = name self._host = host self._mac_address = mac_address self._broadcast_address = broadcast_address self._off_script = Script(hass, off_action) if off_action else None self._state = False self._wol = wakeonlan
async def _async_process_config(hass, config, component): """Process config and add automations. This method is a coroutine. """ entities = [] for config_key in extract_domain_configs(config, DOMAIN): conf = config[config_key] for list_no, config_block in enumerate(conf): automation_id = config_block.get(CONF_ID) name = config_block.get(CONF_ALIAS) or f"{config_key} {list_no}" initial_state = config_block.get(CONF_INITIAL_STATE) action_script = Script( hass, config_block[CONF_ACTION], name, DOMAIN, running_description="automation actions", script_mode=config_block[CONF_MODE], max_runs=config_block[CONF_MAX], max_exceeded=config_block[CONF_MAX_EXCEEDED], logger=_LOGGER, # We don't pass variables here # Automation will already render them to use them in the condition # and so will pass them on to the script. ) if CONF_CONDITION in config_block: cond_func = await _async_process_if(hass, config, config_block) if cond_func is None: continue else: cond_func = None entity = AutomationEntity( automation_id, name, config_block[CONF_TRIGGER], cond_func, action_script, initial_state, config_block.get(CONF_VARIABLES), ) entities.append(entity) if entities: await component.async_add_entities(entities)
def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, level_action, level_template, entity_ids): """Initialize the light.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._level_script = None if level_action is not None: self._level_script = Script(hass, level_action) self._level_template = level_template self._state = False self._brightness = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._level_template is not None: self._level_template.hass = self.hass
async def async_select_sound_mode(self, sound_mode): """Select sound mode.""" if sound_mode in self._sound_mode_templates: sound_mode_script = Script( self.hass, self._sound_mode_templates[sound_mode], self._name, self._domain, ) if self._current_sound_mode_template is None: self._sound_mode = sound_mode self.async_write_ha_state() await sound_mode_script.async_run(context=self._context)
def __init__(self, hass, object_id, name, sequence): """Initialize the script.""" self.object_id = object_id self.entity_id = ENTITY_ID_FORMAT.format(object_id) self.script = Script(hass, sequence, name, self.async_update_ha_state)
class SwitchTemplate(SwitchDevice): """Representation of a Template switch.""" # pylint: disable=too-many-arguments def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self.update() def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" self.update_ha_state(True) track_state_change(hass, entity_ids, template_switch_state_listener) @property def name(self): """Return the name of the switch.""" return self._name @property def is_on(self): """Return true if device is on.""" return self._state @property def should_poll(self): """No polling needed.""" return False @property def available(self): """If switch is available.""" return self._state is not None def turn_on(self, **kwargs): """Fire the on action.""" self._on_script.run() def turn_off(self, **kwargs): """Fire the off action.""" self._off_script.run() def update(self): """Update the state from the template.""" try: state = template.render(self.hass, self._template).lower() if state in _VALID_STATES: self._state = state in ('true', STATE_ON) else: _LOGGER.error( 'Received invalid switch is_on state: %s. Expected: %s', state, ', '.join(_VALID_STATES)) self._state = None except TemplateError as ex: _LOGGER.error(ex) self._state = None
class LightTemplate(Light): """Representation of a templated Light, including dimmable.""" def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, level_action, level_template, entity_ids): """Initialize the light.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._level_script = None if level_action is not None: self._level_script = Script(hass, level_action) self._level_template = level_template self._state = False self._brightness = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._level_template is not None: self._level_template.hass = self.hass @property def brightness(self): """Return the brightness of the light.""" return self._brightness @property def name(self): """Return the display name of this light.""" return self._name @property def supported_features(self): """Flag supported features.""" if self._level_script is not None: return SUPPORT_BRIGHTNESS return 0 @property def is_on(self): """Return true if device is on.""" return self._state @property def should_poll(self): """Return the polling state.""" return False @asyncio.coroutine def async_added_to_hass(self): """Register callbacks.""" @callback def template_light_state_listener(entity, old_state, new_state): """Handle target device state changes.""" self.async_schedule_update_ha_state(True) @callback def template_light_startup(event): """Update template on startup.""" if (self._template is not None or self._level_template is not None): async_track_state_change( self.hass, self._entities, template_light_state_listener) self.async_schedule_update_ha_state(True) self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_START, template_light_startup) @asyncio.coroutine def async_turn_on(self, **kwargs): """Turn the light on.""" optimistic_set = False # set optimistic states if self._template is None: self._state = True optimistic_set = True if self._level_template is None and ATTR_BRIGHTNESS in kwargs: _LOGGER.info("Optimistically setting brightness to %s", kwargs[ATTR_BRIGHTNESS]) self._brightness = kwargs[ATTR_BRIGHTNESS] optimistic_set = True if ATTR_BRIGHTNESS in kwargs and self._level_script: self.hass.async_add_job(self._level_script.async_run( {"brightness": kwargs[ATTR_BRIGHTNESS]})) else: self.hass.async_add_job(self._on_script.async_run()) if optimistic_set: self.async_schedule_update_ha_state() @asyncio.coroutine def async_turn_off(self, **kwargs): """Turn the light off.""" self.hass.async_add_job(self._off_script.async_run()) if self._template is None: self._state = False self.async_schedule_update_ha_state() @asyncio.coroutine def async_update(self): """Update the state from the template.""" print("ASYNC UPDATE") if self._template is not None: try: state = self._template.async_render().lower() except TemplateError as ex: _LOGGER.error(ex) self._state = None if state in _VALID_STATES: self._state = state in ('true', STATE_ON) else: _LOGGER.error( 'Received invalid light is_on state: %s. ' + 'Expected: %s', state, ', '.join(_VALID_STATES)) self._state = None if self._level_template is not None: try: brightness = self._level_template.async_render() except TemplateError as ex: _LOGGER.error(ex) self._state = None if 0 <= int(brightness) <= 255: self._brightness = brightness else: _LOGGER.error( 'Received invalid brightness : %s' + 'Expected: 0-255', brightness) self._brightness = None
class LightTemplate(Light): """Representation of a templated Light, including dimmable.""" def __init__(self, hass, device_id, friendly_name, state_template, icon_template, entity_picture_template, on_action, off_action, level_action, level_template, entity_ids): """Initialize the light.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._icon_template = icon_template self._entity_picture_template = entity_picture_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._level_script = None if level_action is not None: self._level_script = Script(hass, level_action) self._level_template = level_template self._state = False self._icon = None self._entity_picture = None self._brightness = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._level_template is not None: self._level_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass if self._entity_picture_template is not None: self._entity_picture_template.hass = self.hass @property def brightness(self): """Return the brightness of the light.""" return self._brightness @property def name(self): """Return the display name of this light.""" return self._name @property def supported_features(self): """Flag supported features.""" if self._level_script is not None: return SUPPORT_BRIGHTNESS return 0 @property def is_on(self): """Return true if device is on.""" return self._state @property def should_poll(self): """Return the polling state.""" return False @property def icon(self): """Return the icon to use in the frontend, if any.""" return self._icon @property def entity_picture(self): """Return the entity picture to use in the frontend, if any.""" return self._entity_picture @asyncio.coroutine def async_added_to_hass(self): """Register callbacks.""" @callback def template_light_state_listener(entity, old_state, new_state): """Handle target device state changes.""" self.async_schedule_update_ha_state(True) @callback def template_light_startup(event): """Update template on startup.""" if (self._template is not None or self._level_template is not None): async_track_state_change( self.hass, self._entities, template_light_state_listener) self.async_schedule_update_ha_state(True) self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_START, template_light_startup) @asyncio.coroutine def async_turn_on(self, **kwargs): """Turn the light on.""" optimistic_set = False # set optimistic states if self._template is None: self._state = True optimistic_set = True if self._level_template is None and ATTR_BRIGHTNESS in kwargs: _LOGGER.info("Optimistically setting brightness to %s", kwargs[ATTR_BRIGHTNESS]) self._brightness = kwargs[ATTR_BRIGHTNESS] optimistic_set = True if ATTR_BRIGHTNESS in kwargs and self._level_script: self.hass.async_add_job(self._level_script.async_run( {"brightness": kwargs[ATTR_BRIGHTNESS]})) else: yield from self._on_script.async_run() if optimistic_set: self.async_schedule_update_ha_state() @asyncio.coroutine def async_turn_off(self, **kwargs): """Turn the light off.""" yield from self._off_script.async_run() if self._template is None: self._state = False self.async_schedule_update_ha_state() @asyncio.coroutine def async_update(self): """Update the state from the template.""" if self._template is not None: try: state = self._template.async_render().lower() except TemplateError as ex: _LOGGER.error(ex) self._state = None if state in _VALID_STATES: self._state = state in ('true', STATE_ON) else: _LOGGER.error( 'Received invalid light is_on state: %s. Expected: %s', state, ', '.join(_VALID_STATES)) self._state = None if self._level_template is not None: try: brightness = self._level_template.async_render() except TemplateError as ex: _LOGGER.error(ex) self._state = None if 0 <= int(brightness) <= 255: self._brightness = int(brightness) else: _LOGGER.error( 'Received invalid brightness : %s. Expected: 0-255', brightness) self._brightness = None for property_name, template in ( ('_icon', self._icon_template), ('_entity_picture', self._entity_picture_template)): if template is None: continue try: setattr(self, property_name, template.async_render()) except TemplateError as ex: friendly_property_name = property_name[1:].replace('_', ' ') if ex.args and ex.args[0].startswith( "UndefinedError: 'None' has no attribute"): # Common during HA startup - so just a warning _LOGGER.warning('Could not render %s template %s,' ' the state is unknown.', friendly_property_name, self._name) return try: setattr(self, property_name, getattr(super(), property_name)) except AttributeError: _LOGGER.error('Could not render %s template %s: %s', friendly_property_name, self._name, ex)
class SwitchTemplate(SwitchDevice): """Representation of a Template switch.""" def __init__(self, hass, device_id, friendly_name, state_template, icon_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self._icon_template = icon_template self._icon = None self._entities = entity_ids @asyncio.coroutine def async_added_to_hass(self): """Register callbacks.""" state = yield from async_get_last_state(self.hass, self.entity_id) if state: self._state = state.state == STATE_ON @callback def template_switch_state_listener(entity, old_state, new_state): """Handle target device state changes.""" self.hass.async_add_job(self.async_update_ha_state(True)) @callback def template_switch_startup(event): """Update template on startup.""" async_track_state_change( self.hass, self._entities, template_switch_state_listener) self.hass.async_add_job(self.async_update_ha_state(True)) self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_START, template_switch_startup) @property def name(self): """Return the name of the switch.""" return self._name @property def is_on(self): """Return true if device is on.""" return self._state @property def should_poll(self): """Return the polling state.""" return False @property def available(self): """If switch is available.""" return self._state is not None @property def icon(self): """Return the icon to use in the frontend, if any.""" return self._icon def turn_on(self, **kwargs): """Fire the on action.""" self._on_script.run() def turn_off(self, **kwargs): """Fire the off action.""" self._off_script.run() @asyncio.coroutine def async_update(self): """Update the state from the template.""" try: state = self._template.async_render().lower() if state in _VALID_STATES: self._state = state in ('true', STATE_ON) else: _LOGGER.error( 'Received invalid switch is_on state: %s. Expected: %s', state, ', '.join(_VALID_STATES)) self._state = None except TemplateError as ex: _LOGGER.error(ex) self._state = None if self._icon_template is not None: try: self._icon = self._icon_template.async_render() except TemplateError as ex: if ex.args and ex.args[0].startswith( "UndefinedError: 'None' has no attribute"): # Common during HA startup - so just a warning _LOGGER.warning('Could not render icon template %s,' ' the state is unknown.', self._name) return self._icon = super().icon _LOGGER.error('Could not render icon template %s: %s', self._name, ex)
class SwitchTemplate(SwitchDevice): """Representation of a Template switch.""" def __init__(self, hass, device_id, friendly_name, state_template, on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = async_generate_entity_id(ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._on_script = Script(hass, on_action) self._off_script = Script(hass, off_action) self._state = False self._entities = entity_ids @asyncio.coroutine def async_added_to_hass(self): """Register callbacks.""" state = yield from async_get_last_state(self.hass, self.entity_id) if state: self._state = state.state == STATE_ON @callback def template_switch_state_listener(entity, old_state, new_state): """Called when the target device changes state.""" self.hass.async_add_job(self.async_update_ha_state(True)) @callback def template_switch_startup(event): """Update template on startup.""" async_track_state_change( self.hass, self._entities, template_switch_state_listener) self.hass.async_add_job(self.async_update_ha_state(True)) self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_START, template_switch_startup) @property def name(self): """Return the name of the switch.""" return self._name @property def is_on(self): """Return true if device is on.""" return self._state @property def should_poll(self): """No polling needed.""" return False @property def available(self): """If switch is available.""" return self._state is not None def turn_on(self, **kwargs): """Fire the on action.""" self._on_script.run() def turn_off(self, **kwargs): """Fire the off action.""" self._off_script.run() @asyncio.coroutine def async_update(self): """Update the state from the template.""" try: state = self._template.async_render().lower() if state in _VALID_STATES: self._state = state in ('true', STATE_ON) else: _LOGGER.error( 'Received invalid switch is_on state: %s. Expected: %s', state, ', '.join(_VALID_STATES)) self._state = None except TemplateError as ex: _LOGGER.error(ex) self._state = None
class LgWebOSDevice(MediaPlayerDevice): """Representation of a LG WebOS TV.""" def __init__(self, host, name, customize, config, timeout, hass, on_action): """Initialize the webos device.""" from pylgtv import WebOsClient self._client = WebOsClient(host, config, timeout) self._on_script = Script(hass, on_action) if on_action else None self._customize = customize self._name = name # Assume that the TV is not muted self._muted = False # Assume that the TV is in Play mode self._playing = True self._volume = 0 self._current_source = None self._current_source_id = None self._state = STATE_UNKNOWN self._source_list = {} self._app_list = {} self._channel = None @util.Throttle(MIN_TIME_BETWEEN_SCANS, MIN_TIME_BETWEEN_FORCED_SCANS) def update(self): """Retrieve the latest data.""" from websockets.exceptions import ConnectionClosed try: current_input = self._client.get_input() if current_input is not None: self._current_source_id = current_input if self._state in (STATE_UNKNOWN, STATE_OFF): self._state = STATE_PLAYING else: self._state = STATE_OFF self._current_source = None self._current_source_id = None self._channel = None if self._state is not STATE_OFF: self._muted = self._client.get_muted() self._volume = self._client.get_volume() self._channel = self._client.get_current_channel() self._source_list = {} self._app_list = {} conf_sources = self._customize.get(CONF_SOURCES, []) for app in self._client.get_apps(): self._app_list[app['id']] = app if app['id'] == self._current_source_id: self._current_source = app['title'] self._source_list[app['title']] = app elif (not conf_sources or app['id'] in conf_sources or any(word in app['title'] for word in conf_sources) or any(word in app['id'] for word in conf_sources)): self._source_list[app['title']] = app for source in self._client.get_inputs(): if source['id'] == self._current_source_id: self._current_source = source['label'] self._source_list[source['label']] = source elif (not conf_sources or source['label'] in conf_sources or any(source['label'].find(word) != -1 for word in conf_sources)): self._source_list[source['label']] = source except (OSError, ConnectionClosed, TypeError, asyncio.TimeoutError): self._state = STATE_OFF self._current_source = None self._current_source_id = None self._channel = None @property def name(self): """Return the name of the device.""" return self._name @property def state(self): """Return the state of the device.""" return self._state @property def is_volume_muted(self): """Boolean if volume is currently muted.""" return self._muted @property def volume_level(self): """Volume level of the media player (0..1).""" return self._volume / 100.0 @property def source(self): """Return the current input source.""" return self._current_source @property def source_list(self): """List of available input sources.""" return sorted(self._source_list.keys()) @property def media_content_type(self): """Content type of current playing media.""" return MEDIA_TYPE_CHANNEL @property def media_title(self): """Title of current playing media.""" if (self._channel is not None) and ('channelName' in self._channel): return self._channel['channelName'] return None @property def media_image_url(self): """Image url of current playing media.""" if self._current_source_id in self._app_list: icon = self._app_list[self._current_source_id]['largeIcon'] if not icon.startswith('http'): icon = self._app_list[self._current_source_id]['icon'] return icon return None @property def supported_features(self): """Flag media player features that are supported.""" if self._on_script: return SUPPORT_WEBOSTV | SUPPORT_TURN_ON return SUPPORT_WEBOSTV def turn_off(self): """Turn off media player.""" from websockets.exceptions import ConnectionClosed self._state = STATE_OFF try: self._client.power_off() except (OSError, ConnectionClosed, TypeError, asyncio.TimeoutError): pass def turn_on(self): """Turn on the media player.""" if self._on_script: self._on_script.run() def volume_up(self): """Volume up the media player.""" self._client.volume_up() def volume_down(self): """Volume down media player.""" self._client.volume_down() def set_volume_level(self, volume): """Set volume level, range 0..1.""" tv_volume = volume * 100 self._client.set_volume(tv_volume) def mute_volume(self, mute): """Send mute command.""" self._muted = mute self._client.set_mute(mute) def media_play_pause(self): """Simulate play pause media player.""" if self._playing: self.media_pause() else: self.media_play() def select_source(self, source): """Select input source.""" source_dict = self._source_list.get(source) if source_dict is None: _LOGGER.warning("Source %s not found for %s", source, self.name) return self._current_source_id = source_dict['id'] if source_dict.get('title'): self._current_source = source_dict['title'] self._client.launch_app(source_dict['id']) elif source_dict.get('label'): self._current_source = source_dict['label'] self._client.set_input(source_dict['id']) def play_media(self, media_type, media_id, **kwargs): """Play a piece of media.""" _LOGGER.debug( "Call play media type <%s>, Id <%s>", media_type, media_id) if media_type == MEDIA_TYPE_CHANNEL: _LOGGER.debug("Searching channel...") partial_match_channel_id = None perfect_match_channel_id = None for channel in self._client.get_channels(): if media_id == channel['channelNumber']: perfect_match_channel_id = channel['channelId'] continue elif media_id.lower() == channel['channelName'].lower(): perfect_match_channel_id = channel['channelId'] continue elif media_id.lower() in channel['channelName'].lower(): partial_match_channel_id = channel['channelId'] if perfect_match_channel_id is not None: _LOGGER.info( "Switching to channel <%s> with perfect match", perfect_match_channel_id) self._client.set_channel(perfect_match_channel_id) elif partial_match_channel_id is not None: _LOGGER.info( "Switching to channel <%s> with partial match", partial_match_channel_id) self._client.set_channel(partial_match_channel_id) return def media_play(self): """Send play command.""" self._playing = True self._state = STATE_PLAYING self._client.play() def media_pause(self): """Send media pause command to media player.""" self._playing = False self._state = STATE_PAUSED self._client.pause() def media_next_track(self): """Send next track command.""" current_input = self._client.get_input() if current_input == LIVETV_APP_ID: self._client.channel_up() else: self._client.fast_forward() def media_previous_track(self): """Send the previous track command.""" current_input = self._client.get_input() if current_input == LIVETV_APP_ID: self._client.channel_down() else: self._client.rewind()
class CoverTemplate(CoverDevice): """Representation of a Template cover.""" def __init__(self, hass, device_id, friendly_name, state_template, position_template, tilt_template, icon_template, open_action, close_action, stop_action, position_action, tilt_action, entity_ids): """Initialize the Template cover.""" self.hass = hass self.entity_id = async_generate_entity_id( ENTITY_ID_FORMAT, device_id, hass=hass) self._name = friendly_name self._template = state_template self._position_template = position_template self._tilt_template = tilt_template self._icon_template = icon_template self._open_script = Script(hass, open_action) self._close_script = Script(hass, close_action) self._stop_script = Script(hass, stop_action) self._position_script = None if position_action is not None: self._position_script = Script(hass, position_action) self._tilt_script = None if tilt_action is not None: self._tilt_script = Script(hass, tilt_action) self._icon = None self._position = None self._tilt_value = None self._entities = entity_ids if self._template is not None: self._template.hass = self.hass if self._position_template is not None: self._position_template.hass = self.hass if self._tilt_template is not None: self._tilt_template.hass = self.hass if self._icon_template is not None: self._icon_template.hass = self.hass @asyncio.coroutine def async_added_to_hass(self): """Register callbacks.""" state = yield from async_get_last_state(self.hass, self.entity_id) if state: self._position = 100 if state.state == STATE_OPEN else 0 @callback def template_cover_state_listener(entity, old_state, new_state): """Handle target device state changes.""" self.hass.async_add_job(self.async_update_ha_state(True)) @callback def template_cover_startup(event): """Update template on startup.""" async_track_state_change( self.hass, self._entities, template_cover_state_listener) self.hass.async_add_job(self.async_update_ha_state(True)) self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_START, template_cover_startup) @property def name(self): """Return the name of the cover.""" return self._name @property def is_closed(self): """Return if the cover is closed.""" return self._position == 0 @property def current_cover_position(self): """Return current position of cover. None is unknown, 0 is closed, 100 is fully open. """ return self._position @property def current_cover_tilt_position(self): """Return current position of cover tilt. None is unknown, 0 is closed, 100 is fully open. """ return self._tilt_value @property def icon(self): """Return the icon to use in the frontend, if any.""" return self._icon @property def supported_features(self): """Flag supported features.""" supported_features = SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_STOP if self.current_cover_position is not None: supported_features |= SUPPORT_SET_POSITION if self.current_cover_tilt_position is not None: supported_features |= TILT_FEATURES return supported_features @property def should_poll(self): """Return the polling state.""" return False @asyncio.coroutine def async_open_cover(self, **kwargs): """Move the cover up.""" self.hass.async_add_job(self._open_script.async_run()) @asyncio.coroutine def async_close_cover(self, **kwargs): """Move the cover down.""" self.hass.async_add_job(self._close_script.async_run()) @asyncio.coroutine def async_stop_cover(self, **kwargs): """Fire the stop action.""" self.hass.async_add_job(self._stop_script.async_run()) @asyncio.coroutine def async_set_cover_position(self, **kwargs): """Set cover position.""" if ATTR_POSITION not in kwargs: return self._position = kwargs[ATTR_POSITION] self.hass.async_add_job(self._position_script.async_run( {"position": self._position})) @asyncio.coroutine def async_open_cover_tilt(self, **kwargs): """Tilt the cover open.""" self._tilt_value = 100 self.hass.async_add_job(self._tilt_script.async_run( {"tilt": self._tilt_value})) @asyncio.coroutine def async_close_cover_tilt(self, **kwargs): """Tilt the cover closed.""" self._tilt_value = 0 self.hass.async_add_job(self._tilt_script.async_run( {"tilt": self._tilt_value})) @asyncio.coroutine def async_set_cover_tilt_position(self, **kwargs): """Move the cover tilt to a specific position.""" if ATTR_TILT_POSITION not in kwargs: return self._tilt_value = kwargs[ATTR_TILT_POSITION] self.hass.async_add_job(self._tilt_script.async_run( {"tilt": self._tilt_value})) @asyncio.coroutine def async_update(self): """Update the state from the template.""" if self._template is not None: try: state = self._template.async_render().lower() if state in _VALID_STATES: if state in ('true', STATE_OPEN): self._position = 100 else: self._position = 0 else: _LOGGER.error( 'Received invalid cover is_on state: %s. Expected: %s', state, ', '.join(_VALID_STATES)) self._position = None except TemplateError as ex: _LOGGER.error(ex) self._position = None if self._position_template is not None: try: state = float(self._position_template.async_render()) if state < 0 or state > 100: self._position = None _LOGGER.error("Cover position value must be" " between 0 and 100." " Value was: %.2f", state) else: self._position = state except TemplateError as ex: _LOGGER.error(ex) self._position = None except ValueError as ex: _LOGGER.error(ex) self._position = None if self._tilt_template is not None: try: state = float(self._tilt_template.async_render()) if state < 0 or state > 100: self._tilt_value = None _LOGGER.error("Tilt value must be between 0 and 100." " Value was: %.2f", state) else: self._tilt_value = state except TemplateError as ex: _LOGGER.error(ex) self._tilt_value = None except ValueError as ex: _LOGGER.error(ex) self._tilt_value = None if self._icon_template is not None: try: self._icon = self._icon_template.async_render() except TemplateError as ex: if ex.args and ex.args[0].startswith( "UndefinedError: 'None' has no attribute"): # Common during HA startup - so just a warning _LOGGER.warning('Could not render icon template %s,' ' the state is unknown.', self._name) return self._icon = super().icon _LOGGER.error('Could not render icon template %s: %s', self._name, ex)