Go to file
2026-07-09 10:56:18 +00:00
api perf(db): serve presses + downtime-reason texts from the shared reference cache 2026-07-09 12:06:40 +02:00
dist fix(spa): reconnect spinner on connection loss, no demo data in prod 2026-07-09 09:20:20 +02:00
src fix(spa): reconnect spinner on connection loss, no demo data in prod 2026-07-09 09:20:20 +02:00
__init__.py feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
_db.py perf(db): serve presses + downtime-reason texts from the shared reference cache 2026-07-09 12:06:40 +02:00
.gitignore chore: ignore Python bytecode (__pycache__) generated at gateway import 2026-07-06 10:46:01 +02:00
.npmrc.example feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
env.d.ts feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
index.html @ 2026-07-02 20:42:54 +02:00
package.json chore: use yarn (fleet standard) + declare vite devDependency 2026-07-02 09:06:20 +02:00
README.md docs: README — data is wired to live MariaDB (was "currently SAMPLE") 2026-07-06 11:14:22 +02:00
tailwind.config.cjs feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
tsconfig.app.json feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
tsconfig.json feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
tsconfig.node.json feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
vite.config.ts feat: scaffold Temper-Linie live-overview page-module (temper_overview) 2026-07-01 20:41:04 +02:00
yarn.lock chore: use yarn (fleet standard) + declare vite devDependency 2026-07-02 09:06:20 +02:00

SPA_TemperProductionOverview — Temper-Linie · Live-Übersicht

A login-free, read-only whole-line temper overview, built as a Vue 3 SPA that the SPRO Universal Gateway serves as a static page-module under /module/temper_overview/ and that is embedded into Grafana via an <iframe>.

Standalone orientation. This repo is developed on its own (like FastPress, PressV, sp-ui-kit — sibling repos), but it only comes fully alive when mounted into the gateway as a git submodule at modules/temper_overview/. This README bakes in everything a fresh session needs — you shouldn't need the gateway repo open to work on the frontend.

Board it renders (dark, one connected line): Pressen → (cyan ↓) → Ofen → (green ↓) → Fertig, carts hanging under their origin press, oven trays whose background fills with dwell progress, a finished band, and a time-range picker that scopes only the "Fertig" figures. Run npm run dev to see it.


Quick start (standalone dev)

Package manager is yarn 1.22.22 (pinned via packageManager; matches PressV / the fleet). corepack provides it — no global yarn install needed.

# 0) let corepack honour the pinned yarn (one-time per machine)
corepack enable

# 1) auth for the private @sp-ui-kit design-token package (one-time)
cp .npmrc.example .npmrc      # then paste a Gitea PAT with "package: Read" scope
                              # (yarn v1 reads .npmrc for the scoped registry)

# 2) install + run
yarn install
yarn dev                      # http://localhost:5173/module/temper_overview/

With no gateway backend running, the store falls back to bundled sample data (src/data/sample.ts), so yarn dev shows the full design immediately (a DEMO-DATEN tag appears in the header). yarn builddist/ (committed).


How it's wired into the gateway (page-module contract)

This is a gateway module per agent_docs/vue-page-modules.md in the gateway repo. The repo root is a Python package (__init__.py) so the kernel's module loader can import temper_overview and call register(app):

File Role
__init__.py register(app) — mounts dist/ at MODULE_PREFIX + includes the API router
_db.py kernel DB seam (run_select_query) — used once real SQL is wired
api/routes.py the no-auth read API (GET /module/temper_overview/api/overview)
dist/ committed build output — the gateway serves this (deploy host has no Node)
src/ etc. the Vue app source

URL prefix lives in two places that MUST match — change both together: vite.config.tsbase: '/module/temper_overview/' and __init__.pyMODULE_PREFIX = "/module/temper_overview". The frontend derives its API base from import.meta.env.BASE_URL, so it follows the prefix automatically.

Add it to a gateway checkout:

# in the gateway repo (fastAPI)
git submodule add https://git.sprodat.eu/Erik/SPA_TemperProductionOverview.git modules/temper_overview
# MODULES_ENABLED in .env must include temper_overview (or be empty = load all)

