Beispiel #1
0
 def try_connect(self):
     """Try to connect to the Legacy TV."""
     config = {
         CONF_NAME: VALUE_CONF_NAME,
         CONF_DESCRIPTION: VALUE_CONF_NAME,
         CONF_ID: VALUE_CONF_ID,
         CONF_HOST: self.host,
         CONF_METHOD: self.method,
         CONF_PORT: None,
         # We need this high timeout because waiting for auth popup is just an open socket
         CONF_TIMEOUT: TIMEOUT_REQUEST,
     }
     try:
         LOGGER.debug("Try config: %s", config)
         with Remote(config.copy()):
             LOGGER.debug("Working config: %s", config)
             return RESULT_SUCCESS
     except AccessDenied:
         LOGGER.debug("Working but denied config: %s", config)
         return RESULT_AUTH_MISSING
     except UnhandledResponse:
         LOGGER.debug("Working but unsupported config: %s", config)
         return RESULT_NOT_SUPPORTED
     except (ConnectionClosed, OSError) as err:
         LOGGER.debug("Failing config: %s, error: %s", config, err)
         return RESULT_CANNOT_CONNECT
Beispiel #2
0
    def _try_connect(self):
        """Try to connect and check auth."""
        for cfg in SUPPORTED_METHODS:
            config = {
                "name": "HomeAssistant",
                "description": "HomeAssistant",
                "id": "ha.component.samsung",
                "host": self._host,
                "port": self._port,
            }
            config.update(cfg)
            try:
                LOGGER.debug("Try config: %s", config)
                with Remote(config.copy()):
                    LOGGER.debug("Working config: %s", config)
                    self._method = cfg["method"]
                    return RESULT_SUCCESS
            except AccessDenied:
                LOGGER.debug("Working but denied config: %s", config)
                return RESULT_AUTH_MISSING
            except (UnhandledResponse, WebSocketException):
                LOGGER.debug("Working but unsupported config: %s", config)
                return RESULT_NOT_SUPPORTED
            except OSError as err:
                LOGGER.debug("Failing config: %s, error: %s", config, err)

        LOGGER.debug("No working config found")
        return RESULT_NOT_SUCCESSFUL
Beispiel #3
0
    def _try_connect(self):
        """Try to connect and check auth."""
        for method in METHODS:
            config = {
                "name": "HomeAssistant",
                "description": "HomeAssistant",
                "id": "ha.component.samsung",
                "host": self._host,
                "method": method,
                "port": self._port,
                # We need this high timeout because waiting for auth popup is just an open socket
                "timeout": 31,
            }
            try:
                LOGGER.debug("Try config: %s", config)
                with Remote(config.copy()):
                    LOGGER.debug("Working config: %s", config)
                    self._method = method
                    return RESULT_SUCCESS
            except AccessDenied:
                LOGGER.debug("Working but denied config: %s", config)
                return RESULT_AUTH_MISSING
            except UnhandledResponse:
                LOGGER.debug("Working but unsupported config: %s", config)
                return RESULT_NOT_SUPPORTED
            except OSError as err:
                LOGGER.debug("Failing config: %s, error: %s", config, err)

        LOGGER.debug("No working config found")
        return RESULT_NOT_SUCCESSFUL
 def try_connect(self, port):
     """Try to connect to the Legacy TV."""
     if port is not None and port != self.port:
         return RESULT_NOT_SUCCESSFUL
     config = {
         "name": "HomeAssistant",
         "description": "HomeAssistant",
         "id": "ha.component.samsung",
         "host": self.host,
         "method": self.method,
         "port": self.port,
         # We need this high timeout because waiting for auth popup is just an open socket
         "timeout": 31,
     }
     try:
         LOGGER.debug("Try config: %s", config)
         with Remote(config.copy()):
             LOGGER.debug("Working config: %s", config)
             return RESULT_SUCCESS
     except AccessDenied:
         LOGGER.debug("Working but denied config: %s", config)
         return RESULT_AUTH_MISSING
     except UnhandledResponse:
         LOGGER.debug("Working but unsupported config: %s", config)
         return RESULT_NOT_SUPPORTED
     except OSError as err:
         LOGGER.debug("Failing config: %s, error: %s", config, err)
         return RESULT_NOT_SUCCESSFUL
