Skip to content

Commit

Permalink
Add service sequence support
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexxIT committed Mar 1, 2020
1 parent 1de4115 commit ab8330b
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 116 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.1.12 - 2020-03-01

### Added

- Поддержка последовательного выполнения команд (очередей)

## 0.1.11 - 2020-02-22

### Changed
Expand Down
179 changes: 133 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

- [CHANGELOG](https://github.com/AlexxIT/YandexStation/blob/master/CHANGELOG.md)

На середину февраля 2020 поддерживается:
На начало марта 2020 поддерживается:

- Яндекс.Станция (большая)
- Яндекс.Модуль (у меня нет, но по отзывам работает)
Expand Down Expand Up @@ -51,25 +51,98 @@ yandex_station:
token: abcdefghijklmnopqrstuvwxyz
```
## Пример использования
## Примеры использования
Если у вас в конфиге есть другие TTS - читайте раздел "*Несколько TTS в конфиге*".
Для шаблонов не забывайте указывать `data_template`, для остальных команд хватит просто `data`.

Поддерживаются команды на несколько станций одновременно (как TTS, так и media_player).

### Обычный способ вызвать TTS

Зависит от настройки "Режим звука" (из окна медиа-плеера). Будет или произносить текст или выполнять команду. Он же вызывается из окна медиа-плеера.

```yaml
script:
# TTS зависит от настройки "Режим звука"! (произнести или выполнить команду)
yandex_tts:
alias: TTS на Яндекс.Станции
yandex_tts1:
alias: TTS зависит от настройки "Режим звука"!
sequence:
- service: tts.yandex_station_say
entity_id: media_player.yandex_station
data_template:
entity_id: media_player.yandex_station_12345678901234567890
message: Температура в комнате {{ states("sensor.temperature_hall")|round }} градуса.
```

### Второй способ вызвать TTS

Не зависит от настройки "Режим звука".

```yaml
script:
# TTS не зависит от настройки "Режим звука"! и всегда будет произносить фразу
yandex_tts2:
alias: TTS не зависит от настройки "Режим звука"
sequence:
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
media_content_id: Повторяю вашу фразу
media_content_type: text
```

### Продвинутый TTS

Не зависит от настройки "Режим звука", но продолжает слушать после произнесения текста!

В этом режиме поддерживаются эффекты, библиотека звуков и настройка речи:

- [Настройка генерацию речи](https://yandex.ru/dev/dialogs/alice/doc/speech-tuning-docpage/)
```yaml
media_content_id: смелость sil <[500]> город+а берёт
```
- [Наложение эффектов на голос](https://yandex.ru/dev/dialogs/alice/doc/speech-effects-docpage/)
```yaml
media_content_id: <speaker effect="megaphone">Ехал Грека через реку <speaker effect="-">видит Грека в реке рак
```
- [Библиотека звуков](https://yandex.ru/dev/dialogs/alice/doc/sounds-docpage/)
```yaml
media_content_id: <speaker audio="alice-sounds-game-win-1.opus"> У вас получилось!
```

```yaml
script:
yandex_tts3:
alias: TTS c эффектами
sequence:
# Отправляем TTS с эффектами (media_content_type: dialog)
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
media_content_id: <speaker effect="megaphone">Объявление погоды на сегодня...
media_content_type: dialog
# Ожидаем окончания фразы (после dialog нужно дожидаться LISTENING)
- wait_template: "{{ is_state_attr('media_player.yandex_station', 'alice_state', 'LISTENING') }}"
# Останавливаем режим LISTENING
- service: yandex_station.send_command
entity_id: media_player.yandex_station
data:
command: cancelVoiceDialog
```

### Примеры управления станцией

```yaml
script:
yandex_play_album:
alias: Включить Би-2 на Станции
sequence:
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
entity_id: media_player.yandex_station_12345678901234567890
media_content_id: 60062 # ID альбома в Яндекс.Музыка
media_content_type: album # album, track or playlist
Expand All @@ -87,58 +160,72 @@ script:
alias: Звук Станции на HDMI
sequence:
- service: media_player.select_source
entity_id: media_player.yandex_station_12345678901234567890
data:
entity_id: media_player.yandex_station_12345678901234567890
source: HDMI
```

Для шаблонов не забывайте указывать `data_template`, для остальных команд
хватит просто `data`.
## Очередь команд

Поддерживаются команды на несколько станций одновременно (как TTS, так и
media_player).
Команды можно выполнять последовательно, дожидаясь ответа от станции.

## Продвинутое использование TTS
**Внимание!** При ожидании окончания "продвинутого" TTS (`dialog`) необходимо дожидаться статуса `LISTENING` и желательно после выполнять команду `cancelVoiceDialog` (пример есть выше). При работе с обычным TTS (`text` или `tts.yandex_station_say`) необходимо дожидаться статуса `IDLE`, как в примере ниже.

```yaml
script:
# TTS не зависит от настройки "Режим звука"! и всегда будет произносить фразу
yandex_tts2:
alias: TTS на Яндекс.Станции
yandex_queue:
alias: Очередь команд на станции
sequence:
- service: media_player.play_media
data:
entity_id: media_player.yandex_station_12345678901234567890
media_content_id: Повторяю вашу фразу
media_content_type: text
# TTS не зависит от настройки "Режим звука"! и будет продолжать слушать после
# произнесения фразы
yandex_tts3:
alias: TTS на Яндекс.Станции
sequence:
- service: media_player.play_media
data:
entity_id: media_player.yandex_station_12345678901234567890
media_content_id: Мне следует пропылесосить?
media_content_type: dialog
# Устанавливаем громкость станции
- service: media_player.volume_set
entity_id: media_player.yandex_station
data:
volume_level: 0.3
# Узнаём у Яндекса погоду (это выполнение команды, а не TTS!)
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
media_content_id: Какая погода сегодня в Москве?
media_content_type: command
# Ожидаем окончания фразы (после command нужно дожидаться IDLE)
- wait_template: "{{ is_state_attr('media_player.yandex_station', 'alice_state', 'IDLE') }}"
# Узнаём у Яндекса пробки (это выполнение команды, а не TTS!)
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
media_content_id: Какие пробки сегодня в Москве?
media_content_type: command
# Ожидаем окончания фразы (после command нужно дожидаться IDLE)
- wait_template: "{{ is_state_attr('media_player.yandex_station', 'alice_state', 'IDLE') }}"
# Запускаем обычный TTS
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
media_content_id: Хорошего вам дня. А теперь послушайте музыку, которую любите...
media_content_type: text
# Ожидаем окончания фразы (после command нужно дожидаться IDLE)
- wait_template: "{{ is_state_attr('media_player.yandex_station', 'alice_state', 'IDLE') }}"
# Устанавливаем громкость станции
- service: media_player.volume_set
entity_id: media_player.yandex_station
data:
volume_level: 0.2
# Включаем любимую музыку на станции (это выполнение команды, а не TTS!)
- service: media_player.play_media
entity_id: media_player.yandex_station
data:
media_content_id: Включи мою любимую музыку
media_content_type: command
```

В режиме `media_content_type: dialog` поддерживаются:

- [Настройка генерацию речи](https://yandex.ru/dev/dialogs/alice/doc/speech-tuning-docpage/)
```yaml
media_content_id: смелость sil <[500]> город+а берёт
```
- [Наложение эффектов на голос](https://yandex.ru/dev/dialogs/alice/doc/speech-effects-docpage/)
```yaml
media_content_id: <speaker effect="megaphone">Ехал Грека через реку <speaker effect="-">видит Грека в реке рак
```
- [Библиотека звуков](https://yandex.ru/dev/dialogs/alice/doc/sounds-docpage/)
```yaml
media_content_id: <speaker audio="alice-sounds-game-win-1.opus"> У вас получилось!
```

## Продвинутое использование команд

Компонент создаёт сервис `yandex_station.send_command`, которому необходимо передать команду.
Expand Down
18 changes: 10 additions & 8 deletions custom_components/yandex_station/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,17 @@ async def send_command(call: ServiceCall):
return

data = {
ATTR_MEDIA_CONTENT_ID: json.dumps(data),
ATTR_MEDIA_CONTENT_TYPE: 'command',
ATTR_ENTITY_ID: entity_ids,
ATTR_MEDIA_CONTENT_ID: data.get('text'),
ATTR_MEDIA_CONTENT_TYPE: 'dialog',
} if data.get('command') == 'dialog' else {
ATTR_ENTITY_ID: entity_ids,
ATTR_MEDIA_CONTENT_ID: json.dumps(data),
ATTR_MEDIA_CONTENT_TYPE: 'json',
}

await hass.services.async_call(
DOMAIN_MP, SERVICE_PLAY_MEDIA, data, blocking=True
)
await hass.services.async_call(DOMAIN_MP, SERVICE_PLAY_MEDIA, data,
blocking=True)

async def yandex_station_say(call: ServiceCall):
entity_ids = call.data.get(ATTR_ENTITY_ID) or utils.find_station(hass)
Expand All @@ -94,9 +97,8 @@ async def yandex_station_say(call: ServiceCall):
ATTR_ENTITY_ID: entity_ids,
}

await hass.services.async_call(
DOMAIN_MP, SERVICE_PLAY_MEDIA, data, blocking=True
)
await hass.services.async_call(DOMAIN_MP, SERVICE_PLAY_MEDIA, data,
blocking=True)

def add_device(info: dict):
info['yandex_token'] = yandex_token
Expand Down
Loading

0 comments on commit ab8330b

Please sign in to comment.