# 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: — 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:` 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 → 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.