Beispiel #5
0
 def try_connect(self):
     """Try to connect to the TVs with pin."""
     config = {
         CONF_NAME: VALUE_CONF_NAME,
         CONF_DESCRIPTION: VALUE_CONF_NAME,
         CONF_ID: VALUE_CONF_ID,
         CONF_HOST: self.host,
         CONF_METHOD: self.method,
         CONF_SESSION_ID: self.session_id,
         CONF_SESSION_KEY: self.session_key,
         CONF_PORT: self.port,
         # We need this high timeout because waiting for auth popup is just an open socket
         CONF_TIMEOUT: 31,
     }
     try:
         LOGGER.debug("Try config: %s", config)
         with Remote(config.copy()):
             LOGGER.debug("Working config: %s", config)
             return RESULT_SUCCESS
     except AccessDenied:
         LOGGER.debug("Working but denied config: %s", config)
         return RESULT_AUTH_MISSING
     except UnhandledResponse:
         LOGGER.debug("Working but unsupported config: %s", config)
         return RESULT_NOT_SUPPORTED
     except OSError as err:
         LOGGER.debug("Failing config: %s, error: %s", config, err)
         return RESULT_NOT_SUCCESSFUL
    def _try_connect_samsungctl(self, port):
        if self._port is None or port == self._port:
            config = {
                "name": "HomeAssistant",
                "description": "HomeAssistant",
                "id": "ha.component.samsung",
                "host": self._host,
                "method": "legacy" if port == 55000 else "websocket",
                "port": port,
                # We need this high timeout because waiting for auth popup is just an open socket
                "timeout": 31,
            }
            try:
                LOGGER.debug("Try config: %s", config)
                with Remote(config.copy()):
                    LOGGER.debug("Working config: %s", config)
                    self._method = config["method"]
                    return RESULT_SUCCESS
            except AccessDenied:
                LOGGER.debug("Working but denied config: %s", config)
                return RESULT_AUTH_MISSING
            except UnhandledResponse:
                LOGGER.debug("Working but unsupported config: %s", config)
                return RESULT_NOT_SUPPORTED
            except OSError as err:
                LOGGER.debug("Failing config: %s, error: %s", config, err)

        return RESULT_NOT_SUCCESSFUL
 def _get_remote(self):
     """Create or return a remote control instance."""
     if self._remote is None:
         # We need to create a new instance to reconnect.
         try:
             LOGGER.debug("Create SamsungRemote")
             self._remote = Remote(self.config.copy())
         # This is only happening when the auth was switched to DENY
         # A removed auth will lead to socket timeout because waiting for auth popup is just an open socket
         except AccessDenied:
             self._notify_callback()
             raise
     return self._remote
Beispiel #8
0
 def _get_remote(self, avoid_open: bool = False):
     """Create or return a remote control instance."""
     if self._remote is None:
         # We need to create a new instance to reconnect.
         try:
             LOGGER.debug("Create SamsungTVLegacyBridge for %s (%s)",
                          CONF_NAME, self.host)
             self._remote = Remote(self.config.copy())
         # This is only happening when the auth was switched to DENY
         # A removed auth will lead to socket timeout because waiting for auth popup is just an open socket
         except AccessDenied:
             self._notify_callback()
             raise
         except (ConnectionClosed, OSError):
             pass
     return self._remote
def main():
    epilog = "E.g. %(prog)s --host 192.168.0.10 --name myremote KEY_VOLDOWN"
    parser = argparse.ArgumentParser(prog=title,
                                     description=doc,
                                     epilog=epilog)
    parser.add_argument("--version",
                        action="version",
                        version="%(prog)s {0}".format(version))
    parser.add_argument("-v",
                        "--verbose",
                        action="count",
                        help="increase output verbosity")
    parser.add_argument("-q",
                        "--quiet",
                        action="store_true",
                        help="suppress non-fatal output")
    parser.add_argument("-i",
                        "--interactive",
                        action="store_true",
                        help="interactive control")
    parser.add_argument("--host", help="TV hostname or IP address")
    parser.add_argument("--port", type=int, help="TV port number (TCP)")
    parser.add_argument("--method",
                        help="Connection method (legacy or websocket)")
    parser.add_argument("--name", help="remote control name")
    parser.add_argument("--description",
                        metavar="DESC",
                        help="remote control description")
    parser.add_argument("--id", help="remote control id")
    parser.add_argument("--timeout",
                        type=float,
                        help="socket timeout in seconds (0 = no timeout)")
    parser.add_argument(
        "--key-help",
        action="store_true",
        help="print available keys. (key support depends on tv model)")
    parser.add_argument("key",
                        nargs="*",
                        default=[],
                        type=get_key,
                        help="keys to be sent (e.g. KEY_VOLDOWN)")

    args = parser.parse_args()

    if args.quiet:
        log_level = logging.ERROR
    elif not args.verbose:
        log_level = logging.WARNING
    elif args.verbose == 1:
        log_level = logging.INFO
    else:
        log_level = logging.DEBUG

    logging.basicConfig(format="%(message)s", level=log_level)

    if args.key_help:
        keys_help(args.key)

    config = _read_config()
    config.update({k: v for k, v in vars(args).items() if v is not None})

    if not config["host"]:
        logging.error("Error: --host must be set")
        return

    try:
        with Remote(config) as remote:
            for key in args.key:
                if key is None:
                    continue
                key(remote)

            if args.interactive:
                logging.getLogger().setLevel(logging.ERROR)
                from . import interactive
                interactive.run(remote)
            elif len(args.key) == 0:
                logging.warning("Warning: No keys specified.")
    except exceptions.ConnectionClosed:
        logging.error("Error: Connection closed!")
    except exceptions.AccessDenied:
        logging.error("Error: Access denied!")
    except exceptions.UnknownMethod:
        logging.error("Error: Unknown method '{}'".format(config["method"]))
    except socket.timeout:
        logging.error("Error: Timed out!")
    except OSError as e:
        logging.error("Error: %s", e.strerror)
