Создание веб-интерфейса для управления Raspberry Pi 3

Raspberry Pi 3. Создание веб-интерфейса для управления с любого устройства

Дата Автор DmitryОставить комментарий 3 663 просмотров

Моя Raspberry Pi на данный момент трудится в качестве домашнего сервера, держа на себе медиасервер, облако, принт-сервер, электронную библиотеку и торрент-клиент.

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

И процесс создания такого интерфейса я и опишу в сегодняшней статье из цикла публикаций об использовании Raspberry Pi.

Что нам понадобится

Итак, мы будем создавать веб-интерфейс, доступный с любого подключенного к локальной сети устройства по ip-адресу нашей «малины».

Для осуществления описываемых в этой статье действий понадобится:

Кроме того, нужно чтобы на Raspberry Pi был установлен веб-сервер и PHP-интерпретатор. Эти моменты были описаны в предыдущих статьях цикла, поэтому сейчас я не буду останавливаться на них отдельно.

А при создании веб-интерфейса будут использоваться следующие технологии:

  • HTML
  • CSS
  • PHP

Язык разметки HTML, который некоторые ошибочно называют языком программирования — «скелет» любой веб-страницы. HTML-тегами задаются параграфы и вставляются картинки, в HTML-теги облачаются гиперссылки. И не только.

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

И, наконец, PHP — веб-ориентированный язык программирования. Уже более серьезная вещь, чем HTML, позволяющая писать веб-приложения и выполнять команды на сервере. Если нужно удаленно выполнить на Raspberry Pi какую-то команду кликом по кнопке в веб-интерфейсе, то это осуществимо через PHP-интерпретатор.

Не пугайтесь количеству того, что нужно знать и уметь. У нас есть Google, которому можно задавать конкретные вопросы и находить на них конкретные ответы, примеры и объяснения.

Именно так я и поступил, в результате вся работа по созданию веб-интерфейса заняла у меня один полный вечер. Знаний CSS и PHP на тот момент у меня не было вообще, а HTML я знал на уровне новичка.

Ну а повторить описываемые мною действия по этой статье можно в течение 10-15 минут.

Требования к веб-интерфейсу

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

Веб-интерфейс в моем понимании должен:

  • представлять доступ ко всем функциям сервера на Raspberry Pi в удобном виде
  • нормально отображаться на мобильных устройствах и быть достаточно крупным для управления пальцами с сенсорного экрана
  • обладать если не приятным, то хотя бы не отталкивающим дизайном

Исходя из этого формулируем задачу.

Нужно сделать 2 меню: одно вертикальное, для доступа к основным и часто используемым функциям, и одно горизонтальное, для доступа к вспомогательным функциям.

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

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

Создание скелета веб-интерфейса на HTML

Если вы совершенно незнакомы с HTML, то первое, что нужно понять, это иерархию этого языка разметки.

Итак, содержимое любой веб-страницы лежит в контейнере, заключенном между тегами <html> (открывающий тег) и </html> (закрывающий тег).

Внутри этого основного контейнера будут еще 2 контейнера — шапка страницы и тело страницы. В шапке страницы содержится служебная информация. А тело страницы — это то, что мы в конечном счете будем видеть у себя на экране в браузере.

В папке /var/www/html/ на Raspberry Pi создадим (или откроем для редактирования) файл index.html:

sudo nano /var/www/html/index.html

Поставим открывающий тег <html> и запишем шапку сайта:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Raspberry Pi</title>
</head>

Что находится в шапке? Информация для браузера о кодировке страницы и ее заголовок. Позднее шапка страницы у нас расширится, но не будем забегать наперед и для начала ограничимся этим.

Теперь создадим тело страницы:

<body>
<h1 align="center">Домашний сервер на Raspberry Pi 3</h1>

<nav role='navigation'>
  <a href="ССЫЛКА1">Медиасервер Plex</a>
  <a href="ССЫЛКА2">Электронная библиотека</a>
  <a href="ССЫЛКА3">RPi-Monitor</a>  
  <a href="ССЫЛКА4">Transmission</a>  
  <a href="ССЫЛКА5">Nextcloud</a>

</nav>

<ul id="navbar">
      <li><a href="ССЫЛКА6">[Status]</a></li>
      <li><a href="ССЫЛКА7">[Reboot]</a></li>
      <li><a href="ССЫЛКА8">[Transmission reload]</a></li>
      <li><a href="ССЫЛКА9">[CUPS]</a></li>
    </ul>

