Installing the screen
On the host machine, running Debian 13: the Marquee service and its settings, then Chromium full screen from the moment it boots.
Every command is typed on the host machine, in a terminal or over ssh. They're written with sudo; if you work as root, leave it out. In the examples, the host machine's address is 192.168.1.50.
1Download and verify
Fetch the binary and the checksum file, then check one against the other.
curl -fLO https://marquee.yg-devworks.com/telechargements/v1.0.0/ecran-atelier-linux-amd64
curl -fLO https://marquee.yg-devworks.com/telechargements/v1.0.0/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
curl -fLO https://marquee.yg-devworks.com/telechargements/v1.0.0/ecran-atelier-linux-arm64
curl -fLO https://marquee.yg-devworks.com/telechargements/v1.0.0/SHA256SUMS
sha256sum -c SHA256SUMS --ignore-missing
The last command must answer ecran-atelier-linux-amd64: OK (or arm64). If it says anything else, stop right there: the file isn't the one that was published.
2Install the binary
The service expects it in /usr/local/bin, under the name ecran-atelier.
sudo install -m 755 ecran-atelier-linux-amd64 /usr/local/bin/ecran-atelier
sudo install -m 755 ecran-atelier-linux-arm64 /usr/local/bin/ecran-atelier
install sets the execute permissions, and swaps an existing binary for a fresh file rather than overwriting it in place: it's also the command for updates.
3The systemd service
Marquee runs as a systemd service. Create its unit:
sudo nano /etc/systemd/system/ecran-atelier.service
and paste this in:
[Unit]
Description=Marquee, your desk in lights
Documentation=https://marquee.yg-devworks.com/en/guide/ecran.html
After=network-online.target
Wants=network-online.target
[Service]
ExecStart=/usr/local/bin/ecran-atelier
Environment=ADRESSE=:8099
Environment=MUSIC_ASSISTANT=http://127.0.0.1:8095
# The lag between the sound and the spectrum, in milliseconds: the speaker's
# output latency. Tuned on site, by ear and by eye.
Environment=VISUALISEUR_DECALAGE_MS=0
# The port the machines' services (ecran-agent) connect to. With no machine
# token, it stays closed.
Environment=ADRESSE_MACHINES=:8098
# The weather location and the tokens live elsewhere, in mode 600: a systemd
# unit is readable by everyone, and a secret has no business in it.
# The "-" makes that file optional: if it's missing, the screen still shows
# what it knows instead of staying black.
EnvironmentFile=-/etc/ecran-atelier.env
Restart=always
RestartSec=5
# The machine serves music first: the dashboard comes second.
Nice=10
# It reads /proc and /sys for the rail's gauges and writes nothing, so we
# might as well forbid it to.
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
NoNewPrivileges=yes
DynamicUser=yes
[Install]
WantedBy=multi-user.target
- No account to create
DynamicUsergives the service a throwaway user, and theProtect…lines lock it out of the disk: it reads/procand/sysfor its gauges, and writes nothing.- Music first
Nice=10: the machine serves music, the screen comes second.- No secrets here
- Anyone can read a unit. The tokens go in
/etc/ecran-atelier.env, in the next step. - Always up
- If it falls over, it's back five seconds later, and it starts along with the machine.
4The settings file
Your settings and your secrets live in /etc/ecran-atelier.env, which only root can read.
sudo touch /etc/ecran-atelier.env
sudo chmod 600 /etc/ecran-atelier.env
sudo nano /etc/ecran-atelier.env
# The weather location: "lat,lon", or the name of a town.
METEO=50.85,4.35
# The Music Assistant token: see the next step.
MUSIC_ASSISTANT_JETON=<your Music Assistant token>
# One token per Mac: "Name=token;Other name=other token".
JETONS_MACHINES="MacBook Pro=<this Mac's token>"
A Mac's name is the one it will give in its config.json: no “=” and no “;”, 40 characters at most. Generate its token at random, right here:
openssl rand -hex 32
You'll copy it into the Mac's config.json, in the Installing the Mac service chapter. With no machine token at all, port 8098 stays closed: you can leave JETONS_MACHINES aside for now.
A value in this file wins over the one in the unit. Every variable, with its default value, is in the Settings chapter.
5The Music Assistant token
Since 2.10, Music Assistant refuses any anonymous access: Marquee needs a long-lived token. This command gets one using your Music Assistant username and password, which it asks you for (in French: Identifiant, then Mot de passe) without writing them down anywhere, then prints it:
python3 -c '
import getpass, json, urllib.error, urllib.request
def appel(commande, args, jeton=None):
entetes = {"Content-Type": "application/json"}
if jeton:
entetes["Authorization"] = "Bearer " + jeton
corps = json.dumps({"message_id": "marquee", "command": commande, "args": args}).encode()
try:
with urllib.request.urlopen(urllib.request.Request("http://127.0.0.1:8095/api", corps, entetes), timeout=10) as r:
return json.load(r)
except urllib.error.HTTPError as e:
raise SystemExit("Music Assistant a répondu %d à %s" % (e.code, commande))
identifiant = input("Identifiant Music Assistant : ")
connexion = appel("auth/login", {"username": identifiant, "password": getpass.getpass("Mot de passe : "), "device_name": "marquee"})
if not isinstance(connexion, dict) or not connexion.get("access_token"):
raise SystemExit("identifiants refusés")
print(appel("auth/token/create", {"name": "marquee"}, connexion["access_token"]))
'
It needs python3 (sudo apt install python3 if it's missing) and Music Assistant at its usual address on the machine, http://127.0.0.1:8095. Copy the token it prints into /etc/ecran-atelier.env, on the MUSIC_ASSISTANT_JETON line, and nowhere else. It goes by the name marquee in Music Assistant, where you can revoke it.
It expires after a year, and doesn't renew itself. When that day comes, the screen shows “jeton refusé” (token refused), not “erreur réseau” (network error): run the same command again.
The music keys need the players.control scope. A token that can read but not control shows the music, but every press fails, and the screen says so in as many words.
6Start it, and check
sudo systemctl daemon-reload
sudo systemctl enable --now ecran-atelier
The service starts, and will start again with the machine. Check that it answers:
curl -s http://127.0.0.1:8099/sante
The expected answer is {"etat":"ok"}. From your Mac, http://192.168.1.50:8099/ already shows the page: readable, keys inert, since Marquee only takes commands from the screen itself.
Its log, as it happens:
journalctl -u ecran-atelier -f
And after every change to /etc/ecran-atelier.env:
sudo systemctl restart ecran-atelier
7Kiosk mode
The screen shows the page in Chromium, in app mode and full screen, under the labwc Wayland compositor. greetd opens the session at boot, with no password: the machine powers on, the page appears. Install them, along with an account for the display:
sudo apt install labwc greetd chromium
sudo adduser marquee
Switch to that account:
sudo -iu marquee
and write Chromium's launcher:
mkdir -p ~/bin ~/.config/labwc
nano ~/bin/dashboard
#!/bin/sh
# The screen's browser: Chromium in app mode, full screen, under labwc.
# Started by ~/.config/labwc/autostart.
#
# --overscroll-history-navigation=0: a swipe from the edge would mean
# "previous page", and the screen would stay blank.
# --disable-pinch: a pinch would zoom the page.
export HOME=/home/marquee
export XDG_CONFIG_HOME=/home/marquee/.config
export XDG_CACHE_HOME=/home/marquee/.cache
export XDG_DATA_HOME=/home/marquee/.local/share
exec /usr/bin/chromium \
--ozone-platform=wayland \
--user-data-dir=/home/marquee/.config/chromium-dashboard \
--app=http://127.0.0.1:8099/ \
--start-fullscreen \
--no-first-run \
--disable-session-crashed-bubble \
--disable-infobars \
--noerrdialogs \
--overscroll-history-navigation=0 \
--disable-pinch
Make it executable, then have labwc start it when the session opens:
chmod 755 ~/bin/dashboard
nano ~/.config/labwc/autostart
sleep 2
/home/marquee/bin/dashboard &
The sleep 2 gives labwc time to open its Wayland display: started too early, on the first boot, Chromium might not find it. The reference machine also starts waybar, a status bar, just before the launcher: that's optional (sudo apt install waybar, then a waybar & line). Then go back to your own account:
exit
Finally, have greetd start labwc under the marquee account at boot:
sudo nano /etc/greetd/config.toml
[terminal]
vt = 7
[default_session]
command = "labwc"
user = "marquee"
Replace the whole content of the file with these lines: the kiosk session becomes the default session, which greetd restarts on its own if labwc or Chromium falls over, without ever showing a login prompt. Then:
sudo systemctl enable greetd
sudo reboot
After the reboot, the page appears. From then on it reloads itself whenever the service changes version: no more need to touch Chromium.
Taken from the reference machine, on 2026-09-25. The launcher, labwc's autostart and the greetd configuration are its own, give or take the account name and the paths.
8The right time
Install clock synchronization, then check it:
sudo apt install systemd-timesyncd
timedatectl
timedatectl should say System clock synchronized: yes.
Why? The time on the rail is the machine's, and so is the track position: Marquee works it out from the moment Music Assistant recorded it. Checked on 2026-09-25: on a machine whose clock was wrong, track positions were off.
9Sync the spectrum to the sound
A speaker takes a moment to play what it receives: left uncorrected, the spectrum dances ahead of the sound. VISUALISEUR_DECALAGE_MS holds the picture back by that many milliseconds. You tune it on site, by ear and by eye.
- Play a track with sharp attacks: drums, a bass line.
- Watch the bars. If they jump before the beat you hear, the spectrum is early.
- Add or change the line in
/etc/ecran-atelier.env, for exampleVISUALISEUR_DECALAGE_MS=150, then restart the service. - Repeat until picture and sound land together.
sudo nano /etc/ecran-atelier.env
sudo systemctl restart ecran-atelier
The page rereads the offset on every frame: no need to reload Chromium.
10Updating
Download and verify the new version as in step 1, install it as in step 2, then restart the service:
sudo systemctl restart ecran-atelier
The page reloads itself on the new version.