Beispiel #10
0
def main():
    epilog = "E.g. %(prog)s --host 192.168.0.10 --name myremote KEY_VOLDOWN"
    parser = argparse.ArgumentParser(
        prog=title,
        description=doc,
        epilog=epilog
    )
    parser.add_argument(
        "--version",
        action="version",
        version="%(prog)s {0}".format(version)
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="count",
        help="increase output verbosity"
    )
    parser.add_argument(
        "-q",
        "--quiet",
        action="store_true",
        help="suppress non-fatal output"
    )
    parser.add_argument(
        "-i",
        "--interactive",
        action="store_true",
        help="interactive control"
    )
    parser.add_argument(
        "--host",
        help="TV hostname or IP address"
    )
    parser.add_argument(
        "--port",
        type=int,
        help="TV port number (TCP)"
    )
    parser.add_argument(
        "--method",
        help="Connection method (legacy or websocket)"
    )
    parser.add_argument(
        "--name",
        help="remote control name"
    )
    parser.add_argument(
        "--description",
        metavar="DESC",
        help="remote control description"
    )
    parser.add_argument(
        "--id",
        help="remote control id"
    )
    parser.add_argument(
        "--timeout",
        type=float,
        help="socket timeout in seconds (0 = no timeout)"
    )

    parser.add_argument(
        "--start-app",
        help="start an application --start-app \"Netflix\""
    )
    parser.add_argument(
        "--app-metadata",
        help=(
            "pass options string of information the application "
            "can use when it starts up. And example would be the browser. "
            "To have it open directly to a specific URL you would enter: "
            "\"http\/\/www.some-web-address.com\". wrapping the meta data in "
            "quotes will reduce the possibility of a command line parser "
            "error."
        )
    )
    parser.add_argument(
        "--key-help",
        action="store_true",
        help="print available keys. (key support depends on tv model)"
    )
    parser.add_argument(
        "key",
        nargs="*",
        default=[],
        type=get_key,
        help="keys to be sent (e.g. KEY_VOLDOWN)"
    )

    args = parser.parse_args()

    if args.quiet:
        log_level = logging.ERROR
    elif not args.verbose:
        log_level = logging.WARNING
    elif args.verbose == 1:
        log_level = logging.INFO
    else:
        log_level = logging.DEBUG

    if args.key_help:
        keys_help(args.key)

    config = _read_config()
    config.update({k: v for k, v in vars(args).items() if v is not None})

    if not config["host"]:
        logging.error("Error: --host must be set")
        return

    try:
        with Remote(config, log_level) as remote:
            if args.interactive:
                logging.getLogger().setLevel(logging.ERROR)
                from . import interactive
                interactive.run(remote)
            elif config["method"] == 'websocket' and args.start_app:
                app = remote.get_application(args.start_app)
                if args.app_metadata:
                    app.run(args.app_metadata)
                else:
                    app.run()
            elif len(args.key) == 0:
                logging.warning("Warning: No keys specified.")
            else:
                for key in args.key:
                    if key is None:
                        continue
                    key(remote)

    except exceptions.ConnectionClosed:
        logging.error("Error: Connection closed!")
    except exceptions.AccessDenied:
        logging.error("Error: Access denied!")
    except exceptions.UnknownMethod:
        logging.error("Error: Unknown method '{}'".format(config["method"]))
    except socket.timeout:
        logging.error("Error: Timed out!")
    except OSError as e:
        logging.error("Error: %s", e.strerror)
