-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdisplay.py
More file actions
123 lines (110 loc) · 5.81 KB
/
Copy pathdisplay.py
File metadata and controls
123 lines (110 loc) · 5.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""Proprietario esclusivo del pannello LED.
Un solo processo puo' pilotare i GPIO: tutto il rendering passa da qui.
Le sorgenti non disegnano mai direttamente, producono immagini PIL.
"""
import os
import threading
class Display:
def __init__(self, cfg):
panel = cfg["panel"]
# Il catalogo dei profili di registro va indicato prima di creare la
# matrice. Vuoto = **libreria standard**, quella di hzeller senza il
# fork S-PWM: allora non c'e' nessun catalogo da indicare, e scrivere
# la variabile a vuoto farebbe cercare una cartella che non esiste.
if (panel.get("profile_dir") or "").strip():
os.environ["SPWM_PROFILE_DIR"] = panel["profile_dir"]
# Regolazioni fini del driver S-PWM: la libreria le legge dall'ambiente
# al momento della creazione della matrice. Un valore vuoto significa
# "lascia il predefinito", quindi la variabile viene rimossa.
for name, value in (panel.get("spwm_env") or {}).items():
text = str(value).strip()
if text:
os.environ[name] = text
print("[display] %s=%s" % (name, text))
else:
os.environ.pop(name, None)
from rgbmatrix import RGBMatrix, RGBMatrixOptions
options = RGBMatrixOptions()
options.rows = panel["rows"]
options.cols = panel["cols"]
options.chain_length = panel["chain"]
options.parallel = panel["parallel"]
options.hardware_mapping = panel["hardware_mapping"]
options.gpio_slowdown = panel["slowdown"]
options.panel_type = panel.get("panel_type") or ""
# I quattro parametri S-PWM esistono **solo** nel fork: con la
# libreria standard assegnarli farebbe morire il servizio all'avvio,
# cioe' pannello nero. Si guarda se la libreria li conosce, e se non
# li conosce si tira dritto -- e' la stessa cautela dei registri
# forzati, qui applicata a tutto il blocco.
spwm = hasattr(options, "spwm_row_address_type")
if spwm:
options.spwm_row_address_type = panel["spwm_row_address_type"]
options.spwm_scan_rows = panel["spwm_scan_rows"]
options.spwm_data_layout = panel["spwm_data_layout"]
options.spwm_register_config = panel["spwm_register_config"]
# I parametri dei pannelli classici, quelli a indirizzamento diretto.
# Si applicano solo se in configurazione c'e' scritto qualcosa: vuoto
# vuol dire "lascia il predefinito della libreria", che e' quello che
# vuole chi non sa ancora che pannello ha in mano.
for chiave, attributo, tipo in (
("row_address_type", "row_address_type", int),
("multiplexing", "multiplexing", int),
("scan_mode", "scan_mode", int),
("pixel_mapper", "pixel_mapper_config", str),
("led_rgb_sequence", "led_rgb_sequence", str),
("disable_hardware_pulsing", "disable_hardware_pulsing", bool)):
grezzo = panel.get(chiave)
if grezzo in (None, ""):
continue
try:
valore = bool(grezzo) if tipo is bool else tipo(grezzo)
setattr(options, attributo, valore)
print("[display] %s=%s" % (attributo, valore))
except (AttributeError, TypeError, ValueError):
print("[display] la libreria non accetta %s" % attributo)
options.limit_refresh_rate_hz = panel["limit_refresh"]
options.pwm_bits = panel["pwm_bits"]
# Le due leve che permettono di tenere la profondita' alta senza
# pagarla in refresh. Assenti nelle configurazioni precedenti la
# 1.9.4, da cui i valori predefiniti della libreria.
options.pwm_lsb_nanoseconds = int(panel.get("pwm_lsb_nanoseconds", 130))
options.pwm_dither_bits = int(panel.get("pwm_dither_bits", 0))
# Registri RGB forzati. Facoltativo due volte: puo' mancare nella
# configurazione, e puo' mancare nella libreria — un fork piu' vecchio
# non ha la proprieta', e assegnarla farebbe morire il servizio
# all'avvio, cioe' pannello nero per una funzione che l'utente non ha
# nemmeno chiesto. Se non c'e', si tira dritto con il profilo.
registri = str(panel.get("spwm_force_register") or "").strip()
if registri and spwm:
try:
options.spwm_force_register = registri
print("[display] registri RGB forzati: %s" % registri[:60])
except AttributeError:
print("[display] la libreria non accetta registri forzati:"
" si usa il profilo %s" % panel["spwm_register_config"])
options.brightness = cfg["display"]["brightness"]
options.show_refresh_rate = bool(panel.get("show_refresh", False))
# Senza questo la libreria perde l'accesso al catalogo profili.
options.drop_privileges = False
self.matrix = RGBMatrix(options=options)
self.canvas = self.matrix.CreateFrameCanvas()
# La misura la dice la matrice, non la configurazione: con un
# pixel mapper -- o con una catena disposta in piu' righe -- il
# prodotto colonne per catena non e' piu' quello che si vede.
self.width = self.matrix.width
self.height = self.matrix.height
self._lock = threading.Lock()
def set_brightness(self, value):
value = max(0, min(100, int(value)))
with self._lock:
self.matrix.brightness = value
return value
def show(self, image):
"""Mostra un'immagine PIL RGB della dimensione del display."""
with self._lock:
self.canvas.SetImage(image, 0, 0)
self.canvas = self.matrix.SwapOnVSync(self.canvas)
def clear(self):
with self._lock:
self.matrix.Clear()