Baseline: docker stack, provisioning tools, test-data, gateway-as-files (pre-PrimeBAT build)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 11:56:30 -05:00
commit 310b1b3b9e
951 changed files with 17028 additions and 0 deletions

154
README.md Normal file
View File

@@ -0,0 +1,154 @@
# Build-a-Thon — Alarm Analysis Dashboard (Ignition 8.3.7 + Perspective)
Local development environment for the Inductive Automation Build-a-Thon. Native Ignition
features only — **no third-party modules** (contest rule).
## Quickstart
```bash
docker compose up -d
```
- Gateway: <http://localhost:8088> — login `admin` / `password`
- MariaDB: `localhost:3306` — db `ignition`, user `ignition` / `ignition` (root password: `password`)
First start takes a minute or two while the gateway commissions itself (EULA, edition, and
admin credentials are seeded by env vars, so there is no commissioning wizard). Watch with:
```bash
docker compose logs -f ignition
```
The gateway is ready when `curl http://localhost:8088/StatusPing` returns `{"state":"RUNNING"}`.
## Gateway state lives in this repo (gateway-as-files)
The gateway's durable state is bind-mounted from the repo (primebench/TestingPlatform
pattern) — a container recreate can never wipe it, and the gateway never re-commissions:
| Repo path | In container (`data/`) | What's in it |
| ------------------------------------------------ | ----------------------- | ----------------------------------------------- |
| `ignition/gateway/commission/commissioning.json` | `commissioning.json` | Commissioning marker (committed) |
| `ignition/gateway/config/` | `config/` | All config resources: DB connection, journal, API token, **tags**, secrets |
| `ignition/gateway/projects/` | `projects/` | Project files: Perspective views, scripts, timers |
Everything else (internal db, logs, certs) stays ephemeral in the container. The gateway
runs as your host uid/gid (`IGNITION_UID`/`IGNITION_GID`, default 1000), so files stay
owned by you.
**Edit-files workflow:** change files under `ignition/gateway/`, then tell the gateway to
reload — `python3 tools/provision.py scan-config` (config/tags) or `scan-projects`
(project resources). Changes made in the Designer/gateway UI land back in these files,
ready to diff.
## Automated provisioning (REST API)
Gateway config is provisioned through the Ignition 8.3 HTTP API using [tools/provision.py](tools/provision.py)
(stdlib only, no pip installs). On a fresh gateway:
```bash
python3 tools/provision.py mint-token # API token file-drops + gateway restart; updates .env
python3 tools/provision.py provision # secret provider + DB connection + alarm journal + sim tags
```
- `mint-token` writes an `api-token` config resource under `ignition/gateway/config/`,
patches the `Authenticated > API` security levels into gateway read/write permissions,
restarts the gateway (if running; otherwise the token loads on next boot), and saves
`IGN_API=Buildathon:<secret>` to `.env` (gitignored). Only the SHA-256 hash of the
secret is stored in the config files.
- `provision` is idempotent — it skips resources that already exist. It creates:
- file secret provider `local` (MariaDB password lives in the gitignored file
`ignition/gateway/config/secrets/mariadb_password`, referenced by the connection —
the 8.3 API only accepts encrypted or referenced secrets)
- database connection `Buildathon_DB``jdbc:mariadb://db:3306/ignition`
- alarm journal `Journal` → tables `PrimeControls_alarm_events` / `PrimeControls_alarm_event_data`
- imports `test-data/simulation_tags.json` into the `default` tag provider
Ad-hoc API calls use one header: `curl -H "X-Ignition-API-Token: $IGN_API" $GATEWAY_URL/openapi.json`
(source `.env` first).
Two steps remain manual (Designer-only): creating the `Buildathon` Perspective project
(step 3 below) and installing the simulator timer script ([test-data/README.md](test-data/README.md)).
## Manual setup reference (what provision.py does, plus the Designer steps)
### 1. Database connection (MariaDB) — automated
Gateway web UI → **Config → Databases → Connections → Create new Database Connection**
| Setting | Value |
| ----------- | -------------------------------- |
| Name | `Buildathon_DB` |
| Driver | MariaDB |
| Connect URL | `jdbc:mariadb://db:3306/ignition` |
| Username | `ignition` |
| Password | `ignition` |
Note the host is `db` (the compose service name), **not** `localhost` — the gateway reaches
MariaDB over the compose network. Save and confirm the status shows **Valid**.
Ignition 8.3 ships the MariaDB JDBC driver, so no driver install is needed.
### 2. Alarm journal profile — automated
Gateway web UI → **Config → Alarming → Journal → Create new Alarm Journal Profile**
| Setting | Value |
| ------------ | --------------------------- |
| Name | `Journal` (any name works) |
| Type | Database |
| Datasource | `Buildathon_DB` |
| Table prefix | `PrimeControls_` |
Leave the event filters at defaults (store everything) so the analytics have full data.
The journal auto-creates `PrimeControls_alarm_events` and `PrimeControls_alarm_event_data`
in MariaDB the first time an alarm event occurs.
### 3. Perspective project — manual
1. Gateway web UI → **Config → Projects → Create new Project** (or Designer → File → New Project)
- Name: `Buildathon`
2. Open it in the Designer (launch from <http://localhost:8088> → Designer launcher),
then set the project default database: **Project → Project Properties → General →
Default Database** → `Buildathon_DB`. Save the project.
Named queries and bindings that use the "default" database now hit MariaDB.
## Test data
See [test-data/README.md](test-data/README.md) — imports simulation memory tags with alarm
configs and a Jython script that generates realistic alarm activity (baseline alarms across
5 plant areas / 3 priorities, chattering, standing, fleeting, and flood-burst patterns).
## Reset to a completely fresh gateway
Gateway state is repo files now, so `docker compose down -v` alone no longer wipes the
gateway — it only removes the containers and the MariaDB volume. To verify the project
export imports cleanly on a fresh install (the contest judging scenario), set the gateway
files aside and rebuild:
```bash
docker compose down -v # containers + MariaDB volume
mv ignition/gateway ignition/gateway.bak # keep your current state for rollback
mkdir -p ignition/gateway/commission ignition/gateway/config ignition/gateway/projects
cp ignition/gateway.bak/commission/commissioning.json ignition/gateway/commission/
docker compose up -d # boots factory-fresh, auto-commissions
python3 tools/provision.py mint-token # old token lived in gateway.bak
python3 tools/provision.py provision
```
Then import your project export to prove it stands alone. Roll back to your working
state with `docker compose down && rm -rf ignition/gateway && mv ignition/gateway.bak
ignition/gateway && docker compose up -d` (MariaDB journal data is gone either way after
`-v` — the sim regenerates it).
A plain `docker compose down` / `up -d` restarts with everything intact.
## Notes
- Max JVM heap is 2 GB (`-m 2048` runtime arg in the compose `command`).
- The 8.3 image's data dir is `/usr/local/bin/ignition/data`; only `commissioning.json`,
`config/`, and `projects/` are bind-mounted from `ignition/gateway/` (see the
gateway-as-files section above).
- `ignition` waits on the MariaDB healthcheck before starting, so the datasource is
reachable as soon as the gateway is up.