Beispiel #11
0
def main():
    epilog = "E.g. %(prog)s --host 192.168.0.10 --name myremote KEY_VOLDOWN"
    parser = argparse.ArgumentParser(prog=title,
                                     description=doc,
                                     epilog=epilog)
    parser.add_argument("--version",
                        action="version",
                        version="%(prog)s {0}".format(version))
    parser.add_argument("-v",
                        "--verbose",
                        action="count",
                        help="increase output verbosity")
    parser.add_argument("-q",
                        "--quiet",
                        action="store_true",
                        help="suppress non-fatal output")
    parser.add_argument("-i",
                        "--interactive",
                        action="store_true",
                        help="interactive control")
    parser.add_argument("--host", help="TV hostname or IP address")
    parser.add_argument("--token", default=None, help="token for TV's >= 2014")
    parser.add_argument("--port", type=int, help="TV port number (TCP)")
    parser.add_argument("--method",
                        help="Connection method (legacy or websocket)")
    parser.add_argument("--name", help="remote control name")
    parser.add_argument("--description",
                        metavar="DESC",
                        help="remote control description")
    parser.add_argument("--id", help="remote control id")
    parser.add_argument(
        "--volume",
        type=int,
        help=("sets the TV volume to the entered value, a value of -1 will "
              "display the volume level"))
    parser.add_argument(
        "--brightness",
        type=int,
        help=("sets the TV brightness level to the entered value, "
              "a value of -1 will display the brightness level"))
    parser.add_argument(
        "--contrast",
        type=int,
        help=("sets the TV contrast level to the entered value, "
              "a value of -1 will display the contrast level"))
    parser.add_argument(
        "--sharpness",
        type=int,
        help=("sets the TV sharpness level to the entered value, "
              "a value of -1 will display the sharpness level"))
    parser.add_argument("--mute",
                        type=str,
                        choices=['off', 'on', 'state'],
                        help=("sets the mute on or off (not a toggle), "
                              "state displays if the mute if on or off"))

    parser.add_argument(
        "--source",
        type=str,
        help=(
            "changes the input source to the one specified. "
            "You can either enter the TV source name "
            "eg: HDMI1 HDMI2, USB, PC...."
            "or you can enter the programmed label for the source. "
            "This is going to be what is displayed on the OSD when you change "
            "the source from the remote. If you enter 'state' for the source "
            "name it will print out the currently "
            "active source label and name."))

    parser.add_argument(
        "--source-label",
        type=str,
        help=(
            "changes the label for a source. "
            "If you do not use --source to specify the source to change the "
            "label on. It will automatically default to the currently "
            "active source. If you set the label to 'state' it will print out "
            "the current label for a source if specified using --source or "
            "the currently active source"))
    parser.add_argument("--timeout",
                        type=float,
                        help="socket timeout in seconds (0 = no timeout)")
    parser.add_argument("--config-file",
                        type=str,
                        default=None,
                        help="configuration file to load and/or save to")
    parser.add_argument("--start-app",
                        help="start an application --start-app \"Netflix\"")
    parser.add_argument(
        "--app-metadata",
        help=(
            "pass options string of information the application "
            "can use when it starts up. And example would be the browser. "
            "To have it open directly to a specific URL you would enter: "
            "\"http\/\/www.some-web-address.com\". wrapping the meta data in "
            "quotes will reduce the possibility of a command line parser "
            "error."))
    parser.add_argument(
        "--key-help",
        action="store_true",
        help="print available keys. (key support depends on tv model)")
    parser.add_argument("key",
                        nargs="*",
                        default=[],
                        type=get_key,
                        help="keys to be sent (e.g. KEY_VOLDOWN)")

    args = parser.parse_args()

    if args.quiet:
        log_level = logging.ERROR
    elif not args.verbose:
        log_level = logging.WARNING
    elif args.verbose == 1:
        log_level = logging.INFO
    else:
        log_level = logging.DEBUG

    if args.key_help:
        keys_help(args.key)

    if args.config_file is None:
        config = _read_config()
        config.update({k: v for k, v in vars(args).items() if v is not None})
        config = Config(**config)
    else:
        if os.path.isfile(args.config_file):
            config = Config.load(args.config_file)
        else:
            config = _read_config()
            config.update(
                {k: v
                 for k, v in vars(args).items() if v is not None})
            config = Config(**config)
            config.path = args.config_file

    if not config.host:
        logging.error("Error: --host must be set")
        return

    config.log_level = log_level

    if config.upnp_locations is None:
        config.upnp_locations = []

    try:
        with Remote(config) as remote:
            if args.interactive:
                logging.getLogger().setLevel(logging.ERROR)
                from . import interactive
                interactive.run(remote)
            elif config.method == 'websocket' and args.start_app:
                app = remote.get_application(args.start_app)
                if args.app_metadata:
                    app.run(args.app_metadata)
                else:
                    app.run()
            else:
                for key in args.key:
                    if key is None:
                        continue
                    key(remote)

            if args.volume is not None:
                if args.volume == -1:
                    print('Volume:', remote.volume, '%')
                else:
                    remote.volume = args.volume

            elif args.mute is not None:
                if args.mute == 'state':
                    print('Mute:', 'ON' if remote.mute else 'OFF')
                else:
                    remote.mute = args.mute == 'on'

            if args.brightness is not None:
                if args.brightness == -1:
                    print('Brightness:', remote.brightness, '%')
                else:
                    remote.brightness = args.brightness

            if args.contrast is not None:
                if args.contrast == -1:
                    print('Contrast:', remote.contrast, '%')
                else:
                    remote.contrast = args.contrast

            if args.sharpness is not None:
                if args.sharpness == -1:
                    print('Sharpness:', remote.sharpness, '%')
                else:
                    remote.sharpness = args.sharpness

            if args.source_label is not None:
                if args.source is None:
                    if args.source_label == 'state':
                        print('Source Label:', remote.source.label)
                    else:
                        remote.source.label = args.remote_label
                else:
                    for source in remote.sources:
                        if args.source in (source.label, source.name):
                            if args.source_label == 'state':
                                print('Source Label:', source.label)
                            else:
                                source.label = args.source_label
                            break

            elif args.source is not None:
                if args.source == 'state':
                    source = remote.source
                    print('Source: Label =', source.label, 'Name =',
                          source.name)
                else:
                    remote.source = args.source

    except exceptions.ConnectionClosed:
        logging.error("Error: Connection closed!")
    except exceptions.AccessDenied:
        logging.error("Error: Access denied!")
    except exceptions.ConfigUnknownMethod:
        logging.error("Error: Unknown method '{}'".format(config.method))
    except socket.timeout:
        logging.error("Error: Timed out!")
    except OSError as e:
        logging.error("Error: %s", e.strerror)

    if args.config_file:
        config.save()
