# Screen Brightness Service — Manual Setup on Existing Device

This guide describes how to install and configure the **screen-brightness** daemon on an existing reTerminal DM (e.g. a device that was not provisioned with the first-boot flow that includes step 14). The daemon controls LCD backlight from the ambient light sensor and raises brightness when the buzzer is active (alarm), with behaviour aligned to bridge display regulations.

**See also:** [SCREEN-BRIGHTNESS-REGULATIONS.md](SCREEN-BRIGHTNESS-REGULATIONS.md) for the regulatory references.

---

## 1. Prerequisites

- **Hardware:** reTerminal DM (Raspberry Pi CM4-based) with built-in light sensor and buzzer.
- **OS:** Raspberry Pi OS (or compatible) with:
  - Python 3
  - Sysfs nodes present (see [Verify hardware](#2-verify-hardware-below)).

No extra Python packages are required (stdlib only).

---

## 2. Verify hardware

On the device, confirm that the backlight, buzzer, and light sensor are available:

```bash
# Backlight (values 0–5)
cat /sys/class/backlight/lcd_backlight/brightness
cat /sys/class/backlight/lcd_backlight/max_brightness

# Buzzer (0 = off, 1 = on)
cat /sys/class/leds/usr-buzzer/brightness

# Ambient light (lux)
cat /sys/bus/iio/devices/iio:device0/in_illuminance_input
```

If any of these paths are missing, install the reTerminal DM drivers first (Seeed wiki: [reTerminal DM Getting Started](https://wiki.seeedstudio.com/reterminal-dm/)).

---

## 3. Install the service (manual copy)

### 3.1 Create directories and copy files

Run as **root** (or with `sudo`):

```bash
# Script
install -m 755 screen-brightness.py /usr/local/bin/screen-brightness.py

# Systemd unit
install -m 644 screen-brightness.service /etc/systemd/system/screen-brightness.service

# Optional: default config (skip if you already have vessel-specific /etc/screen-brightness.conf)
install -m 644 screen-brightness.conf /etc/screen-brightness.conf
```

Use the files from this repo:

- `emmc-provisioning/cloud-init/fileserver/screen-brightness.py`
- `emmc-provisioning/cloud-init/fileserver/screen-brightness.service`
- `emmc-provisioning/cloud-init/fileserver/screen-brightness.conf`

Copy them to the device first (e.g. via SCP, USB stick, or the deployment script below), then run the `install` commands on the device.

### 3.2 Runtime directory and tmpfiles

Ensure the daemon’s runtime directory exists and is recreated after reboot:

```bash
mkdir -p /run/screen-brightness

# Create tmpfiles.d rule so the directory exists after reboot
cat > /etc/tmpfiles.d/screen-brightness.conf << 'EOF'
d /run/screen-brightness 0755 root root -
EOF
```

### 3.3 Enable and start

```bash
systemctl daemon-reload
systemctl enable screen-brightness.service
systemctl start screen-brightness.service
```

Check status and logs:

```bash
systemctl status screen-brightness.service
journalctl -u screen-brightness.service -f
```

---

## 4. Install using the deployment script

A helper script can install or update the service from **either** a local directory (repo clone/USB) **or** a URL (e.g. your file server). The script lives in the repo at:

`emmc-provisioning/scripts/deploy-screen-brightness-to-device.sh`

### 4.1 On the device (files already on the device)

If you have the three files in a directory on the reTerminal DM (e.g. copied from USB or repo):

```bash
cd /path/to/dir   # directory containing screen-brightness.py, .service, .conf
sudo ./deploy-screen-brightness-to-device.sh
```

The script will install the files, create the tmpfiles.d rule, and start/enable the service. It will **not** overwrite an existing `/etc/screen-brightness.conf` (so vessel-specific tuning is preserved).

### 4.2 On the device (download from URL)

If your file server serves the three files (e.g. from the provisioning portal), pass the base URL as the **first argument** (recommended — works even when `sudo` does not preserve environment variables):

```bash
sudo ./deploy-screen-brightness-to-device.sh "http://file.server:5000/files"
```

Alternatively, if your `sudo` preserves the environment:

```bash
sudo -E BOOTSTRAP_URL="http://file.server:5000/files" ./deploy-screen-brightness-to-device.sh
```

The script will download `screen-brightness.py`, `screen-brightness.service`, and `screen-brightness.conf` from that base URL and show progress per file.

### 4.3 From a host (deploy via SSH)

From your laptop or build host, with the repo checked out and SSH access to the device:

```bash
cd /path/to/repo/emmc-provisioning/scripts
./deploy-screen-brightness-to-device.sh root@192.168.1.100
```

The script will copy the files from `../cloud-init/fileserver/` and run the install steps over SSH.

### 4.4 From a host via a jump server (bastion)

If the reTerminal DM is only reachable through a jump host, set `SSH_JUMP_HOST` and pass the device as the first argument:

```bash
cd /path/to/repo/emmc-provisioning/scripts
SSH_JUMP_HOST="user@jump.example.com" ./deploy-screen-brightness-to-device.sh pi@10.0.0.5
```

The script uses OpenSSH’s `-J` / `ProxyJump` so `ssh` and `scp` go through the jump host to the device.

**Alternative:** put the jump in your SSH config so no env var is needed:

```
# ~/.ssh/config
Host reterminal-guard
  HostName 10.0.0.5
  User pi
  ProxyJump user@jump.example.com
```

Then run:

```bash
./deploy-screen-brightness-to-device.sh reterminal-guard
```

---

## 5. Configuration

- **Config file:** `/etc/screen-brightness.conf` (INI format, optional).  
  If the file is missing, the daemon uses built-in defaults.
- **Reload config without restart:**  
  `sudo systemctl reload screen-brightness`
- **Override (navigator preset):**  
  - Force a fixed level (1–5):  
    `echo 3 | sudo tee /run/screen-brightness/override`  
  - Return to automatic (ambient + buzzer):  
    `echo auto | sudo tee /run/screen-brightness/override`

See comments in `screen-brightness.conf` for lux thresholds and level mapping (NIGHT / DUSK / DAY).

### 5.1 Crew brightness overlay (manual control)

To satisfy the requirement that the navigator can manually control brightness (MSC.191(79) §8.1.2), you can use the **brightness overlay**: a small panel that sits on top of the kiosk (Wayland layer-shell or X11) with buttons **1** **2** **3** **4** **5** and **Auto**.

- **brightness-api.service** — HTTP API on `127.0.0.1:8765`. Accepts `POST /brightness` with `level=1|2|3|4|5|auto`. Runs as root and writes `/run/screen-brightness/override`.
- **brightness-overlay.py** — Gtk3 overlay (same pattern as five-tap-close-chromium). Starts from session autostart; calls the API when a button is tapped.

If step 14 installed them, the overlay appears at the **bottom-right** after login. To install manually on an existing device:

```bash
# API (run as root)
sudo install -m 755 brightness-api.py /usr/local/bin/
sudo install -m 644 brightness-api.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now brightness-api.service

# Overlay (run as pi, autostart)
install -m 755 brightness-overlay.py ~/brightness-overlay.py
# Then add brightness-overlay.desktop to ~/.config/autostart/ (Exec path = your $HOME/brightness-overlay.py)
```

Dependencies: Python 3, PyGObject (Gtk3). On Wayland, `gir1.2-gtklayershell-0.1` for the overlay layer.

---

## 6. State and dashboard integration

The daemon writes a state file for other services (e.g. your alarm dashboard):

```bash
cat /run/screen-brightness/state
```

Example:

```
mode=ALERT
level=5
lux=12
buzzer=1
override=0
updated=1741266000
```

Your dashboard can read this to show current brightness mode or to drive a “night mode” indicator.

---

## 7. Testing buzzer and brightness

To confirm that the screen goes to full brightness when the buzzer is active and stays up during cooldown, run a short beep test on the device:

```bash
# From the device (if you have the script in place)
sudo ./test-buzzer-brightness.sh
```

If the script is not on the device, fetch and run it from your file server (replace with your portal URL):

```bash
curl -fsSL "http://10.130.60.141:5000/files/first-boot/test-buzzer-brightness.sh" -o /tmp/test-buzzer-brightness.sh
chmod +x /tmp/test-buzzer-brightness.sh
sudo /tmp/test-buzzer-brightness.sh
```

The script beeps four times. While it runs, the screen should go to maximum brightness (ALERT) and stay high for about 10 seconds after the last beep (COOLDOWN), then return to ambient level.

---

## 8. Troubleshooting

| Symptom | Check |
|--------|--------|
| Service fails to start | `journalctl -u screen-brightness.service -n 50`; confirm sysfs paths exist (step 2). |
| Brightness never changes | Verify light sensor: `cat /sys/bus/iio/devices/iio:device0/in_illuminance_input` (value should change when you shade the sensor). |
| Buzzer does not raise brightness | 1) Ensure service is running: `systemctl status screen-brightness.service`. 2) Use `test-buzzer-brightness.sh` (it uses the buzzer’s `max_brightness`, often 255). 3) Confirm buzzer sysfs updates while ON: `cat /sys/class/leds/usr-buzzer/brightness` (non-zero means ON), then `cat /run/screen-brightness/state` (mode=ALERT / COOLDOWN). |
| No logs from brightness service | Check that the unit is active: `systemctl is-active screen-brightness.service`. Then `journalctl -u screen-brightness.service -f` (follow). If the service exits, check `journalctl -u screen-brightness.service -n 50` for Python or path errors. |
| Brightness overlay not visible | 1) **Start it now:** from a terminal on the device (VNC or local), run: `python3 /home/pi/brightness-overlay.py` (or `~/brightness-overlay.py`). The panel should appear bottom-right; any errors will show in the terminal. 2) **After deploy:** autostart runs at login — log out and log back in so the overlay starts (it uses a 6 s delay). 3) **API required:** ensure `systemctl status brightness-api.service` is active; the overlay calls 127.0.0.1:8765. 4) **Dependencies:** need PyGObject (Gtk3); on Wayland, `gir1.2-gtklayershell-0.1` for the layer. |
| Config change not applied | Run `sudo systemctl reload screen-brightness` (or restart the service). |

---

## 9. File locations (reference)

| Item | Path |
|------|------|
| Daemon script | `/usr/local/bin/screen-brightness.py` |
| Systemd unit | `/etc/systemd/system/screen-brightness.service` |
| Config | `/etc/screen-brightness.conf` |
| Override (navigator) | `/run/screen-brightness/override` |
| State (read-only) | `/run/screen-brightness/state` |
| tmpfiles.d | `/etc/tmpfiles.d/screen-brightness.conf` |
| Brightness API (crew control) | `/usr/local/bin/brightness-api.py` |
| Brightness API unit | `/etc/systemd/system/brightness-api.service` |
| Overlay script | `$HOME/brightness-overlay.py` |
| Overlay autostart | `$HOME/.config/autostart/brightness-overlay.desktop` |
