Esempio n. 1
0
 def test_media_type_to_string(self):
     self.assertEqual('Unknown',
                      convert.media_type_str(const.MEDIA_TYPE_UNKNOWN))
     self.assertEqual('Video',
                      convert.media_type_str(const.MEDIA_TYPE_VIDEO))
     self.assertEqual('Music',
                      convert.media_type_str(const.MEDIA_TYPE_MUSIC))
     self.assertEqual('TV', convert.media_type_str(const.MEDIA_TYPE_TV))
Esempio n. 2
0
 def test_media_type_to_string(self):
     self.assertEqual('Unknown',
                      convert.media_type_str(MediaType.Unknown))
     self.assertEqual('Video',
                      convert.media_type_str(MediaType.Video))
     self.assertEqual('Music',
                      convert.media_type_str(MediaType.Music))
     self.assertEqual('TV', convert.media_type_str(MediaType.TV))
Esempio n. 3
0
    def __str__(self):
        """Convert this playing object to a readable string."""
        output = []
        output.append('Media type: {0}'.format(
            convert.media_type_str(self.media_type)))
        output.append('Play state: {0}'.format(
            convert.playstate_str(self.play_state)))

        if self.title is not None:
            output.append('     Title: {0}'.format(self.title))

        if self.artist is not None:
            output.append('    Artist: {0}'.format(self.artist))

        if self.album is not None:
            output.append('     Album: {0}'.format(self.album))

        position = self.position
        total_time = self.total_time
        if position is not None and total_time is not None and total_time != 0:
            output.append('  Position: {0}/{1}s ({2:.1%})'.format(
                position, total_time, float(position)/float(total_time)))
        elif position is not None and position != 0:
            output.append('  Position: {0}s'.format(position))
        elif total_time is not None and position != 0:
            output.append('Total time: {0}s'.format(total_time))

        if self.repeat is not None:
            output.append('    Repeat: {0}'.format(
                convert.repeat_str(self.repeat)))

        if self.shuffle is not None:
            output.append('   Shuffle: {0}'.format(self.shuffle))

        return '\n'.join(output)
