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:
parent
ebf4901d22
commit
2b49454237
269
README.md
269
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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user