Restart the gateway; the log shows loaded module: temper_overview. Smoke-test (mind the trailing slash): http://localhost:8800/module/temper_overview/ and …/api/overview.

Deploy rule: always yarn build and commit dist/ when the app changes, then bump the submodule pin in the gateway repo. Never build on the gateway host.


Data API contract

GET /module/temper_overview/api/overview?range=12h|1d|7d|14d|30d → one JSON payload for the whole line. The TypeScript shape is authoritative: src/types/overview.ts; the Python side builds the same shape in api/routes.py. range scopes only the finished figures — presses / on-the-way / oven are always real-time.

{
  "plant": "Werk 1", "generatedAt": "…", "range": "1d",
  "ovenTempC": 185, "ovenAvgMin": 120, "sample": true,
  "presses":  [{ "name":"P1","status":"run","orders":[{"orderNo":"O-4471","colorIndex":0}],
                 "good":1240,"cycleTime":"4.2","notVerladen":34,"note":null,"placeholder":false }],
  "onWay":    { "P3":[{ "cartId":"C-014a","orders":[{"orderNo":"O-4471","qty":54,"colorIndex":0}],"etaMin":3 }] },
  "oven":     [{ "cartId":"C-011","orders":[],"totalMin":120,"remainingMin":42 }],
  "finished": { "carts":47,"parts":5120,"scrap":63,"avgOvenMin":118,
                "byOrder":[{"orderNo":"O-4471","colorIndex":0,"parts":1680}] },
  "finishedList": [{ "cartId":"C-010","orders":[],"ago":"vor 8 min" }]
}

Live data wiring

api/routes.py reads live MariaDB (sample:true only appears in the standalone dev fallback with no backend). Details + the exact column sources are in the gateway memory .claude/memory/temper-line-overview.md. In short: it uses the kernel proxy from .._db import run_select_query (read-only), un-scoped across all presses for plant PLANT_NAME — press list from press_settings.presses; good/chips from active_orders+rejects; run/stop/idle from cycles_new recency; carts + notVerladen from production.temper_tracking with position derived in SQL from the planned timestamps vs NOW() (reprints excluded). finished is scoped by range on ttOutOfOvenAt. Oven temperature is omitted (no sensor). Never echo customer/price fields.


Tech stack (matches PressV / the fleet)

Vue 3.5 · Vite 8 · TypeScript 5.9 · Pinia 3 · vue-router 4 (hash) · vue-i18n 10 (de default, ?lang=en) · PrimeVue 4.5 (Nora + custom Industrial preset, sky primary) · Tailwind v4 (CSS-first) · @sp-ui-kit/tokens (shared design tokens, private registry) · Inter Variable. Dark-first, flat 2px corners, 0s transitions, prefers-reduced-motion disables the conveyor animations.

Store pattern (mirrors PressV productionOverview): src/stores/temperOverview.ts does loadCache() (sessionStorage) → hydrate() (spinner only on cold start) → refresh() (background) → startPolling(12000). Robust to a dev server's SPA fallback: a response without a presses[] array is treated as "no backend" → sample.

Design tokens (recognisable across SPRO apps)

Flow accents match PressV --c-*: press/machine #a78bfa, on-the-way/cart #22d3ee, oven #f97316 (hot #ef4444), finished #34d399. Order chips (from PressV orderColors.ts): #5794F2 #E8825A #B57EDC #4FB7A8. Defined in src/style.css (:root dark + html:not(.dark) light) and src/data/orderColors.ts.

Not yet used but part of the fleet stack — add when needed: @sp-ui-kit/ui-core components and echarts/vue-echarts. The board's by-order bars are CSS today.


Grafana embedding

The gateway sets no X-Frame-Options/CSP, so a Grafana Text panel (HTML mode, disable_sanitize_html = true) can iframe it:

<iframe src="http://<gateway-host>:8800/module/temper_overview/#/"
        width="100%" height="900" style="border:0"></iframe>

Append ?lang=en before the # for English. Design is locked as design #4 "Shop-floor Schematic" — see .claude/memory/temper-line-overview.md and the prototype at modules/fastpress/reference/temper-overview/ in the gateway repo.