def main():
    epilog = "E.g. %(prog)s --host 192.168.0.10 --name myremote KEY_VOLDOWN"
    parser = argparse.ArgumentParser(
        prog=title,
        description=doc,
        epilog=epilog
    )
    parser.add_argument(
        "--version",
        action="version",
        version="%(prog)s {0}".format(version)
    )
    parser.add_argument(
        "-v",
        "--verbose",
        action="count",
        help="increase output verbosity"
    )
    parser.add_argument(
        "-i",
        "--interactive",
        action="store_true",
        help="interactive control"
    )
    parser.add_argument(
        "--host",
        help="TV hostname or IP address"
    )
    parser.add_argument(
        "--name",
        help="remote control name"
    )
    parser.add_argument(
        "--description",
        metavar="DESC",
        help="remote control description"
    )
    parser.add_argument(
        "--volume",
        type=int,
        default=None,
        help=(
            "sets the TV volume to the entered value, a value of -1 will "
            "display the volume level"
        )
    )
    parser.add_argument(
        "--brightness",
        type=int,
        default=None,
        help=(
            "sets the TV brightness level to the entered value, "
            "a value of -1 will display the brightness level"
        )
    )
    parser.add_argument(
        "--contrast",
        type=int,
        default=None,
        help=(
            "sets the TV contrast level to the entered value, "
            "a value of -1 will display the contrast level"
        )
    )
    parser.add_argument(
        "--sharpness",
        type=int,
        default=None,
        help=(
            "sets the TV sharpness level to the entered value, "
            "a value of -1 will display the sharpness level"
        )
    )
    parser.add_argument(
        "--mute",
        type=str,
        default=None,
        choices=['off', 'on', 'state'],
        help=(
            "sets the mute on or off (not a toggle), "
            "state displays if the mute is on or off"
        )
    )
    parser.add_argument(
        "--artmode",
        type=str,
        default=None,
        choices=['off', 'on', 'state'],
        help=(
            "sets the art mode for Frame TV's, "
            "state displays if the art mode is on or off"
        )
    )
    parser.add_argument(
        "--source",
        type=str,
        default=None,
        help=(
            "changes the input source to the one specified. "
            "You can either enter the TV source name "
            "eg: HDMI1 HDMI2, USB, PC...."
            "or you can enter the programmed label for the source. "
            "This is going to be what is displayed on the OSD when you change "
            "the source from the remote. If you enter 'state' for the source "
            "name it will print out the currently "
            "active source label and name."
        )
    )
    parser.add_argument(
        "--config-file",
        type=str,
        default=None,
        help="configuration file to load and/or save to"
    )
    parser.add_argument(
        "--start-app",
        help="start an application --start-app \"Netflix\""
    )
    parser.add_argument(
        "--app-metadata",
        help=(
            "pass options string of information the application "
            "can use when it starts up. And example would be the browser. "
            "To have it open directly to a specific URL you would enter: "
            "\"http\/\/www.some-web-address.com\". wrapping the meta data in "
            "quotes will reduce the possibility of a command line parser "
            "error."
        )
    )
    parser.add_argument(
        "--key-help",
        action="store_true",
        help="print available keys. (key support depends on tv model)"
    )
    parser.add_argument(
        "key",
        nargs="*",
        default=[],
        type=get_key,
        help="keys to be sent (e.g. KEY_VOLDOWN)"
    )

    args = parser.parse_args()

    log_levels = [
        logging.NOTSET,
        logging.INFO,
        logging.WARNING,
        logging.ERROR,
        logging.DEBUG
    ]

    logger.setLevel(log_levels[args.verbose])

    if args.key_help:
        keys_help(args.key)

    if args.config_file is None:
        config = Config
    else:
        config = Config.load(args.config_file)

    config = config(
        host=args.host
    )

    if not config.uuid:
        configs = discover(args.host)
        if len(configs) > 1:
            while True:
                for i, cfg in enumerate(configs):
                    print(i + 1, ':', cfg.model)
                try:
                    # noinspection PyCompatibility
                    answer = raw_input(
                        'Enter the number of the TV you want to pair with:'
                    )
                except NameError:
                    answer = input(
                        'Enter the number of the TV you want to pair with:'
                    )

                try:
                    answer = int(answer) - 1
                    config = configs[answer]
                    break
                except (TypeError, ValueError, IndexError):
                    pass

        elif configs:
            config = configs[0]
        else:
            print('Unable to discover any TV\'s')
            sys.exit(1)

    config.log_level = log_levels[args.verbose]

    if not config.uuid:
        print('No UUID for TV located')
        sys.exit(1)

    if config.upnp_locations is None:
        config.upnp_locations = []

    try:
        with Remote(config) as remote:
            if args.interactive:
                logging.getLogger().setLevel(logging.ERROR)
                from . import interactive
                inter = interactive.Interactive(remote)
                inter.run()
                sys.exit(1)

            if (
                args.key and
                args.key[0] in ('KEY_POWER', 'KEY_POWERON') and
                config.paired and
                not remote.power
            ):
                args.key.pop(0)
                remote.power = True

                import time

                while remote.is_powering_on:
                    time.sleep(0.25)

                if not remote.power:
                    print('Unable to power on the TV')
                    sys.exit(1)

            if config.method == 'websocket' and args.start_app:
                app = remote.get_application(args.start_app)
                if args.app_metadata:
                    app.run(args.app_metadata)
                else:
                    app.run()
            else:
                for key in args.key:
                    if key is None:
                        continue
                    key(remote)

            if args.volume is not None:
                if args.volume == -1:
                    print('Volume:', remote.volume, '%')
                else:
                    remote.volume = args.volume

            elif args.mute is not None:
                if args.mute == 'state':
                    print('Mute:', 'ON' if remote.mute else 'OFF')
                else:
                    remote.mute = args.mute == 'on'

            elif args.artmode is not None:
                if args.artmode == 'state':
                    print('Art Mode:', 'ON' if remote.artmode else 'OFF')
                else:
                    remote.artmode = args.artmode == 'on'

            if args.brightness is not None:
                if args.brightness == -1:
                    print('Brightness:', remote.brightness, '%')
                else:
                    remote.brightness = args.brightness

            if args.contrast is not None:
                if args.contrast == -1:
                    print('Contrast:', remote.contrast, '%')
                else:
                    remote.contrast = args.contrast

            if args.sharpness is not None:
                if args.sharpness == -1:
                    print('Sharpness:', remote.sharpness, '%')
                else:
                    remote.sharpness = args.sharpness

            if args.source is not None:
                if args.source == 'state':
                    source = remote.source
                    print(
                        'Source: Label =', source.label,
                        'Name =', source.name
                    )
                else:
                    remote.source = args.source

    except exceptions.ConnectionClosed:
        logging.error("Error: Connection closed!")
    except exceptions.AccessDenied:
        logging.error("Error: Access denied!")
    except exceptions.ConfigUnknownMethod:
        logging.error("Error: Unknown method '{}'".format(config.method))
    except socket.timeout:
        logging.error("Error: Timed out!")
    except OSError as e:
        logging.error("Error: %s", e.strerror)

    if args.config_file:
        config.save()
