Мой основной компьютер - macbook, который всегда со мной, и на котором я делаю почти все что нужно как дома так и вне его. Но также есть домашний комп, на котором бывает оптимальнее делать ресурсоемкие задачи. Кроме того, некоторые вещи на маке делать неудобно или вовсе невозможно, поэтому на домашнем на разных дисках установлены windows, ubuntu и proxmox с десятком виртуалок под разные случаи. И меня всегда очень напрягала невозможность удаленно включить нужную операционную систему на домашнем, чтобы потом подключиться к ней удаленно и сделать все что нужно.
И что вы думаете - решил я эту проблему. Теперь из любого места я могу запустить нужную мне операционную систему на домашнем компе одним кликом.
Конечно, без Home Assistant не обошлось.
Хорошенько подумав над задачей я увидел всего два надежных реализуемых варианта.
Первый - как то извне управлять GRUB, всегда запускаемым первым.
Второй - физически подключать нужный диск перед включением компьютера.
Поскольку мыжкампутерщики вариант загрузить что придется, руками поправить загрузчик и перезагрузиться не рассматривается. Ну и поскольку речь не о сервере а о бытовом компе варианта удаленной консоли управления тоже нет.
Как например можно реализовать первый вариант? Взять служебный небольшой диск, можно даже флешку или DoM. Установить на нее какую нибудь легковесную linux, и в конфиг ее grub'а записать все остальные диски, имеющиеся на компе. Компьютер должен всегда первым делом загружать эту служебную ось, а она, загрузившись, должна взять откуда то команду о том какую целевую ось загрузить следующей, внести изменения в свой конфиг, и перезагрузить компьютер. А затем из загрузившейся целевой системы первым делом исправить конфиг того загрузчика обратно. В целом рабочий вариант, но мне кажется сложным и ненадежным.
Второй вариант - управлять физическим подключением дисков. В биосе настроить каждый из этих дисков загрузочным, и собственно перед включением компа выключать лишние диски. Кажется надежнее и интереснее, но нужен какой то физический интерфейс управления. На этом варианте я и решил остановиться.
Часть первая - железная.
Купил вот такое четырехканальное zigbee реле Tuya.
Пока ехало, нарисовал и напечатал конструкцию для крепления дисков и реле
Немножко теории:
Современные sata диски по стандарту получают 5 (красный цвет) и 12 (желтый цвет) вольт. В целях совместимости еще 3,3 (оранжевый цвет) вольта иногда можно встретить, но чаще этот провод просто отсутствует.
Для работы SSD дискам нужно только 5 вольт. 12 по моему HDD нужно, а SSD без него прекрасно работают.
Поскольку у меня именно ssd, то врезаться будем в красный провод.
Дисклеймер: я не претендую на истину в последней инстанции, и все что делаю - делаю на свой страх и риск. Разумеется, это грубый обход стандартов, и он может мне аукнуться в будущем, но вряд ли серьезно, так как ничего важного или нерезервируемого на этих дисках нету, да и в целом этот комп мне не очень дорог. Если у вас ситуация другая, может быть вам стоит поискать другой вариант.
После сборки получилась такая конструкция:
Фото к сожалению не финальное, первой сборки, и там есть неточности. На фото реле управляет желтыми проводами, а нужно красными. Верную версию забыл сфотографировать. Верхний диск действительно hdd, правильный диск был занят пока, потом заменю. А еще в финальной версии выкинул колодку и все провода пропаял, на них были потери напряжения и это негативно сказывалось на работе.
Провода включены в нормально закрытые разъемы, то есть в выключенном состоянии реле все диски включены.
Раз дисков 3 а каналов 4 - а зачем же еще канал. А его я подключил к кнопке питания компьютера, прямо на контакты на материнке, в параллель к физической кнопке.
Следующим шагом было запитать реле и подключить его к home assistant. Для питания в закромах нашелся подходящий адаптер, ну а в процессе подключения нет ничего нового.
В результате у меня в HA появилось устройство, управляющее всем что нужно
Часть вторая - программная
Устройство есть, теперь надо сделать красиво.
Делаем скрипты в HA, которые будут нажимать на кнопки. Скрипт в данном контексте - это то же самое что автоматизация, только для ручного запуска, без авто-условий.
Скрипт запуска нужной операционной системы.
alias: Запустить Windows
sequence:
- service: switch.turn_off
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l1
- switch.rele_diskov_kompiutera_l2
- switch.rele_diskov_kompiutera_l2
- service: switch.turn_on
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l3
- switch.rele_diskov_kompiutera_l2
- service: switch.turn_on
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l4
- delay:
hours: 0
minutes: 0
seconds: 1
milliseconds: 0
- service: switch.turn_off
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l4
- service: input_boolean.turn_on
target:
entity_id: input_boolean.compon
data: {}
- delay:
hours: 0
minutes: 0
seconds: 90
milliseconds: 0
- service: switch.turn_off
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l1
- switch.rele_diskov_kompiutera_l2
- switch.rele_diskov_kompiutera_l3
mode: single
Поясню. Сначала на всякий случай подключаем все диски, вдруг осталось что то выключенное. Потом выключаем ненужные диски. Потом нажимаем кнопку питания компа, ждем секунду, и отпускаем ее. Потом включаем вспомогательный переключатель, хранящий в себе состояние компьютера, о нем ниже. Потом ждем 90 секунд, и подключаем остальные диски, они уже не помешают.
Помним, что состояние дисков инвертировано, то есть включая "отключить диск" я его физически отключаю.
Такие же скрипты делаем для остальных операционных систем, номера контактов будут отличаться.
Добавляем еще два скрипта, эмулирующих нажатие кнопки питания.
alias: Тык питание компа
sequence:
- service: switch.turn_on
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l4
- delay:
hours: 0
minutes: 0
seconds: 1
milliseconds: 0
- service: switch.turn_off
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l4
mode: single
alias: Долгий тык питание компа
sequence:
- service: switch.turn_on
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l4
- delay:
hours: 0
minutes: 0
seconds: 5
milliseconds: 0
- service: switch.turn_off
data: {}
target:
entity_id:
- switch.rele_diskov_kompiutera_l4
mode: single
Долгий тык нужен для принудительного выключения компа, если операционная система не реагирует на короткий и не завершает работу правильно.
Теперь можно позапускать скрипты и насладиться перещелкиванием реле и запуском нужных осей. Но еще некрасиво. Добавим еще немного свистелок. Лично мне не хватает наглядной информации о том что сейчас запущено.
Сделаю это так - после запуска каждая из операционных систем будет периодически стучаться в HA представляться и сообщать что она запущена. А тот соответственно будет проверять - было ли обновление состояния, и если нет то считать комп выключенным. Получится такой примитивный активный мониторинг.
В HA добавляем вспомогательный элемент типа Список. Назовем его например compstate и заполним списком с текущими. И еще один типа Переключатель - compon.
Для возможности обращения по api добавим токен. Это делается в параметрах текущего пользователя
Теперь со всех операционных систем надо настроить обращение по api и передачу состояния. Я не буду описывать конкретные методы, они могут отличаться в разных системах. Суть проста. Надо отправить POST запрос на http://ip_адрес_сервера_HA:8123/api/states/input_select.compstate, авторизоваться токеном, и передать json с одним из вариантов, добавленных ранее в список. В большинстве случаев подойдет curl, он есть и для windows. Ну то есть добавляем в cron или в планировщик вызов курла, или делаем это любым другим подходящим способом.
curl \
-H "Authorization: Bearer тут_вставить_токен" \
-H "Content-Type: application/json" \
-d '{"state": "ubuntu"}}' \
http://ip_адрес_сервера_HA:8123/api/states/input_select.compstate
Можно попробовать, и убедиться что состояние вспомогательного элемента compstate меняется.
Теперь делаем автоматизацию, которая будет проверять состояние этого элемента. Я о ней упоминал выше, убедитесь что в скрипте запуска верное имя.
Создаем новую автоматизацию и вставляем код.
alias: Проверка состояния компа
description: ""
trigger:
- platform: state
entity_id:
- input_boolean.compon
from: "off"
to: "on"
condition: []
action:
- repeat:
sequence:
- delay:
hours: 0
minutes: 2
seconds: 0
milliseconds: 0
- if:
- condition: or
conditions:
- condition: state
entity_id: input_select.compstate
state: windows
for:
hours: 0
minutes: 3
seconds: 0
- condition: state
entity_id: input_select.compstate
state: ubuntu
for:
hours: 0
minutes: 3
seconds: 0
- condition: state
entity_id: input_select.compstate
state: proxmox
for:
hours: 0
minutes: 3
seconds: 0
then:
- service: input_boolean.turn_off
target:
entity_id: input_boolean.compon
data: {}
- service: input_select.select_option
target:
entity_id: input_select.compstate
data:
option: offline
while:
- condition: state
entity_id: input_boolean.compon
state: "on"
mode: single
Поясню. После запуска автоматизации при переключении служебного элемента она каждые две минуты повторяет одну и ту же проверку пока включен вспомогательный элемент compon.
Проверяем - если элемент compstate в течение 3 минут уже равен одному из значений списка, то делаем вывод что компьютер выключен или не отвечает, меняем статус на offline и виртуальный переключатель выключаем, после чего завершаем автоматизацию.
Ну и последний пункт - отображаем все на панели управления. Для этого добавляем на панель lovelace вертикальный стек с таким кодом:
type: vertical-stack
cards:
- type: markdown
content: >
{% set p = states('input_boolean.compon') %} Компьютер {{ 'включен' if p
== "on" else 'выключен' if p == "off" }}.
{% set s = states('input_select.compstate') %} Состояние - {{ 'Загружен
windows' if s == "windows" else 'Загружен ubuntu' if s == "ubuntu" else
'Загружен proxmox' if s == "proxmox" else 'offline' if s == "offline" }}.
- type: entities
entities:
- entity: script.windows
- entity: script.ubuntu
- entity: script.proxmox
- entity: script.unknown
- entity: script.unknown_2
Поясню - сверху показываем markdown карточку, в которой выполняем простые сравнения. Если переключатель compon включен то пишем Компьютер включен, иначе Компьютер выключен.
И второй строчкой выводим состояние compstate.
Снизу выводим команды запуска наших скриптов.
Вот что получается:
Я специально сделал скриншот с мобильного, чтобы показать насколько я теперь свободен в запуске нужной системы на домашнем компе :)
Вот как то так. Статья получилась несколько сумбурная, но надеюсь интересная. Помните - Home Assistant это не только ценный мех но и возможность управления другими компьютерами.
Ну и напоследок красивая картинка. Не знаю даже почему она в голове)
Комментарии (19)
artko
20.04.2024 01:04А чем не подошел вариант грузить только proxmox, а в нем виртуалку с нужной ос? (Отдельно вопрос, зачем убунта, если уже есть proxmox, основаньій на дебиане...)
kolabaister Автор
20.04.2024 01:04не хочу терять в производительности и возиться с пробросом видеокарты.
Потому что в убунте есть десктоп) Ну и вообще не стоит нагружать гипервизор непрофильными задачами
NutsUnderline
20.04.2024 01:04+1была статья (вроде тут на хабре но это не точно) - сделали некий девайс на stm32 который решал задачу выбора загрузочного диска в grub
Поиск дает такое https://github.com/stecman/hw-boot-selection https://github.com/rw-hsma-fpga/grub-switch наверное что то еще есть
Суть не в том что это аппаратное устройство а в том что grub может управляться "извне"
kolabaister Автор
20.04.2024 01:04Интересная какая разработка. Но как я понял смысл тут именно в программно-аппаратном комплексе. Программа нужна чтобы не надо было эмулировать клавиатуру и подать не ненадежную комбинацию кнопок вверх/вниз а что то вроде аппаратного api поддержать, а прямого управления по сети она не поддерживает. Может я конечно неправильно понял, по диагонали пробежался.
vp7
20.04.2024 01:04Страх и ужас ;((
А если не будет грузиться, ошибки какие-то выдавать?
У вас же HA крутится на каком-то железе? Я бы добавил туда IP KVM и решил этим проблему. Если аппаратный IP KVM не нравится - возьмите USB свисток с HDMI входом, эмулирующий USB камеру (на Али в пределах 1 т.р.) + эмулятор клавиатуры (реально собрать готовый проект на всяких ESP32). А на релюхи - вывести кнопку включения и reset.
kolabaister Автор
20.04.2024 01:04Ну будут и будут. Выключу и попробую еще раз. Если не получится - ну и ладно, есть и другие варианты решения вопросов, например подключусь к какому нибудь рабочему серверу.
Железные ip kvm - это как то совсем небюджетно. Для домашнего решения перебор.
Второй вариант побюджетнее, не знал про hdmi камеры, спасибо.Но - мне не нравятся такие решения. KVM - это все же про работу и про кровавый энтерпрайс, я же в личной жизни стараюсь автоматизировать до уровня кнопки "сделать красиво". HA в этом плане мне сильно нравится потому что в нем можно почти все сделать. Получившаяся у меня схема отвечает этому критерию.
nsmcan
20.04.2024 01:04Могли бы Вы дать линку на конкретный USB свисток? И как с его помощью получить экран удалённо?
SUNsung
20.04.2024 01:04Вам не нужно получать экран для выбора grub
Я тут почитал коментарии и понял что для решения задачи хватит одной ардуины на esp32.
Esp32 для связи с умным домом (вайфай) а ардуина собственно для того что бы иметь связь с материнкой по ttl. А уже в самом grub сделать запрос запускаемого диска с ttl порта. Включение и ребут так же спокойно делается с esp так как обычно в материнке у кнопок управление землей
vp7
20.04.2024 01:04+1Для grub'а можно использовать serial console (com порт), для ядра linux тоже самое. Но это решает только часть возможных проблем при загрузке и только с linux'ом. Поэтому возможность зайти в BIOS мне кажется очень и очень полезной.
vp7
20.04.2024 01:04Последнее время их появилось очень много. Я купил два на пробу и оба хорошо работают, задержка минимальна (подключил вместо монитора одного компа, на экран другого компа вывел "usb камеру" и свободно пользовался первым компом):
Просто свисток (1900 рублей) https://aliexpress.ru/item/1005004754486040.html
Свисток с дублированием потока (1000 рублей) - есть HDMI In, HDMI Out, перехватывает видео по USB: https://aliexpress.ru/item/1005003576399052.html
Также есть куча свистков за 200-400 рублей, но про них ничего сказать не могу, по отзывам - они не могут держать полноценно Full HD 30/60 FPS, но для задачи "IP KVM на случай проблем с загрузкой" они должны без проблем справиться.
NutsUnderline
20.04.2024 01:04свисток то это не проблема, только вот "за скобками" остался целый программно-аппаратный комплекс который надо собрать на коленке по не особо готовым рецептам.
тут была недавно статья - человек даже готовое решение PiKVM на малинке не осилил
DaemonGloom
20.04.2024 01:04+1Есть ещё пара более простых методов.
Grub можно грузить по pxe (и, соответственно, дать ему любые настройки для загрузки нужного).Или можно отдавать по pxe только переменную для выбора ОС при загрузке, а весь остальной загрузчик и конфиг держать в самом компе. Тогда при отсутствии pxe сервера - компьютер всё равно можно будет загрузить в любую ОС через меню grub.
Ну а отредактировать файл через автоматизацию - это уже просто.
SUNsung
А в чем проблема была ограничится переключением на уровне grub? Насколько мне известно можно взять серверный свисток и просто работать с апи свистка для запуска/ребута и тд внутри локальной сети (если материнка серверная то там уже все есть, свисток не нужен) и подключить как удобно к хомасистент. (если есть такая огромная необходимость к удаленному запуску ПК с выбором операционки)
Да и переключение чисто по питанию такое себе решение. Как минимум при скачке напряжения (когда "могнет" реле) диск может превратится в тыкву.
В целом же я не так много знаю именно за sata, но по логике вешей отсутсвие питания, при наличии живой логической шины может как то "сказатся". Но опять таки я не совсем вкурсе, если sata это независимые интерфейсы и требуется наличие питания "на конце" что бы начался обмен то все хорошо. Но эти это частичный случай какой-то асинхронной шины, где процессор просто "выбирает" нужное подключенное устройсво то как минимум будут потери на подключеных на шине, как максимум можно спалить пины шины.
kolabaister Автор
Чтобы выбрать систему из груба комп уже должен быть включен и нужен доступ к консоли.
Реле управляет питанием дисков только в течение 90 сек после запуска. А так они включены всегда и что бы не случилось с реле или его питанием на дисках это не скажется.
Пока все работает. Да, я тоже не очень знаю спецификацию sata, даже назначение напряжение плохо описано в популярных источниках.
Собственно, как я написал, риски может и есть, но я считаю их допустимыми.
CaptGg
У вас уже используется Wake-on-LAN для включения ПК.
Вам нужно было лишь в запускаемой по-умолчанию ОС добавить скрипт, который при загрузке запрашивает у Home Assistant по http REST API какую ОС необходимо загрузить и если она не совпадает с текущей, то выполняет grub-reboot [номер ОС].
Такое программное решение выглядит проще и надежнее.
Для удобства скрипту можно добавить предложение нажать ESC в течение 5 секунд, чтобы отменить перегрузку локально. Так можно будет включать ПК локально не задумываясь что там выбрано в Home Assistant.
Goron_Dekar
Класс! А как это сделать? Фиксированный IP? DHCP? У меня в компе, который имеет несколько систем, специально настроены разные mac адреса чтобы ip системы зависил от ОС: так проще домашний firewall насторить.
Я когда-то думал для этого использовать DHCP запрос: в ответе сервера указать, какую ОС загрузить в доп. хедерах. Но как это сделать в grub os так и не понял.
CaptGg
На ПК должна быть зафиксирована ОС, загружающаяся по-умолчанию всегда, при помощи grub-set-default. Желательно Linux, т.к. в нем это можно сделать в несколько строк на Bash. После загрузки запускается скрипт, делающий исходящий запрос к Home Assistant API по HTTP, получает ответ какая ОС должна быть загружена и запускает с правами root grub-reboot <номер> && reboot с нужным номером загрузочной записи.
Всё. Не важно какой IP и MAC у ПК, важен лишь доступ с него к Home Assistant.
Goron_Dekar
Точно! Жаль ,что это будет значить двойной ребут, что местами просто не красиво, но в моём случае это отличное решение. И, в отличие от метода, описанного в статье, всегда есть доступ до всех ЖД.