This repository contains detailed research notes and editable draw.io diagrams for GEO SCADA and a cloud-based SCADA implementation.
docs/01-geo-scada-overview.md— Deep dive into Schneider Electric EcoStruxure™ Geo SCADA Expert.docs/02-cloud-scada-implementation.md— Cloud/hybrid SCADA architecture, protocols, and implementation roadmap.docs/03-security-and-operations.md— Security zones, IAM, compliance, and operations for cloud SCADA.docs/04-checklists.md— Step-by-step checklists to execute a cloud SCADA deployment.drawio/— draw.io source diagrams.cloud-scada-overview.drawio— End-to-end hybrid cloud SCADA architecture.cloud-scada-data-flow.drawio— Telemetry/command data flow.security-zones.drawio— Network/security zones and trust boundaries.network-edge.drawio— Detailed network edge devices: internet entry, ISP/edge router, perimeter firewall, DMZ, OT firewall, IT firewall, and internal switches/servers.deployment-roadmap.drawio— 9-phase implementation roadmap.integration_architecture.drawio— Hand-drawn reference (Integration & Interoperability Architecture) used for the brand border and title block style.
- Open https://app.diagrams.net (draw.io).
- Choose File → Open from → Device.
- Select the
.drawiofile in thedrawio/folder. - Edit shapes, colors, labels, and connections as needed.
Each markdown file is self-contained and written in plain language with bullets, tables, and code snippets. Start with the overview, then read the implementation guide, and finally the security and checklists sections.
The drawio/*.drawio files are generated from tools/drawio-gen/diagrams.json by tools/drawio-gen/generate.js. The output is uncompressed by default for easier diffing; use --compress to generate the standard draw.io compressed pipeline.
node tools/drawio-gen/generate.jsThe generator writes uncompressed .drawio XML by default for easier diffing. Use --compress to emit the original compressed .drawio files. When tools/drawio-gen/diagrams.schema.json is present, the spec is validated against the schema before generation.
Use --fix to enable the self-check / auto-fix loop (up to 3 iterations). The generator validates each generated mxGraphModel and tries to fix structural issues (missing geometry, missing edge source/target, duplicate IDs, text labels overlapping blocks) and switch to elk layout for block overlaps or edge crossings.
Use --self-check to validate output and exit with an error if any issues remain (fixes structural issues but does not run layout auto-fix).
node tools/drawio-gen/validate.js
powershell -ExecutionPolicy Bypass -File tools\drawio-gen\validate.ps1
node tools/drawio-gen/validate-mcp.js
node tools/drawio-gen/validate-mcp.js --previewThe Node validator decompresses each file, checks the mxGraphModel root and required root cells, checks that every edge has both a source and a target, detects any text labels that overlap filled blocks, and also checks ID existence, unique IDs, geometry, shape/perimeter, block/edge overlaps, and overall XML well-formedness. The PowerShell validator decompresses the file and uses [xml] to parse the model and confirm the structural root cells (id="0" and id="1" parent="0"). The MCP validator uses the official draw.io MCP server to call get_page and open_drawio_xml and confirm the files open in draw.io. Add --preview to attempt opening the generated diagram(s) directly. If the MCP server is not available, validate-mcp.js exits cleanly with a helpful message. If you have the drawio MCP server configured as an assistant tool, you can call mcp_call_tool with open_drawio_xml and the generated <mxGraphModel> XML to preview it.
node tools/drawio-gen/compare.js drawio/cloud-scada-overview.drawio drawio/integration_architecture.drawioThis compares page size, border, accent bars, title, logo, header line, and title block fields against a reference .drawio file. Add --check to run validation on both files before diffing and to include additional diff rows for shapes, edge style, and labels.
# From the repo root, install dependencies and run scripts in tools/drawio-gen
cd tools/drawio-gen
npm install
# Generate using the local spec
npm run generate
# Generate a single combined file
npx drawio-gen --combined
# Generate from a custom config file
npx drawio-gen --config my-diagrams.json
# Generate to a custom output directory
npx drawio-gen --output dist/
# Validate
npm run validate
# Preview diagrams via MCP (graceful if MCP server is not available)
npm run preview
# Search draw.io shape library
npm run search-shapes
# Extract the <mxGraphModel> XML from a .drawio file
npm run extract-mx -- drawio/my-diagram.drawio
# Generate a diagrams.net URL for the first page
npm run url
# Export PNG/SVG if draw.io desktop CLI is installed
npm run export # uses page.outputFormat
npm run export:png # force all pages to PNG
npm run export:svg # force all pages to SVG
node tools/drawio-gen/export.js --format pdfAll generated diagrams include a Visio-style brand border, accent bars, a header line below the title, and a drawing title block at the bottom right. The style is based on drawio/integration_architecture.drawio.
Set border: true on a page to enable it. Shared brand values can be set once at the top level of tools/drawio-gen/diagrams.json (logo, client, project, confidentiality, border/accent colors). brand.logo can be a text label, a file path like assets/logo.png (auto base64-encoded), or a data:image/... data URI. A page-level brand object overrides those values and adds borderWidth, accent1Width, accent2Width, logoX, logoY, logoWidth, logoHeight, logoBgColor, logoColor, and nested titleBlock. Use titleBlock to override title, client, project, drawn, checked, date, dwgNo, rev, or sheet. The top client/project/confidentiality row only appears when those fields are set.
Nodes support shape, html, tooltip, and link attributes, and edges support custom style and points for routing, labels, and arrowheads.
Pages support layers (array of { id, label }) and node.layer to place a node on a specific layer. The default layer is id="1".
Any node can have a children array. Children use coordinates relative to the parent top-left and are parented to the parent node. Any node with children gets the container flags container=1;pointerEvents=0;collapsible=0;.
kind: "swimlane" creates a titled container with optional startSize, horizontal, and swimlaneFillColor. Children can be placed inside swimlanes the same as group children.
page.autoLayout (none, flow, tree) automatically places nodes missing explicit x/y. flow uses node.rank/node.level for columns and node.group for rows; tree uses node.level/node.rank and edges for BFS levels. Both use a 220x120 grid starting at x=40, y=40.
page.titleBlock.position moves the title block to bottom-right (default), bottom-left, top-right, or top-left.
page.titleBlock.fields appends custom fields ({ key, label, value }) to the title block bottom row. page.titleBlock.logo embeds an image cell inside the title block area.
brand.watermark adds a large low-opacity centered text label and brand.footer adds a small bottom-center label. brand.headerLine.color and brand.headerLine.width override the header line style.
The Windsurf MCP server is configured in .codeium/windsurf/mcp_config.json to use the official draw.io MCP (npx -y @drawio/mcp).
- Layout:
page.layoutaccepts a preset or a JSON layout array;export.js --layoutpasses a layout to the draw.io CLI. - UserObject / object wrappers: nodes and edges can have
data(object),tags(array or string), andplaceholders(boolean); they are wrapped in<object>withdata-*attributes. - Top-level vars:
diagrams.jsonvarsare written to<mxfile vars="...">. - Style builder:
gradientColor,gradientDirection,opacity,fillOpacity,strokeOpacity,glass,shadow,sketch,comic,rotation,direction,flip,arcSize,perimeterSpacing,labelBackgroundColor,labelBorderColor. - Adaptive colors and dark mode:
attrs.adaptiveColorsdefaults toauto;validate-mcp.js --darkpreviews in dark mode. - Source pages:
page.sourcewithtype: "mermaid"ortype: "csv"generates.mmdor.csvsource files. - Diagram presets:
page.kind/page.diagramTypecan be"sequence"(lifelines, messages, activation, replies, creates, destroys) or"table"(rows with optional title/header). - CLI additions:
generate.js --url,export.js --embed,--transparent,--border,--scale,--width,--height,--crop,--all-pages,--page-range. - Search shapes:
search-shapes.js(ormcp-tool.js search_shapes <query>) queries the draw.io MCP server for shape styles. - Edge label readability: edge labels default to
labelBackgroundColor=#ffffffandfontColor=#000000so they remain readable over lines. - Examples:
v2-1-0-layout.drawio,v2-1-0-object.drawio,v2-1-0-sequence.drawio,v2-1-0-styles.drawio,v2-1-0-table.drawio,v2-1-0-csv.csv,v2-1-0-source.mmd.
- Server-side ELK layout: set
page.autoLayouttoelkor an ELK algorithm (elk-layered,elk-tree,elk-radial,elk-force,elk-stress,elk-mrtree,elk-sporeOverlap,elk-rectpacking) to compute node positions and edge waypoints viaelkjsduring generation. generate.jsis now async and runs ELK before building themxGraphModelXML.- Edge waypoints are written as
<Array as="points">inside edge<mxGeometry>. - Self-check / auto-fix loop:
generate.jsvalidates each generated page withvalidate.checkXmland can auto-fix structural issues (missing geometry, missing edge source/target, duplicate IDs, text-overlap labels) and switch toelklayout for block overlaps or edge crossings. Use--fixto enable auto-fix or--self-checkto validate and exit on issues. - XSD validation and XML reference checks:
validate.jsvalidates every generated.drawiofile againstmxgraph.xsdand checks for duplicate IDs, source/target references, parent references, and parent cycles. Usenode tools/drawio-gen/xsd-validate.js <file>to validate a single file against the XSD. - libavoid routing via MCP: set
page.routingtolibavoidin the spec;mcp-tool.jsandvalidate-mcp.jspassroutingtoopen_drawio_xmlwhen previewing.page.postLayoutis reserved forcreate_diagramwhen the MCP server supports it. - Network/SCADA/P&ID
kindaliases:kindvalues such asrouter,switch,plc,rtu,hmi,sensor,valve,pump,tank,motor,fan,gauge, andbreakerresolve to domain-specific draw.io shapes viatools/drawio-gen/shape-aliases.json. search-shapes.jsandmcp-tool.js search_shapes <query>use thequeryparameter to query the draw.io MCP server shape library.- Example:
v2-2-0-elk.drawioandv2-2-0-routing.drawio.
This repo is packaged as a Devin plugin. The skill is named drawio and the plugin namespace is drawio-skill, so the plugin manifest is .devin-plugin/plugin.json (version 2.2.0).
- Install in another project:
devin plugins install <repo>(the skill is invoked as/drawio-skill:drawio). - Install locally from this repo:
devin plugins install ./ - Export manually: copy
skills/drawio/SKILL.md,.devin/skills/drawio/SKILL.md,.windsurf/skills/drawio/SKILL.md, or.agents/skills/drawio/SKILL.mdand thetools/drawio-gen/directory to the target project. TheSKILL.mdfrontmatter containsversion: 2.1.0.
tools/drawio-gen/package.json exposes bin entries, so after installing or linking the package you can run:
npx drawio-gen
npx drawio-validate
npx drawio-compare <a> <b>
npx drawio-search-shapes <query>After installing, ensure tools/drawio-gen/ is copied to the project root, then edit tools/drawio-gen/diagrams.json and run the generator/validate steps above.
See CHANGELOG.md for the versioned roadmap, now through v2.2.0.