示例#1
0
 def __init__(self):
     """Client key will be displayed on the TV when you accept the connection for the first time.
     Store the dict value as an env variable and use it as below. Using TV's ip makes the initial
     response much quicker but it looks for the TVs in ip range if an ip is not found."""
     store = {'client_key': client_key}
     try:
         self.client = WebOSClient(ip_address)
         self.client.connect()
     except gaierror:
         sys.stdout.write(
             f"\rThe TV's IP has either changed or unreachable. Scanning your IP range.."
         )
         self.client = WebOSClient.discover()[0]
         self.client.connect()
     except (TimeoutError, BrokenPipeError):
         sys.stdout.write(
             '\rOperation timed out. The TV might be turned off.')
     for status in self.client.register(store):
         if status == WebOSClient.REGISTERED and not TV._init_status:
             sys.stdout.write('\rConnected to the TV.')
         elif status == WebOSClient.PROMPTED:
             sys.stdout.write(
                 '\rPlease accept the connection request on your TV.')
     # sys.stdout.write(f'\r{store}')  # get the client key dict during the first run and store as in line #18
     self.system = SystemControl(self.client)
     self.system.notify("Jarvis is controlling the TV now."
                        ) if not TV._init_status else None
     self.media = MediaControl(self.client)
     self.app = ApplicationControl(self.client)
     self.source_control = SourceControl(self.client)
     TV._init_status = True
示例#2
0
    def test_bad_list_apps(self):
        client = FakeClient()
        app = ApplicationControl(client)

        client.setup_response("ssap://com.webos.applicationManager/listApps",
                              {"returnValue": False})
        with raises(IOError):
            app.list_apps()
示例#3
0
    def test_bad_launch(self):
        client = FakeClient()
        app = ApplicationControl(client)

        client.setup_response("ssap://system.launcher/launch",
                              {"returnValue": False})
        with raises(IOError):
            app.launch(Application({"id": "123"}))
示例#4
0
    def test_get_current(self):
        client = FakeClient()
        app = ApplicationControl(client)

        client.setup_response(
            "ssap://com.webos.applicationManager/getForegroundAppInfo",
            {"returnValue": True, "appId": "123"})
        assert app.get_current() == "123"
示例#5
0
    def test_list_apps(self):
        client = FakeClient()
        app = ApplicationControl(client)

        appInfo = {"id": "1", "key": "value"}
        fake_response = {
            "returnValue": True,
            "apps": [appInfo]
        }
        client.setup_response("ssap://com.webos.applicationManager/listApps",
                              fake_response)
        assert app.list_apps()[0].data == appInfo
示例#6
0
    def test_close(self):
        client = FakeClient()
        app = ApplicationControl(client)

        client.setup_response("ssap://system.launcher/close",
                              {"returnValue": True})
        app.close({"123": "435"})

        client.assert_sent_message_without_id({
            "type": "request",
            "uri": "ssap://system.launcher/close",
            "payload": {
                "123": "435",
            }
        })
示例#7
0
    def control(self):
        if self._control is None:
            self._control = ApplicationControl(
                self.adapter.create(str(Path().home() / '.lgtv.yaml'),
                                    'living_room'))

        return self._control
示例#8
0
def get_apis(client):
    media = MediaControl(client)
    system = SystemControl(client)
    app = ApplicationControl(client)
    inp = InputControl(client)

    return [
        ServerAPI(
            "mute", "Mute the TV",
            [ArgParameter("state", "True to mute, False to unmute", bool)],
            media.mute),
        ServerAPI("volume_up", "Increase Volume", [], media.volume_up),
        ServerAPI("volume_down", "Decrease Volume", [], media.volume_down),
        ServerAPI("set_volum", "Set Volume",
                  [ArgParameter("level", "Volume Level", int)],
                  media.set_volume),
        ServerAPI("play", "Play", [], media.play),
        ServerAPI("pause", "Pause", [], media.pause),
        ServerAPI("rewind", "Rewind", [], media.rewind),
        ServerAPI("fast_forward", "Fast Forward", [], media.fast_forward),
        ServerAPI("power_off", "Power off TV", [], system.power_off),
        ServerAPI("notify", "Send notification",
                  [ArgParameter("text", "Text to notify", str)],
                  system.notify),
        ServerAPI("type", "Send text input",
                  [ArgParameter("text", "Text to insert", str)], inp.type),
        ServerAPI("delete", "Delete text",
                  [ArgParameter("count", "No of characters to delete", int)],
                  inp.delete),
        ServerAPI("enter", "Press Enter", [], inp.enter),
    ]
    def __init__(self, client):
        self.client: WebOSClient = client

        self._system: SystemControl = SystemControl(client)
        self._media: MediaControl = MediaControl(client)
        self._app: ApplicationControl = ApplicationControl(client)
        self._inp: InputControl = InputControl(client)
