Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8ab82d6
Add independent read-only room browser status
diyanko Oct 14, 2026
e9972b9
Simplify browser overview and clarify reading sources
diyanko Oct 14, 2026
5b67f9e
Separate visitor overview, diagnostics and room guide
diyanko Oct 14, 2026
a036c4d
Start the read-only website at boot on the room subnet
diyanko Oct 14, 2026
bdf3c34
Align the read-only website with everyday panel controls
diyanko Oct 15, 2026
8f872ff
Polish Beta branding and simplify weather details
diyanko Oct 15, 2026
f4f5d3a
Show compact daily weather beside a larger room header
diyanko Oct 16, 2026
bbf6bf8
Match browser icons and weather to panel styling
diyanko Oct 16, 2026
d35943c
Add shared room controls and copyable help references
diyanko Oct 16, 2026
baf0856
Highlight help commands without changing copied text
diyanko Oct 16, 2026
07c5b86
Keep website fonts and disabled controls consistent with the panel
diyanko Oct 16, 2026
67aabe9
Match diagnostics branding to the shared room header
diyanko Oct 16, 2026
e3ef53c
Deliver rejected requests before closing the connection
diyanko Oct 16, 2026
221914d
Match the shared Lighting workspace and blind settings
diyanko Oct 16, 2026
87f7365
Preserve semantic status accents in dark mode
diyanko Oct 16, 2026
1c3efd8
Document and copy individual help commands with shared styling
diyanko Oct 16, 2026
1b02291
Keep navigation compact beside long help references
diyanko Oct 16, 2026
8391c82
Polish responsive lighting controls and blind lock clarity
diyanko Oct 16, 2026
745d8c3
Align weather readings and refresh shared night artwork
diyanko Oct 16, 2026
5c85749
Clear old weather attribution when readings disappear
diyanko Oct 16, 2026
b043097
Use one screen saver preview in display controls
diyanko Oct 16, 2026
741d58b
Confirm panel restart and shutdown from shared web controls
diyanko Oct 16, 2026
af68490
Show the shared numeric version throughout the interface
diyanko Oct 16, 2026
2c0a66f
Keep Beta status in headers and version details in About
diyanko Oct 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 61 additions & 80 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,80 +1,61 @@
# SCR room touch panel

Touch controls for the LESA Smart Conference Room. The original application and
the newer Beta client have separate entrypoints and share the existing room
services. Beta does not yet cover every original feature.

## Choose the version

