Мой гибридный сетап

Игры, фильмы и прочее – с телефона не вставая с дивана

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

Хочу сразу оговориться – делал "для себя" и планировал "по-быстрому за вечер" (процесс растянулся на неделю). Почти со всеми инструментами был незнаком, либо сталкивался всего раз или два в жизни, так что получилось как получилось. Какие-то вещи добавлял или дорабатывал в процессе использования, какие-то в планах были/есть, но нужды в них не чувствую, так что пока забил. Когда-нибудь может быть сделаю все "правильнее" и "красивее", но сейчас пока лень. Работает все нормально – ну и ладно.

Практически весь код для внешнего вида (yaml) делала нейронка. У меня тут ни фантазии, ни вкуса, да и с yaml опять же никогда раньше не работал.

Что было вначале

Игровой ПК со звуковой картой. Телевизор 75" 4K@120Hz (HDR, FreeSync). Просто дублировать основной экран мне не хочется, хочу использовать телик на полную, так что немного заморочился. Кроме телевизора еще два монитора. Ресивер, колонки 5.1.

Подключение к телевизору через HDMI кабель. Подключение к ресиверу от звуковой карты тремя кабелями mini-jack – RCA. Для звука так же использую Equalizer APO – создал профили для разных режимов (небольшой апмикс сабвуфера для 5.1, разные апмиксы для музыки, двухканальных фильмов и сериалов).

Изначально для управления ПК с телефона использовал программу Unified Remote – классная программа, которая предоставляет различные "пульты". С появлением Equalizer APO решил попробовать написать свой пульт для переключения режимов. После этого подумал "я же могу делать пульты для разных штук!". Так, следующим я модернизировал пульт для управления плеером (MPV) – скопировал стандартный, которым пользовался, и добавил туда кнопок, которых мне не хватало. После этого сделал пульт для скана компа на игры и их запуск. Тут уже пришел к использованию Display Magician и его профилей для переключения телевизора в качестве основного либо единственного экрана.

Немного про Display Magician

Мой гибридный сетап

Сначала пытался использовать MultiMonitorTool – и его профили, и прописывать вручную в скрипте PowerShell параметры. Все полная фигня – Windows, как оказалось, плохо работает с экранами если их больше двух. То HDR слетит на телевизоре, но останется включенным в винде, то частота слетит, то расположение экранов, то FreeSync. Display Magician плюс-минус неплохо справляется, остановился на нем. В его графическом интерфейсе создал профили и переключаю их скриптами, используя консольный вариант. Выглядит команда для переключения на нужный профиль примерно так:

C:\Program Files\DisplayMagician\DisplayMagicianConsole.exe ChangeProfile "2348e677-12ba-49f9-9ab7-6810487d683d"

Итак, делая пульт для запуска игр, уже в процессе, я понял, что мне уже не хватает Unified Remote, да и поддержка его в Shortcuts на iOS куда-то исчезла, и сама программа перестала обновляться с 2021 года или около того. Нужно что-то актуальнее. Так, посовещавшись с нейронками, выбор пал на Home Assistant.

Что было потом

Итак, я думал, все будет легко, найду нужные интеграции, автоматизации, дэшборды, за вечер все поставлю, сделаю немного под себя и буду кайфовать. Но поиски каких-нибудь "пультов для ПК" не увенчались успехами, так что пришлось все делать самому.

Я не буду описывать процесс, с чем мне пришлось столкнуться, какие были проблемы, лучше расскажу о том, к чему я пришел в итоге.

Как это работает

Мой гибридный сетап

Так как почти со всем этим я работал впервые, не особо вдаваясь в терминологию и, иногда, даже стараясь не глубоко влезать в предназначение, постараюсь рассказать своими словами, но могу где-то ошибиться.

Итак, на ПК установлен Docker Desktop – программа для запуска контейнеров, работает через WSL2. Стартует с Windows, висит в фоне, ресурсов почти не требует. Контейнер – это что-то типа виртуальной машины, но быстрее и требует меньше ресурсов. Ну типа того. Кто часто с этим работает, наверное, сможет объяснить правильнее.

