n0name45 / node-red-contrib-yandex-station-management

Модуль node-red-contrib-yandex-station-management для управления умными колонками от Яндекс
25 stars 6 forks source link
alice homekit node-red tts yandex-station

Описание

С помощью модуля можно через локальное API управлять вопсроизведением на устройсвах Яндекса:

Работа возможна только с устройствами, которые одновременно:

Для работы требуется токен от Яндекс.Музыки. В модуле в экспериментальном режиме реализована возможность получения токена из логин-пароля(Спасибо слать сюда). Если получение токена не отрабатывает, то стоит попробовать включить и отключить двух-факторную аутентификацию в настройках Яндекса. Источник. Убедиться в безопасности использования учетных данных можно, посмотрев код

Второй из варинатов его получения описан в FAQ

Третий из вариантов получения токена описан тут

Возможна работа с несколькими устройствами(протестировано) и несколькими учетными записями(протестировано).

Состоит из 4 нод, позволяющих гибко настраивать автоматизации и использовать голосовые уведомления:

Установка.

Установка проводится через раздел Manage Palette в Node-Red или при помощи npm. в каталоге с Node-Red (обычно ~/.node-red) выполнить команду:

npm i node-red-contrib-yandex-station-management

Первоначальная настройка.

После установки для начала работы добавить любую ноду, ввести учетные данные(токен) в раздел Login, сохранить и нажать Deploy(обязательно!). Как получить токен - написано в FAQ.

После деплоя в настройках ноды в поле Station должны появиться станции доступные для управления.

Если станция не появилась в списке, то можно подождать пару минут или перезапустить Node-Red.

Описание возможностей и сценариев использования.

Нода Station

Дополнительные настройки для станции. Является опциональной, то есть все будет работать и без этой ноды, но с ней может быть интерсней. Нода ставится вне потока и не имеет входов и выходов.

Connection to device

Управление подключением к станции. Если по каким-то причинам надо, чтобы подключение не производилось - выставить в Disabled.

Network

В состоянии Manual появляется возможность вручную указать адрес станции и порт для подключения. Рекомендуется, если используются docker-ы, HomeAssistant-ы, и прочие случаи, при которых не отрабатывает автоматические определение сетевых реквизитов для подключения.

Kid Control

Реализована возможность ограничения по времени для прослушивания песен, радио, сказок, чтобы маленькие любители ночных историй поскорее засыпали. Настраивается для каждого дня недели. Если не стоит галка Active, то для этого дня ограничения не работают. Phrase to say - фраза, которую скажет Алиса вместо музыки:) При этом работают навыки, будильники, погода, новости и так далее.

Нода IN.

Ставится на старте flow и автоматически отправляет данные о текущем статусе колонки в "сыром" формате и Homekit.

Full status Message("сырой" формат)

Выдает данные без преобразования, то есть в том виде, в каком они получены от устройсва. Структура сообщения:

    {"aliceState":"IDLE",
    "canStop":false,
    "hdmi":
        {"capable":true,
        "present":false},
    "playerState":
        {"duration":180.91,
        "extra":
            {"coverURI":"avatars.yandex.net/get-music-content/2383988/de45408f.a.9039208-1/%%",
            "stateType":"music"},
        "hasNext":true,
        "hasPause":false,
        "hasPlay":false,
        "hasPrev":true,
        "hasProgressBar":true,
        "liveStreamText":"",
        "progress":20,
        "showPlayer":true,
        "subtitle":"Крематорий",
        "title":"Мусорный ветер"},
        "playing":false,
        "timeSinceLastVoiceActivity":30454,
        "volume":0}

Сообщения от устройства могут приходить по несколько штук в секунду, поэтому стоит подумать о необходимости поставить штатную ноду RBE, чтобы фильтровать дубликаты по контенту(название трека(payload.playerState.title), имя исполнителя(payload.playerState.subtitle)).

HomeKit formatted

Внутри выполняется преобразование выдаваемого формата под homekit и ноду можно стыковать прямо с homekit-нодой, в результате чего значиьельно упрощается flow. Юзкейсы можно найти в конце документации.

Для homekit formatted выдачи имеются опции:

Структура сообщения Homekit formatted - Smart Speaker:

{"CurrentMediaState":0,"ConfiguredName":"International String Trio - Tarantella"}

Структура сообщения Homekit formatted - Television:

{"Active":1}

При использовании устройства Television появляется возможность использования "пульта" на iOS.

Нода GET.

Ставится в середине flow и при любом входящем сообщении отправляет на выход в payload последний статус устройства. Структура выдачи аналогична Full status Message ноды IN.

Нода OUT.

Ставится в конце flow и используется для отправки сообщений на устройства. Допускается использование нескольких нод OUT для одного и того же устройства, при этом данные будут от них передаваться через одно соединение с устройством.

Player command.