Esempio n. 4
0
    async def run(self):
        power = self.device.power.power_state == PowerState.On
        playing = await self.device.metadata.playing()
        if self.name == "appletv-office":
            print(self.name, "playing\n", playing)
        app = "None"
        try:
            app = self.device.metadata.app.name
            # print(app)
        except Exception:
            app = "None"
            pass
            # print(self.name, "no app")

        print("\n");
        print("\n");
        print(self.name, "Power", power, "App", app)
        #### ARTWORK
        artwork = await self.device.metadata.artwork(300, 300)
        if artwork:
            try:
                tmp_filename = "/tmp/{}".format(self.name)
                file = open(tmp_filename, "wb")
                file.write(artwork.bytes)
                file.close()

                file = open(tmp_filename, "rb")
                image_data_binary = file.read()
                file.close()
                try:
                    os.remove(tmp_filename)
                finally:
                    pass

                artwork = base64.b64encode(image_data_binary).decode("ascii")

            except Exception as err:
                artwork = None

        o = {
            "power": power,
            "app": app,
            "mediaType": convert.media_type_str(playing.media_type),
            "deviceState": convert.device_state_str(playing.device_state),
            "title": playing.title,
            "artist": playing.artist,
            "album": playing.album,
            "genre": playing.genre,
            "position": playing.position,
            "total_time": playing.total_time,
            "repeat": convert.repeat_str(playing.repeat),
            "shuffle": convert.shuffle_str(playing.shuffle),
        }

        if o != self.state:
            await self.publish("info", json.dumps(o))

        o["artwork"] = artwork
        await self.set_state(o)
    def __str__(self):
        """Convert this playing object to a readable string."""
        output = []

        mtype = convert.media_type_str(self.media_type)
        output.append('Media type: {0} ({1})'.format(mtype, self.media_type))
        pyatv_api.javaHandler.statusEvent("media_type", str(mtype))

        output.append('Play state: {0} ({1})'.format(
            convert.playstate_str(self.play_state), self.play_state))
        pyatv_api.javaHandler.statusEvent(
            "play_state", str(convert.playstate_str(self.play_state)))

        if self.title is not None:
            title = self.title.strip("\0")
            output.append('	 Title: {0}'.format(title))
            pyatv_api.javaHandler.statusEvent("title", str(self.title))

        if self.artist is not None:
            artist = self.artist.strip("\0")
            output.append('	Artist: {0}'.format(artist))
            pyatv_api.javaHandler.statusEvent("artist", str(artist))

        if self.album is not None:
            album = self.album.strip("\0")
            output.append('	 Album: {0}'.format(album))
            pyatv_api.javaHandler.statusEvent("album", str(album))

        if self.genre is not None:
            genre = self.genre.strip("\0")
            output.append('	 Genre: {0}'.format(genre))
            pyatv_api.javaHandler.statusEvent("genre", str(genre))

        position = self.position
        total_time = self.total_time
        if position is not None and total_time is not None and total_time != 0:
            output.append('  Position: {0}/{1}s ({2:.1%})'.format(
                position, total_time,
                float(position) / float(total_time)))
        elif position is not None and position != 0:
            output.append('  Position: {0}s'.format(position))
        elif total_time is not None and position != 0:
            output.append('Total time: {0}s'.format(total_time))
        if position is not None:
            pyatv_api.javaHandler.statusEvent("position", str(position))
        if total_time is not None:
            pyatv_api.javaHandler.statusEvent("total_time", str(total_time))

        if self.repeat is not None:
            output.append('	Repeat: {0}'.format(convert.repeat_str(
                self.repeat)))
            pyatv_api.javaHandler.statusEvent(
                "repeat", str(convert.repeat_str(self.repeat)))

        if self.shuffle is not None:
            output.append('   Shuffle: {0}'.format(self.shuffle))
            pyatv_api.javaHandler.statusEvent("shuffle", str(self.shuffle))

        return '\n'.join(output)
Esempio n. 6
0
    def __str__(self) -> str:
        """Convert this playing object to a readable string."""
        output = []
        output.append(
            "  Media type: {0}".format(convert.media_type_str(self.media_type))
        )
        output.append(
            "Device state: {0}".format(convert.device_state_str(self.device_state))
        )

        if self.title is not None:
            output.append("       Title: {0}".format(self.title))

        if self.artist is not None:
            output.append("      Artist: {0}".format(self.artist))

        if self.album is not None:
            output.append("       Album: {0}".format(self.album))

        if self.genre is not None:
            output.append("       Genre: {0}".format(self.genre))

        position = self.position
        total_time = self.total_time
        if position is not None and total_time is not None and total_time != 0:
            output.append(
                "    Position: {0}/{1}s ({2:.1%})".format(
                    position, total_time, float(position) / float(total_time)
                )
            )
        elif position is not None and position != 0:
            output.append("    Position: {0}s".format(position))
        elif total_time is not None and position != 0:
            output.append("  Total time: {0}s".format(total_time))

        if self.repeat is not None:
            output.append("      Repeat: {0}".format(convert.repeat_str(self.repeat)))

        if self.shuffle is not None:
            output.append("     Shuffle: {0}".format(convert.shuffle_str(self.shuffle)))

        return "\n".join(output)
Esempio n. 7
0
def test_media_type_to_string(media_type, output):
    assert convert.media_type_str(media_type) == output
Esempio n. 8
0
 def test_playing_media_type_and_playstate(self):
     out = str(PlayingDummy())
     self.assertIn(convert.media_type_str(const.MEDIA_TYPE_VIDEO), out)
     self.assertIn(convert.playstate_str(const.PLAY_STATE_PLAYING), out)
Esempio n. 9
0
async def main():
    global config
    global atvs
    global config_map
    global device_map
    global atv_map

    print("Getting global Config")
    mongo = MongoClient(MONGO_HOST)
    db = mongo["settings"]
    collection = db.config
    raw = collection.find_one({"_id": "config"})
    for entry in raw["appletv"]["devices"]:
        ip = socket.gethostbyname(entry['device'])
        config_map[ip] = entry
        print("entry", entry)
        print("  config", ip, entry['name'], entry['device'])
        config.append(entry)
        device_map[entry['device']] = entry
