Exemple #1
0
async def async_setup_entry(hass, config):
    """Set up a config entry."""
    from hangups.auth import GoogleAuthError

    try:
        from .hangouts_bot import HangoutsBot

        bot = HangoutsBot(
            hass,
            config.data.get(CONF_REFRESH_TOKEN),
            hass.data[DOMAIN][CONF_INTENTS],
            hass.data[DOMAIN][CONF_DEFAULT_CONVERSATIONS],
            hass.data[DOMAIN][CONF_ERROR_SUPPRESSED_CONVERSATIONS],
        )
        hass.data[DOMAIN][CONF_BOT] = bot
    except GoogleAuthError as exception:
        _LOGGER.error("Hangouts failed to log in: %s", str(exception))
        return False

    dispatcher.async_dispatcher_connect(
        hass, EVENT_HANGOUTS_CONNECTED,
        bot.async_handle_update_users_and_conversations)

    dispatcher.async_dispatcher_connect(hass,
                                        EVENT_HANGOUTS_CONVERSATIONS_CHANGED,
                                        bot.async_resolve_conversations)

    dispatcher.async_dispatcher_connect(
        hass,
        EVENT_HANGOUTS_CONVERSATIONS_RESOLVED,
        bot.async_update_conversation_commands,
    )

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                               bot.async_handle_hass_stop)

    await bot.async_connect()

    hass.services.async_register(
        DOMAIN,
        SERVICE_SEND_MESSAGE,
        bot.async_handle_send_message,
        schema=MESSAGE_SCHEMA,
    )
    hass.services.async_register(
        DOMAIN,
        SERVICE_UPDATE,
        bot.async_handle_update_users_and_conversations,
        schema=vol.Schema({}),
    )

    hass.services.async_register(DOMAIN,
                                 SERVICE_RECONNECT,
                                 bot.async_handle_reconnect,
                                 schema=vol.Schema({}))

    intent.async_register(hass, HelpIntent(hass))

    return True
def async_setup(hass, config):
    """Initialize the shopping list."""
    @asyncio.coroutine
    def add_item_service(call):
        """Add an item with `name`."""
        data = hass.data[DOMAIN]
        name = call.data.get(ATTR_NAME)
        if name is not None:
            data.async_add(name)

    @asyncio.coroutine
    def complete_item_service(call):
        """Mark the item provided via `name` as completed."""
        data = hass.data[DOMAIN]
        name = call.data.get(ATTR_NAME)
        if name is None:
            return
        try:
            item = [item for item in data.items if item['name'] == name][0]
        except IndexError:
            _LOGGER.error("Removing of item failed: %s cannot be found", name)
        else:
            data.async_update(item['id'], {'name': name, 'complete': True})

    data = hass.data[DOMAIN] = ShoppingData(hass)
    yield from data.async_load()

    intent.async_register(hass, AddItemIntent())
    intent.async_register(hass, ListTopItemsIntent())

    hass.services.async_register(DOMAIN,
                                 SERVICE_ADD_ITEM,
                                 add_item_service,
                                 schema=SERVICE_ITEM_SCHEMA)
    hass.services.async_register(DOMAIN,
                                 SERVICE_COMPLETE_ITEM,
                                 complete_item_service,
                                 schema=SERVICE_ITEM_SCHEMA)

    hass.http.register_view(ShoppingListView)
    hass.http.register_view(CreateShoppingListItemView)
    hass.http.register_view(UpdateShoppingListItemView)
    hass.http.register_view(ClearCompletedItemsView)

    hass.components.conversation.async_register(INTENT_ADD_ITEM, [
        'Add [the] [a] [an] {item} to my shopping list',
    ])
    hass.components.conversation.async_register(
        INTENT_LAST_ITEMS, ['What is on my shopping list'])

    yield from hass.components.frontend.async_register_built_in_panel(
        'shopping-list', 'shopping_list', 'mdi:cart')

    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_ITEMS, websocket_handle_items,
        SCHEMA_WEBSOCKET_ITEMS)

    return True
Exemple #3
0
async def async_setup_entry(hass, config):
    """Set up a config entry."""
    from hangups.auth import GoogleAuthError

    try:
        from .hangouts_bot import HangoutsBot

        bot = HangoutsBot(
            hass,
            config.data.get(CONF_REFRESH_TOKEN),
            hass.data[DOMAIN][CONF_INTENTS],
            hass.data[DOMAIN][CONF_DEFAULT_CONVERSATIONS],
            hass.data[DOMAIN][CONF_ERROR_SUPPRESSED_CONVERSATIONS])
        hass.data[DOMAIN][CONF_BOT] = bot
    except GoogleAuthError as exception:
        _LOGGER.error("Hangouts failed to log in: %s", str(exception))
        return False

    dispatcher.async_dispatcher_connect(
        hass,
        EVENT_HANGOUTS_CONNECTED,
        bot.async_handle_update_users_and_conversations)

    dispatcher.async_dispatcher_connect(
        hass,
        EVENT_HANGOUTS_CONVERSATIONS_CHANGED,
        bot.async_resolve_conversations)

    dispatcher.async_dispatcher_connect(
        hass,
        EVENT_HANGOUTS_CONVERSATIONS_RESOLVED,
        bot.async_update_conversation_commands)

    hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP,
                               bot.async_handle_hass_stop)

    await bot.async_connect()

    hass.services.async_register(DOMAIN, SERVICE_SEND_MESSAGE,
                                 bot.async_handle_send_message,
                                 schema=MESSAGE_SCHEMA)
    hass.services.async_register(DOMAIN,
                                 SERVICE_UPDATE,
                                 bot.
                                 async_handle_update_users_and_conversations,
                                 schema=vol.Schema({}))

    hass.services.async_register(DOMAIN,
                                 SERVICE_RECONNECT,
                                 bot.
                                 async_handle_reconnect,
                                 schema=vol.Schema({}))

    intent.async_register(hass, HelpIntent(hass))

    return True
Exemple #4
0
async def test_http_processing_intent(hass, hass_client, hass_admin_user):
    """Test processing intent via HTTP API."""
    class TestIntentHandler(intent.IntentHandler):
        """Test Intent Handler."""

        intent_type = "OrderBeer"

        async def async_handle(self, intent):
            """Handle the intent."""
            assert intent.context.user_id == hass_admin_user.id
            response = intent.create_response()
            response.async_set_speech("I've ordered a {}!".format(
                intent.slots["type"]["value"]))
            response.async_set_card(
                "Beer ordered",
                "You chose a {}.".format(intent.slots["type"]["value"]))
            return response

    intent.async_register(hass, TestIntentHandler())

    result = await async_setup_component(
        hass,
        "conversation",
        {
            "conversation": {
                "intents": {
                    "OrderBeer": ["I would like the {type} beer"]
                }
            }
        },
    )
    assert result

    client = await hass_client()
    resp = await client.post("/api/conversation/process",
                             json={"text": "I would like the Grolsch beer"})

    assert resp.status == HTTPStatus.OK
    data = await resp.json()

    assert data == {
        "card": {
            "simple": {
                "content": "You chose a Grolsch.",
                "title": "Beer ordered"
            }
        },
        "speech": {
            "plain": {
                "extra_data": None,
                "speech": "I've ordered a Grolsch!"
            }
        },
    }
Exemple #5
0
async def async_setup_intents(hass: HomeAssistant) -> None:
    """Set up the cover intents."""
    intent.async_register(
        hass,
        intent.ServiceIntentHandler(INTENT_OPEN_COVER, DOMAIN,
                                    SERVICE_OPEN_COVER, "Opened {}"),
    )
    intent.async_register(
        hass,
        intent.ServiceIntentHandler(INTENT_CLOSE_COVER, DOMAIN,
                                    SERVICE_CLOSE_COVER, "Closed {}"),
    )