</body>
</html>

Тело страницы заключено между открывающим и закрывающим тегами <body>.

Сверху находится заголовок — «Домашний сервер на Raspberry Pi 3». Он заключен в теги заголовка первого уровня H1 и выровнен по центру страницы.

Далее идут два меню. Первое из них по задумке будет располагаться вертикально, а второе горизонтально. Заметьте, что оба меню тоже заключены в своеобразные контейнеры из открывающего и закрывающего тегов. И в самом конце идет закрывающий тег общего контейнера </html>, внутри которого находятся и шапка страницы (head) и тело страницы (body). В этом вся суть HTML-разметки.

Скелет страницы создан. Я включил в него гиперссылки на основные выполняемые моей «малиной» как сервером функции — медиасервер, каталог электронной библиотеки, мониторинг показателей системы, торрент-качалку и облачное хранилище. Поскольку эти функции на сервере будут задействованы часто, то доступ к ним будет удобно организован с помощью вертикального меню.

За вертикальным меню идет меню горизонтальное, отображающееся одной строкой.

В нем находятся кнопки вывода краткого статуса системы (температура и аптайм), перезагрузки, перезапуска демона Transmission (иногда он начинает тупить, что лечится его перезапуском) и доступа к панели управления управления CUPS.

Это вспомогательные команды. Они не нужны постоянно, и в идеальных условиях к их использованию не придется прибегать вообще. Но поскольку идеальных условий не существует, то просто сделаем так, чтобы они занимали минимум места на странице, но все еще сохраняли свою доступность.


Теперь настало время прописать в пунктах меню конкретные ссылки вместо заглушек «ССЫЛКА1», «ССЫЛКА2» и т.п., которые я написал в примере кода выше.

И тут появляется небольшая проблема.

Дело в том, что веб-доступ к некоторым запущенным на Raspberry Pi процессам осуществляется через обращение к портам, которые они прослушивают. RPi-Monitor, например, доступен по адресу http://ip-адрес-raspberry-pi:8888, на 9091 порту подвешен веб-интерфейс Transmission, а по адресу http://ip-адрес-raspberry-pi/web/index.html:32400 находится интерфейс медиасервера Plex.

Стандартными средствами HTML сделать обращение к порту невозможно. Поэтому придется задействовать яваскрипты, которые будут подставлять номер порта в ссылку непосредственно в момент клика по ней.

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

<a href="/web/index.html" onclick="javascript:event.target.port=32400">Медиасервер Plex</a>
<a href="/ebooks/">Электронная библиотека</a>
<a href="" onclick="javascript:event.target.port=8888">RPi-Monitor</a>  
<a href="" onclick="javascript:event.target.port=9091">Transmission</a>  
<a href="/nextcloud/">Nextcloud</a>

А вот так будут прописаны ссылки на пункты дополнительного горизонтального меню:

<li><a href="/status.php">[Status]</a></li>
<li><a href="/com-reboot.php">[Reboot]</a></li>
<li><a href="/com-transreload.php">[Transmission reload]</a></li>
<li><a href="" onclick="javascript:event.target.port=631">[CUPS]</a></li>

Внесите эти поправки в тело страницы index.html, и на этом процесс создания скелета веб-интерфейса можно будет считать законченным.

Добавление иконки (favicon) для веб-интерфейса

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

Самый простой вариант создания иконки — это найти подходящую картинку и воспользоваться одним из многочисленных онлайн-сервисов по генерации favicon.

Я пользуюсь сервисом realfavicongenerator.net, как самым простым и наглядным.

Итак, находим картинку. Она должна быть квадратной (или близкой по пропорциям к квадрату), не сильно детализированной (на иконке мелких деталей все равно будет не видно) и быть размером не менее чем 260×260 пикселей.

Я погуглил «raspberry pi logo» и спустя 30 секунд уже нашел подходящую картинку со стилизованной малинкой — логотипом Raspberry Pi.

Загружаем картинку в realfavicongenerator (кнопка «Select your favicon image») и сервис начинает генерировать на ее основе иконки под разные платформы. Можно поправить стандартные параметры под себя (например, задать собственный цвет фона иконки вместо стандартного белого), а затем нажимаем на «Generate your favicons and HTML code» и сервис выдает нам архив с файлами иконок и HTML-код для вставки на страницу.