#     config =  get_config()
# print("config_map", config_map.keys())

#     devices = await scan() # get ATVs
    loop = asyncio.get_event_loop()
    atv_map = {}

    scanning = True
    while scanning:
        scanning = False
        print("Scanning for apple tvs...")
        devices = await pyatv.scan(loop, timeout=5)
        # print("  config_map", config_map.keys())
        if not devices:
            print("No apple tvs found", file=sys.stderr)
            scanning = True
        else:
            for atv in devices:
                ip = str(atv.address)
                atv_map[ip] = atv
                print("  found device", atv.address, atv.name)

            for key in config_map.keys():
                #                 print('key', key, config_map[key], atv_map[key]);
                if key in atv_map.keys():
                    atv_map[key].set_credentials(
                        Protocol.AirPlay, config_map[key]["credentials"])
                    config_map[key]["appletv"] = atv_map[key]
                else:
                    print("   ... key ", key, "not in atv_map")
                    scanning = True
                    break

    print("Scan complete!")

    for device in config:
        #         print(".\n")
        #         print(".\n")
        #         print(".\n")
        #         print(".\n")
        #         print(device)

        #         print(".\n")
        #         print(".\n")
        #         print(".\n")
        #         print(".\n")

        #         atv = device['atv']
        #         print("found", device.name, found);
        device['state'] = {
            "power": None,
            "app": None,
            "mediaType": None,
            "deviceState": None,
            "title": None,
            "artist": None,
            "album": None,
            "genre": None,
            "position": None,
            "total_time": None,
            "repeat": None,
            "shuffle": None,
            "artwork": None,
            "contentIdentifier": None,
            "season_number": None,
            "episode_number": None,
            "series_name": None,
        }
        try:
            app = "None"
            # print("ATV Connecting to ", device['name'])

            atv = await pyatv.connect(device['appletv'], loop)
            device['atv'] = atv
            # print("Connected to ATV")
            topic = "appletv/{}/set/command".format(device['device'])
            print("subscribe", topic)
            MQTT.subscribe(topic)
#         except Exception as err:
        finally:
            pass
#             print("Exception err {}".format(err));
#             continue