Exemple #6
0
async def async_setup(hass, config):
    """Activate Alexa component."""
    intents = copy.deepcopy(config[DOMAIN])
    template.attach(hass, intents)

    for intent_type, conf in intents.items():
        if CONF_ACTION in conf:
            conf[CONF_ACTION] = script.Script(hass, conf[CONF_ACTION],
                                              f"Intent Script {intent_type}")
        intent.async_register(hass, ScriptIntentHandler(intent_type, conf))

    return True
def async_setup(hass, config):
    """Activate Alexa component."""
    intents = copy.deepcopy(config[DOMAIN])
    template.attach(hass, intents)

    for intent_type, conf in intents.items():
        if CONF_ACTION in conf:
            conf[CONF_ACTION] = script.Script(
                hass, conf[CONF_ACTION],
                "Intent Script {}".format(intent_type))
        intent.async_register(hass, ScriptIntentHandler(intent_type, conf))

    return True
Exemple #8
0
async def test_http_processing_intent(hass, hass_client):
    """Test processing intent via HTTP API."""
    class TestIntentHandler(intent.IntentHandler):
        """Test Intent Handler."""

        intent_type = 'OrderBeer'

        async def async_handle(self, intent):
            """Handle the intent."""
            response = intent.create_response()
            response.async_set_speech(
                "I've ordered a {}!".format(intent.slots['type']['value']))
            response.async_set_card(
                "Beer ordered",
                "You chose a {}.".format(intent.slots['type']['value']))
            return response

    intent.async_register(hass, TestIntentHandler())

    result = await async_setup_component(hass, 'conversation', {
        'conversation': {
            'intents': {
                'OrderBeer': [
                    'I would like the {type} beer'
                ]
            }
        }
    })
    assert result

    client = await hass_client()
    resp = await client.post('/api/conversation/process', json={
        'text': 'I would like the Grolsch beer'
    })

    assert resp.status == 200
    data = await resp.json()

    assert data == {
        'card': {
            'simple': {
                'content': 'You chose a Grolsch.',
                'title': 'Beer ordered'
            }},
        'speech': {
            'plain': {
                'extra_data': None,
                'speech': "I've ordered a Grolsch!"
            }
        }
    }
async def test_http_processing_intent(hass, aiohttp_client):
    """Test processing intent via HTTP API."""
    class TestIntentHandler(intent.IntentHandler):
        """Test Intent Handler."""

        intent_type = 'OrderBeer'

        async def async_handle(self, intent):
            """Handle the intent."""
            response = intent.create_response()
            response.async_set_speech(
                "I've ordered a {}!".format(intent.slots['type']['value']))
            response.async_set_card(
                "Beer ordered",
                "You chose a {}.".format(intent.slots['type']['value']))
            return response

    intent.async_register(hass, TestIntentHandler())

    result = await async_setup_component(hass, 'conversation', {
        'conversation': {
            'intents': {
                'OrderBeer': [
                    'I would like the {type} beer'
                ]
            }
        }
    })
    assert result

    client = await aiohttp_client(hass.http.app)
    resp = await client.post('/api/conversation/process', json={
        'text': 'I would like the Grolsch beer'
    })

    assert resp.status == 200
    data = await resp.json()

    assert data == {
        'card': {
            'simple': {
                'content': 'You chose a Grolsch.',
                'title': 'Beer ordered'
            }},
        'speech': {
            'plain': {
                'extra_data': None,
                'speech': "I've ordered a Grolsch!"
            }
        }
    }
async def test_http_handle_intent(hass, hass_client, hass_admin_user):
    """Test handle intent via HTTP API."""
    class TestIntentHandler(intent.IntentHandler):
        """Test Intent Handler."""

        intent_type = "OrderBeer"

        async def async_handle(self, intent):
            """Handle the intent."""
            assert intent.context.user_id == hass_admin_user.id
            response = intent.create_response()
            response.async_set_speech("I've ordered a {}!".format(
                intent.slots["type"]["value"]))
            response.async_set_card(
                "Beer ordered",
                "You chose a {}.".format(intent.slots["type"]["value"]))
            return response

    intent.async_register(hass, TestIntentHandler())

    result = await async_setup_component(hass, "intent", {})
    assert result

    client = await hass_client()
    resp = await client.post("/api/intent/handle",
                             json={
                                 "name": "OrderBeer",
                                 "data": {
                                     "type": "Belgian"
                                 }
                             })

    assert resp.status == 200
    data = await resp.json()

    assert data == {
        "card": {
            "simple": {
                "content": "You chose a Belgian.",
                "title": "Beer ordered"
            }
        },
        "speech": {
            "plain": {
                "extra_data": None,
                "speech": "I've ordered a Belgian!"
            }
        },
    }
Exemple #11
0
def async_mock_intent(hass, intent_typ):
    """Set up a fake intent handler."""
    intents = []

    class MockIntentHandler(intent.IntentHandler):
        intent_type = intent_typ

        async def async_handle(self, intent):
            """Handle the intent."""
            intents.append(intent)
            return intent.create_response()

    intent.async_register(hass, MockIntentHandler())

    return intents
Exemple #12
0
def async_mock_intent(hass, intent_typ):
    """Set up a fake intent handler."""
    intents = []

    class MockIntentHandler(intent.IntentHandler):
        intent_type = intent_typ

        @asyncio.coroutine
        def async_handle(self, intent):
            """Handle the intent."""
            intents.append(intent)
            return intent.create_response()

    intent.async_register(hass, MockIntentHandler())

    return intents
Exemple #13
0
async def test_snips_service_intent(hass):
    """Test ServiceIntentHandler via Snips."""
    await async_mock_mqtt_component(hass)

    hass.states.async_set('light.kitchen', 'off')
    calls = async_mock_service(hass, 'light', 'turn_on')
    result = await async_setup_component(hass, "snips", {
        "snips": {},
    })
    assert result
    payload = """
    {
        "input": "turn the light on",
        "intent": {
            "intentName": "Lights",
            "confidenceScore": 0.85
        },
        "siteId": "default",
        "slots": [
            {
                "slotName": "name",
                "value": {
                    "kind": "Custom",
                    "value": "kitchen"
                },
                "rawValue": "green"
            }
        ]
    }
    """

    async_register(hass, ServiceIntentHandler(
        "Lights", "light", 'turn_on', "Turned {} on"))

    async_fire_mqtt_message(hass, 'hermes/intent/Lights',
                            payload)
    await hass.async_block_till_done()

    assert len(calls) == 1
    assert calls[0].domain == 'light'
    assert calls[0].service == 'turn_on'
    assert calls[0].data['entity_id'] == 'light.kitchen'
    assert 'confidenceScore' not in calls[0].data
    assert 'site_id' not in calls[0].data
def async_setup(hass, config):
    """Initialize the shopping list."""
    data = hass.data[DOMAIN] = ShoppingData(hass)
    yield from data.async_load()

    intent.async_register(hass, AddItemIntent())
    intent.async_register(hass, ListTopItemsIntent())

    hass.http.register_view(ShoppingListView)
    hass.http.register_view(UpdateShoppingListItemView)
    hass.http.register_view(ClearCompletedItemsView)

    hass.components.conversation.async_register(INTENT_ADD_ITEM, [
        'Add {item} to my shopping list',
    ])
    hass.components.conversation.async_register(
        INTENT_LAST_ITEMS, ['What is on my shopping list'])

    yield from hass.components.frontend.async_register_built_in_panel(
        'shopping-list', 'shopping_list', 'mdi:cart')

    return True