Внутри Docker – четыре контейнера:

  • Home Assistant – мозг (ну или как минимум полушарие) всей системы. В нем можно писать скрипты для действий и кнопок, автоматизации (что делать, если что-то другое изменилось), и дашборды (интерфейс).
  • Mosquitto – MQTT-брокер, посредник между всеми остальными компонентами. Один отправил сообщение, другой получил и что-то сделал.
  • Zigbee2MQTT – мост между Zigbee-устройствами и Home Assistant. На данный момент используется с USB-стиком для одного датчика температуры и влажности.
  • Music Assistant – сервер для музыки. Через него подключена Яндекс.Музыка. Сервер не видит звуковую карту напрямую, поэтому на Windows запущен Squeezelite – легкий аудиоплеер без интерфейса, который принимает поток от Music Assistant и воспроизводит его через звуковую карту.

На самой Windows работает HASS.Agent – программа для обмена сообщениями между контейнерами и Windows. HASS.Agent работает в двух направлениях:

  1. Команды (HA –> Windows) – Home Assistant отправляет MQTT сообщение, HASS.Agent выполняет соответствующее действие: запуск PowerShell-скрипта, отправляет команду MPV, нажимает медиа-клавишу, меняет громкость.
  2. Сенсоры (Windows –> HA) – HASS.Agent каждую секунду отправляет в Home Assistant данные с ПК: текущая громкость, название текущего файла в MPV, активный профиль EQ-APO, состояние дисплеев. HA использует эти данные в интерфейсе и автоматизациях.
Мой гибридный сетап

Второе, так сказать, полушарие системы – PowerShell-скрипты на Windows. Они делают то, что HA из контейнера не может: переключить профиль экранов через Display Magician, запустить игру, запустить скан игр, поменять профиль EQ-APO. Часть из них запускается по команде от HASS.Agent, часть – через планировщик задач.

Пример скрипта запуска игры
Пример скрипта запуска игры

В планировщике задач Windows 5 фоновых задач, которые стартуют с ПК: Docker, мост для Zigbee-стика, аудио-мост Squeezelite и пара задач для управления UAC при запуске игр (на случай если запуск игры требует подтверждение администратора).

Через Wi-Fi подключен ИК-хаб Broadlink RM4C Mini для управления кондеем.

Вроде бы ничего не забыл, теперь чуть подробнее про некоторые дэшборды.

Game Launcher

С него, наверное, и началось. Ради него я и полез в Home Assistant. Нажал одну кнопку в телефоне – и ПК сам переключился на ТВ, перекинул звук на ресивер и запустил игру. Без клавиатуры, без мыши, не вставая с дивана. Так как часть скриптов уже была реализована в пульте для Unified Remote, вышло еще относительно несложно. Но теперь мне еще хотелось какой-то более современный интерфейс. Итак, как же это работает

Мой гибридный сетап

Для начала, нам нужно найти наши игры. Для этого PowerShell-скрипт сканирует три источника:

  1. Steam – сначала сканер находит все библиотеки Steam через libraryfolders.vdf (игры могут быть на разных дисках), потом в каждой библиотеке читает файлы appmanifest_*.acf – в них название игры и папка установки. По папке ищет подходящий .exe.
  2. NVIDIA App – она сама сканирует комп на наличие игр, но вытащить этот сканер неоткуда. Видимо, сверяется со своими базами онлайн? Без понятия, нашел только кучу скриптов lua, но они какие-то нечитабельные. Зато еще нашел результаты сканирования – мой скрипт просто читает готовый JSON из AppData\Local\NVIDIA Corporation\NVIDIA App\NvBackend\ApplicationStorage.json. Туда попадают в том числе игры не из Steam (а еще некоторые программы).
  3. Папка C:\Shortcuts – для всего остального. Кинул ярлык – игра появилась в списке.

Из всех трёх источников собирается единый список. Дубли отсеиваются, каждый .exe проверяется на существование. Для каждой игры записывается время последнего запуска в отдельный файл – список сортируется сначала по нему (недавние сверху), потом по алфавиту. Избранные – всегда на самом верху и тоже со своей сортировкой.

Постеры, к сожалению, не удалось автоматизировать – добавляю вручную в папку. Скрипт ищет файл с именем игры (очищенным от спецсимволов), поддерживает webp, gif, jpg, png. Если не нашёл – ставит заглушку.