#             found['atv'] = atv
#             fn = found['device']
#             print("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz found", found, fn)
#             atv_map[fn] = atv
#             atv_map[found[device]] = atv
#             atvs.append({
#                 "config": found,
#                 "device": device,
#                 "atv": atv,
#                 })

    while True:
        for item in config:
            # print("item", item)
            device = item['device']
            name = item['name']
            atv = item['atv']
            conf = item
            # print("loop", name)

            app = "None"
            try:
                app = atv.metadata.app.name
                # print(app)
            except Exception:
                app = "None"

            power = atv.power.power_state == PowerState.On
            playing = await atv.metadata.playing()

            artwork = await atv.metadata.artwork(300, 300)
            if artwork:
                try:
                    tmp_filename = "/tmp/{}".format(name)
                    file = open(tmp_filename, "wb")
                    file.write(artwork.bytes)
                    file.close()

                    file = open(tmp_filename, "rb")
                    image_data_binary = file.read()
                    file.close()
                    try:
                        os.remove(tmp_filename)
                    finally:
                        pass

                    artwork = base64.b64encode(image_data_binary).decode(
                        "ascii")

                except Exception as err:
                    artwork = None

            o = {
                "power":
                power,
                "app":
                app,
                "mediaType":
                convert.media_type_str(playing.media_type),
                "deviceState":
                convert.device_state_str(playing.device_state),
                "title":
                playing.title,
                "artist":
                playing.artist,
                "album":
                playing.album,
                "genre":
                playing.genre,
                "position":
                playing.position,
                "total_time":
                playing.total_time,
                "repeat":
                convert.repeat_str(playing.repeat),
                "shuffle":
                convert.shuffle_str(playing.shuffle),
                "artwork":
                artwork,
                "seasonNumber":
                playing.season_number
                if hasattr(playing, 'season_number') else None,
                "episodeNumber":
                playing.episode_number
                if hasattr(playing, 'episode_number') else None,
                "seriesName":
                playing.series_name
                if hasattr(playing, 'series_name') else None,
                "contentIdentifier":
                playing.content_identifier
                if hasattr(playing, 'content_identifier') else None,
            }

            #             try:
            #                 o["contentIdentifier"] = playing.content_identifier
            #             finally:
            #                 pass

            #             try:
            #                 o["season_number"] = playing.season_number
            #             finally:
            #                 pass

            #             try:
            #                 o["episode_number"] = playing.episode_number
            #             finally:
            #                 pass

            #             try:
            #                 o["series_name"] = playing.series_name
            #             finally:
            #                 pass

            #             if convert.device_state_str(playing.device_state) == "Playing":
            #                 print(playing.__dict__)
            #                 print("")

            if o != conf['state']:
                topic = "appletv/{}/status/{}".format(conf['device'], "info")
                # print(topic, json.dumps(o)[:40])
                MQTT.publish(topic, json.dumps(o), retain=True)

            for attr, value in o.items():
                #                 print("attr", attr, "value", value, conf['state'][attr])
                try:
                    if value != conf["state"][attr]:
                        topic = "appletv/{}/status/{}".format(
                            conf['device'], attr)
                        # if  name == "Office":
                        #     print(name, "publish", topic, value)
                        conf['state'][attr] = o[attr]
                        MQTT.publish(topic, o[attr], retain=True)
                except Exception as ex:
                    #                     try:
                    #                         MQTT.publish(topic, value, retain=True)
                    #                     finally:
                    pass

        # process queue


#         print("process queue")
        while True:
            try:
                cmd = command_queue.pop()
                print("dequeue command", cmd)
                device = cmd['device']
                message = cmd['command']

                print("command", device, message)
                if device == "reset":
                    print("RECEIVED RESET.  EXITING...\n\n\n")
                    os._exit(0)

                atv = device_map[device]['atv']

                if message == "STOP":
                    await atv.remote_control.right()
                elif message == "MENU":
                    await atv.remote_control.menu()
                elif message == "SUSPEND":
                    await atv.remote_control.home()
                elif message == "HOME":
                    await atv.remote_control.home()
                elif message == "POWER":
                    await atv.power.turn_off()
                elif message == "UP":
                    await atv.remote_control.up()
                elif message == "DOWN":
                    await atv.remote_control.down()
                elif message == "LEFT":
                    await atv.remote_control.left()
                elif message == "RIGHT":
                    await atv.remote_control.right()
                elif message == "SELECT":
                    await atv.remote_control.select()
                elif message == "PAUSE":
                    await atv.remote_control.pause()
                elif message == "PLAY":
                    await atv.remote_control.play()
                elif message == "BEGINREWIND":
                    await atv.remote_control.skip_backward()
                elif message == "BEGINFORWARD":
                    await atv.remote_control.skip_forward()
                else:
                    print("invalid command", message)
            except Exception:
                break

        await asyncio.sleep(1)
Esempio n. 10
0
def test_playing_media_type_and_playstate():
    out = str(
        Playing(media_type=MediaType.Video, device_state=DeviceState.Playing))
    assert convert.media_type_str(MediaType.Video) in out
    assert convert.device_state_str(DeviceState.Playing) in out