Код будет примерно такой:

<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
<meta name="theme-color" content="#ffffff">

Его нужно вставить в шапку нашего файла index.html (сразу же после открывающего тега <head>), а загруженный с сервиса архив с иконками распаковать в папку /var/www/html/.

Делаем кнопку перезагрузки на PHP

Теперь сделаем кнопку, по нажатию которой в веб-интерфейсе наша Raspberry Pi получает команду на перезагрузку.

Для этого создаем php-файл:

sudo nano /var/www/html/com-reboot.php

И вписываем в него следующее:

<?php
echo shell_exec("sudo reboot");
?>

Язык PHP похож на HTML-разметку, хотя и отличается от нее синтаксисом. По смыслу понятно, что данный код:

  1. Сообщает интерпретатору, что все, идущее в треугольных скобках нужно воспринимать как PHP-код
  2. Выполняет консольную команду «sudo reboot»

По тому же принципу создадим php-файл, выводящий краткий статус:

sudo nano /var/www/html/status.php

И впишем в него код:

<?php
    echo "<b>Uptime:</b> ".shell_exec("uptime")." <br />";
    echo "<b>System Info:</b> " .shell_exec("uname -a"). "<br />";
?>

Что делает этот код? Он выводит на экран текст «Uptime:», затем исполняет консольную команду «uptime» и следом выводит на экран ее ответ. Затем переносит строку, со следующей строки выводит текст «System Info:», выполняет консольную команду «uname -a» и выводит ее ответ.

Ну и команду для перезагрузки демона торрент-качалки Transmission тут же напишем. Создаем файл:

sudo nano /var/www/html/com-transreload.php

И вписываем в него:

<?php
echo shell_exec("sudo /etc/init.d/transmission-daemon stop");
echo shell_exec("sudo /etc/init.d/transmission-daemon start");
?>

Но это еще не все.

Все действия, связанные с работой веб-сервера в Raspbian (и других *nix-системах) выполняются от пользователя пользователя www-data. А в наших php-файлах оказались команды, которые должны выполняться с правами суперпользователя (sudo).

Сможет пользователь www-data запустить исполнение этих команд? Конечно нет.

Как быть?

Есть два способа выхода из ситуации: правильный и не очень.

Не очень правильный способ заключается в том, чтобы наделить пользователя www-data правами суперпользователя. Это нехорошо с точки зрения безопасности. И даже если к «малине» имеете доступ только вы, не стоит приучать себя к использованию подобных решений.

Поэтому воспользуемся другим способом: дадим пользователю www-data доступ к выполнению строго оговоренного списка команд с правами суперпользователя без запроса пароля суперпользователя.

Для этого отредактируем файл настроек:

sudo nano /etc/sudoers

И впишем в него следующие строки:

%www-data ALL=NOPASSWD: /sbin/reboot
%www-data ALL=NOPASSWD: /etc/init.d/transmission-daemon stop
%www-data ALL=NOPASSWD: /etc/init.d/transmission-daemon start

Все. После этого на сервере смогут выполнятся команды «sudo reboot», «sudo /etc/init.d/transmission-daemon stop» и «sudo /etc/init.d/transmission-daemon start».

Если вы в дальнейшем захотите расширить функциональность веб-интерфейса управления «малинкой» и задействовать при этом другие выполняемые из-под суперпользователя команды, то не забывайте прописывать права на исполнение каждой из этих команд для www-data в файл /etc/sudoers.

Придаем веб-интерфейсу окончательный вид через CSS-стиль

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

Все это делается через прописывание CSS-стилей.

Но для начала я хочу сделать так, чтобы все тексты в моем интерфейсе отображались красивым тонким шрифтом.

За эталон я выбрал шрифт, который используется корпорацией Apple в своем дизайне. Он называется San Francisco и недоступен для свободного пользования.

Но есть и общедоступные шрифты, выполненные в подобном стиле и практически неотличимые от оригинального шрифта San Francisco.

После недолгих поисков я остановился на бесплатном шрифте Roboto. Вот так он выглядит:

Создание веб-интерфейса для управления Raspberry Pi 3

Подключим его к нашему веб-интерфейсу. Для этого в шапке файла index.html в любом месте после открывающего тега <head> вставляем следующую строчку:

<link href="https://fonts.googleapis.com/css?family=Roboto:100,300" rel="stylesheet">

Готово. Теперь этот шрифт можно использовать на странице. И если его нет в библиотеке шрифтов какого-то конкретного компьютера или смартфона, то он просто будет подгружаться с сервера Google Fonts.

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

<style type="text/css">

body{
background:#f1f1f1;
}

header, nav  {
  text-align: center;
  margin: 20px 0;
  padding: 10px;
}

nav a {

  font-family:'Roboto', Helvetica Neue,helvetica,arial,verdana,sans-serif;
  font-weight:200;
  font-size: 2.4em;
  text-decoration: none;
  background: #333; 
  border-radius: 5px;
  color: white;
  padding: 3px 8px;
  display: block;
}

p{
font-family:'Roboto', Helvetica Neue,helvetica,arial,verdana,sans-serif;
font-weight:200;
font-size: 2.8em;
line-height: 1.333em; /* 16px/12 =1.33em*/
margin-bottom: 1.25em; /* 15px/12 =1.25em*/
}

h1{
font-family:'Roboto', Helvetica Neue,helvetica,arial,verdana,sans-serif;
margin:0px auto 0 auto;
font-size: 2.8em;
text-align:center;
font-weight:200;
color:#4b4b4b;
}

#navbar {
  font-family:'Roboto', Helvetica Neue,helvetica,arial,verdana,sans-serif;
  font-weight:200;
  font-size: 2.0em;
  text-align: center;
  text-decoration: none;
  background: #333; 
  border-radius: 5px;
  color: white;
  padding: 3px 8px;
      }

#navbar li { display: inline; }

#navbar a {
        color: #fff;
        padding: 3px 8px;
        text-decoration: none;
        display: inline;
        width: 100px;
}

</style>

Этот код целиком нужно вставить в шапку файла index.html, между тегами <head> и </head>.

Вообще, при верстке серьезных проектов таблицу стилей создают в виде отдельного файла style.css, а потом просто ссылаются на этот файл в шапке страницы, но у нас проект простой и таблица стилей маленькая, поэтому можно просто вставлять ее в шапку.

Что делает этот код?

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

В общем, полностью определяет как будет отображаться страница.

В итоге, вот так веб-интерфейс будет выглядеть в браузере компьютера. Он доступен по вводу в адресной строке ip-адреса Raspberry Pi:

Создание веб-интерфейса для управления Raspberry Pi 3

А вот так — на экране айфона:

Создание веб-интерфейса для управления Raspberry Pi 3

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

Слишком сложно? Просто скачайте готовые файлы

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

Если описанные мною действия по-прежнему непонятны и вызывают вопросы — можете просто скачать готовые файлы с Яндекс.Диска. Архив нужно просто распаковать в папку /var/www/html на Raspberry Pi чтобы все заработало.

Пользуйтесь моими наработками, адаптируйте их под себя и свои нужды. Мне не жалко.

Добавляем иконку для доступа к веб-интерфейсу прямо на рабочий стол смартфона

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

На примере iOS и браузера Safari это выглядит так:

Создание веб-интерфейса для управления Raspberry Pi 3

Открываем страницу в браузере. Нажимаем на иконку «Поделиться» в нижнем меню. Выбираем пункт «На экран домой», при необходимости можно отредактировать название, под которым ярлык будет отображаться на рабочем столе. Затем жмем «Добавить» и получаем результат.

Аналогичным способом ярлык помещается на рабочий стол в случае использования Android и Google Chrome.

Заключение

Вот таким образом можно создать одну страницу, с которой можно легко получать доступ ко всем функциям нашей Raspberry Pi как с компьютера, так и со смартфонов/планшетов.

Посредством PHP-команд можно удаленно управлять и подключенными к GPIO «малины» устройствами. Но об использовании GPIO я напишу подробнее в следующих статьях цикла.

Raspberry Pi 3B (английская сборка)в интернет-магазине GearBest Raspberry Pi 3B (китайская сборка)в интернет-магазине GearBest


P.S.: я завел паблик Вконтакте и канал в Telegram. Подписывайтесь, и получайте все обновления блога прямо в свою ленту новостей!

Понравилась статья? Выразите благодарность автору переводом любой суммы на ваше усмотрение :)

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *