[IMP] iot: Dual screen support for RPI4
We now support the RPI4 which has 2 micro-HDMI outputs, while the prvious driver only supported one display. We add support for a second display. Taskid: 2123511 X-original-commit: 5886c3a864c990fcd7b852baafab752e7da90494
This commit is contained in:
@@ -6,7 +6,7 @@ from usb import core
|
||||
from gatt import DeviceManager as Gatt_DeviceManager
|
||||
import subprocess
|
||||
import json
|
||||
from re import sub
|
||||
from re import sub, finditer
|
||||
import urllib3
|
||||
import os
|
||||
import socket
|
||||
@@ -302,14 +302,20 @@ class Manager(Thread):
|
||||
|
||||
def get_connected_displays(self):
|
||||
display_devices = {}
|
||||
hdmi = subprocess.check_output(['tvservice', '-n']).decode('utf-8').replace('\n', '')
|
||||
if hdmi.find('=') != -1 and hdmi.split('=')[1] != "Unk-Composite dis":
|
||||
hdmi_serial = sub('[^a-zA-Z0-9 ]+', '', hdmi.split('=')[1]).replace(' ', '_')
|
||||
|
||||
displays = subprocess.check_output(['tvservice', '-l']).decode()
|
||||
x_screen = 0
|
||||
for match in finditer('Display Number (\d), type HDMI (\d)', displays):
|
||||
display_id, hdmi_id = match.groups()
|
||||
display_name = subprocess.check_output(['tvservice', '-nv', display_id]).decode().rstrip().split('=')[1]
|
||||
display_identifier = sub('[^a-zA-Z0-9 ]+', '', display_name).replace(' ', '_') + "_" + str(hdmi_id)
|
||||
iot_device = IoTDevice({
|
||||
'identifier': hdmi_serial,
|
||||
'name': hdmi.split('=')[1],
|
||||
'identifier': display_identifier,
|
||||
'name': display_name,
|
||||
'x_screen': str(x_screen),
|
||||
}, 'display')
|
||||
display_devices[hdmi_serial] = iot_device
|
||||
display_devices[display_identifier] = iot_device
|
||||
x_screen += 1
|
||||
|
||||
if not len(display_devices):
|
||||
# No display connected, create "fake" device to be accessed from another computer
|
||||
|
||||
@@ -35,8 +35,9 @@ class DisplayDriver(Driver):
|
||||
self.event_data = threading.Event()
|
||||
self.owner = False
|
||||
self.rendered_html = ''
|
||||
self.load_url()
|
||||
self.call_xdotools('F11')
|
||||
if self.device_identifier != 'distant_display':
|
||||
self._x_screen = device.get('x_screen', '0')
|
||||
self.load_url()
|
||||
|
||||
@property
|
||||
def device_identifier(self):
|
||||
@@ -68,20 +69,22 @@ class DisplayDriver(Driver):
|
||||
event_manager.device_changed(self)
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
while self.device_identifier != 'distant_display':
|
||||
time.sleep(60)
|
||||
if self.url != 'http://localhost:8069/point_of_sale/display/':
|
||||
# Refresh the page every minute
|
||||
self.call_xdotools('F5')
|
||||
|
||||
def update_url(self, url=None):
|
||||
os.environ['DISPLAY'] = ":0." + self._x_screen
|
||||
os.environ['XAUTHORITY'] = '/run/lightdm/pi/xauthority'
|
||||
firefox_env = os.environ.copy()
|
||||
firefox_env['HOME'] = '/tmp'
|
||||
firefox_env['DISPLAY'] = ':0.0'
|
||||
firefox_env['XAUTHORITY'] = '/run/lightdm/pi/xauthority'
|
||||
firefox_env['HOME'] = '/tmp/' + self._x_screen
|
||||
self.url = url or 'http://localhost:8069/point_of_sale/display/'
|
||||
if self.device_identifier != 'distant_display':
|
||||
subprocess.Popen(['firefox', self.url], env=firefox_env)
|
||||
new_window = subprocess.call(['xdotool', 'search', '--onlyvisible', '--screen', self._x_screen, '--class', 'Firefox'])
|
||||
subprocess.Popen(['firefox', self.url], env=firefox_env)
|
||||
if new_window:
|
||||
self.call_xdotools('F11')
|
||||
|
||||
def load_url(self):
|
||||
url = None
|
||||
@@ -101,10 +104,10 @@ class DisplayDriver(Driver):
|
||||
return self.update_url(url)
|
||||
|
||||
def call_xdotools(self, keystroke):
|
||||
os.environ['DISPLAY'] = ":0.0"
|
||||
os.environ['DISPLAY'] = ":0." + self._x_screen
|
||||
os.environ['XAUTHORITY'] = "/run/lightdm/pi/xauthority"
|
||||
try:
|
||||
subprocess.call(['xdotool', 'search', '--sync', '--onlyvisible', '--class', 'Firefox', 'windowactivate', 'key', keystroke])
|
||||
subprocess.call(['xdotool', 'search', '--sync', '--onlyvisible', '--screen', self._x_screen, '--class', 'Firefox', 'key', keystroke])
|
||||
return "xdotool succeeded in stroking " + keystroke
|
||||
except:
|
||||
return "xdotool threw an error, maybe it is not installed on the IoTBox"
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
Section "Device"
|
||||
Identifier "fbdev0"
|
||||
Driver "fbdev"
|
||||
Option "fbdev" "/dev/fb0"
|
||||
EndSection
|
||||
|
||||
Section "Device"
|
||||
Identifier "fbdev1"
|
||||
Driver "fbdev"
|
||||
Option "fbdev" "/dev/fb1"
|
||||
EndSection
|
||||
|
||||
# Dummy device to use Xlib in KeyboardUSBDriver when no monitor is connected
|
||||
Section "Device"
|
||||
Identifier "dummy"
|
||||
Driver "dummy"
|
||||
EndSection
|
||||
|
||||
Section "Monitor"
|
||||
Identifier "Monitor0"
|
||||
EndSection
|
||||
|
||||
Section "Monitor"
|
||||
Identifier "Monitor1"
|
||||
EndSection
|
||||
|
||||
Section "Monitor"
|
||||
Identifier "DummyMonitor"
|
||||
EndSection
|
||||
|
||||
Section "Screen"
|
||||
Identifier "Screen0"
|
||||
Monitor "Monitor0"
|
||||
Device "fbdev0"
|
||||
Subsection "Display"
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
Section "Screen"
|
||||
Identifier "Screen1"
|
||||
Monitor "Monitor1"
|
||||
Device "fbdev1"
|
||||
Subsection "Display"
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
Section "Screen"
|
||||
Identifier "DummyScreen"
|
||||
Monitor "DummyMonitor"
|
||||
Device "dummy"
|
||||
Subsection "Display"
|
||||
EndSubSection
|
||||
EndSection
|
||||
|
||||
Section "ServerLayout"
|
||||
Identifier "Multihead"
|
||||
Screen 0 "Screen0"
|
||||
Screen 1 "Screen1" rightof "Screen0"
|
||||
Screen 2 "DummyScreen" rightof "Screen1"
|
||||
EndSection
|
||||
@@ -3,6 +3,6 @@
|
||||
user-authority-in-system-dir=true
|
||||
|
||||
[SeatDefaults]
|
||||
xserver-command=/usr/bin/X -s 0 dpms -nolisten tcp
|
||||
xserver-command=/usr/bin/X -s 0 -layout Multihead dpms -nolisten tcp
|
||||
greeter-hide-users=false
|
||||
autologin-user=pi
|
||||
autologin-user=pi
|
||||
|
||||
@@ -50,6 +50,7 @@ PKGS_TO_INSTALL="
|
||||
xdotool \
|
||||
unclutter \
|
||||
x11-utils \
|
||||
xserver-xorg-video-dummy \
|
||||
openbox \
|
||||
rpi-update \
|
||||
adduser \
|
||||
@@ -159,6 +160,9 @@ systemctl disable hostapd.service
|
||||
# cf: https://www.raspberrypi.org/documentation/configuration/raspi-config.md
|
||||
echo "disable_overscan=1" >> /boot/config.txt
|
||||
|
||||
# Separate framebuffers for both screens on RPI4
|
||||
sed -i '/dtoverlay/d' /boot/config.txt
|
||||
|
||||
# exclude /drivers folder from git info to be able to load specific drivers
|
||||
echo "addons/hw_drivers/drivers/" > /home/pi/odoo/.git/info/exclude
|
||||
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Start Openbox on the second display as described in
|
||||
# http://openbox.org/wiki/Help:FAQ > "How do I run Openbox across multiple X screens?"
|
||||
|
||||
XAUTHORITY=/run/lightdm/pi/xauthority DISPLAY=:0.1 openbox &
|
||||
exec openbox-session
|
||||
Reference in New Issue
Block a user