def async_setup(hass, config):
    """Initialize the shopping list."""
    data = hass.data[DOMAIN] = ShoppingData(hass)
    yield from data.async_load()

    intent.async_register(hass, AddItemIntent())
    intent.async_register(hass, ListTopItemsIntent())

    hass.http.register_view(ShoppingListView)
    hass.http.register_view(UpdateShoppingListItemView)
    hass.http.register_view(ClearCompletedItemsView)

    hass.components.conversation.async_register(INTENT_ADD_ITEM, [
        'Add {item} to my shopping list',
    ])
    hass.components.conversation.async_register(INTENT_LAST_ITEMS, [
        'What is on my shopping list'
    ])

    hass.components.frontend.register_built_in_panel(
        'shopping-list', 'Shopping List', 'mdi:cart')

    return True
Exemple #16
0
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """Set up the Intent component."""
    hass.http.register_view(IntentHandleView())

    await integration_platform.async_process_integration_platforms(
        hass, DOMAIN, _async_process_intent)

    intent.async_register(
        hass,
        intent.ServiceIntentHandler(intent.INTENT_TURN_ON, HA_DOMAIN,
                                    SERVICE_TURN_ON, "Turned {} on"),
    )
    intent.async_register(
        hass,
        intent.ServiceIntentHandler(intent.INTENT_TURN_OFF, HA_DOMAIN,
                                    SERVICE_TURN_OFF, "Turned {} off"),
    )
    intent.async_register(
        hass,
        intent.ServiceIntentHandler(intent.INTENT_TOGGLE, HA_DOMAIN,
                                    SERVICE_TOGGLE, "Toggled {}"),
    )

    return True
Exemple #17
0
def async_setup(hass, config):
    """Initialize the ais bookmarks list."""
    @asyncio.coroutine
    def add_bookmark_service(call):
        """Add an current played item to bookmark"""
        d = hass.data[DOMAIN]
        d.async_add(call, True)

    @asyncio.coroutine
    def add_favorite_service(call):
        """Add an current played item to favorite."""
        d = hass.data[DOMAIN]
        d.async_add(call, False)

    @asyncio.coroutine
    def get_bookmarks_service(call):
        """Return the list of bookmarks to app list"""
        d = hass.data[DOMAIN]
        list_info = {}
        list_idx = 0
        for item in reversed(d.bookmarks):
            if "media_stream_image" in item and item[
                    "media_stream_image"] is not None:
                img = item["media_stream_image"]
            else:
                img = "/static/icons/tile-win-310x150.png"
            list_info[list_idx] = {}
            list_info[list_idx]["title"] = item["name"]
            if item["name"].startswith(item["source"]):
                list_info[list_idx]["name"] = item["name"]
            else:
                list_info[list_idx]["name"] = (
                    ais_global.G_NAME_FOR_AUDIO_NATURE.get(
                        item["source"], item["source"]) + " " + item["name"])
            list_info[list_idx]["thumbnail"] = img
            list_info[list_idx]["uri"] = item["media_content_id"]
            list_info[list_idx]["audio_type"] = item["source"]
            list_info[list_idx]["media_source"] = item["source"]
            list_info[list_idx]["icon"] = "mdi:bookmark-music"
            list_info[list_idx]["icon_remove"] = "mdi:delete-forever"
            list_info[list_idx]["editable"] = True
            list_info[list_idx]["id"] = item["id"]
            list_info[list_idx][
                "media_position"] = ais_global.get_milliseconds_formated(
                    item["media_position"])
            list_info[list_idx]["media_position_ms"] = item["media_position"]
            list_idx = list_idx + 1
        # create lists
        hass.states.async_set("sensor.aisbookmarkslist", -1, list_info)

    @asyncio.coroutine
    def get_favorites_service(call):
        """Return the list of favorites to app list"""
        audio_source = None
        if "audio_source" in call.data:
            audio_source = call.data["audio_source"]

        d = hass.data[DOMAIN]
        list_info = {}
        list_idx = 0
        for item in reversed(d.favorites):
            if audio_source is None or audio_source == item["source"]:
                if ("media_stream_image" in item
                        and item["media_stream_image"] is not None):
                    img = item["media_stream_image"]
                else:
                    img = "/static/icons/tile-win-310x150.png"
                list_info[list_idx] = {}
                list_info[list_idx]["title"] = item["name"]
                if item["name"].startswith(item["source"]):
                    list_info[list_idx]["name"] = item["name"]
                else:
                    list_info[list_idx]["name"] = (
                        ais_global.G_NAME_FOR_AUDIO_NATURE.get(
                            item["source"], item["source"]) + " " +
                        item["name"])
                list_info[list_idx]["thumbnail"] = img
                list_info[list_idx]["uri"] = item["media_content_id"]
                list_info[list_idx]["audio_type"] = item["source"]
                list_info[list_idx][
                    "icon_type"] = ais_global.G_ICON_FOR_AUDIO.get(
                        item["source"], "mdi:play")
                list_info[list_idx]["icon_remove"] = "mdi:delete-forever"
                list_info[list_idx]["editable"] = True
                if audio_source == ais_global.G_AN_PODCAST:
                    list_info[list_idx]["icon"] = "mdi:podcast"
                else:
                    list_info[list_idx]["icon"] = "mdi:play"
                list_info[list_idx]["id"] = item["id"]
                list_idx = list_idx + 1

        # create lists
        if audio_source is None:
            # get all items
            hass.states.async_set("sensor.aisfavoriteslist", -1, list_info)
        else:
            # check if the change was done form remote
            import homeassistant.components.ais_ai_service as ais_ai

            if audio_source == ais_global.G_AN_RADIO:
                hass.states.async_set("sensor.radiolist", -1, list_info)
                if (ais_ai.CURR_ENTITIE == "input_select.radio_type"
                        and ais_ai.CURR_BUTTON_CODE == 23):
                    ais_ai.set_curr_entity(hass, "sensor.radiolist")
                    hass.async_add_job(
                        hass.services.async_call("ais_ai_service", "say_it",
                                                 {"text": "Wybierz stację"}))
            elif audio_source == ais_global.G_AN_PODCAST:
                hass.states.async_set("sensor.podcastnamelist", -1, list_info)
                if (ais_ai.CURR_ENTITIE == "input_select.podcast_type"
                        and ais_ai.CURR_BUTTON_CODE == 23):
                    ais_ai.set_curr_entity(hass, "sensor.podcastnamelist")
                    hass.async_add_job(
                        hass.services.async_call("ais_ai_service", "say_it",
                                                 {"text": "Wybierz audycję"}))
            elif audio_source == ais_global.G_AN_MUSIC:
                hass.states.async_set("sensor.youtubelist", -1, list_info)
            elif audio_source == ais_global.G_AN_SPOTIFY:
                hass.states.async_set("sensor.spotifylist", -1, list_info)
            elif audio_source == ais_global.G_AN_AUDIOBOOK:
                hass.states.async_set("sensor.audiobookschapterslist", -1,
                                      list_info)

    @asyncio.coroutine
    def play_bookmark_service(call):
        """Play selected bookmark"""
        bookmark_id = int(call.data.get("id"))
        # get item from list
        state = hass.states.get("sensor.aisbookmarkslist")
        attr = state.attributes
        track = attr.get(bookmark_id)

        #
        if track["media_source"] == ais_global.G_AN_LOCAL:
            last_slash = track["uri"].rfind("/")
            if last_slash > 0:
                dir_path = track["uri"][0:last_slash]
            else:
                dir_path = track["uri"]
            hass.async_add_job(
                hass.services.async_call(
                    "ais_drives_service",
                    "browse_path",
                    {
                        "path": dir_path,
                        "file_path": track["uri"],
                        "seek_position": track["media_position_ms"],
                    },
                ))

        elif track["media_source"] == ais_global.G_AN_MUSIC:
            hass.async_add_job(
                hass.services.async_call(
                    "ais_yt_service",
                    "select_track_uri",
                    {
                        "id": bookmark_id,
                        "media_source": ais_global.G_AN_BOOKMARK
                    },
                ))
        else:
            _audio_info = json.dumps({
                "IMAGE_URL":
                track["thumbnail"],
                "NAME":
                track["title"],
                "audio_type":
                track["audio_type"],
                "MEDIA_SOURCE":
                track["media_source"],
                "media_content_id":
                track["uri"],
                "media_position_ms":
                track["media_position_ms"],
            })
            # set stream uri, image and title
            hass.async_add_job(
                hass.services.async_call(
                    "media_player",
                    "play_media",
                    {
                        "entity_id": ais_global.G_LOCAL_EXO_PLAYER_ENTITY_ID,
                        "media_content_type": "ais_content_info",
                        "media_content_id": _audio_info,
                    },
                ))

    @asyncio.coroutine
    def play_favorite_service(call):
        """Play selected favorite"""
        favorite_id = int(call.data.get("id"))
        # get item from list
        state = hass.states.get("sensor.aisfavoriteslist")
        attr = state.attributes
        track = attr.get(favorite_id)

        _audio_info = json.dumps({
            "IMAGE_URL": track["thumbnail"],
            "NAME": track["title"],
            "audio_type": track["audio_type"],
            "MEDIA_SOURCE": ais_global.G_AN_FAVORITE,
            "media_content_id": track["uri"],
        })
        # set stream uri, image and title
        hass.async_add_job(
            hass.services.async_call(
                "media_player",
                "play_media",
                {
                    "entity_id": ais_global.G_LOCAL_EXO_PLAYER_ENTITY_ID,
                    "media_content_type": "ais_content_info",
                    "media_content_id": _audio_info,
                },
            ))

    @asyncio.coroutine
    def delete_bookmark_service(call):
        """Delete selected bookmark"""
        bookmark_id = int(call.data.get("id"))
        state = hass.states.get("sensor.aisbookmarkslist")
        attr = state.attributes
        track = attr.get(bookmark_id)
        d = hass.data[DOMAIN]
        d.async_remove_bookmark(track["id"], True)

    @asyncio.coroutine
    def delete_favorite_service(call):
        """Delete selected favorite"""
        favorite_id = int(call.data.get("id"))
        state = hass.states.get("sensor.aisfavoriteslist")
        attr = state.attributes
        track = attr.get(favorite_id)
        d = hass.data[DOMAIN]
        d.async_remove_bookmark(track["id"], False)

    data = hass.data[DOMAIN] = BookmarksData(hass)
    intent.async_register(hass, AddFavoriteIntent())
    intent.async_register(hass, AddBookmarkIntent())
    intent.async_register(hass, ListTopBookmarkIntent())
    intent.async_register(hass, PlayLastBookmarkIntent())
    hass.services.async_register(DOMAIN, SERVICE_ADD_BOOKMARK,
                                 add_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_ADD_FAVORITE,
                                 add_favorite_service)
    hass.services.async_register(DOMAIN, SERVICE_GET_BOOKMARKS,
                                 get_bookmarks_service)
    hass.services.async_register(DOMAIN, SERVICE_GET_FAVORITES,
                                 get_favorites_service)
    hass.services.async_register(DOMAIN, SERVICE_PLAY_BOOKMARK,
                                 play_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_PLAY_FAVORITE,
                                 play_favorite_service)
    hass.services.async_register(DOMAIN, SERVICE_DELETE_BOOKMARK,
                                 delete_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_DELETE_FAVORITE,
                                 delete_favorite_service)

    hass.components.conversation.async_register(
        INTENT_ADD_FAVORITE,
        ["Dodaj do ulubionych", "Do ulubionych", "Lubię to"])
    hass.components.conversation.async_register(INTENT_ADD_BOOKMARK,
                                                ["Dodaj zakładkę", "Zakładka"])
    hass.components.conversation.async_register(
        INTENT_LAST_BOOKMARKS, ["Jakie mam zakładki", "Jakie są zakładki"])
    hass.components.conversation.async_register(
        INTENT_PLAY_LAST_BOOKMARK,
        ["Włącz ostatnią zakładkę", "Włącz zakładkę", "Ostatnia zakładka"],
    )

    yield from data.async_load()

    hass.states.async_set("sensor.aisbookmarkslist", -1, {})
    hass.states.async_set("sensor.aisfavoriteslist", -1, {})

    return True
