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
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
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!" } }, }
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 {}"), )
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
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!" } }, }
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
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
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
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
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
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
def async_setup(hass, config): """Initialize the shopping list.""" intent.async_register(hass, ChangeLightState()) return True
async def async_setup_intents(hass): intent.async_register(hass, PlexAssistantIntent()) hass.components.conversation.async_register( "Plex", ["Tell Plex to {command}", "{command} with Plex"], )
async def async_setup_intents(hass: HomeAssistant) -> None: """Set up the light intents.""" intent.async_register(hass, SetIntentHandler())
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
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
async def async_setup_intents(hass: HomeAssistant) -> None: """Set up the humidifier intents.""" intent.async_register(hass, HumidityHandler()) intent.async_register(hass, SetModeHandler())
async def async_setup_intents(hass): """Set up the Shopping List intents.""" intent.async_register(hass, AddItemIntent()) intent.async_register(hass, ListTopItemsIntent())