| Version | Source and setup |
|---|---|
| Original application | [main.py](main.py); requires the installed custom ROS clients and room environment |
| Earlier Beta baseline | [app/scr_touch_panel.py](app/scr_touch_panel.py) on `main`; installed launcher expects Ubuntu/Python 2.7 |
| Fresh Pi OS and current Beta | [Branch README](https://github.com/LESA-RPI/scr.touch_panel/blob/experiment/fresh-pi-setup-20261013/README.md); Python 3 setup and newer interface under review in [PR #1](https://github.com/LESA-RPI/scr.touch_panel/pull/1) |

The newer interface calls the original application **Legacy**. This baseline
uses **Original**. Check the cabinet's installed release before maintenance;
the default branch does not identify what is running on a device.

## Try the baseline without room hardware

Use desktop Python 3.11 or newer with Tk available. `python -m tkinter` checks
Tk. On Linux, install distribution Tk and virtual-environment packages if needed.

```sh
git clone https://github.com/LESA-RPI/scr.touch_panel.git
cd scr.touch_panel
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -r app/requirements.txt
python -B app/scr_touch_panel.py --windowed --duration 600 --theme light
```

On Windows, use `python` in place of `python3` and activate with
`.venv\Scripts\Activate.ps1`. This preview moves no room devices and starts no
recording. Desktop requirements are separate from the installed Ubuntu stack.
For fresh Raspberry Pi OS, use the branch guide above rather than this launcher.

## Operate the baseline

In this version, Settings returns to Original controls and its touch strip
returns to Beta. Credits are in Settings. Lighting sliders send automatically;
confirmation means controller readback, not measured physical brightness.
Opening Original or exiting waits for restoration of Beta's starting light scene.
If the result is uncertain, stop changing lights and coordinate with the room host.

Practice annotations have `recording: false`; they do not start a sensor recorder.
System reports panel readings and advertised services, not physical sensor health.
A stationary two-second press leaves the black screen; its backlight stays on.
The updated branch has different navigation and additional features.

## Install, maintain or restore

| Need | Reference |
|---|---|
| Connect lighting and establish ownership | [Connection checks](WORKFLOWS.md#before-connected-control) |
| Switch modes or recover an uncertain result | [Switching and recovery](WORKFLOWS.md#switching-and-recovery) |
| Set up autostart or roll back | [Startup and rollback](WORKFLOWS.md#startup-and-rollback) |
| Restore hardware or provision a replacement | [Backup and rebuild](WORKFLOWS.md#backup-and-rebuild) |
| Add a profile or experiment adapter | [Interface contracts](docs/interface.md) |

The installed launcher expects the older Python 2.7/Tk/Pillow environment and
custom ROS workspace. Desktop Python 3 preview support does not migrate that
launcher. Existing room servers remain separate dependencies; upgrading the
panel does not require replacing them. Coordinate ownership before live control.

Git preserves source, not a complete system. Obtain private configuration and
recovery bundles from the room custodian. Check manifests, scope and read-error
records: an incomplete image is not an exact clone. Keep captures, credentials,
participant data and host settings outside this public repository.

Run `python -m pytest tests` with pytest installed. Baseline checks cover profiles,
lighting restoration and uncertain results. Earlier bounded cabinet trials do not
qualify another release, replacement hardware or prolonged reliability. Preserve
release hashes and original contributors when cleaning public documentation.

General panel code belongs here; Project-X owns its optional recorder integration.
Browser/tablet clients are planned, not implemented.

Beta: **Diyanko Bhowmik**, with Codex assistance. Original contributors remain in
Git history. The supplied LESA logo is retained unchanged.
# SCR room browser interface

A browser companion to the touch panel, with the same Home controls, one Lighting
workspace (White light, Scenes, Programmes and Channels), instruction workflow,
preferences, guide and help. The panel owns
all commands. Diagnostics remain observation-only. Legacy opens the original
application on the cabinet; its original actuator controls stay there.

Browser control is opt-in: pass `--panel-control-socket` to `browser/serve.py`, or
set `SCR_WEB_CONTROL_SOCKET` for `browser/start.sh`, pointing to the panel’s
private socket. Enable its matching `--control-socket` / `SCR_CONTROL_SOCKET`.
Both run as the same user. Keep the explicit bind address and client-subnet
allowlist. Everyone on that configured subnet can use controls; there is no
separate staff login. Without a bridge, controls disable and guide/help remain
available. No browser hardware driver is imported.

Commands use the existing panel queue, require a fresh revision and are never
automatically retried. Confirmed readback alone selects Lights on/off. Pending,
uncertain or disconnected states clear that selection. Running instructions block
lighting from both interfaces. All three original blind actions are visible;
movement has a saved Locked/Unlocked setting, locked by default, and requires a connected
controller. None is installed in the new interface. Gradient, Sun and Circ remain visible with
disconnected Apply/Start controls until their adapters are integrated. Empty Legacy
placeholders and the redundant Enable Sliders gate are omitted. Experiment mode does not
start a recorder. Service-start/restart references are monospace text with Copy,
never executable buttons. Each documented step explains the computer, purpose
and expected result, with its own Copy button and a Copy all option for the topic.
Dark backgrounds stay neutral gray; controls, weather and status use restrained
teal, warm and green/amber accents shared with the panel.
Weather readings use aligned labels and values, with dashes for missing readings.
Earlier forecasts are dated and hide current-day details until fresh data returns.
Screen & controls can preview the touch panel's screen saver. The idle timer and
preview open the same screen; its first touch returns to Home without activating
a control. Date & weather contains clock-format and temperature preferences.
System & help can restart or shut down the touch panel when its power controls
are available. Each request requires a confirmation and an acknowledgement that
recordings and experiments have stopped. The panel validates ownership, restores
lighting and saves its state before the operating-system action. These controls
do not stop other room computers or recorders. A restart or shutdown disconnects
this website; unknown requests are never retried automatically.
Desktop layouts place white-light controls side by side. Landscape tablets keep
large controls; phones put lights first with expandable blinds and a compact
Room tools section selector. Numeric light
values can be typed or adjusted with sliders. Enter or leaving a valid field
applies the selection; Escape cancels. Empty or out-of-range values never dispatch.
Polling preserves an edit, and the panel still validates its original revision.
The website bundles the same Cantarell family used by the panel, so its layout
does not depend on a visitor's installed fonts. Unmodified font files retain
their [SIL Open Font License](browser/fonts/LICENSE).

Run `python -m pytest tests`. HTTP tests use loopback mock services and cover Host,
Origin, nonce, subnet, bounded command bodies, static allowlists and read-only
diagnostics. Browser interaction and native Pi qualification are separate checks.
Do not merge the draft experiment branch without researcher approval.

Panel-owned guide/help, design roles and Lucide paths are exported by
`app/export_room_content.py` in the panel branch to `browser/room-content.json`.
Live controller state supplies the same content and preferences. Preserve source
provenance when rebuilding browser assets. The artwork notices remain in
[browser/icons/LICENSE](browser/icons/LICENSE). Original contributors are retained
in repository history. The interface is maintained by Diyanko Bhowmik.
115 changes: 115 additions & 0 deletions WORKFLOWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,121 @@ Theme times use the panel process's configured timezone. Auto changes wait for
appearance, date/time, schedule and screen rows. Font and study defaults are launch
configuration; no separate settings service is needed.

## Read-only browser status

The browser status server is independent of Tk, ROS client bindings and Project-X.
It uses Python 3.11's standard library and the existing LESA logo. It imports no
control adapter and exposes no actuator, recorder or maintenance command route.

```sh
# Local-only review; no room queries.
python -B browser/serve.py

# Room host: substitute verified private interface/master addresses.
python -B browser/serve.py --bind PANEL_PRIVATE_IP --allow-clients ROOM_SUBNET_CIDR --port 8768 \
--label "Cabinet Pi" --master http://ROOM_PRIVATE_IP:11311 \
--weather-latitude 42.7284 --weather-longitude -73.6918
```

The server binds one explicit private IPv4 address and accepts socket peers only
from the explicit trusted client subnet. Non-loopback hosting requires that subnet;
forwarding headers do not grant access. Open the
printed literal-IP URL; Host/Origin checks intentionally refuse other hostnames.
No router forwarding, firewall changes or public hosting are part of this setup.
There is no sign-in: allowed subnet clients can view the limited status payload.
The touch-panel Pi hosts this trial, accessible from the room's SCR_AP LAN. Keep
it on that trusted network. A subnet cannot identify a Wi-Fi SSID: other devices
on the same wired LAN also have access. Router guest isolation remains the network
owner's responsibility. This does not secure existing ROS services.

One sampler refreshes host resources and the ROS master's `getSystemState` graph
every 30 seconds, independent of visitor count. It registers no node, starts no
producer and calls no device services. Omit `--master` for host-only operation.
The graph response is capped at 256 KiB; its subprocess ends after four seconds.
HTTP requests have a four-second absolute deadline and a two-second idle timeout.
Requests serve only an in-memory snapshot and explicitly listed static assets.
No directory listing, arbitrary file access, CORS or write endpoints are provided.

Overview has no technical status; `/diagnostics` shows host resources and room
registrations, and `/guide` explains use and failures. They share fixed navigation,
the same cached API and a white surface. There are no appearance switches or storage
cards. A diagnostic view is an audience choice, not a staff permission boundary.
Host readings describe the server computer, not every room computer. Diagnostics
names that source explicitly; a host-only preview is labelled as such.
The supplied main logo is unchanged; its blank margins are trimmed only by layout.
The clock
shows Troy's America/New_York time using the viewing device's clock. Service cards
show advertised/partly advertised/not advertised registrations, not physical health
or recording state. After failure, previous observations retain their original
age. Samples older than 90 seconds are labelled stale. Visible pages poll every
30 seconds; hidden tabs pause requests. Snapshot data includes no raw recordings,
participant information, service-provider names, paths or private master address.

### Independent website startup

Home matches the cabinet's everyday layout, with stacked lights/blinds labels
beside time and weather. All four website action buttons are disabled and have
no handlers. Advanced · diagnostics opens the existing read-only diagnostics;
Demo & guide opens the room guide. There are no new actuator endpoints or roles.

Retain each published release under `~/scr-browser-status/releases/COMMIT` and
point `~/scr-browser-status/current` to the selected release. This is separate from
`~/scr-panel/current`. Stop an earlier standalone website only after checking its
exact command; never kill the panel or room processes to free the website port.

Create `~/.config/scr-browser-status/deployment.env` with mode 0600 and verified
values. Keep deployment addresses outside this public repository:

```ini
SCR_WEB_BIND=PANEL_PRIVATE_IP
SCR_WEB_CLIENTS=ROOM_SUBNET_CIDR
SCR_WEB_PORT=8768
SCR_WEB_LABEL="Cabinet Pi"
SCR_WEB_MASTER=http://ROOM_PRIVATE_IP:11311
SCR_WEB_LATITUDE=42.7284
SCR_WEB_LONGITUDE=-73.6918
```

Install the included unit and enable this user to run services before login:

```sh
mkdir -p ~/.config/systemd/user
cp ~/scr-browser-status/current/browser/scr-browser-status.service ~/.config/systemd/user/
loginctl enable-linger "$USER"
systemctl --user daemon-reload
systemctl --user enable --now scr-browser-status.service
systemctl --user status scr-browser-status.service
```

Enabling linger may require administrator approval on another installation.
Confirm `loginctl show-user "$USER" -p Linger` reports `yes`. The existing panel
desktop autostart stays intact. The website retries after 15 seconds if its bind
address is not ready during boot; missing source data is reported as unavailable.
Initial weather/graph sampling can delay HTTP readiness by about 14 seconds.
If DHCP changes the Pi address, update the private environment and restart this
website service. Do not change room network settings for this application.

Use `systemctl --user restart scr-browser-status.service` for a website-only reload
and `journalctl --user -u scr-browser-status.service -n 30` for errors. Roll back with
`systemctl --user disable --now scr-browser-status.service`; an earlier release can
be selected by repointing only the website's `current` symlink. Disable linger only
if this installation enabled it and no other user services need it. No lighting
restoration is needed because the website owns no lights. Verify a service restart
first; qualify a physical boot later when someone is in the room.

Outdoor weather reuses `app/weather.py`, the panel's validated Open-Meteo helper.
The sampler refreshes at most once per 15 minutes, with an eight-second subprocess
deadline and 32 KiB response limit. Failures retain the last successful values
and their observation age; old or failed data is labelled and its daylight bar
hidden. Coordinates above describe Troy, not indoor room conditions. No generated
values are substituted when weather is unavailable. It is independent of room ROS.

Keep presentation dependent on `docs/interface.md`, not on ROS service paths. The
server's host, graph and weather functions are the current source boundary; the
browser uses the normalized versioned JSON and freshness fields. A future backend
can replace a source behind that boundary without rewriting each view. Add an
adapter only for a real new source; a plugin framework is not needed for this trial.

## Backup and rebuild

The Git repository preserves panel source. It does not preserve the installed
Expand Down
Loading