def async_setup(hass, config):
    """Initialize the ais bookmarks list."""
    @asyncio.coroutine
    def add_bookmark_service(call):
        """Add an current played item to bookmark"""
        d = hass.data[DOMAIN]
        attr = call.data.get("attr")
        if attr is not None:
            d.async_add(attr, True)

    @asyncio.coroutine
    def add_favorite_service(call):
        """Add an current played item to favorite."""
        d = hass.data[DOMAIN]
        attr = call.data.get("attr")
        if attr is not None:
            d.async_add(attr, False)

    @asyncio.coroutine
    def get_bookmarks_service(call):
        """Return the list of bookmarks to app LOV"""
        d = hass.data[DOMAIN]
        lv_options = [ais_global.G_EMPTY_OPTION]
        for item in reversed(d.bookmarks):
            lv_options.append(item['source'] + '; ' + item['name'])
        hass.async_add_job(
            hass.services.async_call(
                'input_select', 'set_options', {
                    "entity_id": "input_select.ais_bookmark_last_played",
                    "options": lv_options
                }))

    @asyncio.coroutine
    def get_favorites_service(call):
        """Return the list of favorites to app LOV"""
        d = hass.data[DOMAIN]
        lv_options = [ais_global.G_EMPTY_OPTION]
        for item in reversed(d.favorites):
            lv_options.append(item['source'] + '; ' + item['name'])
        hass.async_add_job(
            hass.services.async_call(
                'input_select', 'set_options', {
                    "entity_id": "input_select.ais_bookmark_favorites",
                    "options": lv_options
                }))

    @asyncio.coroutine
    def play_bookmark_service(call):
        """Play selected bookmark"""
        bookmark = call.data.get("bookmark")
        d = hass.data[DOMAIN]
        name = bookmark.split(';', 1)[1].strip()
        album = bookmark.split(';', 1)[0].strip()
        item = next((itm for itm in d.bookmarks
                     if (itm['name'] == name and itm['source'] == album)),
                    None)
        if item is not None:
            # set the global bookmark
            ais_global.set_media_bookmark(item['media_content_id'],
                                          item['media_position'])
            hass.async_add_job(
                hass.services.async_call(
                    'input_select', 'set_options', {
                        "entity_id": "input_select.folder_name",
                        "options": item['options']
                    }))
            hass.async_add_job(
                hass.services.async_call(
                    'input_select', 'select_option', {
                        "entity_id": "input_select.folder_name",
                        "option": item['option']
                    }))
            # call without a services to avoid the double automation trigger
            # hass.states.async_set('input_select.folder_name',
            #                       item['option'],
            #                       {"options": item['options'],
            #                        "friendly_name": "Przeglądaj",
            #                        "icon": "mdi:folder-search"},
            #                        force_update=True)
            # else:
            #     hass.async_add_job(
            #         hass.services.async_call(
            #             'media_player',
            #             'play_media', {
            #                 "entity_id": "media_player.wbudowany_glosnik",
            #                 "media_content_type": "audio/mp4",
            #                 "media_content_id": item['media_content_id']
            #             })
            #     )
            #     _audio_info = json.dumps(
            #         {"IMAGE_URL": item["media_stream_image"], "NAME": item['name'], "MEDIA_SOURCE": item['source']}
            #     )
            #     # set stream image and title
            #     hass.async_add_job(
            #         hass.services.async_call(
            #             'media_player',
            #             'play_media', {
            #                 "entity_id": "media_player.wbudowany_glosnik",
            #                 "media_content_type": "ais_info",
            #                 "media_content_id": _audio_info
            #             })
            #     )
            #
            #     hass.async_add_job(
            #         hass.services.async_call(
            #             'media_player',
            #             'media_seek', {
            #                 "entity_id": "media_player.wbudowany_glosnik",
            #                 "seek_position": item['media_position']
            #             })
            #     )
    @asyncio.coroutine
    def play_favorite_service(call):
        """Play selected favorite"""
        favorite = call.data.get("favorite")
        d = hass.data[DOMAIN]
        name = favorite.split(';', 1)[1].strip()
        source = favorite.split(';', 1)[0].strip()
        item = next((itm for itm in d.favorites
                     if (itm['name'] == name and itm['source'] == source)),
                    None)
        if item is not None:
            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'play_media', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "media_content_type": "audio/mp4",
                        "media_content_id": item['media_content_id']
                    }))
            _audio_info = json.dumps({
                "IMAGE_URL": item["media_stream_image"],
                "NAME": item['name'],
                "MEDIA_SOURCE": item['source']
            })
            # set stream image and title
            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'play_media', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "media_content_type": "ais_info",
                        "media_content_id": _audio_info
                    }))

    data = hass.data[DOMAIN] = BookmarksData(hass)
    intent.async_register(hass, AddFavoriteIntent())
    intent.async_register(hass, ListTopBookmarkIntent())
    intent.async_register(hass, PlayLastBookmarkIntent())
    hass.services.async_register(DOMAIN, SERVICE_ADD_BOOKMARK,
                                 add_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_ADD_FAVORITE,
                                 add_favorite_service)
    hass.services.async_register(DOMAIN, SERVICE_GET_BOOKMARKS,
                                 get_bookmarks_service)
    hass.services.async_register(DOMAIN, SERVICE_GET_FAVORITES,
                                 get_favorites_service)
    hass.services.async_register(DOMAIN, SERVICE_PLAY_BOOKMARK,
                                 play_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_PLAY_FAVORITE,
                                 play_favorite_service)

    hass.components.conversation.async_register(INTENT_ADD_FAVORITE, [
        'Dodaj do ulubionych',
        'Do ulubionych',
        'Lubię to',
    ])
    hass.components.conversation.async_register(
        INTENT_LAST_BOOKMARKS, ['Jakie mam zakładki', 'Jakie są zakładki'])
    hass.components.conversation.async_register(
        INTENT_PLAY_LAST_BOOKMARK,
        ['Włącz ostatnią zakładkę', 'Włącz zakładkę', 'Ostatnia zakładka'])

    yield from data.async_load()
    return True