Вот такую  первую попавшуюся картинку взял в качестве заглушки
Вот такую  первую попавшуюся картинку взял в качестве заглушки

Долгий тап по карточке открывает попап с опциями: показывает полный путь к .exe, открывает папку с игрой на ПК или скрывает игру из списка – как раз на случай, когда сканер нашёл не саму игру, а её лаунчер или какую-то другую программу из того же списка NVIDIA App. Там же – кнопка добавления в избранное.

Мой гибридный сетап

Нажимаешь на карточку – HA отправляет MQTT-команду с путём к .exe, HASS.Agent принимает её и запускает главный PowerShell-скрипт. Тот по цепочке вызывает остальные: отключает UAC через задачу в Планировщике по SSH, переключает аудиовыход на ресивер, переключает дисплей на ТВ-профиль через Display Magician.

После этого скрипт ждёт ~12 секунд, пока экраны стабилизируются, сворачивает все окна, запускает игру и включает мониторинг процесса – HA каждые 30 секунд проверяет, запущена ли игра и пока она запущена рисует дополнительные анимации. В конце – UAC включается обратно, запускается повторный скан папок, чтобы обновить сортировку по последнему запуску.

Пульт для MPV

Уже давно перешел с MPC-HC на MPV плеер и в Unified Remote делал под него так же пульт. Поэтому тут было вначале несложно – просто перенести имеющийся функционал в Home Assistant.

Мой гибридный сетап

Большинство кнопок работают через одну и ту же цепочку: нажал в HA –> MQTT –> HASS.Agent –> отправляет JSON-команду в named pipe \\.\pipe\mpvserver.

Named pipe – это канал, через который программы могут общаться друг с другом. MPV при запуске создаёт его, и любая программа на том же ПК может записать туда команду – MPV прочитает и выполнит. По сути, каждая кнопка – это одна строчка, например

echo {"command": ["cycle", "pause"]} > \\.\pipe\mpvserver

Исключение – громкость: она управляется не через MPV, а через изменение системной громкости Windows. Кнопки тише/громче отправляют команду нажатия медиа-клавиш, а слайдер напрямую выставляет значение через HASS.Agent.

На пульте:

  • Громкость – три кнопки (тише, мьют, громче) и слайдер на всю ширину. Слайдер синхронизирован с Windows в обе стороны: двигаешь на телефоне – громкость меняется на ПК, меняешь на ПК – слайдер обновляется. Поверх слайдера отображается название текущего файла в MPV – отдельный сенсор в HASS.Agent. PowerShell-скрипт каждую секунду читает заголовок окна MPV и отправляет в HA.
  • Перемотка – плюс-минус 5 секунд и плюс-минус 60 секунд. Раньше для этого нажимал в Unified Remote стрелки клавиатуры влево-вправо и вверх-вниз соответственно, привык. Теперь же это отдельная команда на перемотку на конкретное количество секунд.
  • Fullscreen – переключение полноэкранного режима. Хотя автоматом запускается сразу в полноэкранном режиме.
  • Anime4K – включение/выключение апскейла для аниме. Отправляет хоткей Ctrl+4 или Ctrl+0 через тот же named pipe в зависимости от текущего состояния. Кнопка подсвечивается фиолетовым, когда апскейл активен. Состояние читается из файла на ПК раз в секунду.
  • Аудио и субтитры – переключение дорожек. Удобно для случаев, когда в файле несколько аудиодорожек или субтитров (а это почти всегда).
  • Навигация по главам – prev/next chapter, для файлов с разбивкой на главы.
  • Prev/Next файл – переключение между файлами в плейлисте MPV. Изначально MPV запускает только те файлы, которые ты ему дашь и не смотрит на остальные файлы в папке. Решается это изменением файла конфига MPV.
  • Play/Pause.

Медиатека

Пульт я сделал быстро, но еще не закончив работу над ним, мне пришла в голову идея о том, что было бы удобно, если бы этот пульт мог не только управлять просмотром, но и запускать фильмы и сериалы. Решил разделить условно для своего комфорта все на три категории: аниме, полнометражки, сериалы.

Мой гибридный сетап