Beispiel #13
0
def main():
    auto_discover.start()

    epilog = "E.g. %(prog)s --host 192.168.0.10 --name myremote KEY_VOLDOWN"
    parser = argparse.ArgumentParser(prog=title,
                                     description=doc,
                                     epilog=epilog)
    parser.add_argument("--version",
                        action="version",
                        version="%(prog)s {0}".format(version))
    parser.add_argument("-v",
                        "--verbose",
                        action="count",
                        help="increase output verbosity")
    parser.add_argument("-q",
                        "--quiet",
                        action="store_true",
                        help="suppress non-fatal output")
    parser.add_argument("-i",
                        "--interactive",
                        action="store_true",
                        help="interactive control")
    parser.add_argument("--host", help="TV hostname or IP address")
    parser.add_argument("--token", default=None, help="token for TV's >= 2014")
    parser.add_argument("--port", type=int, help="TV port number (TCP)")
    parser.add_argument("--method",
                        help="Connection method (legacy or websocket)")
    parser.add_argument("--name", help="remote control name")
    parser.add_argument("--description",
                        metavar="DESC",
                        help="remote control description")
    parser.add_argument("--id", help="remote control id")
    parser.add_argument(
        "--volume",
        type=int,
        default=None,
        help=("sets the TV volume to the entered value, a value of -1 will "
              "display the volume level"))
    parser.add_argument(
        "--brightness",
        type=int,
        default=None,
        help=("sets the TV brightness level to the entered value, "
              "a value of -1 will display the brightness level"))
    parser.add_argument(
        "--contrast",
        type=int,
        default=None,
        help=("sets the TV contrast level to the entered value, "
              "a value of -1 will display the contrast level"))
    parser.add_argument(
        "--sharpness",
        type=int,
        default=None,
        help=("sets the TV sharpness level to the entered value, "
              "a value of -1 will display the sharpness level"))
    parser.add_argument("--mute",
                        type=str,
                        default=None,
                        choices=['off', 'on', 'state'],
                        help=("sets the mute on or off (not a toggle), "
                              "state displays if the mute is on or off"))
    parser.add_argument("--artmode",
                        type=str,
                        default=None,
                        choices=['off', 'on', 'state'],
                        help=("sets the art mode for Frame TV's, "
                              "state displays if the art mode is on or off"))

    parser.add_argument(
        "--source",
        type=str,
        default=None,
        help=(
            "changes the input source to the one specified. "
            "You can either enter the TV source name "
            "eg: HDMI1 HDMI2, USB, PC...."
            "or you can enter the programmed label for the source. "
            "This is going to be what is displayed on the OSD when you change "
            "the source from the remote. If you enter 'state' for the source "
            "name it will print out the currently "
            "active source label and name."))

    parser.add_argument(
        "--source-label",
        type=str,
        default=None,
        help=(
            "changes the label for a source. "
            "If you do not use --source to specify the source to change the "
            "label on. It will automatically default to the currently "
            "active source. If you set the label to 'state' it will print out "
            "the current label for a source if specified using --source or "
            "the currently active source"))
    parser.add_argument("--timeout",
                        type=float,
                        help="socket timeout in seconds (0 = no timeout)")
    parser.add_argument("--config-file",
                        type=str,
                        default=None,
                        help="configuration file to load and/or save to")
    parser.add_argument("--start-app",
                        help="start an application --start-app \"Netflix\"")
    parser.add_argument(
        "--app-metadata",
        help=(
            "pass options string of information the application "
            "can use when it starts up. And example would be the browser. "
            "To have it open directly to a specific URL you would enter: "
            "\"http\/\/www.some-web-address.com\". wrapping the meta data in "
            "quotes will reduce the possibility of a command line parser "
            "error."))
    parser.add_argument(
        "--key-help",
        action="store_true",
        help="print available keys. (key support depends on tv model)")
    parser.add_argument("key",
                        nargs="*",
                        default=[],
                        type=get_key,
                        help="keys to be sent (e.g. KEY_VOLDOWN)")

    args = parser.parse_args()

    if args.quiet:
        log_level = logging.ERROR
    elif not args.verbose:
        log_level = logging.WARNING
    elif args.verbose == 1:
        log_level = logging.INFO
    else:
        log_level = logging.DEBUG

    if args.key_help:
        keys_help(args.key)

    try:

        if args.config_file is None:
            config = _read_config()
            config.update(
                {k: v
                 for k, v in vars(args).items() if v is not None})
            config = Config(**config)
        else:
            config = {k: v for k, v in vars(args).items() if v is not None}
            config = Config.load(args.config_file)(**config)

    except exceptions.ConfigError:
        import traceback
        traceback.print_exc()

        return

    config.log_level = log_level

    if config.upnp_locations is None:
        config.upnp_locations = []

    if not config.host or not config.uuid:
        configs = discover(config.host)
        if len(configs) > 1:

            while True:
                for i, cfg in enumerate(configs):
                    print(i + 1, ':', cfg.model)
                try:
                    # noinspection PyCompatibility
                    answer = raw_input(
                        'Enter the number of the TV you want to pair with:')
                except NameError:
                    answer = input(
                        'Enter the number of the TV you want to pair with:')

                try:
                    answer = int(answer) - 1
                    cfg = configs[answer]
                    break
                except (TypeError, ValueError, IndexError):
                    pass

        elif configs:
            cfg = configs[0]

        else:
            print('Unable to discover any TV\'s')
            exit_func(0)
            # this never actually happens it is only here to make my IDE happy
            raise RuntimeError
    else:
        cfg = config

    try:
        with Remote(cfg) as remote:
            if args.interactive:
                logging.getLogger().setLevel(logging.ERROR)
                from . import interactive
                inter = interactive.Interactive(remote)
                inter.run()
                exit_func(0)

            if (args.key and args.key[0] in ('KEY_POWER', 'KEY_POWERON')
                    and cfg.paired and not remote.power):
                args.key.pop(0)

                import threading

                event = threading.Event()

                def callback(_, state):
                    if state:
                        event.set()

                auto_discover.register_callback(callback, cfg.uuid)
                remote.power = True

                event.wait(10.0)
                auto_discover.unregister_callback(callback, cfg.uuid)

                if not event.isSet():
                    print('Unable to send command TV is not powered on.')
                    exit_func(1)

            if cfg.method == 'websocket' and args.start_app:
                app = remote.get_application(args.start_app)
                if args.app_metadata:
                    app.run(args.app_metadata)
                else:
                    app.run()
            else:
                for key in args.key:
                    if key is None:
                        continue
                    key(remote)

            if args.volume is not None:
                if args.volume == -1:
                    print('Volume:', remote.volume, '%')
                else:
                    remote.volume = args.volume

            elif args.mute is not None:
                if args.mute == 'state':
                    print('Mute:', 'ON' if remote.mute else 'OFF')
                else:
                    remote.mute = args.mute == 'on'

            elif args.artmode is not None:
                if args.artmode == 'state':
                    print('Art Mode:', 'ON' if remote.artmode else 'OFF')
                else:
                    remote.artmode = args.artmode == 'on'

            if args.brightness is not None:
                if args.brightness == -1:
                    print('Brightness:', remote.brightness, '%')
                else:
                    remote.brightness = args.brightness

            if args.contrast is not None:
                if args.contrast == -1:
                    print('Contrast:', remote.contrast, '%')
                else:
                    remote.contrast = args.contrast

            if args.sharpness is not None:
                if args.sharpness == -1:
                    print('Sharpness:', remote.sharpness, '%')
                else:
                    remote.sharpness = args.sharpness

            if args.source_label is not None:
                if args.source is None:
                    if args.source_label == 'state':
                        print('Source Label:', remote.source.label)
                    else:
                        remote.source.label = args.remote_label
                else:
                    for source in remote.sources:
                        if args.source in (source.label, source.name):
                            if args.source_label == 'state':
                                print('Source Label:', source.label)
                            else:
                                source.label = args.source_label
                            break

            elif args.source is not None:
                if args.source == 'state':
                    source = remote.source
                    print('Source: Label =', source.label, 'Name =',
                          source.name)
                else:
                    remote.source = args.source

    except exceptions.ConnectionClosed:
        logging.error("Error: Connection closed!")
    except exceptions.AccessDenied:
        logging.error("Error: Access denied!")
    except exceptions.ConfigUnknownMethod:
        logging.error("Error: Unknown method '{}'".format(cfg.method))
    except socket.timeout:
        logging.error("Error: Timed out!")
    except OSError as e:
        logging.error("Error: %s", e.strerror)

    if args.config_file:
        cfg.save()
        exit_func(0)