Exemple #19
0
def async_setup(hass, config):
    """Initialize the shopping list."""
    @asyncio.coroutine
    def add_item_service(call):
        """Add an item with `name`."""
        data = hass.data[DOMAIN]
        name = call.data.get(ATTR_NAME)
        if name is not None:
            data.async_add(name)

    @asyncio.coroutine
    def complete_item_service(call):
        """Mark the item provided via `name` as completed."""
        data = hass.data[DOMAIN]
        name = call.data.get(ATTR_NAME)
        if name is None:
            return
        try:
            item = [item for item in data.items if item["name"] == name][0]
        except IndexError:
            _LOGGER.error("Removing of item failed: %s cannot be found", name)
        else:
            data.async_update(item["id"], {"name": name, "complete": True})

    data = hass.data[DOMAIN] = ShoppingData(hass)
    yield from data.async_load()

    intent.async_register(hass, AddItemIntent())
    intent.async_register(hass, ListTopItemsIntent())

    hass.services.async_register(DOMAIN,
                                 SERVICE_ADD_ITEM,
                                 add_item_service,
                                 schema=SERVICE_ITEM_SCHEMA)
    hass.services.async_register(DOMAIN,
                                 SERVICE_COMPLETE_ITEM,
                                 complete_item_service,
                                 schema=SERVICE_ITEM_SCHEMA)

    hass.http.register_view(ShoppingListView)
    hass.http.register_view(CreateShoppingListItemView)
    hass.http.register_view(UpdateShoppingListItemView)
    hass.http.register_view(ClearCompletedItemsView)

    hass.components.frontend.async_register_built_in_panel(
        "shopping-list", "shopping_list", "mdi:cart")

    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_ITEMS, websocket_handle_items,
        SCHEMA_WEBSOCKET_ITEMS)
    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_ADD_ITEM, websocket_handle_add,
        SCHEMA_WEBSOCKET_ADD_ITEM)
    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_UPDATE_ITEM,
        websocket_handle_update,
        SCHEMA_WEBSOCKET_UPDATE_ITEM,
    )
    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_CLEAR_ITEMS,
        websocket_handle_clear,
        SCHEMA_WEBSOCKET_CLEAR_ITEMS,
    )

    return True
Exemple #20
0
def async_setup(hass, config):
    """Initialize the shopping list."""

    intent.async_register(hass, ChangeLightState())

    return True
Exemple #21
0
async def async_setup_intents(hass):
    intent.async_register(hass, PlexAssistantIntent())
    hass.components.conversation.async_register(
        "Plex",
        ["Tell Plex to {command}", "{command} with Plex"],
    )
Exemple #22
0
async def async_setup_intents(hass: HomeAssistant) -> None:
    """Set up the light intents."""
    intent.async_register(hass, SetIntentHandler())