Управление воспроизведением колонки. Нода ждет, что в payload строкой придет одна из следующих команд: play, stop, next, prev, forward(вперед на 10 секунд), backward(назад на 10 секунд), volumeup, volumedown

Voice command.

Отправка команды, вместо того, чтобы говорить ее колонке голосом: "Включи свет", "Включи музыку", "Включи мой плейлист", "Отключись через 15 минут" и так далее.

TTS.

Воспроизведение голосом отправленных фраз - Text to Speech. Не имеет ограничения по символам. Параметры для TTS могут задаваться как в настройках, так и некоторые из них могут быть переопределены входящим сообщением.

Добавление голосу жизни и красок.
Раставляйте ударения

При необходимости ударные гласные в словах следует отмечать знаком «+», например:

остр+ота
м+ука
Разделяйте слова

Длинные слова можно разбить на слова покороче и проставить ударения для каждого из этих коротких слов, например:

мн+ого пр+офильный с+еми пал+атинск

Меняйте написание слов

Некоторые слова можно попробовать писать так, как они слышатся:

«ненастный» — нен+асный
«пожалуйста» — пож+алуста
Добавляйте паузы

Чтобы задать паузу между словами, используйте синтаксис sil <[ количество_миллисекунд ]>. Например:

смелость sil <[500]> город+а берёт

Каждый отделенный пробелами пунктуационный знак обозначается паузой в 50-100 мс.

Добавляйте звуки из библиотеки
<speaker audio=\"alice-sounds-game-win-1.opus\"> У вас получилось!

Homekit Formatted.

Ловит вывод от Homekit от устройств SmartSpeaker(вкл/выкл) и Television(вкл/выкл + пульт) модуля NRCHB. Встроена функция проверки hap.context,предотвращающая зацикливание. Стыкуется напрямую с Homekit нодой. Опция "Default command" указывает, какую голосовую команду запустить, если нет текущего трека для старта воспроизведения, а играть что-то надо. Например, "Включи мою музыку" или "Включи детские песни".

RAW Command.

Получает сообщение в формате JSON внутри payload и передает его колонке без обработки. Возможна отправка нескольких сообщений в одном сообщении payload в виде массива. Известные команды:

  1. Перемотка на позицию в секундах
    {
    "command": "rewind",
    "position" : 120
    }
  2. Продолжить воспроизведение
    {
    "command": "play"
    }
  3. Остановка вопроизведения
    {
    "command": "stop"
    }
  4. Предыдущий трек
    {
    "command": "prev"
    }
  5. Следующий трек
    {
    "command": "next"
    }
  6. Включить исполнителя по ID
{
    "command": "playMusic",
    "id": "2",
    "type":"artist"
}
  1. Включить трек по ID

    {
    "command": "playMusic",
    "id": "44731403",
    "type": "track"
    }
  2. Включить плейлист по ID

    {
    "command": "playMusic",
    "id": "44731403:1234556",
    "type": "playlist"
    }
  3. Установка громкости в диапазоне 0-1

    {
    "command" : "setVolume",
    "volume" : 0.2
    }
  4. Включить радио

    {
    "command": "playRadio",
    "id": "detskoe"
    }
  5. Режим повтора. "One"/"All"/"None"

    {
    "command": "repeat",
    "mode": "One"
    }
  6. Режим вразброс. Срабатывает, когда есть очередь треков(включен плейоист, альбом, артист) true/false

    {
    "command": "shuffle",
    "enable": true
    }
  7. Принудительно включить режим индикации Алисы - занято, слушаю, простой "LISTENING"/"BUSY"/"IDLE"

    {
    "command": "showAliceVisualState",
    "aliceStateName": "LISTENING",
    "recognizedPhrase": ""
    }
  8. Отправить "Текст" для TTS. Больше не работает!

    {
    "command" : "sendText",
    "text" : "Повторяй за мной 'Текст'"
    }
  9. Отправить голосовую команду.

    {
    "command" : "sendText",
    "text" : "Включи музыку"
    }
  10. Прервать "слушание" после TTS и не только:

    {
    "command": "serverAction",
    "serverActionEventPayload": {
        "type": "server_action",
        "name": "on_suggest"
    }
    }
  11. Отправить "Текст" для TTS со спецэффектами (raw режим):

    {
    "command": "serverAction",
    "serverActionEventPayload": {
        "type": "server_action",
        "name": "update_form",
        "payload": {
            "form_update": {
                "name": "personal_assistant.scenarios.repeat_after_me",
                "slots": [
                    {
                        "type": "string",
                        "name": "request",
                        "value": "<speaker effect='megaphone'>Ехал Грека через реку <speaker effect='-'>видит Грека в реке рак"
                    }
                ]
            },
            "resubmit": true
        }
    }
    }

Stop listening.

Принудительное прерывания "слушания" Алисы при любом входящем в ноду сообщении. Аналогично 12 команде предыдущего раздела

Пример использования нескольких RAW команд

Остановить проигрывание музыки и сказать текст громкостью 0.8

[
    {"command":"stop"},
    {
        "command": "serverAction",
        "serverActionEventPayload": {
            "type": "server_action",
            "name": "on_suggest"
        }
    },
    {"command":"setVolume","volume":0.8},
    {
        "command": "serverAction",
        "serverActionEventPayload": {
            "type": "server_action",
            "name": "update_form",
            "payload": {
                "form_update": {
                    "name": "personal_assistant.scenarios.repeat_after_me",
                    "slots": [
                        {
                            "type": "string",
                            "name": "request",
                            "value": "<speaker effect='megaphone'>Ехал Грека через реку <speaker effect='-'>видит Грека в реке рак"
                        }
                    ]
                },
                "resubmit": true
            }
        }
    }
]

Примеры использования.

Управление воспроизведением устройства.

Есть ряд способов управлением воспроизведения музыки на колонках.

  1. Из Node-Red. В ноду OUT в режиме Player Command надо отправлять в виде строки одну из команд: play, stop, next, prev, forward, backward. Примеры идут вместе с плагином! alt text
  2. Из ui-dashboard. Благодарю участников сообщества Node-Red на sprut.ai за подгтовку примеров. Если плагин с дашбордом не стоит, его надо поставить. После этого имортировать пример из ноды и по адресу /ui найдутся элементы управления.

alt text alt text

Есть еще один вариант от @twocolors, в примерах.

Добавляется простым flow и выглядит отлично)

alt text alt text

  1. Из Homekit. Ноды IN и GET имеют возможность выдачи сообщений в готовом для Homekit формате. Можно самостоятельно подготовить сообщение к отправке в Homekit, а можно просто воспользоваться нужной настройкой внутри нод. Разумным будет установка галки Unique messages для IN-ноды, чтобы не заваливать Homekit одинаковыми сообщениями.

В списке устройств NRCHB есть Smart Speaker. Из коробки с помощью простого flow можно управлять состоянием вкл-выкл воспроизведения и видеть название трека. Работает только на iOS 14 или macOS Big Sur. Элементы управления внутри Homekit не работают, их еще не завезли Homekit-ноду.

Если требуется работать на старых версиях iOS/macOS или надо управлять воспроизведением со штатного инструмента Пульт из панели управления, то можно собрать flow на базе homekit-нод TV, ноды IN в соотвествующем формате и OUT. При этом OUT-нода в Homekit-формате умеет "понимать" вход от SmartSpeaker, Television и обоих вместе. Проверка сообщений на зацикливание встроена в ноду OUT. alt text alt text

FAQ.

Q:Как получить oAuth-токен?

A:Как один из вариантов - https://music-yandex-bot.ru

Q:Как получить обложку трека?

A: Ссылку на обложку Яндекс Музыки можно взять из статусного сообщения: payload.playerState.extra.coverURI

В начало добавить https:// а в конце вместо %% размер обложки, например 600x600. https://avatars.yandex.net/get-music-content/2383988/de45408f.a.9039208-1/600x600

Q:Как узнать ИД станции? Это может понадобиться,чтобы отличать станции, если их не одна.

A:Приложение Яндекс на телефоне - Устройства - Управление устройствами - Выбрать станцию - Дополнительная информация

Q:Почему название трека в Homekit меняется не сразу после переключения?

A: Это нормально, так как для отображния используется имя устройства, а изменения имен в Homekit отражаются, так как имеют наименьший приоритете перед статусами и состояниями.

Q: Элементы управления внутри Homekit "засерены" и не работают

A: Если используется тип устройства Smart Speaker, то да, там они не работают и я не нашел как сделать их активными. Если у кого-то получится их сделать активными, то создание issue поможет остальным. Сейчас альтернатива - это устройство ТВ и привязка к нему пульта. Получаетя как AppleTV. Пример есть внутри NRCHB

Q: После запуска Node-Red не видны устройство/устройства.

A: Такое случается, если устройсвта не найдены в сети. Стоит понимать, что протокол zeroconf, который используется для поиска выдает не стабильный результат. Один поиск из 5 заканчивается отсуствием найденных устройств. Как решение - просто подождать пару минут и повторный поиск найдет всех пропавших с радаров

Q: Как добавить пример из ноды?

A: В меню Node-Red есть пункт Import, а в нем раздел Examples. Внутри папки с названием плагина найдутся все примеры.

Команды для управления станции взяты тут. Спасибо автору.

ENG

Node-Red integration with Yandex Devices through websocket:

- Yandex Station(tested)
- Yandex Mini(tested)
- Yandex Station Max(tested)
- Yandex Module(not tested)
- JBL Link Music(not tested)
- JBL Link Portable(tested)

Installation

Run the following command in your Node-RED user directory - typically `~/.node-red`

npm i node-red-contrib-yandex-station-management

You need Yandex music token to work propertly.