From 2b494542370c486aaee50fcce5629377808e72fb Mon Sep 17 00:00:00 2001 From: igurielidze Date: Thu, 2 Apr 2026 00:50:35 +0400 Subject: [PATCH] Rewrite README with complete tool documentation Covers data sources, workflow, export options, Ignition view structure, device-specific bindings, tag tree, gateway integration, and project structure. Co-Authored-By: Claude Opus 4.6 (1M context) --- README.md | 269 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 190 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index cc84994..2f722f3 100644 --- a/README.md +++ b/README.md @@ -1,42 +1,113 @@ # SCADA Device Layout Tool -Interactive canvas-based tool for designing SCADA device layouts. Built with SvelteKit + Svelte 5 + TypeScript + HTML5 Canvas. +Visual layout editor for designing conveyor system SCADA views. Generates Ignition Perspective views with full tag bindings, deployable directly to an Ignition gateway. -## Project Structure +Built with SvelteKit + Svelte 5 + TypeScript + HTML5 Canvas. +## What It Does + +- Drag-and-drop placement of conveyor system devices (VFDs, photoeyes, EPCs, sensors, controls, etc.) onto a canvas +- Trace PDF blueprints as background reference while placing devices +- Assign device IDs from Excel manifests to placed symbols +- Export production-ready Ignition Perspective `view.json` with tag bindings (color/state/priority), pan/zoom controls, tooltips, and alarm filters +- Deploy directly to the Ignition gateway filesystem with automatic project rescan + +## Data Sources + +### Excel Device Manifests +`svelte-app/static/projectes/{PROJECT}/excel/*.xlsx` + +Each file represents one MCM (Module Control Module) with device IO data. Parsed at build time (Vite plugin) into `devices-manifest.json` — device IDs mapped to symbol types, organized by MCM. + +### PDF Blueprints +`svelte-app/static/projectes/{PROJECT}/pdf/*.pdf` + +Conveyor layout drawings rendered as canvas background for accurate device tracing. + +### SVG Symbols +`svelte-app/static/symbols/*.svg` + +Vector graphics for each device type. Rendered programmatically on canvas for consistent stroke width at any size. + +### Ignition Tag Tree +Tag paths follow the Ignition tag provider hierarchy: ``` -scada_device_layout/ -├── projectes/ # Project data (outside svelte-app) -│ └── CDW5/ -│ └── excel/ -│ ├── Amazon CDW5_Devices IO.xlsx -│ └── Amazon CDW5_IP Addresses_Local.xlsx -├── svelte-app/ # Main application -│ ├── src/ -│ │ ├── lib/ -│ │ │ ├── stores/layout.svelte.ts # Central state (LayoutStore) -│ │ │ ├── canvas/renderer.ts # Canvas draw loop (HiDPI-aware) -│ │ │ ├── canvas/interactions.ts # Mouse/keyboard, drag-and-drop -│ │ │ ├── canvas/collision.ts # AABB, spacing, snap -│ │ │ ├── symbols.ts # Symbol definitions, image cache -│ │ │ ├── symbol-config.ts # EPC, induction, photoeye, curve config -│ │ │ ├── pdf.ts # PDF background (pdfjs-dist v5) -│ │ │ ├── export.ts # SVG export, JSON save/load -│ │ │ └── projects.ts # Project/MCM discovery -│ │ ├── components/ -│ │ │ ├── Canvas.svelte # Canvas + PDF background + context menu -│ │ │ ├── Toolbar.svelte # Left panel: project/MCM, settings, palette -│ │ │ ├── Palette.svelte # Symbol palette (drag to place) -│ │ │ └── DeviceDock.svelte # Right panel: device list from Excel -│ │ └── routes/+page.svelte # App layout -│ ├── static/ -│ │ ├── symbols/ # SVG symbol files -│ │ └── projectes/ # Build-generated manifests + MCM placeholders -│ │ ├── manifest.json # Project/MCM manifest (auto-generated) -│ │ └── devices-manifest.json # Device list per MCM (auto-generated) -│ └── vite.config.ts # Vite plugins for manifest generation +System/{MCM}/ + VFD/APF/ - Variable Frequency Drives + Station/Emergency_Pull_Cord/ - EPCs + Station/Start/ - Start Buttons (S) + Station/Start_Stop/ - Start/Stop Buttons (SS) + Station/Jam_Reset/ - Jam Reset Buttons (JR) + Station/Jam_Reset_Chute_Bank/ - Chute Enable Buttons + Sensor/Tracking/ - Tracking Photoeyes (TPE) + Sensor/Laser/ - Laser Photoeyes (LPE) + Sensor/Jam/ - Jam Photoeyes (JPE) + Sensor/Full/ - Full Photoeyes (FPE) + Sensor/Pressure/ - Pressure Sensors (PS) + Network_Node/FIO/ - Field I/O Modules (FIOM) + Network_Node/HUB/ - Hub Modules (FIOH) + Network_Node/SIO/ - Serial I/O Modules + Network_Node/DPM/ - Distribution Power Modules + Beacon/ - Beacon Lights (BCN) + Solenoid/ - Solenoid Valves (SOL) + Diverter/ - Diverter Limit Switches + PDP/ - Power Distribution Panels + Chute/Conveyance/ - Chute Conveyors + Tipper/ - Tipper Conveyors + Extendo/ - Extendo Conveyors ``` +## How It Works + +### 1. Project Setup +Select a project and MCM from the toolbar. Device manifest and PDF blueprint load automatically. + +### 2. Layout Design +- Drag symbols from the palette onto the canvas +- Resize conveyors, spurs, and curves by dragging handles +- Rotate (R), mirror (M), snap to grid +- Shift+drag constrains to horizontal/vertical +- Mouse wheel to zoom, middle-click to pan + +### 3. Device Assignment +- Drag device IDs from the right dock onto placed symbols +- IDs match by conveyance family (conveyor IDs work on spurs, curves, inductions, extendos) +- Labels render inside conveyance shapes as bold text (parsed: `UL17_22_VFD` -> `UL / 17-22`) + +### 4. Export Options + +| Button | Output | Description | +|--------|--------|-------------| +| **SVG** | `{MCM}_Detailed_View.svg` | Standard SVG with shapes, labels, embedded layout data | +| **JSON** | `{MCM}_layout.json` | Layout data for backup/restore | +| **SCADA** | `{MCM}_Detailed_View.json` | Ignition `ia.shapes.svg` component JSON | +| **Deploy** | Writes to Ignition | `view.json` + `resource.json` to gateway project directory | + +### 5. Ignition View Structure +Generated `view.json` includes: + +- **Pan/zoom container** — mouse wheel zoom, pointer-move panning, double-click reset +- **SVG component** — all device shapes with per-element tag bindings: + - `color` — indirect tag binding to `[{fc}_SCADA_TAG_PROVIDER]{tagpath}/Color` with 21-color state map + - `state` — indirect tag binding to `[{fc}_SCADA_TAG_PROVIDER]{tagpath}/State` with 35-state map + - `priority` — indirect tag binding to `[{fc}_SCADA_TAG_PROVIDER]{tagpath}/Priority` (5 levels) + - `fill.paint` / `stroke.paint` — dynamic coloring based on device type + - `style.display` — alarm-based visibility filters (`show_fio`, `show_pes`, `show_beacons`, etc.) +- **Markdown tooltip** — hover tooltips with device state/priority, glow effects on active elements +- **Zoom controls** — reset, zoom in/out, percentage dropdown +- **Message handler** — `focusDevice` for external navigation + +### Device-Specific Bindings + +| Device Type | Fill Binding | Notes | +|-------------|-------------|-------| +| Conveyor/Chute/Spur/Induction | `elements[0].fill.paint` + text contrast | Background + text color | +| DPM | `elements[0].fill.paint` only | First triangle path | +| MCM | `elements[1].fill.paint` only | Second triangle path | +| EPC | `elements[0].stroke.paint` + `elements[1].elements[1].fill.paint` | Polyline stroke + icon inner | +| Buttons (JR/S/SS) | Text `fill.paint` only | Background keeps static color | +| Photoeye/FIO/Beacon/etc. | `elements[0].fill.paint` | Standard fill | + ## Setup & Run ```sh @@ -45,61 +116,101 @@ npm install npm run dev # Dev server at http://localhost:5173 ``` -## Build & Preview +## Gateway Integration -```sh -npm run build # Production build to build/ -npm run preview # Preview at http://localhost:4173 +### Deploy Target +Files are written to: +``` +C:/Program Files/Inductive Automation/Ignition/data/projects/{PROJECT}/ + com.inductiveautomation.perspective/views/DetailedView/{MCM}/ + view.json # Full Perspective view with bindings + resource.json # Resource metadata with SHA-256 signature ``` -## Excel Data +### Automatic Project Rescan +A gateway timer script (5s interval) watches for `.deploy-pending` trigger files and calls `IgnitionGateway.get().getProjectManager().requestScan()` so the Designer picks up new views without a gateway restart. -Place Excel files in `projectes/{PROJECT}/excel/`: +Gateway Timer Script setup: +```python +import os +basePath = "C:/Program Files/Inductive Automation/Ignition/data/projects" +projects = ["CDW5_SCADA"] +for proj in projects: + viewsDir = os.path.join(basePath, proj, "com.inductiveautomation.perspective", "views") + if not os.path.exists(viewsDir): + continue + for root, dirs, files in os.walk(viewsDir): + if ".deploy-pending" in files: + trigger = os.path.join(root, ".deploy-pending") + os.remove(trigger) + from com.inductiveautomation.ignition.gateway import IgnitionGateway + IgnitionGateway.get().getProjectManager().requestScan() + system.util.getLogger("SCADADeploy").info("Deployed view: " + root) +``` -- **Devices IO** (`*Devices IO*.xlsx`): Contains MCM sheets with device assignments. Columns: Controller name, Signal type, Address name, Assigned device, Description. -- **IP Addresses** (`*IP Address*.xlsx`): Network structure sheets with VFDs, FIOMs, DPMs. +## Project Structure -The Vite build plugin auto-parses these into `devices-manifest.json` at build time. - -## Features - -- **Canvas rendering** with `requestAnimationFrame` loop and dirty flag -- **HiDPI zoom** — canvas buffer scales to `DPR x zoomLevel` (capped at 4x) for crisp rendering at any zoom -- **Configurable canvas size** — W/H adjustable in Settings, saved per MCM -- **Symbol palette** (left dock) — drag generic symbols onto canvas -- **Device dock** (right dock) — per-MCM device list parsed from Excel, grouped by symbol type. Drag to place with auto-labeling. Placed devices disappear from the list; deleting from canvas restores them. -- **3-slice photoeye resize** — extending PEs stretches only the middle beam, left/right caps stay fixed -- **PDF background** — load reference PDFs behind the canvas, adjustable scale/position -- **SVG export** with Inkscape-compatible labels -- **JSON save/load** — layout state persisted to localStorage per project/MCM -- **Undo** (Ctrl+Z), multi-select, snap-to-grid, collision detection - -## Symbol Types - -Conveyance: Conveyor, Chute, Tipper, Curved Conveyor/Chute (30/45/60/90), Spur, Extendo, Induction, Diverter -I/O: FIO/SIO/FIOH -Sensors: Photoeye, Pressure Sensor -Controls: Jam Reset, Start, Start Stop, Chute Enable, Package Release, Beacon, Solenoid -Other: PDP, DPM, MCM, EPC, IP Camera +``` +scada_device_layout/ + svelte-app/ + src/ + lib/ + canvas/ + renderer.ts # Canvas draw loop, symbol rendering + interactions.ts # Mouse/keyboard handlers, drag-and-drop + hit-testing.ts # Shape-aware click detection + collision.ts # Spacing violation detection + render-theme.ts # Visual constants (colors, sizes) + grid-snap.ts # Grid snapping + distance.ts # Geometry helpers + geometry.ts # Oriented box math + stores/ + layout.svelte.ts # Central state (symbols, selection, settings) + export.ts # SVG/JSON/SCADA export, Ignition deploy + ignition-view.ts # Full view.json generator with all bindings + symbols.ts # Symbol definitions, type checks, image cache + symbol-config.ts # Geometry constants (EPC, induction, photoeye, etc.) + label-utils.ts # Label parsing (UL17_22_VFD -> UL / 17-22) + serialization.ts # Save/load with size migration + pdf.ts # PDF background rendering + projects.ts # Project/MCM discovery + types.ts # TypeScript interfaces + components/ + Canvas.svelte # Main canvas + PDF + context menu + Toolbar.svelte # Left sidebar (project, settings, palette, Ignition deploy) + Palette.svelte # Symbol picker with groups + DeviceDock.svelte # Right sidebar (device ID assignment) + static/ + symbols/ # SVG files for each device type + projectes/ # Project data (Excel, PDF, manifests) + vite.config.ts # Vite plugins: manifest gen, Excel parser, deploy endpoint +``` ## Device Classification (from Excel) -| Excel suffix | Symbol | Notes | -|---|---|---| -| TPE, LPE, JPE, FPE, BDS, TS | Photoeye | All PE variants | -| EPC | EPC | 2 channels per EPC, only 1 symbol | -| JR_PB | Jam Reset | _LT variants skipped (indicator light) | -| S_PB | Start | | -| SS_SPB / SS_STPB | Start Stop | | -| EN_PB | Chute Enable | | -| PR_PB | Package Release | | -| SOL | Solenoid | | -| DIV_LS | Diverter | | -| BCN | Beacon | All color variants consolidated | -| VFD (from IP sheet) | Conveyor | VFD = conveyor drive | -| FIO*, SIO*, FIOM, FIOH | FIO/SIO/FIOH | From both controller and device columns | -| DPM | DPM | From IP sheet | -| PDP CB + PMM | PDP | Consolidated per PDP unit | -| PS | Pressure Sensor | | +| Suffix | Symbol | Tag Path | +|--------|--------|----------| +| VFD | Conveyor | VFD/APF | +| EPC | EPC | Station/Emergency_Pull_Cord | +| TPE | Photoeye | Sensor/Tracking | +| LPE | Photoeye | Sensor/Laser | +| JPE | Photoeye | Sensor/Jam | +| FPE | Photoeye | Sensor/Full | +| PS | Pressure Sensor | Sensor/Pressure | +| BDS, TS | Photoeye | Sensor/Tracking | +| JR_PB | Jam Reset | Station/Jam_Reset | +| S_PB | Start | Station/Start | +| SS_SPB/STPB | Start Stop | Station/Start_Stop | +| EN_PB | Chute Enable | Station/Jam_Reset_Chute_Bank | +| BCN | Beacon | Beacon | +| SOL | Solenoid | Solenoid | +| DIV_LS | Diverter | Diverter | +| FIOM | FIO/SIO/FIOH | Network_Node/FIO | +| FIOH | FIO/SIO/FIOH | Network_Node/HUB | +| SIO | FIO/SIO/FIOH | Network_Node/SIO | +| DPM | DPM | Network_Node/DPM | +| PDP | PDP | PDP | + +Note: `_PB`/`_SPB`/`_STPB` suffixes are stripped from tag paths to match PLC naming. Skipped: ENSH/ENW (encoders), VFD_DISC (disconnect), _LT (lights), EPC 2nd channel, ESTOP, SCALE, STO, PRX, LRPE.