Exemple #23
0
def async_setup(hass, config):
    """Initialize the ais bookmarks list."""
    @asyncio.coroutine
    def add_bookmark_service(call):
        """Add an current played item to bookmark"""
        d = hass.data[DOMAIN]
        attr = call.data.get("attr")
        if attr is not None:
            d.async_add(attr, True)

    @asyncio.coroutine
    def add_favorite_service(call):
        """Add an current played item to favorite."""
        d = hass.data[DOMAIN]
        attr = call.data.get("attr")
        if attr is not None:
            d.async_add(attr, False)

    @asyncio.coroutine
    def get_bookmarks_service(call):
        """Return the list of bookmarks to app LOV"""
        d = hass.data[DOMAIN]
        lv_options = [ais_global.G_EMPTY_OPTION]
        for item in reversed(d.bookmarks):
            lv_options.append(item['source'] + '; ' + item['name'])
        hass.async_add_job(
            hass.services.async_call(
                'input_select', 'set_options', {
                    "entity_id": "input_select.ais_bookmark_last_played",
                    "options": lv_options
                }))

    @asyncio.coroutine
    def get_favorites_service(call):
        """Return the list of favorites to app LOV"""
        d = hass.data[DOMAIN]
        lv_options = [ais_global.G_EMPTY_OPTION]
        for item in reversed(d.favorites):
            lv_options.append(item['source'] + '; ' + item['name'])
        hass.async_add_job(
            hass.services.async_call(
                'input_select', 'set_options', {
                    "entity_id": "input_select.ais_bookmark_favorites",
                    "options": lv_options
                }))

    @asyncio.coroutine
    def play_bookmark_service(call):
        """Play selected bookmark"""
        bookmark = call.data.get("bookmark")
        d = hass.data[DOMAIN]
        name = bookmark.split(';', 1)[1].strip()
        source = bookmark.split(';', 1)[0].strip()
        item = next((itm for itm in d.bookmarks
                     if (itm['name'] == name and itm['source'] == source)),
                    None)
        if item is not None:
            if source == ais_global.G_AN_LOCAL:
                hass.async_add_job(
                    hass.services.async_call(
                        'input_select', 'set_options', {
                            "entity_id": "input_select.folder_name",
                            "options": item['options']
                        }))
                hass.async_add_job(
                    hass.services.async_call(
                        'input_select', 'select_option', {
                            "entity_id": "input_select.folder_name",
                            "option": item['option']
                        }))
            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'play_media', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "media_content_type": "audio/mp4",
                        "media_content_id": item['media_content_id']
                    }))
            _audio_info = json.dumps({
                "IMAGE_URL": item["media_stream_image"],
                "NAME": item['name'],
                "MEDIA_SOURCE": item['source']
            })
            # set stream image and title
            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'play_media', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "media_content_type": "ais_info",
                        "media_content_id": _audio_info
                    }))

            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'media_seek', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "seek_position": item['media_position']
                    }))
            # maybe we should remove bookmark if it was selected???
            # d.async_remove_bookmark(item['id'])
    @asyncio.coroutine
    def play_favorite_service(call):
        """Play selected favorite"""
        favorite = call.data.get("favorite")
        d = hass.data[DOMAIN]
        name = favorite.split(';', 1)[1].strip()
        source = favorite.split(';', 1)[0].strip()
        item = next((itm for itm in d.favorites
                     if (itm['name'] == name and itm['source'] == source)),
                    None)
        if item is not None:
            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'play_media', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "media_content_type": "audio/mp4",
                        "media_content_id": item['media_content_id']
                    }))
            _audio_info = json.dumps({
                "IMAGE_URL": item["media_stream_image"],
                "NAME": item['name'],
                "MEDIA_SOURCE": item['source']
            })
            # set stream image and title
            hass.async_add_job(
                hass.services.async_call(
                    'media_player', 'play_media', {
                        "entity_id": "media_player.wbudowany_glosnik",
                        "media_content_type": "ais_info",
                        "media_content_id": _audio_info
                    }))

    data = hass.data[DOMAIN] = BookmarksData(hass)
    intent.async_register(hass, AddFavoriteIntent())
    intent.async_register(hass, ListTopBookmarkIntent())
    hass.services.async_register(DOMAIN, SERVICE_ADD_BOOKMARK,
                                 add_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_ADD_FAVORITE,
                                 add_favorite_service)
    hass.services.async_register(DOMAIN, SERVICE_GET_BOOKMARKS,
                                 get_bookmarks_service)
    hass.services.async_register(DOMAIN, SERVICE_GET_FAVORITES,
                                 get_favorites_service)
    hass.services.async_register(DOMAIN, SERVICE_PLAY_BOOKMARK,
                                 play_bookmark_service)
    hass.services.async_register(DOMAIN, SERVICE_PLAY_FAVORITE,
                                 play_favorite_service)

    hass.components.conversation.async_register(INTENT_ADD_FAVORITE, [
        'Dodaj do ulubionych',
        'Do ulubionych',
        'Lubię to',
    ])
    hass.components.conversation.async_register(INTENT_LAST_BOOKMARKS,
                                                ['Jakie mam zakładki'])

    yield from data.async_load()
    return True
