Each <name>.drawio.svg now has the corresponding <name>.drawio XML embedded as content="..." on the root <svg> element. Opening the SVG in draw.io (File → Open, or drag-drop) loads the full editable model — no need to keep the .drawio file around for editing. Updated diagrams/README.md to reflect that both file formats are now round-trippable from the start. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
100 lines
10 KiB
XML
100 lines
10 KiB
XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 900 620" font-family="Arial, sans-serif" font-size="13" content="<mxfile host="app.diagrams.net" modified="2026-04-22T12:00:00.000Z" agent="Claude Code placeholder" etag="initial" version="22.0.0" type="device">
|
||
<diagram name="safety-rules" id="safetyRules">
|
||
<mxGraphModel dx="1200" dy="700" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="900" pageHeight="700" math="0" shadow="0">
|
||
<root>
|
||
<mxCell id="0" />
|
||
<mxCell id="1" parent="0" />
|
||
<mxCell id="title" value="Safety rules — asymmetric by direction" style="text;html=1;fontSize=16;fontStyle=1;align=center;" vertex="1" parent="1">
|
||
<mxGeometry x="150" y="20" width="600" height="30" as="geometry" />
|
||
</mxCell>
|
||
|
||
<mxCell id="dryrun_box" value="DRY-RUN&#10;(direction = draining)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFF3E0;strokeColor=#E65100;strokeWidth=2;fontSize=14;fontStyle=1;verticalAlign=top;" vertex="1" parent="1">
|
||
<mxGeometry x="80" y="80" width="340" height="340" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="dr_upstream" value="upstream children — KEEP" style="text;html=1;fontSize=13;align=left;" vertex="1" parent="1">
|
||
<mxGeometry x="100" y="140" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="dr_downstream" value="downstream children — STOP" style="text;html=1;fontSize=13;align=left;fontStyle=1;fontColor=#E65100;" vertex="1" parent="1">
|
||
<mxGeometry x="100" y="170" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="dr_machinegroups" value="machineGroups — STOP" style="text;html=1;fontSize=13;align=left;fontStyle=1;fontColor=#E65100;" vertex="1" parent="1">
|
||
<mxGeometry x="100" y="200" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="dr_control" value="control loop — BLOCKED" style="text;html=1;fontSize=13;align=left;fontStyle=1;fontColor=#E65100;" vertex="1" parent="1">
|
||
<mxGeometry x="100" y="230" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="dr_note" value="safetyControllerActive = true&#10;&#10;Pumps must stop before sucking air." style="text;html=1;fontSize=12;align=left;fontStyle=2;" vertex="1" parent="1">
|
||
<mxGeometry x="100" y="290" width="300" height="80" as="geometry" />
|
||
</mxCell>
|
||
|
||
<mxCell id="overfill_box" value="OVERFILL&#10;(direction = filling)" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFEBEE;strokeColor=#C62828;strokeWidth=2;fontSize=14;fontStyle=1;verticalAlign=top;" vertex="1" parent="1">
|
||
<mxGeometry x="480" y="80" width="340" height="340" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="of_upstream" value="upstream children — STOP ⚠" style="text;html=1;fontSize=13;align=left;fontStyle=1;fontColor=#C62828;" vertex="1" parent="1">
|
||
<mxGeometry x="500" y="140" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="of_downstream" value="downstream children — KEEP" style="text;html=1;fontSize=13;align=left;" vertex="1" parent="1">
|
||
<mxGeometry x="500" y="170" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="of_machinegroups" value="machineGroups — KEEP" style="text;html=1;fontSize=13;align=left;" vertex="1" parent="1">
|
||
<mxGeometry x="500" y="200" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="of_control" value="control loop — ACTIVE" style="text;html=1;fontSize=13;align=left;" vertex="1" parent="1">
|
||
<mxGeometry x="500" y="230" width="300" height="24" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="of_note" value="Level control keeps commanding downstream MGC.&#10;&#10;⚠ &quot;upstream STOP&quot; is only correct in a cascaded layout. In a gravity-sewer station the inflow can&apos;t be stopped — log the spill instead." style="text;html=1;fontSize=12;align=left;fontStyle=2;" vertex="1" parent="1">
|
||
<mxGeometry x="500" y="290" width="300" height="120" as="geometry" />
|
||
</mxCell>
|
||
|
||
<mxCell id="trigger_title" value="Triggers (either condition fires the rule):" style="text;html=1;fontSize=13;fontStyle=1;align=left;" vertex="1" parent="1">
|
||
<mxGeometry x="80" y="450" width="740" height="20" as="geometry" />
|
||
</mxCell>
|
||
<mxCell id="trigger_list" value="• vol &lt; triggerLowVol (triggerLowVol = minVol × (1 + pct/100))&#10;• vol &gt; triggerHighVol (triggerHighVol = maxVolOverflow × pct/100)&#10;• remainingTime &lt; timeleftToFullOrEmptyThresholdSeconds (if enabled)" style="text;html=1;fontSize=12;align=left;" vertex="1" parent="1">
|
||
<mxGeometry x="80" y="480" width="740" height="80" as="geometry" />
|
||
</mxCell>
|
||
</root>
|
||
</mxGraphModel>
|
||
</diagram>
|
||
</mxfile>">
|
||
<title>Safety rules — asymmetric by direction</title>
|
||
|
||
<text x="450" y="30" text-anchor="middle" font-weight="bold" font-size="16">Safety rules — asymmetric by direction</text>
|
||
|
||
<!-- DRY-RUN box -->
|
||
<rect x="80" y="80" width="340" height="340" fill="#FFF3E0" stroke="#E65100" stroke-width="2" />
|
||
<text x="250" y="112" text-anchor="middle" font-weight="bold" font-size="14">DRY-RUN</text>
|
||
<text x="250" y="130" text-anchor="middle" font-size="13" fill="#6F4A19">(direction = draining)</text>
|
||
|
||
<text x="100" y="162" font-size="13">upstream children — <tspan font-weight="bold">KEEP</tspan></text>
|
||
<text x="100" y="188" font-size="13" fill="#E65100">downstream children — <tspan font-weight="bold">STOP</tspan></text>
|
||
<text x="100" y="214" font-size="13" fill="#E65100">machineGroups — <tspan font-weight="bold">STOP</tspan></text>
|
||
<text x="100" y="240" font-size="13" fill="#E65100">control loop — <tspan font-weight="bold">BLOCKED</tspan></text>
|
||
|
||
<line x1="100" y1="268" x2="400" y2="268" stroke="#E65100" stroke-dasharray="3 3" />
|
||
<text x="100" y="294" font-size="12" font-style="italic">safetyControllerActive = true</text>
|
||
<text x="100" y="316" font-size="12" font-style="italic">Pumps must stop before sucking air.</text>
|
||
|
||
<!-- OVERFILL box -->
|
||
<rect x="480" y="80" width="340" height="340" fill="#FFEBEE" stroke="#C62828" stroke-width="2" />
|
||
<text x="650" y="112" text-anchor="middle" font-weight="bold" font-size="14">OVERFILL</text>
|
||
<text x="650" y="130" text-anchor="middle" font-size="13" fill="#7A1919">(direction = filling)</text>
|
||
|
||
<text x="500" y="162" font-size="13" fill="#C62828">upstream children — <tspan font-weight="bold">STOP</tspan> ⚠</text>
|
||
<text x="500" y="188" font-size="13">downstream children — <tspan font-weight="bold">KEEP</tspan></text>
|
||
<text x="500" y="214" font-size="13">machineGroups — <tspan font-weight="bold">KEEP</tspan></text>
|
||
<text x="500" y="240" font-size="13">control loop — <tspan font-weight="bold">ACTIVE</tspan></text>
|
||
|
||
<line x1="500" y1="268" x2="800" y2="268" stroke="#C62828" stroke-dasharray="3 3" />
|
||
<text x="500" y="294" font-size="12" font-style="italic">Level control keeps commanding downstream MGC.</text>
|
||
<text x="500" y="324" font-size="12" font-style="italic" fill="#C62828">⚠ "upstream STOP" is only correct in a cascaded layout.</text>
|
||
<text x="500" y="342" font-size="12" font-style="italic" fill="#C62828">In a gravity-sewer station the inflow can't be</text>
|
||
<text x="500" y="360" font-size="12" font-style="italic" fill="#C62828">stopped — log the spill instead.</text>
|
||
|
||
<!-- Triggers block -->
|
||
<text x="80" y="470" font-weight="bold" font-size="13">Triggers (either condition fires the rule):</text>
|
||
<text x="100" y="498" font-size="12">• vol < triggerLowVol (triggerLowVol = minVol × (1 + pct/100))</text>
|
||
<text x="100" y="520" font-size="12">• vol > triggerHighVol (triggerHighVol = maxVolOverflow × pct/100)</text>
|
||
<text x="100" y="542" font-size="12">• remainingTime < timeleftToFullOrEmptyThresholdSeconds (if enabled)</text>
|
||
</svg>
|