Esempio n. 11
0
async def main():
    global config
    global atvs

    mongo = MongoClient(MONGO_HOST)
    db = mongo["settings"]
    collection = db.config
    raw = collection.find_one({"_id": "config"})
    for entry in raw["appletv"]["devices"]:
        # print("entry", entry["device"], entry)
        config.append(entry)

    loop = asyncio.get_event_loop()

    devices = await pyatv.scan(loop, timeout=5)
    if not devices:
        print("No apple tvs found", file=sys.stderr)
        return

    for device in devices:
        print(device)
        print("\n")

        found = find_config(device.name)
        if found:
            topic = "appletv/{}/set/command".format(device.name)
            MQTT.subscribe(topic)
            found['state'] = {
                "power": None,
                "app": None,
                "mediaType": None,
                "deviceState": None,
                "title": None,
                "artist": None,
                "album": None,
                "genre": None,
                "position": None,
                "total_time": None,
                "repeat": None,
                "shuffle": None,
                "artwork": None,
            };
            # connected = False
            # while not connected:
            #     try:
            #         print("CONNECTING TO ", device.address, device.name)
            #         atv = await pyatv.connect(device, loop)
            #         print(" -> CONNECTED", device.address)
            #         connected = True
            #     except Exception:
            #         await atv.close(loop)
            #         pass

            atv = device
            atvs.append({ 
                "config": found,
                "device": device,
                "atv": atv, 
                })

    while True:
        for item in atvs:
            device = item['device']
            name = device.name
            atv = item['atv']
            config = item['config']

            app = "None"
            try:
                app = atv.metadata.app.name
                # print(app)
            except Exception:
                app = "None"
           
            power = atv.power.power_state == PowerState.On
            playing = await atv.metadata.playing()
            o = {
                "power": power,
                "app": app,
                "mediaType": convert.media_type_str(playing.media_type),
                "deviceState": convert.device_state_str(playing.device_state),
                "title": playing.title,
                "artist": playing.artist,
                "album": playing.album,
                "genre": playing.genre,
                "position": playing.position,
                "total_time": playing.total_time,
                "repeat": convert.repeat_str(playing.repeat),
                "shuffle": convert.shuffle_str(playing.shuffle),
            }

            if o != config['state']:
                 MQTT.publish("info", json.dumps(o), retain=True)

            artwork = await atv.metadata.artwork(300, 300)
            if artwork:
                try:
                    tmp_filename = "/tmp/{}".format(name)
                    file = open(tmp_filename, "wb")
                    file.write(artwork.bytes)
                    file.close()

                    file = open(tmp_filename, "rb")
                    image_data_binary = file.read()
                    file.close()
                    try:
                        os.remove(tmp_filename)
                    finally:
                        pass

                    artwork = base64.b64encode(image_data_binary).decode("ascii")

                except Exception as err:
                    artwork = None

            o['artwork'] = artwork
            for attr, value in o.items():
#                 print("attr", attr, "value", value, config['state'][attr])
                if value != config["state"][attr]:
                    topic = "appletv/{}/status/{}".format(config['device'], attr)
                    if  device.name == "Office":
                        print(device.name, "publish", topic, value)
                    config['state'][attr] = o[attr]
                    MQTT.publish(topic, value, retain=True)

        await asyncio.sleep(1)
Esempio n. 12
0
 def test_playing_media_type_and_playstate(self):
     out = str(PlayingDummy())
     self.assertIn(convert.media_type_str(MediaType.Video), out)
     self.assertIn(convert.device_state_str(DeviceState.Playing), out)
Esempio n. 13
0
 def test_unknown_media_type_to_str(self):
     self.assertEqual('Unsupported', convert.media_type_str(999))
Esempio n. 14
0
def test_media_type_to_string():
    assert "Unknown" == convert.media_type_str(MediaType.Unknown)
    assert "Video" == convert.media_type_str(MediaType.Video)
    assert "Music" == convert.media_type_str(MediaType.Music)
    assert "TV" == convert.media_type_str(MediaType.TV)
Esempio n. 15
0
def test_unknown_media_type_to_str():
    assert "Unsupported" == convert.media_type_str(999)
Esempio n. 16
0
 def test_media_type_to_string(self):
     self.assertEqual("Unknown", convert.media_type_str(MediaType.Unknown))
     self.assertEqual("Video", convert.media_type_str(MediaType.Video))
     self.assertEqual("Music", convert.media_type_str(MediaType.Music))
     self.assertEqual("TV", convert.media_type_str(MediaType.TV))