def setup(hass, config):

	base = {
		"jsonrpc": "2.0",
		"id": 1
	}
	
	audio_playlist = 0
	video_playlist = 1
	
	audio_player_type = 'audio'
	video_player_type = 'video'
	
	def wrap_payload(payload):
		d = payload.copy()
		d.update(base)
		return d
	
	def get_url(kodi_location=''):
		if kodi_location == 'bedroom':
			return 'http://192.168.1.4:8085' + '/jsonrpc'
		else:
			return 'http://192.168.1.17:8089' + '/jsonrpc'
			
	def get_entity(kodi_location=''):
		if kodi_location == 'bedroom':
			return 'media_player.bedroom'
		else:
			return 'media_player.downstairs'
	
	
	################## Find Players #######################
	def find_active_player(kodi_location):
		logger.info('Searching for an active player...')
		payload = {
			"method": "Player.GetActivePlayers"
		}
		resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
		code = resp.status_code
		if code != 200:
			logger.error('Received {} instead of 200'.format(str(code)))
		elif "error" in resp.json():
			logger.error('Received error response'.format(str(code)))
		else:
			players = resp.json()['result']
			
			for player in players:
				# only one audio or video player can be active at a time, but need to make sure we don't accidentally get a photo player
				if player['type'] in [audio_player_type, video_player_type]:
					playerid = player['playerid']
					the_type = player['type']
					logger.info('Active {} player found with id of {}'.format(the_type, str(playerid)))
					
					return the_type, playerid		
				
		logger.info('No active player found')
		return None	
	
	################## Media Info #######################
	def get_current_media_info(kodi_location):
		player_info = find_active_player(kodi_location)
		
		if player_info is not None:
			player_type, playerid = player_info
			logger.info('Attempting to retrieve info on current item for player with id of {}...'.format(str(playerid)))
			payload = {
				"method": "Player.GetProperties",
				"params": {
					"playerid": playerid,
					"properties": [
						"time",
						"totaltime"
					]
				}
			}
			resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
			code = resp.status_code
			if code != 200:
				logger.error('Received {} instead of 200'.format(str(code)))
			elif "error" in resp.json():
				logger.error('Received error response'.format(str(code)))
			else:
				result = resp.json()['result']
				t = result['time']
				current_time_seconds = t['seconds'] + t['minutes'] * 60 + t['hours'] * 3600
				t = result['totaltime']
				total_time_seconds = t['seconds'] + t['minutes'] * 60 + t['hours'] * 3600
				logger.info('Current time is {} seconds out of total time of {} seconds'.format(str(current_time_seconds), str(total_time_seconds)))
				return playerid, current_time_seconds, total_time_seconds
		
		return None
	
	################## Player Operations #######################
	def stop_active_player(kodi_location):
		player_info = find_active_player(kodi_location)
		
		if player_info is not None:
			player_type, playerid = player_info
			logger.info('Active {} player found with id of {} so attempting to stop it...'.format(player_type, str(playerid)))
			payload = {
				"method": "Player.Stop",
				"params": {
					"playerid": playerid
				}
			}
			resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
			code = resp.status_code
			if code != 200:
				logger.error('Received {} instead of 200'.format(str(code)))
			elif "error" in resp.json():
				logger.error('Received error response'.format(str(code)))
			else:
				logger.info('Active {} player with id of {} stopped successfully'.format(player_type, str(playerid)))
		
	def play_pause_active_player(kodi_location):
		player_info = find_active_player(kodi_location)
		
		if player_info is not None:
			player_type, playerid = player_info
			logger.info('Attempting to toggle the play/pause state for {} player with id of {}...'.format(player_type, str(playerid)))
			payload = {
				"method": "Player.PlayPause",
				"params": {
					"playerid": playerid
				}
			}
			resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
			code = resp.status_code
			if code != 200:
				logger.error('Received {} instead of 200'.format(str(code)))
			elif "error" in resp.json():
				logger.error('Received error response'.format(str(code)))
			else:
				logger.info('{} player with id of {} play/pause state successfully toggled'.format(player_type, str(playerid)))
	
		
	def go_to_within_track(kodi_location, time_hours=0, time_minutes=0, time_seconds=0):
		if time_hours == '':
			time_hours = 0
		if time_minutes == '':
			time_minutes = 0
		if time_seconds == '':
			time_seconds == 0
		time_seconds = int(time_seconds) + 60 * int(time_minutes) + 3600 * int(time_hours)
			
		resp = get_current_media_info(kodi_location)
		if resp is not None:
			player_type, playerid, current_time_seconds, total_time_seconds = resp
			
			if time_seconds < 0:
				time_seconds = 0
			elif time_seconds > total_time_seconds:
				time_seconds = total_time_seconds
				
				
			logger.info('Attempting to change time of current {} player with id of {} to {} seconds...'.format(player_type, str(playerid), str(time_seconds)))
			
			hours = 0
			minutes = 0
			seconds = 0
			
			if time_seconds > 59:
				minutes = int(time_seconds / 60)
				seconds = int(time_seconds) - (minutes * 60)
				
				if minutes > 59:
					hours = int(minutes / 60)
					minutes = minutes - (hours * 60)
			else:
				seconds = time_seconds
			
			payload = {
				"method": "Player.Seek",
				"params": {
					"playerid": playerid,
					"value": {
						"hours": hours,
						"minutes": minutes,
						"seconds": seconds
					}
				}
			}
			logger.info(payload)
			resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
			code = resp.status_code
			if code != 200:
				logger.error('Received {} instead of 200'.format(str(code)))
			elif "error" in resp.json():
				logger.error('Received error response')
				logger.error(resp.json())
			else:
				logger.info('Successfully changed time of {} player with id of {}'.format(player_type, str(playerid)))
			
		
	def seek_within_track(kodi_location, direction='forward', time_hours=0, time_minutes=0, time_seconds=0):
		if time_hours == '':
			time_hours = 0
		if time_minutes == '':
			time_minutes = 0
		if time_seconds == '':
			time_seconds == 0
		time_seconds = int(time_seconds) + 60 * int(time_minutes) + 3600 * int(time_hours)
		if direction.lower() == 'back':
			time_seconds = -1 * time_seconds
		
		resp = get_current_media_info(kodi_location)
		if resp is not None:
			player_type, playerid, current_time_seconds, total_time_seconds = resp
			logger.info('Attempting to change time for {} player with id of {} by {} seconds...'.format(player_type, str(playerid), str(time_seconds)))
			
			new_time = current_time_seconds + time_seconds
			go_to_within_track(kodi_location, time_seconds=new_time)
			
			
	def next_track(kodi_location):
		hass.services.call('media_player', 'media_next_track', {'entity_id': get_entity(kodi_location)})
		
	def prev_track(kodi_location):
		hass.services.call('media_player', 'media_previous_track', {'entity_id': get_entity(kodi_location)})
	
	################## Manage Playlist #######################
	def clear_playlist(kodi_location, playlist):
		logger.info('Attempting to clear existing playlist with id of {}...'.format(str(playlist)))
		payload = {
			"method": "Playlist.Clear",
			"params": {
				"playlistid": playlist
			}
		}
		resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
		code = resp.status_code
		if code != 200:
			logger.error('Received {} instead of 200'.format(str(code)))
		elif "error" in resp.json():
			logger.error('Received error response'.format(str(code)))
		else:
			logger.info('Playlist with id of {} cleared successfully'.format(str(playlist)))
			
			
	def add_item_to_playlist(kodi_location, playlist, item):
		logger.info('Adding {} to playlist with id of {}...'.format(item, str(playlist)))
		payload = {
			"method": "Playlist.Add",
			"params": {
				"playlistid": playlist,
				"item": {
					"file": item
				}
			}
		}
		resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
		code = resp.status_code
		if code != 200:
			logger.error('Received {} instead of 200'.format(str(code)))
		elif "error" in resp.json():
			logger.error('Received error response'.format(str(code)))
		else:
			logger.info('Item added successfully')


	def start_playing_playlist(kodi_location, playlist, shuffle=False):
		logger.info('Attempting to start playing playlist with id of {} in shuffle mode of {}...'.format(str(playlist), str(shuffle)))
		payload = {
			"method": "Player.Open",
			"params": {
				"item": {
					"playlistid": playlist
				},
				"options": {
					"shuffled": shuffle
				}
			}
		}
		resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
		code = resp.status_code
		if code != 200:
			logger.error('Received {} instead of 200'.format(str(code)))
		elif "error" in resp.json():
			logger.error('Received error response'.format(str(code)))
		else:
			logger.info('Playlist with id of {} is now playing'.format(str(playlist)))
			
	################## Search Libraries #######################
	def search_songs(kodi_location, kodi_song=None, kodi_artist=None, kodi_album=None):
		logger.info('Searching song database with arguments: kodi_song={}, kodi_artist={}, kodi_album={}...'.format(kodi_song, kodi_artist, kodi_album))
		and_list = []
		song_list = []
		if kodi_song is not None:
			d = {
				"field": "title",
				"value": kodi_song,
				"operator": "contains"
			}
			and_list.append(d)
			
		if kodi_artist is not None:
			d = {
				"field": "artist",
				"value": kodi_artist,
				"operator": "contains"
			}
			and_list.append(d)
			
		if kodi_album is not None:
			d = {
				"field": "album",
				"value": kodi_album,
				"operator": "contains"
			}
			and_list.append(d)
	
		# query audio library to find desired songs
		payload = {
			"method": "AudioLibrary.GetSongs",
			"params": {
				"properties": [
					"title",
					"artist",
					"album",
					"file",
					"track"
				],
				"filter": {
					"and": and_list
				}
			}
		}
		resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
		code = resp.status_code
		
		if code != 200:
			logger.error('Received {} instead of 200'.format(str(code)))
		elif "error" in resp.json():
			logger.error('Received error response'.format(str(code)))
		else:
			# sort the song list to be in correct album order
			try:
				unsorted_songs = resp.json()['result']['songs']
			except KeyError:
				unsorted_songs = []
				
			songs = sorted(unsorted_songs, key=lambda k: k['track'])
			logger.info('Search found {} songs that met criteria.'.format(str(len(songs))))

			for item in songs:
				song_list.append(item['file'])
				
		return song_list
		
	def search_videos(kodi_location, title):
		logger.info('Searching video database with arguments: title={}...'.format(title))
		and_list = []
		video_list = []
	
		d = {
			"field": "title",
			"value": title,
			"operator": "contains"
		}
		and_list.append(d)
			
		# query video library to find desired video
		payload = {
			"method": "VideoLibrary.GetMovies",
			"params": {
				"properties": [
					"title",
					"file"
				],
				"filter": {
					"and": and_list
				}
			}
		}
		resp = requests.post(get_url(kodi_location), json=wrap_payload(payload))
		code = resp.status_code
		
		if code != 200:
			logger.error('Received {} instead of 200'.format(str(code)))
		elif "error" in resp.json():
			logger.error('Received error response'.format(str(code)))
		else:
			# sort the song list to be in correct album order
			try:
				videos = resp.json()['result']['movies']
			except KeyError:
				videos = []
				
			logger.info('Search found {} videos that met criteria.'.format(str(len(videos))))

			for item in videos:
				video_list.append(item['file'])
				
		return video_list

	################################### Intent Handling ####################################
	class GenericIntentHandler(intent.IntentHandler):
		def random_response(self):
			responses = [
				"OK",
				"Sure",
				"If you insist",
				"Done",
				"No worries",
				"I can do that",
				"Leave it to me",
				"Consider it done",
				"As you wish",
				"By your command",
				"Affirmative",
				"Roger",
				"Right away",
				"No Problem",
				"Ten Four"
			]
			
			return random.choice(responses)
		
		def extract_location(self, intent_obj):
			logger.info(intent_obj.slots)
			
			if 'kodi_location' in intent_obj.slots:
				return intent_obj.slots['kodi_location']['value']
			else:
				return intent_obj.platform
			
	class PauseResumeKodiMediaIntent(GenericIntentHandler):
		intent_type = 'PauseResumeKodiMediaIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			play_pause_active_player(kodi_location)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
	
	class StopKodiMediaIntent(GenericIntentHandler):
		intent_type = 'StopKodiMediaIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			stop_active_player(kodi_location)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	class KodiNextTrackIntent(GenericIntentHandler):
		intent_type = 'KodiNextTrackIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			next_track(kodi_location)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	class KodiPrevTrackIntent(GenericIntentHandler):
		intent_type = 'KodiPrevTrackIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			prev_track(kodi_location)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	class KodiGoToTimeIntent(GenericIntentHandler):
		intent_type = 'KodiGoToTimeIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			param_dict = copy(intent_obj.slots)
			try:
				del param_dict['kodi_location']
			except KeyError:
				pass
			go_to_within_track(kodi_location, **param_dict)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
	
	class KodiDeltaTimeIntent(GenericIntentHandler):
		intent_type = 'KodiDeltaTimeIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			param_dict = copy(intent_obj.slots)
			try:
				del param_dict['kodi_location']
			except KeyError:
				pass
			seek_within_track(kodi_location, **param_dict)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
		
	class PlayKodiVideoIntent(GenericIntentHandler):
		intent_type = 'PlayKodiVideoIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			param_dict = copy(intent_obj.slots)
			try:
				del param_dict['kodi_location']
			except KeyError:
				pass
				
			video_list = search_videos(kodi_location, **param_dict)
			if video_list:
				# only continue if we found at least one video
				
				# look for an active player and stop it if it is playing
				stop_active_player(kodi_location)
				
				# get the playlist and clear it
				clear_playlist(kodi_location, video_playlist)

				# we only want one song even if we found multiples so just add the first one to the play list
				add_item_to_playlist(kodi_location, video_playlist, video_list[0])
				
				# start playing the playlist
				start_playing_playlist(kodi_location, video_playlist)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	class PlayKodiSongIntent(GenericIntentHandler):
		intent_type = 'PlayKodiSongIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			param_dict = copy(intent_obj.slots)
			try:
				del param_dict['kodi_location']
			except KeyError:
				pass
				
			try:
				param_dict['kodi_song'] = param_dict['kodi_song']['value']
			except KeyError:
				pass
			
			try:
				param_dict['kodi_artist'] = param_dict['kodi_artist']['value']
			except KeyError:
				pass
				
			try:
				param_dict['kodi_album'] = param_dict['kodi_album']['value']
			except KeyError:
				pass
				
			song_list = search_songs(kodi_location, **param_dict)
			if song_list:
				# only continue if we found at least one song
				
				# look for an active player and stop it if it is playing
				stop_active_player(kodi_location)
				
				# get the playlist and clear it
				clear_playlist(kodi_location, audio_playlist)

				# we only want one song even if we found multiples so just add the first one to the play list
				add_item_to_playlist(kodi_location, audio_playlist, song_list[0])
				
				# start playing the playlist
				start_playing_playlist(kodi_location, audio_playlist)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	class PlayKodiArtistIntent(GenericIntentHandler):
		intent_type = 'PlayKodiArtistIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			param_dict = copy(intent_obj.slots)
			try:
				del param_dict['kodi_location']
			except KeyError:
				pass
				
			try:
				param_dict['kodi_artist'] = param_dict['kodi_artist']['value']
			except KeyError:
				pass
				
			song_list = search_songs(kodi_location, **param_dict)
			if song_list:
				# only continue if we found at least one song
				
				# look for an active audio player and stop it if it is playing
				stop_active_player(kodi_location)
				
				# get the playlist and clear it
				clear_playlist(kodi_location, audio_playlist)

				# add these songs to the playlist
				for song in song_list:
					add_item_to_playlist(kodi_location, audio_playlist, song)
				
				# start playing the playlist
				start_playing_playlist(kodi_location, audio_playlist, shuffle=True)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	class PlayKodiAlbumIntent(GenericIntentHandler):
		intent_type = 'PlayKodiAlbumIntent'
		
		@asyncio.coroutine
		def async_handle(self, intent_obj):
			kodi_location = self.extract_location(intent_obj)
			param_dict = copy(intent_obj.slots)
			try:
				del param_dict['kodi_location']
			except KeyError:
				pass
				
			try:
				param_dict['kodi_artist'] = param_dict['kodi_artist']['value']
			except KeyError:
				pass
				
			try:
				param_dict['kodi_album'] = param_dict['kodi_album']['value']
			except KeyError:
				pass
				
			song_list = search_songs(kodi_location, **param_dict)
			if song_list:
				# only continue if we found at least one song
				
				# look for an active audio player and stop it if it is playing
				stop_active_player(kodi_location)
				
				# get the playlist and clear it
				clear_playlist(kodi_location, audio_playlist)

				# add these songs to the playlist
				for song in song_list:
					add_item_to_playlist(kodi_location, audio_playlist, song)
				
				# start playing the playlist
				start_playing_playlist(kodi_location, audio_playlist)
		
			response = intent_obj.create_response()
			response.async_set_speech(self.random_response())
			return response
			
	intent.async_register(hass, PauseResumeKodiMediaIntent())
	intent.async_register(hass, StopKodiMediaIntent())
	intent.async_register(hass, KodiNextTrackIntent())
	intent.async_register(hass, KodiPrevTrackIntent())
	intent.async_register(hass, KodiGoToTimeIntent())
	intent.async_register(hass, KodiDeltaTimeIntent())
	
	intent.async_register(hass, PlayKodiVideoIntent())
	intent.async_register(hass, PlayKodiSongIntent())
	intent.async_register(hass, PlayKodiArtistIntent())
	intent.async_register(hass, PlayKodiAlbumIntent())
	
	
	return True