Все это добро беспорядочно хранилось в общем на трех жестких дисках. Создал на каждом отдельную папку playlists в корне, внутри папки с категориями anime, movies, shows. Все три папки playlists с каждого жесткого диска монтированы в контейнер HA. Да, над неймингом я не заморачивался. Более того, когда я это начинал делать, я еще даже не был уверен, что в итоге выйдет, так что даже названия дашборда и вкладок менял несколько раз, но в итоге забил – «Что значит имя? Роза пахнет розой, хоть розой назови ее, хоть нет».

Итак. Поскольку папки находятся уже внутри контейнера, то и сканер для всего этого – скрипт на python внутри самого HA, а не PowerShell-скрипты, как в случае с играми. При запуске он рекурсивно обходит три папки playlists, находит все видеофайлы (mkv, mp4, avi, m4v, mov), строит дерево папок и файлов, и сохраняет результат в JSON. Попутно для каждого видеофайла генерирует превью через FFmpeg – кадр на 10-й минуте, и, если не получилось из-за того, что файл короче 10 минут – делает превью на 5-й секунде.

Результат сохраняется в JSON-файл – плоский список всех тайтлов с вложенными сезонами и файлами. Из него же потом работает и навигация, админка и запуск. В нем для каждого элемента хранятся путь, имя, alias (кастомное отображаемое имя), ссылка на постер и флаг скрытия.

Выглядит это как-то так. Три кнопки категорий. Папки с тайтлами отображаются в виде постеров (тут тоже вручную добавлять), сами видеофайлы – вертикальные превью с названием. Так как названия часто бывают слишком длинными, то сделал так, что шаблон вытаскивает в этом интерфейсе номер серии и расширение. То есть, вместо, например, «[SOFCJ-Raws] Naruto Shippuuden - 006 (DVDRip 768x576 x264 VFR 10bit AC3).mkv» получается просто «006.mkv». Но вроде бы это работает не всегда. Иногда названия видимо слишком сложные бывают, хотя такое редко встречается.

Мой гибридный сетап

При нажатии на файл происходит запуск – переключение вывода звука на звуковую карту, отправка команды в HASS.Agent с путем к файлу с параметром запуска в полноэкранном режиме на телевизоре. Также, происходит замена пути контейнера на Windows-путь.

- action: mqtt.publish data: topic: homeassistant/button/MONOKURO/mpv_play_file/action payload: > {% set win_path = file_path | replace('/media/disk_d', 'D:\\playlists') | replace('/media/disk_e', 'E:\\playlists') | replace('/media/disk_i', 'I:\\playlists') | replace('/', '\\') %} "{{ win_path }}" --fs --fs-screen={{ states('sensor.tv_screen_number') | int(1) - 1 }}

Для управления всем этим так же сделал своего рода админ-панель. В ней можно как раз запускать скан, менять отображаемое имя тайтла/сезона/серии, присваивать имя постера, а также скрывать папку/файл – например, если это папка с дополнительными озвучками или сабами. Была мысля, конечно, дополнительно реализовать в ней возможность указать какую папку с озвучкой/сабами использовать, но... чет я так заебался, пока все это делал, да ну его.

Мой гибридный сетап

Немного про ТВ

Мой гибридный сетап

Для телевизора я сделал всего две кнопки – переключение уровня подсветки (мин/макс) и переключение источника ввода на HDMI1 (ПК).

Для этого HA посылает команды напрямую в телевизор через ADB – инструмент для отладки Android. Чтобы ночью лишний раз не слепил, посылаем команду на установку подсветки на уровень 1. Чтобы вернуть на максимум – 255.

Мой гибридный сетап

Для переключения источника ввода я не смог найти правильную команду (ну, я не особо и пытался, честно говоря), поэтому в данном случае используется что-то по типу макроса – HA отправляет цепочку команд. Открыть меню входов –> нажать вниз –> нажать OK. Да, костыльно. Но работает. Может быть когда-нибудь вернусь к этому и попробую еще раз сделать нормально, но... посмотрим.

Sound Control

Мой гибридный сетап

