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) <noreply@anthropic.com>
This commit is contained in:
igurielidze 2026-04-02 00:50:35 +04:00
parent ebf4901d22
commit 2b49454237

269
README.md
View File

@ -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.