Kiosk2.0: различия между версиями

Материал из wiki.nntc.nnov.ru
Перейти к навигации Перейти к поиску
(Новая страница: «=Киоск на базе пустого образа Alt jeos (ISO installer)= Качаем отсюда: wget https://mirror.yandex.ru/altlinux-starterkits/x…»)
 
(Поворот экрана на 90 градусов по часовой стрелке)
 
(не показано 57 промежуточных версий 2 участников)
Строка 13: Строка 13:
 
В этом разделе всё делается в рутовой консоли. Т.к. sudo по умолчанию в ОС Альт не присутствует (ниже мы его добавим).
 
В этом разделе всё делается в рутовой консоли. Т.к. sudo по умолчанию в ОС Альт не присутствует (ниже мы его добавим).
  
Обновим индекс репозитория
+
Обновим индекс репозитория, дистрибутив, ядро
  
  apt-get update
+
  apt-get update && apt-get dist-upgrade -y && apt-get install update-kernel -y && update-kernel -f
  
Обновим дистрибутив (в рамках одной рабочей ветки. Например, P10)
+
Перезагрузимся для загрузки с новым ядром (если оно обновилось)
  
  apt-get dist-upgrade
+
  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==
 +
 
 +
<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 (если необходима)==
 +
 
 +
===Платформа===
 +
 
 +
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
  
apt-get install update-kernel
+
Кратко: для выяснения idVendor и idProduct выполните команду
update-kernel -f
 
  
Перезагружаемся
+
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
 
  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

Содержание

Киоск на базе пустого образа 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