Привет, Хабр!
Хочется поделиться опытом настройки Raspberry Pi 3B+ в качестве киоска с GUI на базе библиотеки Kivy для Python 3. Почему именно Kivy? Просто мы уже имеем продукт, разработанный на Python, нам бы хотелось добавить к нему графический интерфейс. Стоит отметить, что до Kivy мы перепробовали несколько вариантов, включая wxWidgets и даже браузер на Chromium с веб-приложением. Все эти альтернативы оказались бессильны против Kivy, лёгкой и быстрой. Очень хороший обзор этой библиотеки уже есть на Хабре.
Мы будем использовать Raspbian Lite с Python 3.7 и системой управления процессами и сервисами Supervisor. Кстати, очень удобной является утилитка Raspberry Pi Imager, с помощью которой можно подготовить SD-карточку. После первой загрузки нашего малыша RPi логинимся с помощью стандартного логина pi и пароля raspberry. Далее выполняем:
Выбираем пятый пункт Interfacing Options, в появившемся меню нас интересует второй пункт SSH, с помощью которого мы включим удалённый доступ для удобства.
Итак, удобно откинувшись в любимом кресле, продолжим настройку RPi через любой удобный ssh-клиент.
Давайте создадим пользователя с удобным для нас именем, разрешим ему пользоваться sudo и перезагрузимся:
После перезагрузки залогинимся через ssh уже с новыми данными для kivygui и удалим стандартную учётку pi:
Не лишним будет указать, что мы пользуемся американской раскладкой клавиатуры:
Наше тестовое приложение будет находиться в отдельной папке, создадим её:
Теперь давайте в текстовом редакторе nano создадим скрипт для запуска Python-приложения /home/kivygui/helloworld/run.sh со следующим содержимым:
Сделаем в nano и пример простенького интерфейса в файле /home/kivygui/helloworld/start.py:
Нам понадобится pip3:
Также я сталкивался с тем, что при установке nodm не всегда загружались все необходимые пакеты, поэтому на всякий случай установим их заранее:
Теперь давайте установим nodm и оконный менеджер matchbox:
Настал черёд Kivy:
Теперь научим нашу систему показывать нам графический интерфейс вместо консольного приглашения, скроем все диагностические сообщения и покажем графический экран загрузки системы:
Если есть желание, консоль tty1 вообще можно отключить:
Теперь давайте установим Supervisor:
Создадим папку для логов:
Теперь давайте ненадолго остановим службу Supervisor для переконфигурации:
Добавим с помощью редактора nano в кофигурационный файл /etc/supervisor/supervisord.conf следующее:
Также давайте дадим пользователям kivygui и root дополнительные возможности. Для этого воспользуемся командой:
Приведём файл к следующему виду:
Теперь мы можем запускать службу:
На подключенном к RPi мониторе мы увидим заветное приветствие. Осталось только перезагрузиться, чтобы проверить работу графического экрана загрузки.
На самом деле, nodm можно заменить lightdm с автологином. Это будет абсолютно аналогичное nodm решение. Тем более, сам разработчик nodm рекомендует этот подход.
Хочется поделиться опытом настройки Raspberry Pi 3B+ в качестве киоска с GUI на базе библиотеки Kivy для Python 3. Почему именно Kivy? Просто мы уже имеем продукт, разработанный на Python, нам бы хотелось добавить к нему графический интерфейс. Стоит отметить, что до Kivy мы перепробовали несколько вариантов, включая wxWidgets и даже браузер на Chromium с веб-приложением. Все эти альтернативы оказались бессильны против Kivy, лёгкой и быстрой. Очень хороший обзор этой библиотеки уже есть на Хабре.
Окружение
Мы будем использовать Raspbian Lite с Python 3.7 и системой управления процессами и сервисами Supervisor. Кстати, очень удобной является утилитка Raspberry Pi Imager, с помощью которой можно подготовить SD-карточку. После первой загрузки нашего малыша RPi логинимся с помощью стандартного логина pi и пароля raspberry. Далее выполняем:
$ sudo raspi-config
Выбираем пятый пункт Interfacing Options, в появившемся меню нас интересует второй пункт SSH, с помощью которого мы включим удалённый доступ для удобства.
Итак, удобно откинувшись в любимом кресле, продолжим настройку RPi через любой удобный ssh-клиент.
Пользователь
Давайте создадим пользователя с удобным для нас именем, разрешим ему пользоваться sudo и перезагрузимся:
$ sudo useradd -m kivygui -s /bin/bash
$ sudo passwd kivygui
$ sudo usermod -a -G sudo kivygui
$ sudo reboot
После перезагрузки залогинимся через ssh уже с новыми данными для kivygui и удалим стандартную учётку pi:
$ sudo userdel pi
$ sudo rm -r /home/pi/
Не лишним будет указать, что мы пользуемся американской раскладкой клавиатуры:
$ sudo sed -i 's/XKBLAYOUT="gb"/XKBLAYOUT="us"/' /etc/default/keyboard
Тестовое приложение
Наше тестовое приложение будет находиться в отдельной папке, создадим её:
$ mkdir /home/kivygui/helloworld
Теперь давайте в текстовом редакторе nano создадим скрипт для запуска Python-приложения /home/kivygui/helloworld/run.sh со следующим содержимым:
export DISPLAY=:0.0
xset s off -dpms
exec matchbox-window-manager &
while true; do
exec python3 start.py
done
Сделаем в nano и пример простенького интерфейса в файле /home/kivygui/helloworld/start.py:
import kivy
kivy.require('1.11.0')
from kivy.app import App
from kivy.uix.label import Label
class MyApp(App):
def build(self):
return Label(text='Hello, world!')
if __name__ == '__main__':
MyApp().run()
Графический пользовательский интерфейс
Нам понадобится pip3:
$ sudo apt-get update -y
$ sudo apt-get install -y python3-pip
Также я сталкивался с тем, что при установке nodm не всегда загружались все необходимые пакеты, поэтому на всякий случай установим их заранее:
$ sudo apt-get install -y desktop-base gtk2-engines-pixbuf libxklavier16 xserver-xorg xserver-xorg-input-all xserver-xorg-input-libinput xserver-xorg-input-wacom xserver-xorg-legacy xserver-xorg-video-all xserver-xorg-video-amdgpu xserver-xorg-video-ati xserver-xorg-video-fbdev xserver-xorg-video-nouveau xserver-xorg-video-radeon xserver-xorg-video-vesa
Теперь давайте установим nodm и оконный менеджер matchbox:
$ sudo DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=true apt-get install -y x11-xserver-utils nodm matchbox-window-manager
$ echo "/usr/sbin/nodm" | sudo tee /etc/X11/default-display-manager
$ sudo sed -i -e "s/NODM_ENABLED=false/NODM_ENABLED=true/" -e "s/NODM_USER=root/NODM_USER=kivygui/" -e "s/NODM_X_OPTIONS='-nolisten tcp'/NODM_X_OPTIONS='-nolisten tcp -nocursor'/" /etc/default/nodm
Настал черёд Kivy:
$ sudo apt-get install -y libsdl2-dev libsdl2-image-dev libsdl2-mixer-dev libsdl2-ttf-dev pkg-config libgl1-mesa-dev libgles2-mesa-dev python-setuptools libgstreamer1.0-dev git-core gstreamer1.0-plugins-{bad,base,good,ugly} gstreamer1.0-{omx,alsa} python-dev libmtdev-dev xclip xsel libjpeg-dev
$ sudo python3 -m pip install --user kivy
Теперь научим нашу систему показывать нам графический интерфейс вместо консольного приглашения, скроем все диагностические сообщения и покажем графический экран загрузки системы:
$ sudo rm /etc/systemd/system/default.target
$ sudo rm /etc/systemd/system/getty@tty1.service.d/autologin.conf
$ sudo ln -s /lib/systemd/system/graphical.target /etc/systemd/system/default.target
$ sudo sed -i '$ s/$/ quiet splash consoleblank=0 loglevel=0 logo.nologo plymouth.ignore-serial-consoles/' /boot/cmdline.txt
$ sudo sed -i 's/console=tty1/console=tty3/' /boot/cmdline.txt
Если есть желание, консоль tty1 вообще можно отключить:
$ sudo systemctl disable getty@tty1
Supervisord
Теперь давайте установим Supervisor:
$ sudo apt-get install -y supervisor
Создадим папку для логов:
$ mkdir /home/kivygui/logs
Теперь давайте ненадолго остановим службу Supervisor для переконфигурации:
$ sudo systemctl stop supervisor
Добавим с помощью редактора nano в кофигурационный файл /etc/supervisor/supervisord.conf следующее:
[program:rungui]
command=sh run.sh
directory=/home/kivygui/helloworld
user=root
autostart=true
autorestart=true
startsecs = 5
startretries=3
stderr_logfile=/home/kivygui/logs/rungui.err.log
stdout_logfile=/home/kivygui/logs/rungui.out.log
stderr_logfile_maxbytes=5MB
stdout_logfile_maxbytes=5MB
stopsignal=INT
stopwaitsecs=5
Также давайте дадим пользователям kivygui и root дополнительные возможности. Для этого воспользуемся командой:
$ sudo visudo
Приведём файл к следующему виду:
#
# This file MUST be edited with the 'visudo' command as root.
#
# Please consider adding local content in /etc/sudoers.d/ instead of
# directly modifying this file.
#
# See the man page for details on how to write a sudoers file.
#
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# Host alias specification
# User alias specification
# Cmnd alias specification
# User privilege specification
root ALL=(ALL:ALL) ALL
kivygui ALL=(ALL:ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
kivygui ALL = NOPASSWD: /usr/bin/supervisorctl
kivygui ALL = NOPASSWD: /usr/bin/python3.7
kivygui ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload
kivygui ALL=(ALL) NOPASSWD: /usr/bin/supervisord
root ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload
root ALL = NOPASSWD: /usr/bin/supervisorctl
root ALL = NOPASSWD: /usr/bin/python3.7
root ALL=(ALL) NOPASSWD: /usr/bin/supervisord
Теперь мы можем запускать службу:
$ sudo systemctl start supervisor
На подключенном к RPi мониторе мы увидим заветное приветствие. Осталось только перезагрузиться, чтобы проверить работу графического экрана загрузки.
P.S.
На самом деле, nodm можно заменить lightdm с автологином. Это будет абсолютно аналогичное nodm решение. Тем более, сам разработчик nodm рекомендует этот подход.
Tanner
Зачем вам supervisord, который запускается systemd? Это же избыточно. Напишите юнит для systemd, который запустит ваш rungui.
Bumeranghc Автор
Вы абсолютно правы, только лишь для управления запуском простенькой программки на Kivy это действительно overkill. Дело в том, что на боевой системе у нас бегают ещё кое-какие важные вещи, для которых Supervisord уже желателен. Просто решил оставить и этот пример, вдруг кому пригодится.