示例#10
0
    def test_launch(self):
        client = FakeClient()
        app = ApplicationControl(client)

        client.setup_response("ssap://system.launcher/launch",
                              {"returnValue": True})
        application = Application({"id": "123"})
        app.launch(application, content_id="1", params={"a": "b"})

        client.assert_sent_message_without_id({
            "type": "request",
            "uri": "ssap://system.launcher/launch",
            "payload": {
                "id": "123",
                "contentId": "1",
                "params": {"a": "b"}
            }
        })
示例#11
0
 def __init__(self):
     self.ws = WebOSClient(S.config.get('host'))
     self.ws.connect()
     assert (2 in self.ws.register(S.config)), "Not registered to TV yet"
     self.ac = ApplicationControl(self.ws)
     self.ic = InputControl(self.ws)
     self.mc = MediaControl(self.ws)
     self.sc = SystemControl(self.ws)
     self.srcc = SourceControl(self.ws)
     self.tv = TvControl(self.ws)
示例#12
0
文件: lgws.py 项目: wookiesh/lgws
    def __init__(self, configFile="~/.config/lgtv"):
        log = logging.getLogger(__name__)
        self.config = self.load_config(configFile) or {}

        self.ws = WebOSClient(self.config.get('host'))
        self.ws.connect()
        assert (2 in self.ws.register(self.config)), "Not registered to TV yet"
        self.ac = ApplicationControl(self.ws)
        self.ic = InputControl(self.ws)
        self.mc = MediaControl(self.ws)
        self.sc = SystemControl(self.ws)
        self.srcc = SourceControl(self.ws)
        self.tv = TvControl(self.ws)

        self.apps = {a["id"]: a for a in self.ac.list_apps()}
        # self.ac.subscribe_get_current(self.__on_app_changed)
        # self.mc.subscribe_get_volume(self.__on_volume_changed)

        self.current = self.volume = None
示例#13
0
文件: lgws.py 项目: wookiesh/lgws
class Client(object):
    @staticmethod
    def load_config(configFile="~/.config/lgtv"):
        log.debug("Loading config from " + configFile)
        if os.path.exists(os.path.expanduser(configFile)):
            with open(os.path.expanduser(configFile), 'r') as fp:
                config = json.load(fp)

            log.debug(config)
            return config

    def __init__(self, configFile="~/.config/lgtv"):
        log = logging.getLogger(__name__)
        self.config = self.load_config(configFile) or {}

        self.ws = WebOSClient(self.config.get('host'))
        self.ws.connect()
        assert (2 in self.ws.register(self.config)), "Not registered to TV yet"
        self.ac = ApplicationControl(self.ws)
        self.ic = InputControl(self.ws)
        self.mc = MediaControl(self.ws)
        self.sc = SystemControl(self.ws)
        self.srcc = SourceControl(self.ws)
        self.tv = TvControl(self.ws)

        self.apps = {a["id"]: a for a in self.ac.list_apps()}
        # self.ac.subscribe_get_current(self.__on_app_changed)
        # self.mc.subscribe_get_volume(self.__on_volume_changed)

        self.current = self.volume = None

    def __on_app_changed(self, status, payload):
        self.log.debug(f'app: {payload}')
        self.current = self.apps[payload]

    def __on_volume_changed(self, status, payload):
        self.log.debug(f'volume :{payload}')
        self.volume = payload
示例#14
0
#!/usr/bin/env python3

from pywebostv.controls import ApplicationControl

from lib import init

client = init()

app = ApplicationControl(client)
apps = app.list_apps()
netflix = [x for x in apps if "netflix" in x["title"].lower()][0]
launch_info = app.launch(netflix)
print(launch_info)

# netflix.py ends here
示例#15
0
def launch_app(name, client):
    ctl = ApplicationControl(client)
    apps = ctl.list_apps()
    app = [x for x in apps if name in x["title"].lower()][0]
    launch_info = ctl.launch(app)
    return launch_info
示例#16
0
class TV:
    """All the TV controls wrapped in individual functions."""
    _init_status = False

    def __init__(self):
        """Client key will be displayed on the TV when you accept the connection for the first time.
        Store the dict value as an env variable and use it as below. Using TV's ip makes the initial
        response much quicker but it looks for the TVs in ip range if an ip is not found."""
        store = {'client_key': client_key}
        try:
            self.client = WebOSClient(ip_address)
            self.client.connect()
        except gaierror:
            sys.stdout.write(
                f"\rThe TV's IP has either changed or unreachable. Scanning your IP range.."
            )
            self.client = WebOSClient.discover()[0]
            self.client.connect()
        except (TimeoutError, BrokenPipeError):
            sys.stdout.write(
                '\rOperation timed out. The TV might be turned off.')
        for status in self.client.register(store):
            if status == WebOSClient.REGISTERED and not TV._init_status:
                sys.stdout.write('\rConnected to the TV.')
            elif status == WebOSClient.PROMPTED:
                sys.stdout.write(
                    '\rPlease accept the connection request on your TV.')
        # sys.stdout.write(f'\r{store}')  # get the client key dict during the first run and store as in line #18
        self.system = SystemControl(self.client)
        self.system.notify("Jarvis is controlling the TV now."
                           ) if not TV._init_status else None
        self.media = MediaControl(self.client)
        self.app = ApplicationControl(self.client)
        self.source_control = SourceControl(self.client)
        TV._init_status = True

    def increase_volume(self):
        """Increases the volume by 10 units. Doesn't return anything"""
        for _ in range(10):
            self.media.volume_up()
        self.system.notify(
            f"Jarvis::Increased Volume: {self.media.get_volume()['volume']}%")

    def decrease_volume(self):
        """Decreases the volume by 10 units. Doesn't return anything"""
        for _ in range(10):
            self.media.volume_down()
        self.system.notify(
            f"Jarvis::Decreased Volume: {self.media.get_volume()['volume']}%")

    def get_volume(self):
        """Get volume status. Returns: {'scenario': 'mastervolume_tv_speaker', 'volume': 9, 'muted': False}"""
        self.system.notify(
            f"Jarvis::Current Volume: {self.media.get_volume()['volume']}%")
        return self.media.get_volume()['volume']

    def set_volume(self, target):
        """The argument is an integer from 1 to 100. Doesn't return anything."""
        self.media.set_volume(target)
        self.system.notify(
            f"Jarvis::Volume has been set to: {self.media.get_volume()['volume']}%"
        )

    def mute(self):
        """status=True mutes the TV. status=False un-mutes it."""
        self.system.notify(f"Jarvis::Muted")
        self.media.mute(True)

    def play(self):
        self.system.notify(f"Jarvis::Play")
        self.media.play()

    def pause(self):
        self.system.notify(f"Jarvis::Paused")
        self.media.pause()

    def stop(self):
        self.system.notify(f"Jarvis::Stop")
        self.media.stop()

    def rewind(self):
        self.system.notify(f"Jarvis::Rewind")
        self.media.rewind()

    def forward(self):
        self.system.notify(f"Jarvis::Forward")
        self.media.fast_forward()

    def audio_output(self):
        """Returns the currently used audio output source as AudioOutputSource instance"""
        media_output_source = self.media.get_audio_output()
        sys.stdout.write(f'{media_output_source}')

    def audio_output_source(self):
        """Returns a list of AudioOutputSource instances"""
        audio_outputs = self.media.list_audio_output_sources()
        sys.stdout.write(f'{audio_outputs}')
        return audio_outputs

    def set_audio_output_source(self):
        """AudioOutputSource instance"""
        # noinspection PyUnresolvedReferences
        self.media.set_audio_output(audio_output_source[0])

    def list_apps(self):
        """Returns the list of available apps on the TV"""
        apps = self.app.list_apps()
        app_list = [app["title"] for app in apps]
        return app_list

    def launch_app(self, app_name):
        """launches an application"""
        app_launcher = [
            x for x in self.app.list_apps()
            if app_name.lower() in x["title"].lower()
        ][0]
        return self.app.launch(app_launcher, content_id=None)

    def close_app(self, app_name):
        """closes a particular app using the launch_info received from launch_app()"""
        self.app.close(TV().launch_app(app_name))

    def source(self):
        """Returns a list of InputSource instances"""
        sources = self.source_control.list_sources()
        sources_list = [source['label'] for source in sources]
        return sources_list

    def set_source(self, val):
        """Accepts an InputSource instance"""
        sources = self.source_control.list_sources()
        index = TV().source().index(val)
        self.source_control.set_source(sources[index])
        return sources

    def current_app(self):
        """Returns the title of te current app that is running"""
        app_id = self.app.get_current(
        )  # Returns the application ID (string) of the
        foreground_app = [
            x for x in self.app.list_apps() if app_id == x["id"]
        ][0]
        return foreground_app['title']

    def shutdown(self):
        """Notifies the TV about shutdown and shuts down after 3 seconds"""
        self.system.notify(f'Jarvis::SHUTTING DOWN now')
        time.sleep(3)
        self.system.power_off()
示例#17
0
文件: youtube.py 项目: flepied/lgtv
#!/usr/bin/env python3

from pywebostv.controls import ApplicationControl

from lib import init

client = init()

app = ApplicationControl(client)
apps = app.list_apps()
youtube = [x for x in apps if "youtube" in x["title"].lower()][0]
launch_info = app.launch(youtube)
print(launch_info)

# youtube.py ends here