Exemple #25
0
def async_setup(hass, config):
    """Initialize the shopping list."""
    @asyncio.coroutine
    def add_item_service(call):
        """Add an item with `name`."""
        data = hass.data[DOMAIN]
        name = call.data.get(ATTR_NAME)
        if name is not None:
            data.async_add(name)

    @asyncio.coroutine
    def complete_item_service(call):
        """Mark the item provided via `name` as completed."""
        data = hass.data[DOMAIN]
        name = call.data.get(ATTR_NAME)
        if name is None:
            return
        try:
            item = [item for item in data.items if item['name'] == name][0]
        except IndexError:
            _LOGGER.error("Removing of item failed: %s cannot be found", name)
        else:
            data.async_update(item['id'], {'name': name, 'complete': True})

    data = hass.data[DOMAIN] = ShoppingData(hass)
    yield from data.async_load()

    intent.async_register(hass, AddItemIntent())
    intent.async_register(hass, ListTopItemsIntent())

    hass.services.async_register(
        DOMAIN, SERVICE_ADD_ITEM, add_item_service, schema=SERVICE_ITEM_SCHEMA
    )
    hass.services.async_register(
        DOMAIN, SERVICE_COMPLETE_ITEM, complete_item_service,
        schema=SERVICE_ITEM_SCHEMA
    )

    hass.http.register_view(ShoppingListView)
    hass.http.register_view(CreateShoppingListItemView)
    hass.http.register_view(UpdateShoppingListItemView)
    hass.http.register_view(ClearCompletedItemsView)

    hass.components.conversation.async_register(INTENT_ADD_ITEM, [
        'Add [the] [a] [an] {item} to my shopping list',
    ])
    hass.components.conversation.async_register(INTENT_LAST_ITEMS, [
        'What is on my shopping list'
    ])

    yield from hass.components.frontend.async_register_built_in_panel(
        'shopping-list', 'shopping_list', 'mdi:cart')

    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_ITEMS,
        websocket_handle_items,
        SCHEMA_WEBSOCKET_ITEMS)
    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_ADD_ITEM,
        websocket_handle_add,
        SCHEMA_WEBSOCKET_ADD_ITEM)
    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_UPDATE_ITEM,
        websocket_handle_update,
        SCHEMA_WEBSOCKET_UPDATE_ITEM)
    hass.components.websocket_api.async_register_command(
        WS_TYPE_SHOPPING_LIST_CLEAR_ITEMS,
        websocket_handle_clear,
        SCHEMA_WEBSOCKET_CLEAR_ITEMS)

    return True
Exemple #26
0
async def async_setup_intents(hass: HomeAssistant) -> None:
    """Set up the humidifier intents."""
    intent.async_register(hass, HumidityHandler())
    intent.async_register(hass, SetModeHandler())
Exemple #27
0
async def async_setup_intents(hass):
    """Set up the Shopping List intents."""
    intent.async_register(hass, AddItemIntent())
    intent.async_register(hass, ListTopItemsIntent())