Kiosk2.0: различия между версиями
Vovan (обсуждение | вклад) (→Установка необходимых пакетов через apt-get) |
Vovan (обсуждение | вклад) (→Поворот экрана на 90 градусов по часовой стрелке) |
||
(не показана 51 промежуточная версия 2 участников) | |||
Строка 20: | Строка 20: | ||
reboot | reboot | ||
+ | |||
+ | ==Оптимизация скорости загрузки== | ||
+ | |||
+ | Просто бросьте это в рутовую консоль: | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /etc/default/grub | ||
+ | GRUB_AUTOUPDATE_CFG=true | ||
+ | GRUB_AUTOUPDATE_CFGNAME=/boot/grub/grub.cfg | ||
+ | GRUB_VMLINUZ_SYMLINKS=default | ||
+ | GRUB_VMLINUZ_FAILSAFE=default | ||
+ | GRUB_TIMEOUT=0 | ||
+ | GRUB_CMDLINE_LINUX_DEFAULT='panic=30 splash' | ||
+ | GRUB_CMDLINE_LINUX='failsafe vga=normal' | ||
+ | GRUB_TERMINAL_OUTPUT='gfxterm' | ||
+ | GRUB_GFXMODE='auto' | ||
+ | GRUB_DEFAULT='saved' | ||
+ | GRUB_SAVEDEFAULT=true | ||
+ | GRUB_BACKGROUND="/etc/bootsplash/themes/current/images/silent-800x600.jpg" | ||
+ | GRUB_WALLPAPER="/etc/bootsplash/themes/current/images/silent-800x600.jpg" | ||
+ | GRUB_COLOR_NORMAL="black/black" | ||
+ | GRUB_COLOR_HIGHLIGHT="white/black" | ||
+ | GRUB_DISTRIBUTOR="ALT Linux" | ||
+ | GRUB_BOOTLOADER_ID="altlinux" | ||
+ | EOF | ||
+ | |||
+ | update-grub | ||
+ | </pre> | ||
==Установка необходимых пакетов через apt-get== | ==Установка необходимых пакетов через apt-get== | ||
− | apt-get -y -q install wget nano xorg-server xdotool usb-modeswitch-data usb-modeswitch openssh sudo su xterm xhost git npm gcc10-c++ gcc-c++ make epm usbutils autosshd unclutter | + | <b>Примечание:</b> Пакет chromium был заменён на firefox-esr. Если нужен chromium-browser, то можно его отдельно поставить из пакета chromium. |
+ | |||
+ | apt-get -y -q install wget nano xorg-server kernel-modules-drm-std-def xinit xorg-drv-qxl xorg-drv-vesa xorg-drv-vmware xorg-drv-intel xorg-drv-nouveau xorg-drv-radeon xorg-drv-ati xorg-drv-amdgpu xorg-drv-r128 xorg-drv-synaptics xorg-drv-vboxvideo xorg-drv-vmmouse xorg-drv-wacom xorg-drv-input xorg-drv-video xdotool usb-modeswitch-data usb-modeswitch openssh sudo su xterm xhost git npm gcc10-c++ gcc-c++ make epm usbutils autosshd unclutter firefox-esr wkhtmltopdf pulseaudio-daemon alsa-plugins-pulse pulseaudio-utils aplay amixer alsa-utils fonts-ttf-ubuntu-font-family fonts-ttf-dejavu fonts-ttf-ms cups | ||
+ | |||
+ | ==Создание и настройка пользователей kiosk и kioskdisplay== | ||
+ | |||
+ | useradd kiosk | ||
+ | |||
+ | usermod -a -G audio kiosk | ||
+ | |||
+ | useradd kioskdisplay | ||
+ | |||
+ | установка пароля | ||
+ | |||
+ | passwd kiosk | ||
+ | |||
+ | добавляем пользователя kiosk в группу wheel (для sudo su) | ||
+ | |||
+ | usermod kiosk -aG wheel | ||
+ | |||
+ | и в группу dialout (для доступа к устройствам /dev/tty*) | ||
+ | |||
+ | usermod kiosk -aG dialout | ||
+ | |||
+ | делаем sudo su без пароля для пользователя kiosk (просто бросьте это в рутовую консоль): | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /etc/sudoers | ||
+ | User_Alias WHEEL_USERS = %wheel | ||
+ | User_Alias XGRP_USERS = %xgrp | ||
+ | Defaults:XGRP_USERS env_keep += "DISPLAY XAUTHORITY" | ||
+ | |||
+ | kiosk ALL=(ALL) NOPASSWD: ALL | ||
+ | |||
+ | @includedir /etc/sudoers.d | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | ==Автологин пользователей kioskdisplay на консоли tty1== | ||
+ | |||
+ | Просто бросьте это в рутовую консоль: | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /lib/systemd/system/getty\@tty1.service | ||
+ | [Unit] | ||
+ | Description=Getty on %I | ||
+ | Documentation=man:agetty(8) man:systemd-getty-generator(8) | ||
+ | Documentation=http://0pointer.de/blog/projects/serial-console.html | ||
+ | After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target | ||
+ | After=rc-local.service | ||
+ | |||
+ | Before=getty.target | ||
+ | IgnoreOnIsolate=yes | ||
+ | |||
+ | Conflicts=rescue.service | ||
+ | Before=rescue.service | ||
+ | |||
+ | ConditionPathExists=/dev/tty0 | ||
+ | |||
+ | [Service] | ||
+ | #ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM | ||
+ | ExecStart=-/sbin/agetty --autologin kioskdisplay --noclear %I $TERM | ||
+ | Type=idle | ||
+ | Restart=always | ||
+ | RestartSec=0 | ||
+ | UtmpIdentifier=%I | ||
+ | TTYPath=/dev/%I | ||
+ | TTYReset=yes | ||
+ | TTYVHangup=yes | ||
+ | TTYVTDisallocate=yes | ||
+ | IgnoreSIGPIPE=no | ||
+ | SendSIGHUP=yes | ||
+ | |||
+ | UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION | ||
+ | |||
+ | [Install] | ||
+ | WantedBy=getty.target | ||
+ | DefaultInstance=tty1 | ||
+ | EOF | ||
+ | |||
+ | systemctl daemon-reload | ||
+ | </pre> | ||
+ | |||
+ | Делаем симлинк: | ||
+ | <pre> | ||
+ | ln -sf /lib/systemd/system/getty\@tty1.service '/etc/systemd/system/getty.target.wants/getty@tty1.service' | ||
+ | </pre> | ||
+ | |||
+ | ==Отключение жестов на уровне Xorg== | ||
+ | |||
+ | Пока не проверено! | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /etc/X11/xorg.conf.d/40-libinput.conf | ||
+ | Section "InputClass" | ||
+ | Identifier "libinput touchscreen catchall" | ||
+ | MatchIsTouchscreen "on" | ||
+ | Option "Tapping" "off" | ||
+ | Option "ClickMethod" "none" | ||
+ | EndSection | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | ==Создание стартового скрипта .xinitrc в домашнем каталоге пользователя kiosk== | ||
+ | |||
+ | Скрипт запускает сессию Xorg, устанавливает разрешение экрана, запускает браузер chromium в режиме киоска и подгружает в него стартовую страницу. | ||
+ | |||
+ | Здесь может быть запущено веб приложение, стартующее на локальном хосте (для этого можно поставить платформу nodejs) | ||
+ | |||
+ | <b>Примечание:</b> В ходе реальных тестов так и не удалось запустить chromium-browser с отключением жестов. Поэтому вернулись к использованию firefox. Но запуск chromium-browser был оставлен в .xinitrc, но закомментирован. | ||
+ | |||
+ | Просто бросьте это в рутовый терминал: | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /home/kioskdisplay/.xinitrc | ||
+ | W=1280 | ||
+ | H=1024 | ||
+ | xrandr -s ${W}x${H} | ||
+ | unclutter -idle 0 & | ||
+ | amixer -D default sset Master 100% | ||
+ | amixer -D default sset PCM 100% | ||
+ | #/bin/rm -rf ~/.config/chromium | ||
+ | #chromium-browser --kiosk --incognito "http://localhost:3000" & | ||
+ | #xdotool search --sync --onlyvisible --class "chromium" windowsize ${W} ${H} | ||
+ | #xdotool search --sync --onlyvisible --class "chromium" windowmove 0 0 | ||
+ | /bin/rm -rf ~/.mozilla | ||
+ | firefox --new-instance --kiosk --touch-events=disabled "http://localhost:3000" & | ||
+ | xdotool search --sync --onlyvisible --class "firefox" windowsize ${W} ${H} | ||
+ | xdotool search --sync --onlyvisible --class "firefox" windowmove 0 0 | ||
+ | |||
+ | while true; do | ||
+ | sleep 1 | ||
+ | done | ||
+ | EOF | ||
+ | |||
+ | chown kioskdisplay: /home/kioskdisplay/.xinitrc | ||
+ | echo 'startx' >> /home/kioskdisplay/.bashrc | ||
+ | </pre> | ||
==Минимальная установка платформы NodeJS (если необходима)== | ==Минимальная установка платформы NodeJS (если необходима)== | ||
− | cd /tmp && wget https://nodejs.org/dist/v18.16.1/node-v18.16.1-linux-x64.tar.xz && unxz node-v18.16.1-linux-x64.tar.xz && cd /opt && tar -xpf /tmp/node-v18.16.1-linux-x64.tar | + | ===Платформа=== |
+ | |||
+ | cd /tmp && wget https://nodejs.org/dist/v18.16.1/node-v18.16.1-linux-x64.tar.xz && unxz node-v18.16.1-linux-x64.tar.xz && cd /opt && tar -xpf /tmp/node-v18.16.1-linux-x64.tar && echo 'PATH="/opt/node-v18.16.1-linux-x64/bin:$PATH"' >> /etc/bashrc && source /etc/bashrc | ||
+ | |||
+ | ===Пример веб-приложения с автоматическим стартом=== | ||
+ | |||
+ | Просто бросьте это в консоль: | ||
+ | |||
+ | <pre> | ||
+ | |||
+ | mkdir -p /home/kiosk/server/bin | ||
+ | cat << 'EOF' > /home/kiosk/server/bin/www | ||
+ | const http = require('http'); | ||
+ | |||
+ | const port = process.env.PORT || 3000; | ||
+ | |||
+ | const server = http.createServer((req, res) => { | ||
+ | let url = req.url; | ||
+ | let content = ''; | ||
+ | |||
+ | if (url === '/') { | ||
+ | content = ` | ||
+ | <h1>Welcome to the Home Page!</h1> | ||
+ | <p><a href="/about">About Us</a></p> | ||
+ | <p><a href="/contact">Contact Us</a></p> | ||
+ | `; | ||
+ | } else if (url === '/about') { | ||
+ | content = ` | ||
+ | <h1>About Us</h1> | ||
+ | <p>We are a company that provides amazing services.</p> | ||
+ | <p><a href="/">Home</a></p> | ||
+ | <p><a href="/contact">Contact Us</a></p> | ||
+ | `; | ||
+ | } else if (url === '/contact') { | ||
+ | content = ` | ||
+ | <h1>Contact Us</h1> | ||
+ | <p>You can reach us at example@example.com</p> | ||
+ | <p><a href="/">Home</a></p> | ||
+ | <p><a href="/about">About Us</a></p> | ||
+ | `; | ||
+ | } else { | ||
+ | res.writeHead(404, { 'Content-Type': 'text/plain' }); | ||
+ | res.end('Page not found'); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | res.writeHead(200, { 'Content-Type': 'text/html' }); | ||
+ | res.end(content); | ||
+ | }); | ||
+ | |||
+ | server.listen(port, () => { | ||
+ | console.log(`Server is running on port ${port}`); | ||
+ | }); | ||
+ | EOF | ||
+ | |||
+ | chown kiosk: /home/kiosk/server -R | ||
+ | |||
+ | cat << 'EOF' > /etc/systemd/system/kiosk.service | ||
+ | [Unit] | ||
+ | Description=KIOSK | ||
+ | Requires=network-online.target | ||
+ | After=network-online.target | ||
+ | |||
+ | [Service] | ||
+ | Environment=PORT=3000 | ||
+ | Restart=always | ||
+ | RestartSec=5 | ||
+ | WorkingDirectory=/home/kiosk/server | ||
+ | ExecStart=/opt/node-v18.16.1-linux-x64/bin/node ./bin/www | ||
+ | User=kiosk | ||
+ | Group=kiosk | ||
+ | [Install] | ||
+ | WantedBy=multi-user.target | ||
+ | EOF | ||
+ | |||
+ | systemctl daemon-reload | ||
+ | |||
+ | systemctl enable --now kiosk.service | ||
+ | |||
+ | </pre> | ||
+ | |||
+ | =Решение проблем= | ||
+ | |||
+ | ==MTU на сетевом интерфейсе== | ||
+ | |||
+ | В файл | ||
+ | |||
+ | iplink | ||
+ | |||
+ | в каталоге сетевого интерфейса добавить строчку | ||
+ | |||
+ | mtu 1400 | ||
+ | |||
+ | Значение mtu подбирать исходя из ситуации | ||
+ | |||
+ | ==Перенастроить Xorg на VESA== | ||
+ | |||
+ | Бывает нужно, если родные драйвера intel или amdgpu не работают | ||
+ | |||
+ | Заменить фрагмент в файле | ||
+ | |||
+ | /etc/X11/xorg.conf | ||
+ | |||
+ | |||
+ | <pre> | ||
+ | Section "Device" | ||
+ | Identifier "Card0" | ||
+ | Driver "vesa" | ||
+ | EndSection | ||
+ | </pre> | ||
+ | |||
+ | ==Не работает терминал оплаты== | ||
+ | |||
+ | <pre> | ||
+ | /home/kiosk/server/pos | ||
+ | chmod +x sb_pilot u2updater | ||
+ | chmod 775 upnixmn.out | ||
+ | </pre> | ||
+ | |||
+ | ==Гаснет дисплей при простое== | ||
+ | |||
+ | Просто бросьте это в консоль: | ||
+ | |||
+ | <pre> | ||
+ | cat << EOF > /etc/X11/xorg.conf.d/90-disable-timeouts.conf | ||
+ | Section "ServerFlags" | ||
+ | Option "StandbyTime" "0" | ||
+ | Option "SuspendTime" "0" | ||
+ | Option "OffTime" "0" | ||
+ | Option "BlankTime" "0" | ||
+ | EndSection | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | ==Дать конкретное имя tty устройству== | ||
+ | |||
+ | Сначала нужно узнать несколько параметров для конструирования строчки для udev: https://askubuntu.com/questions/978485/udev-rule-with-serial-for-ttyusb-not-working | ||
+ | |||
+ | Кратко: для выяснения idVendor и idProduct выполните команду | ||
+ | |||
+ | lsusb | ||
+ | |||
+ | ,выдёргивая и вставляя устройство tty. Как будет понятно: какое из них нужное вам, берёте оттуда эти данные. | ||
+ | |||
+ | Когда всё будет готово, сформируйте вот такой текст и бросьте его в рутовую консоль: | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /etc/udev/rules.d/42-usb-serial-ttyS42.rules | ||
+ | SUBSYSTEM=="tty", ATTRS{idVendor}=="079b", ATTRS{idProduct}=="0028", MODE="0666", SYMLINK+="ttyS42" | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | Если у существующего устройства нужно просто поменять режим доступа к файлу устройства: | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /etc/udev/rules.d/47-usb-serial-ttyUSB0.rules | ||
+ | SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0666" | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | Затем | ||
+ | |||
+ | udevadm control --reload | ||
+ | reboot | ||
+ | |||
+ | ==Система загружается и просит настройки по dhcp раньше чем usb-модем инициализировался и готов это дать== | ||
+ | |||
+ | Добавить скрипт (просто бросьте это в консоль) | ||
+ | <pre> | ||
+ | cat << 'EOF' > /opt/check_gw.sh | ||
+ | #!/bin/bash | ||
+ | check_result=$(ip ro | grep default | wc -l) | ||
+ | if [ $check_result -eq 0 ]; then | ||
+ | dhcpcd | ||
+ | exit 0 | ||
+ | fi | ||
+ | #echo 'wg is ok' | ||
+ | exit 0 | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | chmod +x /opt/check_gw.sh | ||
+ | |||
+ | Запускать раз в минуту через crontab рута | ||
+ | |||
+ | ==Установить временнУю зону вместо UTC== | ||
+ | |||
+ | ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime | ||
+ | |||
+ | ==Поворот экрана на 90 градусов по часовой стрелке== | ||
+ | |||
+ | Тут обратить внимание на разрешение, частоту и название монитора. Вынесены в отдельные переменные. | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /home/kioskdisplay/.xinitrc | ||
+ | W=1080 | ||
+ | H=1920 | ||
+ | F=60 | ||
+ | MON=HDMI-2 | ||
+ | xrandr --newmode $(cvt ${W} ${H} ${F} | sed 's/Modeline //g' | tail -1) | ||
+ | xrandr --addmode ${MON} ${W}x${H}_${F} | ||
+ | xrandr -s ${W}x${H} | ||
+ | xrandr -o left | ||
+ | unclutter -idle 0 & | ||
+ | amixer -D default sset Master 100% | ||
+ | amixer -D default sset PCM 100% | ||
+ | #/bin/rm -rf ~/.config/chromium | ||
+ | #chromium-browser --kiosk --incognito "http://localhost:3000" & | ||
+ | #xdotool search --sync --onlyvisible --class "chromium" windowsize ${W} ${H} | ||
+ | #xdotool search --sync --onlyvisible --class "chromium" windowmove 0 0 | ||
+ | /bin/rm -rf ~/.mozilla | ||
+ | firefox --new-instance --kiosk --touch-events=disabled "https://nntc.nnov.ru" & | ||
+ | xdotool search --sync --onlyvisible --class "firefox" windowsize ${W} ${H} | ||
+ | xdotool search --sync --onlyvisible --class "firefox" windowmove 0 0 | ||
+ | |||
+ | tail -f /dev/null | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | ==Если при этом не совпадает положение курсора от тачскрина== | ||
+ | |||
+ | apt-get install xinput-calibrator | ||
+ | |||
+ | Далее переходим в пользователя, от которого запускается X сервер и | ||
+ | |||
+ | export DISPLAY=:0 | ||
+ | |||
+ | затем | ||
+ | |||
+ | xinput-calibrator | ||
+ | |||
+ | затем тыкаем в "мишень" калибратора на экране. После того, как окно калибратора на экране закрылось - смотрим в консоль, из которой он был запущен и следуем инструкциям из вывода команды. | ||
+ | |||
+ | ==Перевернуть координаты touchscreen== | ||
+ | |||
+ | ===На уровне параметра для модуля ядра=== | ||
+ | |||
+ | Работало для модуля ядра | ||
+ | |||
+ | usbtouchscreen | ||
+ | |||
+ | echo 'options usbtouchscreen swap_xy=1' > /etc/modprobe.d/usbtouchscreen.conf | ||
+ | reboot | ||
+ | |||
+ | ===На уровне Xorg=== | ||
+ | |||
+ | Работало для модуля ядра | ||
+ | |||
+ | hid_multitouch | ||
+ | |||
+ | <pre> | ||
+ | cat << 'EOF' > /usr/share/X11/xorg.conf.d/90-rotate-touch.conf | ||
+ | Section "InputClass" | ||
+ | Identifier "ILITEK ILITEK-TP" | ||
+ | MatchProduct "ILITEK ILITEK-TP" | ||
+ | MatchIsTouchscreen "on" | ||
+ | Option "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1" | ||
+ | EndSection | ||
+ | EOF | ||
+ | </pre> | ||
+ | |||
+ | Поворот на 90 градусов | ||
+ | |||
+ | Option "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1" | ||
+ | |||
+ | Поворот на 180 градусов | ||
+ | |||
+ | Option "TransformationMatrix" "0 -1 1 1 0 0 0 0 1" | ||
+ | |||
+ | ==Если координаты touchscreen не совпадают с местом, куда нажимать пальцем== | ||
+ | |||
+ | Скорее всего дисплей работает не в родном разрешении. Нужно подобрать разрешение экспериментально пробуя варианты: | ||
+ | |||
+ | xrandr -s 1024x768 | ||
+ | |||
+ | или | ||
+ | |||
+ | xrandr -s 1280x1024 | ||
+ | |||
+ | или для совсем плохих мониторов | ||
+ | |||
+ | xrandr -s 800x600 | ||
+ | |||
+ | И заменить соответствующую команду в файле | ||
+ | |||
+ | /home/kioskdisplay/.xinitrc | ||
+ | |||
+ | Посмотреть список разрешений | ||
+ | |||
+ | xrandr -d :0 | ||
+ | |||
+ | ==Очистить очередь печати== | ||
+ | |||
+ | Однострочник берёт все задачи, кладёт команды для очистки задач в файл /tmp/clear-cups-queue.sh, выполняет его, удаляет файл, проверяет очередь | ||
+ | |||
+ | lpstat -o | awk {'print "cancel -a " $1'} >> /tmp/clear-cups-queue.sh;bash /tmp/clear-cups-queue.sh;/bin/rm /tmp/clear-cups-queue.sh;lpstat -o | ||
+ | |||
+ | ==Оптимизация journalctl== | ||
+ | |||
+ | find /var/log/journal -name "*.journal" | xargs rm | ||
+ | sed -i 's/#SystemMaxUse=/SystemMaxUse=1M/g' /etc/systemd/journald.conf | ||
+ | systemctl restart systemd-journald | ||
+ | |||
+ | ==Синхронизация времени через crontab== | ||
+ | |||
+ | apt-get update -q -y && apt-get install ntpdate -y | ||
+ | |||
+ | |||
+ | EDITOR=nano crontab -e | ||
+ | |||
+ | Добавить строчку | ||
+ | |||
+ | 1 */3 * * * /usr/sbin/ntpdate 0.ru.pool.ntp.org | ||
+ | |||
+ | Проверить | ||
+ | |||
+ | crontab -l | ||
+ | |||
+ | ==Запуск одного приложения в startx без менеджера окон== | ||
+ | <pre> | ||
+ | cat << 'EOF' > ~/.xinitrc | ||
+ | xrandr -s 1280x1024 | ||
+ | firefox & | ||
+ | sleep 5s | ||
+ | xdotool search --sync --onlyvisible --class "firefox" windowsize 1280 1024 | ||
+ | xdotool search --sync --onlyvisible --class "firefox" windowmove 5 5 | ||
+ | EOF | ||
+ | </pre> |
Текущая версия на 15:28, 23 мая 2024
Содержание
- 1 Киоск на базе пустого образа Alt jeos (ISO installer)
- 1.1 Обновление ОС и ядра
- 1.2 Оптимизация скорости загрузки
- 1.3 Установка необходимых пакетов через apt-get
- 1.4 Создание и настройка пользователей kiosk и kioskdisplay
- 1.5 Автологин пользователей kioskdisplay на консоли tty1
- 1.6 Отключение жестов на уровне Xorg
- 1.7 Создание стартового скрипта .xinitrc в домашнем каталоге пользователя kiosk
- 1.8 Минимальная установка платформы NodeJS (если необходима)
- 2 Решение проблем
- 2.1 MTU на сетевом интерфейсе
- 2.2 Перенастроить Xorg на VESA
- 2.3 Не работает терминал оплаты
- 2.4 Гаснет дисплей при простое
- 2.5 Дать конкретное имя tty устройству
- 2.6 Система загружается и просит настройки по dhcp раньше чем usb-модем инициализировался и готов это дать
- 2.7 Установить временнУю зону вместо UTC
- 2.8 Поворот экрана на 90 градусов по часовой стрелке
- 2.9 Если при этом не совпадает положение курсора от тачскрина
- 2.10 Перевернуть координаты touchscreen
- 2.11 Если координаты touchscreen не совпадают с местом, куда нажимать пальцем
- 2.12 Очистить очередь печати
- 2.13 Оптимизация journalctl
- 2.14 Синхронизация времени через crontab
- 2.15 Запуск одного приложения в startx без менеджера окон
Киоск на базе пустого образа Alt jeos (ISO installer)
Качаем отсюда:
wget https://mirror.yandex.ru/altlinux-starterkits/x86_64/release/alt-p10-jeos-sysv-20230610-x86_64.iso
Устанавливаем на железо или в виртуальную машину, настраиваем сеть и доступ по ssh.
Дальнейшие действия выполняем по ssh...
Обновление ОС и ядра
В этом разделе всё делается в рутовой консоли. Т.к. sudo по умолчанию в ОС Альт не присутствует (ниже мы его добавим).
Обновим индекс репозитория, дистрибутив, ядро
apt-get update && apt-get dist-upgrade -y && apt-get install update-kernel -y && update-kernel -f
Перезагрузимся для загрузки с новым ядром (если оно обновилось)
reboot
Оптимизация скорости загрузки
Просто бросьте это в рутовую консоль:
cat << 'EOF' > /etc/default/grub GRUB_AUTOUPDATE_CFG=true GRUB_AUTOUPDATE_CFGNAME=/boot/grub/grub.cfg GRUB_VMLINUZ_SYMLINKS=default GRUB_VMLINUZ_FAILSAFE=default GRUB_TIMEOUT=0 GRUB_CMDLINE_LINUX_DEFAULT='panic=30 splash' GRUB_CMDLINE_LINUX='failsafe vga=normal' GRUB_TERMINAL_OUTPUT='gfxterm' GRUB_GFXMODE='auto' GRUB_DEFAULT='saved' GRUB_SAVEDEFAULT=true GRUB_BACKGROUND="/etc/bootsplash/themes/current/images/silent-800x600.jpg" GRUB_WALLPAPER="/etc/bootsplash/themes/current/images/silent-800x600.jpg" GRUB_COLOR_NORMAL="black/black" GRUB_COLOR_HIGHLIGHT="white/black" GRUB_DISTRIBUTOR="ALT Linux" GRUB_BOOTLOADER_ID="altlinux" EOF update-grub
Установка необходимых пакетов через apt-get
Примечание: Пакет chromium был заменён на firefox-esr. Если нужен chromium-browser, то можно его отдельно поставить из пакета chromium.
apt-get -y -q install wget nano xorg-server kernel-modules-drm-std-def xinit xorg-drv-qxl xorg-drv-vesa xorg-drv-vmware xorg-drv-intel xorg-drv-nouveau xorg-drv-radeon xorg-drv-ati xorg-drv-amdgpu xorg-drv-r128 xorg-drv-synaptics xorg-drv-vboxvideo xorg-drv-vmmouse xorg-drv-wacom xorg-drv-input xorg-drv-video xdotool usb-modeswitch-data usb-modeswitch openssh sudo su xterm xhost git npm gcc10-c++ gcc-c++ make epm usbutils autosshd unclutter firefox-esr wkhtmltopdf pulseaudio-daemon alsa-plugins-pulse pulseaudio-utils aplay amixer alsa-utils fonts-ttf-ubuntu-font-family fonts-ttf-dejavu fonts-ttf-ms cups
Создание и настройка пользователей kiosk и kioskdisplay
useradd kiosk
usermod -a -G audio kiosk
useradd kioskdisplay
установка пароля
passwd kiosk
добавляем пользователя kiosk в группу wheel (для sudo su)
usermod kiosk -aG wheel
и в группу dialout (для доступа к устройствам /dev/tty*)
usermod kiosk -aG dialout
делаем sudo su без пароля для пользователя kiosk (просто бросьте это в рутовую консоль):
cat << 'EOF' > /etc/sudoers User_Alias WHEEL_USERS = %wheel User_Alias XGRP_USERS = %xgrp Defaults:XGRP_USERS env_keep += "DISPLAY XAUTHORITY" kiosk ALL=(ALL) NOPASSWD: ALL @includedir /etc/sudoers.d EOF
Автологин пользователей kioskdisplay на консоли tty1
Просто бросьте это в рутовую консоль:
cat << 'EOF' > /lib/systemd/system/getty\@tty1.service [Unit] Description=Getty on %I Documentation=man:agetty(8) man:systemd-getty-generator(8) Documentation=http://0pointer.de/blog/projects/serial-console.html After=systemd-user-sessions.service plymouth-quit-wait.service getty-pre.target After=rc-local.service Before=getty.target IgnoreOnIsolate=yes Conflicts=rescue.service Before=rescue.service ConditionPathExists=/dev/tty0 [Service] #ExecStart=-/sbin/agetty -o '-p -- \\u' --noclear %I $TERM ExecStart=-/sbin/agetty --autologin kioskdisplay --noclear %I $TERM Type=idle Restart=always RestartSec=0 UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes TTYVTDisallocate=yes IgnoreSIGPIPE=no SendSIGHUP=yes UnsetEnvironment=LANG LANGUAGE LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT LC_IDENTIFICATION [Install] WantedBy=getty.target DefaultInstance=tty1 EOF systemctl daemon-reload
Делаем симлинк:
ln -sf /lib/systemd/system/getty\@tty1.service '/etc/systemd/system/getty.target.wants/getty@tty1.service'
Отключение жестов на уровне Xorg
Пока не проверено!
cat << 'EOF' > /etc/X11/xorg.conf.d/40-libinput.conf Section "InputClass" Identifier "libinput touchscreen catchall" MatchIsTouchscreen "on" Option "Tapping" "off" Option "ClickMethod" "none" EndSection EOF
Создание стартового скрипта .xinitrc в домашнем каталоге пользователя kiosk
Скрипт запускает сессию Xorg, устанавливает разрешение экрана, запускает браузер chromium в режиме киоска и подгружает в него стартовую страницу.
Здесь может быть запущено веб приложение, стартующее на локальном хосте (для этого можно поставить платформу nodejs)
Примечание: В ходе реальных тестов так и не удалось запустить chromium-browser с отключением жестов. Поэтому вернулись к использованию firefox. Но запуск chromium-browser был оставлен в .xinitrc, но закомментирован.
Просто бросьте это в рутовый терминал:
cat << 'EOF' > /home/kioskdisplay/.xinitrc W=1280 H=1024 xrandr -s ${W}x${H} unclutter -idle 0 & amixer -D default sset Master 100% amixer -D default sset PCM 100% #/bin/rm -rf ~/.config/chromium #chromium-browser --kiosk --incognito "http://localhost:3000" & #xdotool search --sync --onlyvisible --class "chromium" windowsize ${W} ${H} #xdotool search --sync --onlyvisible --class "chromium" windowmove 0 0 /bin/rm -rf ~/.mozilla firefox --new-instance --kiosk --touch-events=disabled "http://localhost:3000" & xdotool search --sync --onlyvisible --class "firefox" windowsize ${W} ${H} xdotool search --sync --onlyvisible --class "firefox" windowmove 0 0 while true; do sleep 1 done EOF chown kioskdisplay: /home/kioskdisplay/.xinitrc echo 'startx' >> /home/kioskdisplay/.bashrc
Минимальная установка платформы NodeJS (если необходима)
Платформа
cd /tmp && wget https://nodejs.org/dist/v18.16.1/node-v18.16.1-linux-x64.tar.xz && unxz node-v18.16.1-linux-x64.tar.xz && cd /opt && tar -xpf /tmp/node-v18.16.1-linux-x64.tar && echo 'PATH="/opt/node-v18.16.1-linux-x64/bin:$PATH"' >> /etc/bashrc && source /etc/bashrc
Пример веб-приложения с автоматическим стартом
Просто бросьте это в консоль:
mkdir -p /home/kiosk/server/bin cat << 'EOF' > /home/kiosk/server/bin/www const http = require('http'); const port = process.env.PORT || 3000; const server = http.createServer((req, res) => { let url = req.url; let content = ''; if (url === '/') { content = ` <h1>Welcome to the Home Page!</h1> <p><a href="/about">About Us</a></p> <p><a href="/contact">Contact Us</a></p> `; } else if (url === '/about') { content = ` <h1>About Us</h1> <p>We are a company that provides amazing services.</p> <p><a href="/">Home</a></p> <p><a href="/contact">Contact Us</a></p> `; } else if (url === '/contact') { content = ` <h1>Contact Us</h1> <p>You can reach us at example@example.com</p> <p><a href="/">Home</a></p> <p><a href="/about">About Us</a></p> `; } else { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Page not found'); return; } res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(content); }); server.listen(port, () => { console.log(`Server is running on port ${port}`); }); EOF chown kiosk: /home/kiosk/server -R cat << 'EOF' > /etc/systemd/system/kiosk.service [Unit] Description=KIOSK Requires=network-online.target After=network-online.target [Service] Environment=PORT=3000 Restart=always RestartSec=5 WorkingDirectory=/home/kiosk/server ExecStart=/opt/node-v18.16.1-linux-x64/bin/node ./bin/www User=kiosk Group=kiosk [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl enable --now kiosk.service
Решение проблем
MTU на сетевом интерфейсе
В файл
iplink
в каталоге сетевого интерфейса добавить строчку
mtu 1400
Значение mtu подбирать исходя из ситуации
Перенастроить Xorg на VESA
Бывает нужно, если родные драйвера intel или amdgpu не работают
Заменить фрагмент в файле
/etc/X11/xorg.conf
Section "Device" Identifier "Card0" Driver "vesa" EndSection
Не работает терминал оплаты
/home/kiosk/server/pos chmod +x sb_pilot u2updater chmod 775 upnixmn.out
Гаснет дисплей при простое
Просто бросьте это в консоль:
cat << EOF > /etc/X11/xorg.conf.d/90-disable-timeouts.conf Section "ServerFlags" Option "StandbyTime" "0" Option "SuspendTime" "0" Option "OffTime" "0" Option "BlankTime" "0" EndSection EOF
Дать конкретное имя tty устройству
Сначала нужно узнать несколько параметров для конструирования строчки для udev: https://askubuntu.com/questions/978485/udev-rule-with-serial-for-ttyusb-not-working
Кратко: для выяснения idVendor и idProduct выполните команду
lsusb
,выдёргивая и вставляя устройство tty. Как будет понятно: какое из них нужное вам, берёте оттуда эти данные.
Когда всё будет готово, сформируйте вот такой текст и бросьте его в рутовую консоль:
cat << 'EOF' > /etc/udev/rules.d/42-usb-serial-ttyS42.rules SUBSYSTEM=="tty", ATTRS{idVendor}=="079b", ATTRS{idProduct}=="0028", MODE="0666", SYMLINK+="ttyS42" EOF
Если у существующего устройства нужно просто поменять режим доступа к файлу устройства:
cat << 'EOF' > /etc/udev/rules.d/47-usb-serial-ttyUSB0.rules SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE="0666" EOF
Затем
udevadm control --reload reboot
Система загружается и просит настройки по dhcp раньше чем usb-модем инициализировался и готов это дать
Добавить скрипт (просто бросьте это в консоль)
cat << 'EOF' > /opt/check_gw.sh #!/bin/bash check_result=$(ip ro | grep default | wc -l) if [ $check_result -eq 0 ]; then dhcpcd exit 0 fi #echo 'wg is ok' exit 0 EOF
chmod +x /opt/check_gw.sh
Запускать раз в минуту через crontab рута
Установить временнУю зону вместо UTC
ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime
Поворот экрана на 90 градусов по часовой стрелке
Тут обратить внимание на разрешение, частоту и название монитора. Вынесены в отдельные переменные.
cat << 'EOF' > /home/kioskdisplay/.xinitrc W=1080 H=1920 F=60 MON=HDMI-2 xrandr --newmode $(cvt ${W} ${H} ${F} | sed 's/Modeline //g' | tail -1) xrandr --addmode ${MON} ${W}x${H}_${F} xrandr -s ${W}x${H} xrandr -o left unclutter -idle 0 & amixer -D default sset Master 100% amixer -D default sset PCM 100% #/bin/rm -rf ~/.config/chromium #chromium-browser --kiosk --incognito "http://localhost:3000" & #xdotool search --sync --onlyvisible --class "chromium" windowsize ${W} ${H} #xdotool search --sync --onlyvisible --class "chromium" windowmove 0 0 /bin/rm -rf ~/.mozilla firefox --new-instance --kiosk --touch-events=disabled "https://nntc.nnov.ru" & xdotool search --sync --onlyvisible --class "firefox" windowsize ${W} ${H} xdotool search --sync --onlyvisible --class "firefox" windowmove 0 0 tail -f /dev/null EOF
Если при этом не совпадает положение курсора от тачскрина
apt-get install xinput-calibrator
Далее переходим в пользователя, от которого запускается X сервер и
export DISPLAY=:0
затем
xinput-calibrator
затем тыкаем в "мишень" калибратора на экране. После того, как окно калибратора на экране закрылось - смотрим в консоль, из которой он был запущен и следуем инструкциям из вывода команды.
Перевернуть координаты touchscreen
На уровне параметра для модуля ядра
Работало для модуля ядра
usbtouchscreen
echo 'options usbtouchscreen swap_xy=1' > /etc/modprobe.d/usbtouchscreen.conf reboot
На уровне Xorg
Работало для модуля ядра
hid_multitouch
cat << 'EOF' > /usr/share/X11/xorg.conf.d/90-rotate-touch.conf Section "InputClass" Identifier "ILITEK ILITEK-TP" MatchProduct "ILITEK ILITEK-TP" MatchIsTouchscreen "on" Option "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1" EndSection EOF
Поворот на 90 градусов
Option "TransformationMatrix" "-1 0 1 0 -1 1 0 0 1"
Поворот на 180 градусов
Option "TransformationMatrix" "0 -1 1 1 0 0 0 0 1"
Если координаты touchscreen не совпадают с местом, куда нажимать пальцем
Скорее всего дисплей работает не в родном разрешении. Нужно подобрать разрешение экспериментально пробуя варианты:
xrandr -s 1024x768
или
xrandr -s 1280x1024
или для совсем плохих мониторов
xrandr -s 800x600
И заменить соответствующую команду в файле
/home/kioskdisplay/.xinitrc
Посмотреть список разрешений
xrandr -d :0
Очистить очередь печати
Однострочник берёт все задачи, кладёт команды для очистки задач в файл /tmp/clear-cups-queue.sh, выполняет его, удаляет файл, проверяет очередь
lpstat -o | awk {'print "cancel -a " $1'} >> /tmp/clear-cups-queue.sh;bash /tmp/clear-cups-queue.sh;/bin/rm /tmp/clear-cups-queue.sh;lpstat -o
Оптимизация journalctl
find /var/log/journal -name "*.journal" | xargs rm sed -i 's/#SystemMaxUse=/SystemMaxUse=1M/g' /etc/systemd/journald.conf systemctl restart systemd-journald
Синхронизация времени через crontab
apt-get update -q -y && apt-get install ntpdate -y
EDITOR=nano crontab -e
Добавить строчку
1 */3 * * * /usr/sbin/ntpdate 0.ru.pool.ntp.org
Проверить
crontab -l
Запуск одного приложения в startx без менеджера окон
cat << 'EOF' > ~/.xinitrc xrandr -s 1280x1024 firefox & sleep 5s xdotool search --sync --onlyvisible --class "firefox" windowsize 1280 1024 xdotool search --sync --onlyvisible --class "firefox" windowmove 5 5 EOF