YandexStation
YandexStation copied to clipboard
Проблема с авторизацией после обновления 2023.3
Проблема с авторизацией после обновления 2023.3
Home Assistant 2023.3.1 Yandex Station v3.12.0
Не получается авторизоваться. У меня приложения Я.Ключ. Настройки авторизации аккаунта - логин и пароль, также включена авторизация по QR коду.
Пробовал регистрировать интеграцию разными способами. Логин пароль - Авторизация по паролю невозможна. Если выбрать Код - Неверный пароль Авторизация по Куки - выдаёт ошибку "Unknown error occurred". Авторизация по почте - выдаёт ошибку как на картинке. Авторизация по QR коду - выдаёт ошибку как на картинке.
Делал полное удаление с перезагрузкой - не помогло.
Logger: custom_components.yandex_smart_home.notifier
Source: custom_components/yandex_smart_home/notifier.py:137
Integration: Yandex Smart Home (documentation, issues)
First occurred: 12:30:16 (1 occurrences)
Last logged: 12:30:16
Failed to send state notification: [401] b'Unauthorized\n
Обновился. Yandex Station v3.12.1
Аналогично, при попытке авторизоваться по QR коду появляется картинка:
И интеграция не добавляется.
У меня приложения Я.Ключ. Настройки авторизации аккаунта - логин и пароль, также включена авторизация по QR коду.
Присоединюсь, такая же фигня(
И у меня также
Retrying setup: too many values to unpack (expected 2)
Откатился на 2023.2 - все заработало
+1
Retrying setup: too many values to unpack (expected 2)
YS: 3.12.1 HA: 2023.3.1 Works well!
Удалял интеграцию, перезагружал. Устанавливал, перезагружал. При авторизации через QR код вылетает картинка:
Но сама интеграция в списке не появляется. Пожалуйста, скажите хоть куда копать...
В логи копать. Всегда первый шаг искать ошибки в логах
В том то всё и дело, что в попытках авторизоваться через QR код в логах сервера ничего не появляется нового.
как я решил проблему: удалил в hacs интеграцию яндекс.станции (хотя стояла последняя 3.12.1), установил ее заново, перезагрузил HA, в id.yandex.ru/security/enter-methods поменял обычный пароль на я-ключ, и в приложении его получил. Установил интеграцию используя qr-код. До этих манипуляций я-ключ был, удалил и поставил заново.
Это не решение проблемы. Это костыли. У меня на Яндекс ПАРОЛЬ завязано 100500 сервисов и не только в HA.
Мне кажется Яндекс ведут себя неадекватно.
Короче, история у меня такая. У меня работала интеграция Yandex.Station и было всё хорошо. После обновления 2023.3 у меня началось:
too many values to unpack (expected 2)
Удалял, ставил, но всё равно не авторизовывалось ни по паролю, ни по то почте. Тогда то я и решил попробовать QR код, хотя этот способ вынуждал меня на забитый телефон ставить ещё одно ненужное гавно-приложение.
В процессе установки ЯКлюч спросил меня, не хочу ли выйти из всех аккаунтов залогиненых. Я, естественно, ответил "НЕТ!!!". Но в конце установки это чудо-приложение мне написало, что авторизация по паролю более недоступна и всё же вышла отовсюду где я был залогинен. (#@&%!)
Интеграция Yandex.Station успешно залогинилась, но зато отвалилось всё остальное. Как я писал выше, у меня на ПАРОЛЬ завязано 100500 сервисов и не только в HA. Самым унизительным было заново подключать и настраивать ПЯТЬ колонок с Алисой ибо они тоже перестали авторизовываться.
Чтобы дальше использовать пароль в настройках гавно-приложения Я(#@&%!)Ключ выставил возможность авторизовываться как по паролю, так и по ключу. Выставил тот же пароль, что у меня был.
Как уже выяснилось потом, после восстановления авторизации по паролю и установки того же самого пароля Я(#@&%!*)Ключ сбросило мне ещё и Токен. Я получил второй круг ада по повторной настройке всего и вся для подключения к службам ТЫндекса.
Сейчас всё заработало как и раньше, кроме интеграции Yandex.Station.
Лично я подозреваю, что у Яндекса авторизация "Только по QR коду" и "По QR коду и по паролю" чем-то отличается в API и по этому меня приложение не пускает. Токен сменился. Куку и по почте - не проходит.
У меня сейчас настроена авторизация "По QR коду и по паролю". Я подозреваю, что если я настрою "Только по QR коду", то всё заработает. Но тогда у меня отвалится куча всего остального. Для меня это не вариант.
Кроме как ждать пока разработчик интеграции пофиксит авторизацию мне остаётся только наслаждаться возможностью пофлудить про HA в русскоязычном комьюнити и отвести душу :-)
Прописал в configuration.yaml свои данные
yandex_station: username: <login>@yande.ru password: <password>
И снова интеграция не появилась и в логах пусто.
+1 Retrying setup: too many values to unpack (expected 2)
Плюсую. Y.S v3.11.0 H.A 2023.3.2
Имеется две Я.Станции мини. Одна перестала отображать обновление карточки 3 дня назад. HA версию, при этом, не трогал. Вторая Я.С. обновляла свою карточку на дашборде и управлялась с него. Обновил версию HA - отвалились обе.
В интеграциях: Повторная настройка: too many values to unpack (expected 2)
Имеется две Я.Станции мини. Одна перестала отображать обновление карточки 3 дня назад. HA версию, при этом, не трогал. Вторая Я.С. обновляла свою карточку на дашборде и управлялась с него. Обновил версию HA - отвалились обе.
Скорее всего у тебя Токен сменился. Я вот как раз через это прошёл. Не сбрасывая и не удаляя станции в Яндекс приложении настроить их снова. Если у тебя интеграция Yandex Smart подключена через облако, то нужно отключить, поменять ключ и подключить снова. Если же Yandex Smart подключён локально, то нужно отключить привязку НА САЙТЕ ЯНДЕКСА, поменять ключ и снова подключить. В Яндекс приложении для умного дома ничего делать не нужно. В HS-е только прописать новый Токен в конфиге и рестартануть. Больше ничего делать не нужно, а то можно потерять привязку и настройку устройств.
Короче, тайна сисек раскрыта. Яндекс что-то изменил в авторизации по паролю и теперь активно навязывает авторизацию через приложение по одноразовому паролю или QR коду. Когда вы первый раз ставите приложение Я(#@&%!)Ключ (простите за #@&%! но иначе не скажешь), не зависимо от того, что вы нажимаете оно выходит из всех приложений, запрещает авторизацию по паролю и меняет токен. Если после этого выбрать авторизацию по паролю + по QR коду, то авторизация по QR коду перестаёт работать. Есть подозрение, что Я(#@&%!)Ключ снова меняет токен, но это не точно. После этого авторизация работает только по паролю, даже если в приложении Я(#@&%!)Ключ выставлена настройка Пароль + QR. Если Вы удаляете Я(#@&%!)Ключ и ставите снова, выбирая восстановиться из облачного хранилища, то всё равно QR не работает, скорее всего потому, что токен уже другой. Если при повторной установке Я(#@&%!)Ключ пройти всё заново, то уже токен не меняется и с устройств не разлогинивается. Единственный минус - вы теряете возможность авторизовываться по паролю. Если снова выбрать авторизацию Пароль + QR в настройках приложения Я(#@&%!)Ключ, то поменяется токен и снова не будет работать QR авторизация. Вот такая вот #@&%!. Т.е. по факту остаётся два варианта - авторизация по паролю, которая уже нигде не работает по API или QR код без пароля с завязкой на чудо-приложение Я(#@&%!)Ключ. По факту Яндекс всем навязал авторизацию по своему приложения ибо #@&%! так надо. И нефиг авторизовывается по API без привязки к смартфону. (Бесит такой подход, даже Google куда адекватнее в этом).
В качестве альтернативы для разработчиков интеграции могу предложить внедрить способ авторизации по ссылке: https://yandex.ru/activate Это единственное, что ещё работает по API кроме QR. Работает у тех и только у тех, кто не настраивал QR.
Не смотря на то, что в приложении Я(#@&%!)Ключ и в профиле Тындекса есть настройка авторизации "Пароль + QR", по факту она не работает. Либо QR и навязанная двухфакторная авторизация, либо пароль. Вместе - никак.
Занавес! Тему можно закрывать.
P.S. Спасибо Тындексу и разработчикам приложения Я(#@&%!)Ключ за потерянные часы жизни!
Я обновил Core (2023.3.3), следом интеграции: Yandex Smart Home, Yandex.Station всё встало на свои места :)
Короче, тайна сисек раскрыта. Яндекс что-то изменил в авторизации по паролю и теперь активно навязывает авторизацию через приложение по одноразовому паролю или QR коду. Когда вы первый раз ставите приложение Я(#@&%!)Ключ (простите за #@&%! но иначе не скажешь), не зависимо от того, что вы нажимаете оно выходит из всех приложений, запрещает авторизацию по паролю и меняет токен. Если после этого выбрать авторизацию по паролю + по QR коду, то авторизация по QR коду перестаёт работать. Есть подозрение, что Я(#@&%!)Ключ снова меняет токен, но это не точно. После этого авторизация работает только по паролю, даже если в приложении Я(#@&%!)Ключ выставлена настройка Пароль + QR. Если Вы удаляете Я(#@&%!)Ключ и ставите снова, выбирая восстановиться из облачного хранилища, то всё равно QR не работает, скорее всего потому, что токен уже другой. Если при повторной установке Я(#@&%!)Ключ пройти всё заново, то уже токен не меняется и с устройств не разлогинивается. Единственный минус - вы теряете возможность авторизовываться по паролю. Если снова выбрать авторизацию Пароль + QR в настройках приложения Я(#@&%!)Ключ, то поменяется токен и снова не будет работать QR авторизация. Вот такая вот #@&%!. Т.е. по факту остаётся два варианта - авторизация по паролю, которая уже нигде не работает по API или QR код без пароля с завязкой на чудо-приложение Я(#@&%!)Ключ. По факту Яндекс всем навязал авторизацию по своему приложения ибо #@&%! так надо. И нефиг авторизовывается по API без привязки к смартфону. (Бесит такой подход, даже Google куда адекватнее в этом).
В качестве альтернативы для разработчиков интеграции могу предложить внедрить способ авторизации по ссылке: https://yandex.ru/activate Это единственное, что ещё работает по API кроме QR. Работает у тех и только у тех, кто не настраивал QR.
Не смотря на то, что в приложении Я(#@&%!)Ключ и в профиле Тындекса есть настройка авторизации "Пароль + QR", по факту она не работает. Либо QR и навязанная двухфакторная авторизация, либо пароль. Вместе - никак.
Занавес! Тему можно закрывать.
P.S. Спасибо Тындексу и разработчикам приложения Я(#@&%!)Ключ за потерянные часы жизни!
Так работать стало или нет?
Помогите разобраться - пропала яндекс станция из интеграции Yandex.Station -самой станции нет есть только эквалайзер, в сети станция есть . Переустанавливал - не помогает, что может быть?
Не знаю как с авторизацией в Яндекс станции но я смог сделать авторизацию с получением токена. Можете попробовать использовать чтобы получить токен: https://gitlab.com/KirMozor/YandexMusicApi/-/blob/main/Src/Token.cs
Сущности Yandex станций пропали после обновлений HA с версии 2023.3. Обновления интеграции до версии 3,12,2 не принесли результата. Появляется только сущность эквалайзер. Колонки: 2 Станции Мини 2 Яндекс с дисплеем и Станция Макс Яндекс. Если заменить оригинальный yandex_quasar.py версии 3,12,2 на другой (код ниже), то сущности появляются, но TTS работает только на Станция Макс Яндекс.
Установлено: Яндекс.Станция для Home Assistant 3.12.2 Home Assistant 2023.4.6
В логах после инициализации колонок и отправки команды TTS " test":
2023-05-18 11:57:34.871 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_quasar] Получение списка устройств.
2023-05-18 11:57:37.959 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_quasar] Start quasar updates connection
2023-05-18 11:57:41.967 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_session] Обновление CSRF-токена, proxy: None
2023-05-18 11:57:43.708 WARNING (MainThread) [custom_components.yandex_station.core.utils] Can't get media_players
File "/config/custom_components/yandex_station/core/utils.py", line 378, in get_media_players
2023-05-18 11:57:43.772 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Локальное подключение
2023-05-18 11:57:43.772 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Обновление токена устройства
2023-05-18 11:57:43.772 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_session] Get music token
2023-05-18 11:57:43.970 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Вход | Установка кастомной иконки: yandex:station-mini-2
2023-05-18 11:57:44.088 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Кухня | Установка кастомной иконки: yandex:station-mini-2
2023-05-18 11:57:44.088 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Макс 0f81 | Установка кастомной иконки: yandex:station-max
2023-05-18 11:57:44.089 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Локальное подключение
2023-05-18 11:57:44.089 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Обновление токена устройства
2023-05-18 11:57:44.089 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_session] Get music token
2023-05-18 11:57:44.138 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Локальное подключение
2023-05-18 11:57:44.138 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Обновление токена устройства
2023-05-18 11:57:44.139 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_session] Get music token
2023-05-18 12:07:01.914 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Останавливаем локальное подключение
2023-05-18 12:07:01.914 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Останавливаем локальное подключение
2023-05-18 12:07:01.914 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Останавливаем локальное подключение
2023-05-18 12:07:01.915 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Вход | Возврат в облачный режим
2023-05-18 12:07:01.915 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Кухня | Возврат в облачный режим
2023-05-18 12:07:01.915 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Макс 0f81 | Возврат в облачный режим
2023-05-18 12:07:02.140 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_quasar] Получение списка устройств.
2023-05-18 12:07:02.669 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_quasar] Start quasar updates connection
2023-05-18 12:07:02.701 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_session] Обновление CSRF-токена, proxy: None
2023-05-18 12:07:03.385 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Вход | Установка кастомной иконки: yandex:station-mini-2
2023-05-18 12:07:03.386 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Кухня | Установка кастомной иконки: yandex:station-mini-2
2023-05-18 12:07:03.387 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Макс 0f81 | Установка кастомной иконки: yandex:station-max
2023-05-18 12:07:03.388 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Локальное подключение
2023-05-18 12:07:03.388 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Обновление токена устройства
2023-05-18 12:07:03.390 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Локальное подключение
2023-05-18 12:07:03.390 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Обновление токена устройства
2023-05-18 12:07:03.391 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Локальное подключение
2023-05-18 12:07:03.391 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Обновление токена устройства
2023-05-18 12:07:16.811 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Останавливаем локальное подключение
2023-05-18 12:07:16.811 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Макс 0f81 | Возврат в облачный режим
2023-05-18 12:07:16.815 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Макс 0f81 | Установка кастомной иконки: yandex:station-max
2023-05-18 12:07:16.817 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Локальное подключение
2023-05-18 12:07:16.817 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Макс 0f81 | Обновление токена устройства
2023-05-18 12:08:50.018 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Останавливаем локальное подключение
2023-05-18 12:08:50.019 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Кухня | Возврат в облачный режим
2023-05-18 12:08:50.022 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Кухня | Установка кастомной иконки: yandex:station-mini-2
2023-05-18 12:08:50.024 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Локальное подключение
2023-05-18 12:08:50.024 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Кухня | Обновление токена устройства
2023-05-18 12:09:07.468 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Останавливаем локальное подключение
2023-05-18 12:09:07.468 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Вход | Возврат в облачный режим
2023-05-18 12:09:07.472 DEBUG (MainThread) [custom_components.yandex_station.media_player] Яндекс Станция Вход | Установка кастомной иконки: yandex:station-mini-2
2023-05-18 12:09:07.476 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Локальное подключение
2023-05-18 12:09:07.476 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_glagol] Яндекс Станция Вход | Обновление токена устройства
2023-05-18 13:16:55.060 DEBUG (MainThread) [custom_components.yandex_station] Yandex say to: media_player.yandex_station_0f81
2023-05-18 13:16:55.064 DEBUG (MainThread) [custom_components.yandex_station.core.yandex_quasar] Яндекс Станция Макс 0f81 => cloud | test
2023-05-18 13:17:01.674 DEBUG (MainThread) [custom_components.yandex_station] Yandex say to: media_player.yandex_station_entrance
2023-05-18 13:17:07.130 DEBUG (MainThread) [custom_components.yandex_station] Yandex say to: media_player.yandex_station_kitchen
Рабочий вариант yandex_quasar.py
сущности появляются, но TTS работает только на Станция Макс Яндекс.
`
import asyncio
import json
import logging
from typing import Optional
from aiohttp import WSMsgType
from .yandex_session import YandexSession
_LOGGER = logging.getLogger(__name__)
IOT_TYPES = {
"on": "devices.capabilities.on_off",
"temperature": "devices.capabilities.range",
"fan_speed": "devices.capabilities.mode",
"thermostat": "devices.capabilities.mode",
"heat": "devices.capabilities.mode",
"volume": "devices.capabilities.range",
"pause": "devices.capabilities.toggle",
"mute": "devices.capabilities.toggle",
"channel": "devices.capabilities.range",
"input_source": "devices.capabilities.mode",
"brightness": "devices.capabilities.range",
"color": "devices.capabilities.color_setting",
"work_speed": "devices.capabilities.mode",
"humidity": "devices.capabilities.range",
"ionization": "devices.capabilities.toggle",
"backlight": "devices.capabilities.toggle",
# kettle:
"keep_warm": "devices.capabilities.toggle",
"tea_mode": "devices.capabilities.mode",
# don't work
"hsv": "devices.capabilities.color_setting",
"rgb": "devices.capabilities.color_setting",
"temperature_k": "devices.capabilities.color_setting",
}
MASK_EN = "0123456789abcdef-"
MASK_RU = "оеаинтсрвлкмдпуяы"
URL_USER = "https://iot.quasar.yandex.ru/m/user"
URL_V3_USER = "https://iot.quasar.yandex.ru/m/v3/user"
def encode(uid: str) -> str:
"""Кодируем UID в рус. буквы. Яндекс привередливый."""
return "ХА " + "".join([MASK_RU[MASK_EN.index(s)] for s in uid])
def decode(uid: str) -> Optional[str]:
"""Раскодируем UID из рус.букв."""
try:
return "".join([MASK_EN[MASK_RU.index(s)] for s in uid[3:]])
except Exception:
return None
class YandexQuasar:
# all devices
devices = None
online_updated: asyncio.Event = None
updates_task: asyncio.Task = None
def __init__(self, session: YandexSession):
self.session = session
self.online_updated = asyncio.Event()
self.online_updated.set()
@property
def hass_id(self):
for device in self.devices:
if device["name"] == "Yandex Intents":
return device["id"]
return None
async def init(self):
"""Основная функция. Возвращает список колонок."""
_LOGGER.debug("Получение списка устройств.")
r = await self.session.get(f"{URL_V3_USER}/devices")
resp = await r.json()
assert resp["status"] == "ok", resp
self.devices = []
for house in resp["households"]:
if "sharing_info" in house:
continue
self.devices += house["all"]
@property
def speakers(self):
return [
d
for d in self.devices
if d["type"].startswith("devices.types.smart_speaker.")
]
@property
def modules(self):
# modules don't have cloud scenarios
return [
d
for d in self.devices
if "quasar_info" in d
and d["quasar_info"]["platform"].startswith(
("yandexmodule", "yandex_tv", "goya")
)
]
async def load_speakers(self) -> list:
speakers = self.speakers
# Яндекс начали добавлять device_id и platform с полным списком
# устройств
# for speaker in speakers:
# await self.load_speaker_config(speaker)
scenarios = await self.load_scenarios()
for speaker in speakers:
device_id = speaker['id']
try:
if device_id not in scenarios:
await self.add_scenario(device_id)
scenarios = await self.load_scenarios()
speaker['scenario_id'] = scenarios[device_id]['id']
except:
print('bad')
return speakers
async def load_speaker_config(self, device: dict):
"""Загружаем device_id и platform для колонок. Они не приходят с полным
списком устройств.
"""
r = await self.session.get(f"{URL_USER}/devices/{device['id']}/configuration")
resp = await r.json()
assert resp["status"] == "ok", resp
# device_id and platform
device.update(resp["quasar_info"])
async def load_scenarios(self) -> dict:
"""Получает список сценариев, которые мы ранее создали."""
r = await self.session.get(f"{URL_USER}/scenarios")
resp = await r.json()
assert resp["status"] == "ok", resp
return {
decode(d["name"]): d
for d in resp["scenarios"]
if d["name"].startswith("ХА ")
}
async def add_scenario(self, device_id: str):
"""Добавляет сценарий-пустышку."""
name = encode(device_id)
payload = {
"name": name,
"icon": "home",
"triggers": [{"type": "scenario.trigger.voice", "value": name[3:]}],
"steps": [
{
"type": "scenarios.steps.actions",
"parameters": {
"requested_speaker_capabilities": [],
"launch_devices": [
{
"id": device_id,
"capabilities": [
{
"type": "devices.capabilities.quasar.server_action",
"state": {
"instance": "phrase_action",
"value": "пустышка",
},
}
],
}
],
},
}
],
}
r = await self.session.post(f"{URL_USER}/scenarios", json=payload)
resp = await r.json()
if resp["status"] != "ok":
print()
assert resp["status"] == "ok", resp
async def add_intent(self, name: str, text: str, num: int):
speaker = (
[
{
"type": "devices.capabilities.quasar.server_action",
"state": {"instance": "phrase_action", "value": text},
}
]
if text
else [
{
"type": "devices.capabilities.quasar.server_action",
"state": {
"instance": "text_action",
"value": "Yandex Intents громкость 100",
},
}
]
)
payload = {
"name": name,
"icon": "home",
"triggers": [{"type": "scenario.trigger.voice", "value": name}],
"steps": [
{
"type": "scenarios.steps.actions",
"parameters": {
"requested_speaker_capabilities": speaker,
"launch_devices": [
{
"id": self.hass_id,
"capabilities": [
{
"type": "devices.capabilities.range",
"state": {
"instance": "volume",
"relative": False,
"value": num,
},
}
],
}
],
},
}
],
}
r = await self.session.post(f"{URL_USER}/scenarios", json=payload)
resp = await r.json()
assert resp["status"] == "ok", resp
async def send(self, device: dict, text: str, is_tts: bool = False):
"""Запускает сценарий на выполнение команды или TTS."""
# skip send for yandex modules
if "scenario_id" not in device:
return
_LOGGER.debug(f"{device['name']} => cloud | {text}")
action = "phrase_action" if is_tts else "text_action"
name = encode(device["id"])
payload = {
"name": name,
"icon": "home",
"triggers": [{"type": "scenario.trigger.voice", "value": name[3:]}],
"steps": [
{
"type": "scenarios.steps.actions",
"parameters": {
"requested_speaker_capabilities": [],
"launch_devices": [
{
"id": device["id"],
"capabilities": [
{
"type": "devices.capabilities.quasar.server_action",
"state": {"instance": action, "value": text},
}
],
}
],
},
}
],
}
sid = device["scenario_id"]
r = await self.session.put(f"{URL_USER}/scenarios/{sid}", json=payload)
resp = await r.json()
assert resp["status"] == "ok", resp
r = await self.session.post(f"{URL_USER}/scenarios/{sid}/actions")
resp = await r.json()
assert resp["status"] == "ok", resp
async def load_local_speakers(self):
"""Загружает список локальных колонок. Не используется."""
try:
r = await self.session.get("https://quasar.yandex.net/glagol/device_list")
resp = await r.json()
return [
{"device_id": d["id"], "name": d["name"], "platform": d["platform"]}
for d in resp["devices"]
]
except:
_LOGGER.exception("Load local speakers")
return None
async def get_device_config(self, device: dict) -> dict:
payload = {
"device_id": device["quasar_info"]["device_id"],
"platform": device["quasar_info"]["platform"],
}
r = await self.session.get(
"https://quasar.yandex.ru/get_device_config", params=payload
)
resp = await r.json()
assert resp["status"] == "ok", resp
return resp["config"]
async def set_device_config(self, device: dict, device_config: dict):
_LOGGER.debug(f"Меняем конфиг станции: {device_config}")
payload = {
"device_id": device["quasar_info"]["device_id"],
"platform": device["quasar_info"]["platform"],
}
r = await self.session.post(
"https://quasar.yandex.ru/set_device_config",
params=payload,
json=device_config,
)
resp = await r.json()
assert resp["status"] == "ok", resp
async def get_device(self, deviceid: str):
r = await self.session.get(f"{URL_USER}/devices/{deviceid}")
resp = await r.json()
assert resp["status"] == "ok", resp
return resp
async def device_action(self, deviceid: str, **kwargs):
_LOGGER.debug(f"Device action: {kwargs}")
actions = []
for k, v in kwargs.items():
type_ = (
"devices.capabilities.custom.button" if k.isdecimal() else IOT_TYPES[k]
)
state = (
{"instance": k, "value": v, "relative": True}
if k in ("volume", "channel")
else {"instance": k, "value": v}
)
actions.append({"type": type_, "state": state})
r = await self.session.post(
f"{URL_USER}/devices/{deviceid}/actions", json={"actions": actions}
)
resp = await r.json()
assert resp["status"] == "ok", resp
async def update_online_stats(self):
if not self.online_updated.is_set():
await self.online_updated.wait()
return
self.online_updated.clear()
# _LOGGER.debug(f"Update speakers online status")
try:
r = await self.session.get("https://quasar.yandex.ru/devices_online_stats")
resp = await r.json()
assert resp["status"] == "ok", resp
except:
return
finally:
self.online_updated.set()
for speaker in resp["items"]:
for device in self.devices:
if (
"quasar_info" not in device
or device["quasar_info"]["device_id"] != speaker["id"]
):
continue
device["online"] = speaker["online"]
break
async def _updates_connection(self, handler):
r = await self.session.get("https://iot.quasar.yandex.ru/m/v3/user/devices")
resp = await r.json()
assert resp["status"] == "ok", resp
ws = await self.session.ws_connect(resp["updates_url"], heartbeat=60)
_LOGGER.debug("Start quasar updates connection")
async for msg in ws:
if msg.type != WSMsgType.TEXT:
break
resp = msg.json()
# "ping", "update_scenario_list"
if resp.get("operation") != "update_states":
continue
try:
resp = json.loads(resp["message"])
for upd in resp["updated_devices"]:
if not upd.get("capabilities"):
continue
for cap in upd["capabilities"]:
state = cap.get("state")
if not state:
continue
if cap["type"] == "devices.capabilities.quasar.server_action":
for speaker in self.speakers:
if speaker["id"] == upd["id"]:
entity = speaker.get("entity")
if not entity:
break
state["entity_id"] = entity.entity_id
state["name"] = entity.name
await handler(state)
break
except:
_LOGGER.debug(f"Parse quasar update error: {msg.data}")
async def _updates_loop(self, handler):
while True:
try:
await self._updates_connection(handler)
except Exception as e:
_LOGGER.debug(f"Quasar update error: {e}")
await asyncio.sleep(30)
def handle_updates(self, handler):
self.updates_task = asyncio.create_task(self._updates_loop(handler))
def stop(self):
if self.updates_task:
self.updates_task.cancel()
async def set_account_config(self, key: str, value):
kv = ACCOUNT_CONFIG.get(key)
assert kv and value in kv["values"], f"{key}={value}"
if kv.get("api") == "user/settings":
# https://iot.quasar.yandex.ru/m/user/settings
r = await self.session.post(
URL_USER + "/settings", json={kv["key"]: kv["values"][value]}
)
else:
r = await self.session.get("https://quasar.yandex.ru/get_account_config")
resp = await r.json()
assert resp["status"] == "ok", resp
payload: dict = resp["config"]
payload[kv["key"]] = kv["values"][value]
r = await self.session.post(
"https://quasar.yandex.ru/set_account_config", json=payload
)
resp = await r.json()
assert resp["status"] == "ok", resp
BOOL_CONFIG = {"да": True, "нет": False}
ACCOUNT_CONFIG = {
"без лишних слов": {
"api": "user/settings",
"key": "iot",
"values": {
"да": {"response_reaction_type": "sound"},
"нет": {"response_reaction_type": "nlg"},
},
},
"ответить шепотом": {
"api": "user/settings",
"key": "tts_whisper",
"values": BOOL_CONFIG,
},
"анонсировать треки": {
"api": "user/settings",
"key": "music",
"values": {
"да": {"announce_tracks": True},
"нет": {"announce_tracks": False},
},
},
"скрывать названия товаров": {
"api": "user/settings",
"key": "order",
"values": {
"да": {"hide_item_names": True},
"нет": {"hide_item_names": False},
},
},
"звук активации": {"key": "jingle", "values": BOOL_CONFIG}, # /get_account_config
"одним устройством": {
"key": "smartActivation", # /get_account_config
"values": BOOL_CONFIG,
},
"понимать детей": {
"key": "useBiometryChildScoring", # /get_account_config
"values": BOOL_CONFIG,
},
"рассказывать о навыках": {
"key": "aliceProactivity", # /get_account_config
"values": BOOL_CONFIG,
},
"взрослый голос": {
"key": "contentAccess", # /get_account_config
"values": {
"умеренный": "medium",
"семейный": "children",
"безопасный": "safe",
"без ограничений": "without",
},
},
"детский голос": {
"key": "childContentAccess", # /get_account_config
"values": {
"безопасный": "safe",
"семейный": "children",
},
},
"имя": {
"key": "spotter", # /get_account_config
"values": {
"алиса": "alisa",
"яндекс": "yandex",
},
},
}
`
Сущности Yandex станций пропали после обновлений HA с версии 2023.3. Обновления интеграции до версии 3,12,2 не принесли результата. Появляется только сущность эквалайзер. Колонки: 2 Станции Мини 2 Яндекс с дисплеем и Станция Макс Яндекс. Если заменить оригинальный yandex_quasar.py версии 3,12,2 на другой (код ниже), то сущности появляются, но TTS работает только на Станция Макс Яндекс. `
У меня тоже пропали сущности станций после обновления до 2023.5.4. Воспользовался вашим файлом (взял из него только метод load_speakers) и все заработало как и раньше. Есть колонки мини с часами и лайт - на всех и tts работает и вся остальная функциональность.
Рабочий вариант yandex_quasar.py
Впервые пытаюсь настроить интеграцию.
Home Assistant была версии 7.3.
Интеграция не появлялась в установленных после прохождения QR-кода, после попыток ввода одноразового ключа, Coocies тоже выдают ошибку.
Обновил Home Assistant на версию 8.0.
Тоже не запускается.
До этого у меня стояла и стоит интеграция Yandex Smart Home.
Надеюсь она не мешает.
Попробовал вставить ваш код в /config/custom_components/yandex_station/core/yandex_quasar.py
.
Ничего не изменилось.
Что делать-то?
Сущности Yandex станций пропали после обновлений HA с версии 2023.3. Обновления интеграции до версии 3,12,2 не принесли результата. Появляется только сущность эквалайзер. Колонки: 2 Станции Мини 2 Яндекс с дисплеем и Станция Макс Яндекс. Если заменить оригинальный yandex_quasar.py версии 3,12,2 на другой (код ниже), то сущности появляются, но TTS работает только на Станция Макс Яндекс. `
У меня тоже пропали сущности станций после обновления до 2023.5.4. Воспользовался вашим файлом (взял из него только метод load_speakers) и все заработало как и раньше. Есть колонки мини с часами и лайт - на всех и tts работает и вся остальная функциональность.
Подтверждаю, заменил у себя только метод load_speakers и появились сущности и весь функционал как и был до того как пропал
Добрый день! Сейчас столкнулся с подобной проблемой YS 3.12.4 не проходит авторизация а если таки проходит то не появляются сами устройства. При этом еще два сервера HA с такими же версиями софта работают без проблем. Есть какое то решение? Ну или может кто подскажет в чем причина такого поведения?
Если сервера работают - заберите с них авторизацию и войдите по токену
Если сервера работают - заберите с них авторизацию и войдите по токену
в home assistant токен можно найти ./.storage/core.config_entries
Если сервера работают - заберите с них авторизацию и войдите по токену
КАК ЭТО МОЖНО СДЕЛАТЬ, ОБЪЯСНИТЕ ПЛИЗ? ЧТО ОТКУДА И КУДА СКОПИРОВАТЬ?