Как я уже упоминал, для звука я использую Equalizer APO. Его настройки хранятся в текстовых файлах, главный из которых config.txt. Внутри него записи по типу Include: mode.txt. Внутри mode.txt еще другие атомарные файлы с настройками. Переключение режимов происходит скриптом PowerShell – скрипт находит не закомментированную строку с Include, комментирует ее и раскомментировывает нужную строку и режим тут же меняется налету.

Выглядит это примерно так

config.txt файл в любом текстовом редакторе
config.txt файл в любом текстовом редакторе
Он же, но в редакторе Equalizer APO
Он же, но в редакторе Equalizer APO

Отдельно регулируется дополнительное усиление сабвуфера. Для этого используется нелинейный ползунок от 0 до 200, разбитый на три зоны:

  • 0-50 – от -20 дБ до -5 дБ, шаг 0.3 дБ. Тут точность не особо нужна, в любом случае, просто если захочется побаловаться и сравнить звучание с сабом и без.
  • 50-100% – от -5 дБ до 0 дБ (то есть, 0 дБ это середина ползунка), шаг 0.1 дБ. В некоторых режимах нужно сделать саб потише, в некоторых – погромче, так что в этом диапазоне мне нужно больше точности.
  • 100-200% – от 0 дБ до +5 дБ (шаг 0.05 дБ) – самый точный диапазон, чтобы не переборщить с басом. Не перенапрягать технику и не получать пердеж в уши, вместо мощных ударов.

Для всего это, конечно же, есть и сенсоры. То есть, если я что-то ручками поменяю в текстовом файле или через специальный редактор, то HA подхватит эти изменения и отобразит актуальную информацию.

Маленькие удобства для телефона

На iOS использую Shortcuts («Команды»). Кто вдруг не знает – это встроенная программа для создания своих скриптов. Наверное, одна из самых веских причин перейти на Home Assistant. Делаешь любую дичь внутри HA, а потом делаешь на нее скрипт в Командах. Выводишь его хоть на основной экран, хоть на тапы по корпусу телефона, хоть на жесты часов. Да, apple вроде только относительно недавно показала жесты на своих часах, но я ими пользовался еще когда у меня была третья серия – делал Sleep и WoL, play/pause. Кроме того, все команды можно использовать через Сири, так что сразу еще и голосовое управление (я такое не люблю).

Но сейчас, как я и говорил, Unified Remote перестал поддерживать эти Команды и тут HA приходит на выручку.

Итак, использовал я их не то чтобы на максимум, всего лишь небольшие упрощения.

  • Четыре команды для запуска нужного дэшборда в виде ярлыков на основном экране телефона.
  • Изменение профиля APO и плюс-минус 0.1 дБ сабвуфера в виде кнопок в окне виджетов (через SSH, тут даже без участия HA).
  • Включение-выключение света в комнате – так же в виде кнопки в окне виджетов, но кроме этого еще и повесил на жест на часах. Теперь включаю-выключаю свет движением руки. Даже при интеграции светильника в Home Kit, если создать подобную команду через него, система просит разблокировать телефон. А вот HA не просит – удобно.
  • Кнопка для изменения уровня подсветки (мин/макс) телевизора.
Мой гибридный сетап

Для ярлыков можно ставить свою картинку, но я не пробовал, мне влом. Возможно, там есть определенные требования для нее, а может и нет.

А также, сделал автоматизации – при запуске определенных приложений отправляется команда паузы. Это как раз для тех случаев, когда девушку внезапно отвлекли где-то в телефоне (работа, подруги), чтобы не нужно было потом перематывать назад (:

Мой гибридный сетап

One more thing...

Не так давно добавил управление кондиционером с помощью ИК-хаба, подключил датчик температуры и влажности через USB Zigbee-стик – осталось допилить автоматизацию кондея по датчику. Интегрировал Яндекс Музыку – чтоб запускать яму с телефона сразу на компе. Ну и думаю, может что-то типа будильника еще сделать. Просыпаешься – а тут музыка играет, и уже прям доброе утро!

В общем...

Еще есть что добавить, многое можно улучшить, абсолютно все желательно привести в порядок, да и с неймингами у меня явные проблемы... Но чета так влом. Оно ж работает, многого не просит – ну и пускай! Как говорится: работает – не трогай! Делаю по мере появления идей, хотелок, сил и времени.

139
47
11
6
3
1
1
150 комментариев