diff --git a/README.md b/README.md index 7e2e0a3..7743651 100644 --- a/README.md +++ b/README.md @@ -399,6 +399,10 @@ This integration actualy register a service, called by `unified_remote.call` That service allows you to call your remotes. +> Unfortunally Unified Remote doesn't return any type of errors if you call an inexistent remote, so the only way to know if something goes wrong is if you make sure that HASS is connected with Unified Remote client, but nothing happens when you call your remote. + +> If you are sure about remote info but nothing happens, it can be a bug with Unified Remote, in that case, just restart the server of your computer. + - Just call the service with following service_data ```yaml @@ -406,6 +410,13 @@ remote: remote_name (NOT THE REMOTE ID) action: remote_action ``` +- You also can call remote that was not declared on devices.yml, like that: + +```yaml +remote_id: remote_id +action: remote_action +``` + For example: This call will open Amazon Prime Video on my default browser. @@ -415,6 +426,13 @@ remote: prime_video action: launch ``` +That will do the same, but without declare it first. + +```yaml +remote_id: Unified.AmazonPrimeVideo +action: launch +``` + - For adding buttons on your home assistant lovelace, use `Manual Card` element with `call-service` action, like: ```yaml diff --git a/custom_components/unified_remote/__init__.py b/custom_components/unified_remote/__init__.py index 8d39983..477ad19 100644 --- a/custom_components/unified_remote/__init__.py +++ b/custom_components/unified_remote/__init__.py @@ -2,14 +2,14 @@ import logging as log from datetime import timedelta -import homeassistant.helpers.config_validation as cv -import voluptuous as vol -from homeassistant.const import CONF_HOST, CONF_PORT -from homeassistant.helpers.event import track_time_interval from requests import ConnectionError +import homeassistant.helpers.config_validation as cv +import voluptuous as vol from custom_components.unified_remote.cli.connection import Connection from custom_components.unified_remote.cli.remotes import Remotes +from homeassistant.const import CONF_HOST, CONF_PORT +from homeassistant.helpers.event import track_time_interval DOMAIN = "unified_remote" @@ -74,6 +74,15 @@ def validate_response(response): raise ConnectionError() +def call_remote(id, action): + try: + CONNECTION.exe_remote(id, action) + _LOGGER.debug(f'Call -> Remote ID: "{id}"; Action: "{action}"') + # Log if request fails. + except ConnectionError: + _LOGGER.warning("Unable to call remote. Host is off") + + def setup(hass, config): """Setting up Unified Remote Integration""" # Fetching configuration entries. @@ -123,8 +132,15 @@ def handle_call(call): """Handle the service call.""" # Fetch service data. remote_name = call.data.get("remote", DEFAULT_NAME) + remote_id = call.data.get("remote_id", DEFAULT_NAME) action = call.data.get("action", DEFAULT_NAME) + # Allows user to pass remote id without declaring it on remotes.yml + if remote_id is not None: + if not (remote_id == "" or action == ""): + call_remote(remote_id, action) + return None + # Check if none or empty service data was parsed. if not (remote_name == "" or action == ""): remote = REMOTES.get_remote(remote_name) @@ -138,14 +154,7 @@ def handle_call(call): remote_id = remote["id"] # Check if given action exists in remote control list. if action in remote["controls"]: - try: - CONNECTION.exe_remote(remote_id, action) - _LOGGER.debug( - f'Call -> Remote: "{remote_name}"; Remote ID: "{remote_id}"; Action: "{action}"' - ) - # Log if request fails. - except ConnectionError: - _LOGGER.warning("Unable to call remote. Host is off") + call_remote(remote_id, action) else: # Log if called remote doens't exists on remotes.yml. _LOGGER.warning( diff --git a/custom_components/unified_remote/switch.py b/custom_components/unified_remote/switch.py index f4ca0eb..70fcea1 100644 --- a/custom_components/unified_remote/switch.py +++ b/custom_components/unified_remote/switch.py @@ -11,15 +11,14 @@ # Additional consts declarations REMOTE_NAME = "remote" +REMOTE_ID = "remote_id" REMOTE_ACTION = "action" -# Remote structure definition. -EMPTY_REMOTE = {REMOTE_ACTION: "", REMOTE_NAME: ""} - # Remote config entry definition. REMOTE_CONFIG = vol.Schema( { vol.Required(REMOTE_NAME, default=""): cv.string, + vol.Optional(REMOTE_ID): cv.string, vol.Required(REMOTE_ACTION, default=""): cv.string, } ) @@ -28,9 +27,9 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( { vol.Required("name"): cv.string, - vol.Required(SERVICE_TURN_ON, default=EMPTY_REMOTE): REMOTE_CONFIG, - vol.Optional(SERVICE_TURN_OFF, default=EMPTY_REMOTE): REMOTE_CONFIG, - vol.Optional(SERVICE_TOGGLE, default=EMPTY_REMOTE): REMOTE_CONFIG, + vol.Required(SERVICE_TURN_ON, default=None): REMOTE_CONFIG, + vol.Optional(SERVICE_TURN_OFF): REMOTE_CONFIG, + vol.Optional(SERVICE_TOGGLE): REMOTE_CONFIG, } ) @@ -64,21 +63,21 @@ def __init__(self, hass, name, remotes): def turn_on(self) -> None: """Turn the entity on.""" remote = self._remotes.get(SERVICE_TURN_ON) - if remote != EMPTY_REMOTE: + if remote is not None: self.call(domain="unified_remote", service="call", service_data=remote) self._state = True def turn_off(self): """Turn the entity off.""" remote = self._remotes.get(SERVICE_TURN_OFF) - if remote != EMPTY_REMOTE: + if remote is not None: self.call(domain="unified_remote", service="call", service_data=remote) self._state = False def toggle(self): """Toggle the entity.""" remote = self._remotes.get(SERVICE_TOGGLE) - if remote != EMPTY_REMOTE: + if remote is not None: self.call(domain="unified_remote", service="call", service_data=remote) self._state = not self._state diff --git a/linter.sh b/linter.sh new file mode 100755 index 0000000..df0c625 --- /dev/null +++ b/linter.sh @@ -0,0 +1,6 @@ +black custom_components/unified_remote/*.py; +isort custom_components/unified_remote/*.py; +flake8 custom_components/unified_remote/*.py; +black custom_components/unified_remote/cli/*.py; +isort custom_components/unified_remote/cli/*.py; +flake8 custom_components/unified_remote/cli/*.py; \ No newline at end of file