Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# Auto detect text files and perform LF normalization
* text=auto

# Generated BOM rows retain a final tab for an empty Designators TSV field.
docs/wiring/out/*.bom.tsv -whitespace
42 changes: 42 additions & 0 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Validate

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
local-contracts:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Check out repository
uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6

- name: Set up Python
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
with:
python-version: "3.12"

- name: Run repository contracts
run: python3 -m unittest discover -s tests -v

- name: Run wiring contracts
run: python3 -m unittest discover -s docs/wiring -p 'test_*.py' -v

- name: Compile Python sources
run: python3 -m compileall -q src scripts tests docs/wiring

- name: Verify default service rendering
run: |
python3 scripts/render_kiosk_service.py > /tmp/matrix-led.service
cmp kiosk/matrix-led.service /tmp/matrix-led.service

- name: Check shell syntax
run: |
bash -n kiosk/matrix-led-start.sh
bash -n scripts/bootstrap.sh
59 changes: 59 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Conway Pointcloud Garden agent guide

This repository is the Artwork Score and conservation package for a live media
art installation. Start by reading `PROJECT.md`, then `CONTEXT.md`. Read
relevant decisions in `docs/adr/` before changing hardware identity,
installation behavior, or preservation boundaries.

## Boundaries

- Preserve artwork media, generated wiring artifacts, firmware packages, and
prior installation evidence. Reclassify uncertain material; do not delete it.
- Do not infer current hardware from filenames, repository recency, or an
unreachable machine.
- Do not run live tests, switch the relay, restart services, deploy files, or
alter Point2 unless the task explicitly requires live hardware work.
- Keep credentials and private network material out of committed fixtures.
- Treat `screen_config/` as Historical Receiver Firmware, not an installation
source.
- Tests must use local fixtures by default. Point2 checks are opt-in and must
distinguish host unavailability from assertion failures.

## Commands

```bash
python3 -m unittest discover -s tests -v
python3 -m unittest discover -s docs/wiring -p 'test_*.py' -v
python3 -m compileall -q src tests docs/wiring
```

Run live Point2 contracts only when the machine is intentionally in scope and
reachable:

```bash
CONWAY_RUN_LIVE_TESTS=1 CONWAY_TEST_TARGET=reid@point2 \
python3 -m unittest tests.test_point2_installation -v
```

Before editing a function, class, or method, use the repository's GitNexus
index to inspect upstream impact. Run GitNexus change detection before every
commit that changes source symbols.

## Agent skills

### Issue tracker

Issues and PRDs live in GitHub Issues for
`ReidSurmeier/conway-garden-controller`. See
`docs/agents/issue-tracker.md`.

### Triage labels

Use the standard `needs-triage`, `needs-info`, `ready-for-agent`,
`ready-for-human`, and `wontfix` labels. See
`docs/agents/triage-labels.md`.

### Domain docs

This is a single-context repository with terms in `CONTEXT.md` and decisions
in `docs/adr/`. See `docs/agents/domain.md`.
22 changes: 17 additions & 5 deletions CONSERVATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ Verified on 2026-05-15:
profile.
- Adafruit AHT20 enclosure temperature/humidity sensor was detected on I2C bus
1 at address `0x38` and added to the health snapshot when present.
- The current wiring packet includes three Easycargo 30 mm enclosure fans.
They are powered from protected 5 V fan branches and controlled from the Pi
GPIO fan-control path using the AHT20 enclosure reading.

## 3. Normal Operation

Expand Down Expand Up @@ -92,12 +95,15 @@ The full BoM is in `HARDWARE_BOM.md`. Core components:
| MicroSD card | System disk | Replaceable from gold image |
| Geekworm X1201 | UPS and power-loss signal | Replaceable only if new UPS exposes equivalent GPIO behavior |
| Samsung 30Q cells | UPS batteries | Replaceable with compatible protected/approved cells per X1201 requirements |
| MEAN WELL LRS-150F | Display PSU | Replaceable with equivalent 5 V supply with sufficient current and physical fit |
| LCLCTC DIN rail SSR | Switches display PSU/load path | Replaceable with equivalent rated relay/SSR |
| MEAN WELL LRS-50-5 | Controller PSU | Replaceable with equivalent always-on 5 V supply with sufficient current and physical fit |
| MEAN WELL LRS-150F-5 | LED-panel PSU | Replaceable with equivalent 5 V supply with sufficient current and physical fit |
| LCLCTC DIN rail SSR | Switches LED-panel PSU line input | Replaceable with equivalent rated relay/SSR |
| APIELE push buttons | START/STOP inputs | Replaceable with normally-open momentary switches |
| Adafruit AHT20 | Enclosure temperature/humidity sensor | Replaceable with compatible I2C enclosure sensor if software and wiring are updated |
| Three Easycargo 30 mm fans | Enclosure cooling | Replace with equivalent 5 V fans after checking current draw, airflow, and control wiring |
| NovaStar MSD300-1 | Sender card | Replaceable with compatible sender; requires remapping/reverification |
| NovaStar MRV412 | Receiver card | Replaceable with compatible receiver; requires config backup/reload |
| LED panels | Display surface | Replace modules/panels only after isolating cable/power/mapping faults |
| NovaStar NV3210 | Receiver card | Replaceable with compatible receiver; requires config backup/reload |
| Six LED matrix panels | Display surface | Replace modules/panels only after isolating cable/power/mapping faults |

## 6. Wiring

Expand All @@ -113,14 +119,16 @@ GPIO numbers are BCM numbers.
| AHT20 GND | - | 6 | Ground |
| AHT20 SDA | 2 | 3 | I2C data, address `0x38` |
| AHT20 SCL | 3 | 5 | I2C clock |
| Fan enable/control | See wiring packet | See wiring packet | Pi GPIO fan-control harness; fan motor power comes from fused 5 V |

The controller config is `/etc/matrix-controller/controller.yaml`; the repo
snapshot is `config/controller.yaml`.

## 7. Enclosure Temperature Sensor

An Adafruit AHT20 is wired to the Pi I2C bus and is used for enclosure
temperature/humidity monitoring.
temperature/humidity monitoring. The enclosure temperature reading is the
software input for turning the three enclosure fans on and off.

| Signal | Pi header pin | Notes |
|---|---:|---|
Expand All @@ -137,6 +145,8 @@ Runtime requirements:
`enclosure_humidity=<value>%RH` when the sensor is present.
- The sensor is optional for boot: if it is unplugged, the health check should
continue without failing the whole artwork.
- The fan wiring remains protected 5 V for motor power; the Pi GPIO path is
only the control path.

Short active-display test on 2026-05-15:

Expand Down Expand Up @@ -245,10 +255,12 @@ changing the web app.
| Each install | Verify START and STOP buttons |
| Each install | Verify `sudo pinctrl get 6` is HIGH on wall power |
| Each install | Confirm the AHT20 health log includes enclosure temp/humidity |
| Each install | Confirm all three enclosure fans turn on from the temperature-control path |
| Each install | Unplug wall power once and confirm safe shutdown if commissioning |
| Monthly | Inspect cables, ribbons, fuses, relay terminals, and panel seating |
| Monthly | Read `journalctl -t conway-health --since "30 days ago"` |
| Monthly | Review enclosure temperature trend from `conway-health` |
| Monthly | Check that all three enclosure fans spin freely and are clear of dust |
| Monthly | Confirm `systemctl --failed` returns zero units |
| Monthly | Confirm `/etc/apt/apt.conf.d/20auto-upgrades` still disables apt periodic work |
| On change | Commit code/config, update docs, and make a gold image |
Expand Down
17 changes: 17 additions & 0 deletions CONTEXT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Conway Pointcloud Garden domain

## Glossary

| Term | Meaning |
| --- | --- |
| Artwork Score | The versioned software, media, operating instructions, wiring knowledge, and preservation evidence needed to perform Conway Pointcloud Garden. |
| Original Installation | The Raspberry Pi installation verified as `conway-garden-1` in May 2026. It is historical evidence, not the current machine identity. |
| Point2 Replacement Installation | The Raspberry Pi 5 replacement installed and verified through Tailscale as `Point2` on 2026-07-21. |
| Controller PSU | The always-on MEAN WELL LRS-50-5 5 V supply for the controller side of the artwork. |
| LED-panel PSU | The relay-switched MEAN WELL LRS-150F-5 5 V supply for the six LED matrix panels. |
| START button | The dedicated front-panel input that starts display behavior. |
| STOP button | The dedicated front-panel input that stops display behavior without cutting controller power. |
| Display power relay | The controller-owned switch for the LED-panel PSU path. |
| Display chain | Raspberry Pi micro HDMI to DVI, NovaStar MSD300-1 sender, Ethernet cable, NovaStar NV3210 receiver, ribbon cables, and six LED matrix panels. |
| Historical Receiver Firmware | Preserved MRV412 configuration and firmware material whose presence records prior service research but does not identify the installed receiver. |
| Live Installation Evidence | Time-stamped observations, checksums, service state, and display tests captured from a reachable installation. |
12 changes: 9 additions & 3 deletions DISPLAY_MAPPING.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Display Mapping

**Current verified state:** 2026-05-15
**Display chain:** Raspberry Pi 5 -> HDMI -> NovaStar MSD300-1 sender ->
NovaStar MRV412 receiver -> LED panels
**Current verified app-side state:** 2026-05-15

**Current hardware correction:** 2026-07-08
**Display chain:** Raspberry Pi 5 -> micro HDMI/DVI -> NovaStar MSD300-1
sender -> NovaStar NV3210 receiver -> six LED matrix panels

The app-side mapping evidence below is from the 2026-05-15 live verification.
The receiver-card name and panel count were corrected in the 2026-07-08 wiring
packet.

## Current Working App Mapping

Expand Down
28 changes: 18 additions & 10 deletions HARDWARE_BOM.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Hardware BoM

**Current source status:** verified against the 2026-05-15 live system and the
V4 supply spreadsheet. Spreadsheet notes are historical where they conflict
with verified Pi behavior.
**Current source status:** verified against the 2026-05-15 live system, the V4
supply spreadsheet, and the 2026-07-08 wiring correction for the NV3210
receiver, two 5 V PSUs, six LED matrix panels, AHT20 enclosure sensor, and
three enclosure fans. Spreadsheet notes are historical where they conflict
with verified Pi behavior or the updated wiring packet.

Spreadsheet source:
https://docs.google.com/spreadsheets/d/1t827FBauN-OOxP_h4DBD_ax0KM9MAw7U8CcPHHLapTA/edit?usp=sharing
Expand All @@ -18,25 +20,28 @@ https://docs.google.com/spreadsheets/d/1t827FBauN-OOxP_h4DBD_ax0KM9MAw7U8CcPHHLa
| GPIO screw terminal block breakout | 1 | Stable wiring to Pi header | Replaceable with equivalent Pi 5 header breakout. |
| APIELE momentary push button | 2 in final system | START and STOP inputs | Any normally-open momentary switch can replace. |
| LCLCTC DIN rail solid-state relay | 1 | Switches display power/load path | Replace with equivalent SSR/relay rated for the load. Update `relay.active_high` if needed. |
| MEAN WELL LRS-150F | 1 | Display/LED power supply | Replace with equivalent 5 V supply with adequate current and physical fit. |
| Blue Sea Systems 5025 ST blade fuse block | 1 | Fused distribution | Replaceable with equivalent fuse block. |
| MEAN WELL LRS-50-5 | 1 | Always-on 5 V controller power supply | Feeds the fuse block for X1201/Pi, MSD300-1, NV3210, and the three fans. Replace with equivalent 5 V supply with adequate current and physical fit. |
| MEAN WELL LRS-150F-5 | 1 | Relay-switched 5 V LED-panel power supply | Feeds the six LED matrix panels. Replace with equivalent 5 V supply with adequate current and physical fit. |
| Blue Sea Systems 5025 ST blade fuse block | 1 | Fused distribution for controller/display electronics | Protects X1201/Pi, MSD300-1, NV3210, and the three fans. It does not feed the LED panels. |
| ATC-3 ATC blade fuse | As needed | Branch fuse | Replace with the same rating unless wiring/load is redesigned. |
| UL489 circuit breaker | 1 | Input/load protection | Replace with same rating/type unless power design is reviewed. |
| Ground terminal block | 1 | Case-bonded protective earth distribution | Incoming ground connects here, then bonds ground to both power supplies. |
| Adafruit AHT20 | 1 | Enclosure temperature/humidity sensor on Pi I2C | Feeds enclosure-temperature data to the software path that controls the fans and logs health. |
| Easycargo 30 mm fan | 3 | Enclosure cooling fans | Motor power comes from protected 5 V fan branches; on/off control is documented through the Pi GPIO fan-control harness. |
| 22 AWG stranded wire | As needed | Low-voltage wiring | Match current capacity, insulation, and routing. |
| Lever nuts / terminal blocks | As needed | Serviceable splices and distribution | Replace with equivalent rated connectors. |
| XHF adhesive cable tie mounts | As needed | Strain relief/cable management | Replaceable. |
| Crimping tool kit | 1 | Build/service tool | Not part of artwork runtime. |
| Noctua NF-A4x10 | 2 | Quiet cooling option | Replace with equivalent 40 mm fan if cooling is needed. Verify airflow and noise. |

## Display Chain

| Component | Qty | Function | Replaceability / notes |
|---|---:|---|---|
| NovaStar MSD300-1 sender card | 1 | Receives HDMI/DVI source and sends data to LED receiver chain | Replaceable with compatible NovaStar sender, but mapping must be reverified. Export config if possible. |
| NovaStar MRV412 receiver card | 1+ | Drives LED modules/panels | Replaceable with compatible receiver card only with saved config or remapping. |
| LED panels/modules | As installed | Display surface | Replace panel/module after isolating ribbon cable, power, receiver output, and sender mapping. |
| Ribbon/data cables | As installed | Panel data path | Keep spares. Many color/stripe faults are cable/connector issues. |
| Panel power leads | As installed | Panel power path | Keep spares. Check voltage drop and terminal tightness. |
| NovaStar NV3210 receiver card | 1 | Receives Ethernet data from the MSD300-1 and drives the LED matrix panel ribbon outputs | Replaceable with compatible receiver card only with saved config or remapping. |
| LED matrix panels | 6 | Display surface | Replace panel/module after isolating ribbon cable, power, receiver output, and sender mapping. |
| Ribbon/data cables | 6 | NV3210-to-panel data path | Keep spares. Many color/stripe faults are cable/connector issues. |
| Panel power leads | 6 | LED PSU to panel 5 V power path | Keep spares. Check voltage drop and terminal tightness. |

## Verified GPIO/Wiring

Expand All @@ -46,6 +51,9 @@ https://docs.google.com/spreadsheets/d/1t827FBauN-OOxP_h4DBD_ax0KM9MAw7U8CcPHHLa
| STOP button | 19 | 35 | Press pulls LOW to GND |
| Relay/SSR control | 20 | 38 | Active high |
| X1201 PLD | 6 | 31 | HIGH = wall power OK, LOW = wall power lost |
| AHT20 SDA | 2 | 3 | I2C data, address `0x38` |
| AHT20 SCL | 3 | 5 | I2C clock |
| Fan enable/control | See wiring packet | See wiring packet | Pi GPIO fan-control harness commands the three fans; motor power comes from fused 5 V. |

## Superseded Spreadsheet Notes

Expand Down
86 changes: 86 additions & 0 deletions PROJECT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Conway Pointcloud Garden status

## Goal

Keep Conway Pointcloud Garden performable as a media artwork by preserving its
Artwork Score, hardware relationships, installation evidence, and recovery
path without confusing historical artifacts with the current installation.

## Current objective

Reconcile the public GitHub repository, the preserved dirty home checkout, the
Point2 Replacement Installation, and the current documentation standard in a
clean Orca worktree. Preserve the resolved NV3210 Display Chain, retain MRV412
firmware as history, and make local validation independent of live hardware.

## Confirmed working

- GitHub `main` is available at commit `173934c` with the complete prior
Artwork Score and the later MRV412 firmware package.
- The Original Installation was audited as `conway-garden-1` in May 2026.
- On 2026-07-21, the Point2 Replacement Installation passed five live
integration checks: Conway document and canvas, the 312 by 416 mapping
rotated into a 416 by 312 region, nontrivial framebuffer output, durable
service/runtime identity, and controller safe-idle/GPIO ownership.
- The Point2 keyring interruption was reproduced and repaired by launching
kiosk Chromium with `--password-store=basic`.
- The kiosk launcher now selects either `chromium-browser` or `chromium`, and
the bootstrap can render explicit Original or Point2 account profiles while
preserving the Original Installation defaults.
- The preserved home checkout contains the July wiring packet, its generated
artifacts, domain and agent documentation, and the Point2 integration tests.
- GitHub has no Pages site or deployment record for this repository.
- A fresh 2026-07-31 Droplet snapshot contains no Conway, Point2, or Matrix
Controller runtime.

## Failed approaches

- The original Bookworm installation procedure assumed the `pi` user and
could not be applied unchanged to Point2's Debian 13 `reid` environment.
- A healthy systemd service and HTTP listener did not prove that Chromium had
reached the artwork; a first-run keyring dialog left the browser blank.
- Treating the newest repository artifact as the current receiver identity
would contradict the user's resolved NV3210 hardware correction.
- Live integration tests cannot distinguish a product failure from an offline
Point2 host when they run unconditionally.

## Decisions

- The Display Chain uses the NV3210 identity. See
`docs/adr/0001-preserve-receiver-firmware-as-history.md`.
- `screen_config/` is Historical Receiver Firmware and is not an installation
input.
- The clean Canonical Checkout is `/home/reidsurmeier/src/conway-garden-controller`.
The dirty home checkout remains untouched until its intended changes are
reviewed and merged through the clean worktree.
- Point2 is an external hardware deployment, not a Droplet or GitHub Pages
deployment.
- Local validation must be hermetic. Tests that inspect Point2 are explicit
live checks and must report offline state separately from source failures.
- Do not change relay, service, or deployed files while Point2 is offline.

## Blockers

- Point2 is offline on 2026-07-31 and was last seen by Tailscale on
2026-07-22. Current services, framebuffer, relay, power, and physical display
state are unverified.
- The July home-checkout package must be reviewed and transferred without
losing the later GitHub `screen_config/` commit.
- The new Point2 installation profile has only local rendering evidence; it
has not been applied to or live-verified on the offline host.
- A gold SD-card image and tested backup/restore record are not verified.
- Physical receiver labeling, NovaStar export custody, electrical inspection,
and publication rights for artwork media require human evidence.

## Next action

Validate the complete repository locally, review firmware and media custody,
and record all hardware-only follow-ups as GitHub issues. When Point2 returns
online, rerun the five live contracts before changing its deployment.

## Last verified

2026-07-31 from the authenticated GitHub API, a clean `origin/main` clone,
the preserved dirty home checkout, recovered July 8 and July 21 session
evidence, the current Tailscale peer record, and a fresh Droplet snapshot.
Point2 was offline, so no current runtime or physical-state claim is made.
Loading