igurielidze 2b49454237 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>
2026-04-02 00:50:35 +04:00

217 lines
9.4 KiB
Markdown

# SCADA Device Layout Tool
Visual layout editor for designing conveyor system SCADA views. Generates Ignition Perspective views with full tag bindings, deployable directly to an Ignition gateway.
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:
```
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
cd svelte-app
npm install
npm run dev # Dev server at http://localhost:5173
```
## Gateway Integration
### 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
```
### 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.
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)
```
## Project Structure
```
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)
| 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.