Сломался пульт от телевизора. За вечер написал свой — на айфон
Пульт от телевизора начал жить своей жизнью: нажимаешь «вниз» — переключается вход, нажимаешь громкость — уходит в меню. Телевизор при этом отличный, умный, на Android TV. Обидная ситуация: устройство целое, а управлять им нечем.
Первым делом я пошёл туда, куда идут все: в приложение Google Home. Телевизор там виден, громкость даже регулируется. А кнопка «Открыть пульт» — серая и не нажимается. Почему — не объясняют. Погуглил: жалуются многие, рецепта нет.
Дальше можно было купить новый пульт и ждать неделю. Но телевизор — обычное сетевое устройство, оно стоит в моей же квартире, в моей же сети. Значит, до него можно достучаться напрямую. Сел разбираться вместе с Claude Code.
Сначала костыль, потом приложение
Первая версия заработала минут за двадцать: маленький сервер на макбуке, который говорит с телевизором, и веб-страница с кнопками — открываешь её на телефоне в браузере. Работает. Но есть изъян: всё это живёт, пока включён макбук. Пульт, который зависит от ноутбука, — так себе пульт.
Поэтому дальше я переписал протокол связи с телевизором на Swift — и получилось нативное приложение для айфона, которое говорит с телевизором само, без посредников. Ни облака, ни аккаунта, ни единого запроса наружу: только домашняя сеть.
Место, где всё пошло не по плану
Кнопки заработали сразу. А вот плитки быстрого запуска приложений — нет. В протоколе пульта есть команда «открой приложение», телевизор её принимает и... ничего не делает. Молча.
Я перебрал все известные способы записать такую команду: имя пакета, ссылку через магазин приложений, две разновидности системных ссылок, и даже прямое указание точки входа. Каждый раз проверял результат объективно — считывал с телевизора, что у него сейчас на экране. Каждый раз телевизор оставался на своём месте.
Вывод неприятный, но полезный: на этой прошивке штатный способ запуска приложений просто не работает. Пришлось написать внутри приложения собственный клиент ADB — это отладочный протокол Android. Через него команда запуска отрабатывает всегда. Так в маленьком пульте оказалось два сетевых протокола вместо одного, и оба — свои, написанные с нуля.
Иконки, которые не пришлось рисовать
Хотелось, чтобы плитки выглядели как в лаунчере телевизора, а не как кружочки из иконочного набора. Оказалось, можно не рисовать: у приложений для Android TV внутри лежит готовый широкий баннер — тот самый, который телевизор показывает на главном экране. Мы его просто достали из самого телевизора. Для двух приложений, у которых баннера нет, плитку собрали из их же иконки на её собственном фоне — чтобы ряд читался единым целым.
А телевизор, оказывается, был болен
По дороге всплыла отдельная история. Телевизор время от времени пропадал из сети: картинка на экране есть, а не отвечает ни на что. Сначала я решил, что он спит. Потом заметил странность: уже открытые соединения продолжали работать, а новые он отшивал.
Разгадка нашлась в диагностике: телевизор отвечал, что у него завис системный процесс. В таком состоянии он и сеть не держит, и не будится — ни по сети, ни магическим пакетом. Лечится только перезагрузкой изнутри системы. С тех пор всё ровно.
Чем это кончилось
Пульт живёт на трёх устройствах в доме: два айфона и айпад. Кольцо навигации, назад и домой, крупная качелька звука, ввод текста с клавиатуры телефона вместо тыканья стрелками по экранной раскладке, плитки любимых приложений и зелёная точка, показывающая, что на телевизоре поднят VPN.
Подписчики попросили такое же — и я выложил исходники. Забрать можно на GitHub, лицензия свободная. Внутри репозитория нет никаких ключей: привязка к телевизору делается на своей стороне. Инструкция написана так, что её может выполнить не только человек, но и ИИ-агент: скачал, открыл у себя Claude Code, сказал «поставь по инструкции» — дальше он сам найдёт телевизор в сети, проведёт привязку и соберёт пульт под ваши приложения.
Подробности и ссылка на код — на странице приложения.