devagent-ignition 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- devagent_hmi.py +471 -0
- devagent_ignition-0.1.0.dist-info/METADATA +204 -0
- devagent_ignition-0.1.0.dist-info/RECORD +133 -0
- devagent_ignition-0.1.0.dist-info/WHEEL +4 -0
- devagent_ignition-0.1.0.dist-info/entry_points.txt +2 -0
- devagent_spatial/__init__.py +1 -0
- devagent_spatial/_resources/README.md +187 -0
- devagent_spatial/_resources/RELEASE_MANIFEST.json +312 -0
- devagent_spatial/_resources/SHA256SUMS.txt +270 -0
- devagent_spatial/_resources/SOURCE_PROVENANCE.json +186 -0
- devagent_spatial/_resources/assets/agent.js +102 -0
- devagent_spatial/_resources/assets/creator.css +247 -0
- devagent_spatial/_resources/assets/creator_2d.mjs +16 -0
- devagent_spatial/_resources/assets/creator_original_r9.mjs +58 -0
- devagent_spatial/_resources/assets/creator_original_v8.mjs +120 -0
- devagent_spatial/_resources/assets/creator_r9_diagnostics.mjs +53 -0
- devagent_spatial/_resources/assets/creator_scene.mjs +128 -0
- devagent_spatial/_resources/assets/creator_ui.mjs +60 -0
- devagent_spatial/_resources/assets/customer_documents.js +110 -0
- devagent_spatial/_resources/assets/equipment_controls.mjs +27 -0
- devagent_spatial/_resources/assets/facility2d.css +24 -0
- devagent_spatial/_resources/assets/facility2d_app.mjs +45 -0
- devagent_spatial/_resources/assets/facility2d_core.mjs +114 -0
- devagent_spatial/_resources/assets/facility2d_simulation.mjs +167 -0
- devagent_spatial/_resources/assets/facility2d_viewer.html +7 -0
- devagent_spatial/_resources/assets/fallback_scene.js +17 -0
- devagent_spatial/_resources/assets/flow_geometry.mjs +218 -0
- devagent_spatial/_resources/assets/harness.js +78 -0
- devagent_spatial/_resources/assets/live_design_review.js +129 -0
- devagent_spatial/_resources/assets/operations_ui.js +305 -0
- devagent_spatial/_resources/assets/operator_viewer.html +64 -0
- devagent_spatial/_resources/assets/project_package.js +52 -0
- devagent_spatial/_resources/assets/r9_transport.mjs +70 -0
- devagent_spatial/_resources/assets/runtime_feed.js +30 -0
- devagent_spatial/_resources/assets/studio.html +139 -0
- devagent_spatial/_resources/assets/style.css +191 -0
- devagent_spatial/_resources/assets/test_workspace.html +195 -0
- devagent_spatial/_resources/assets/three_scene.js +442 -0
- devagent_spatial/_resources/assets/unified_engineer.js +101 -0
- devagent_spatial/_resources/assets/v076_fat_ui.js +40 -0
- devagent_spatial/_resources/assets/v078_command_ui.js +44 -0
- devagent_spatial/_resources/assets/viewer.html +45 -0
- devagent_spatial/_resources/assets/viewer.js +112 -0
- devagent_spatial/_resources/design-system.json +130 -0
- devagent_spatial/_resources/examples/CV101-command-contract-PENDING.json +30 -0
- devagent_spatial/_resources/examples/cv101_guided.json +272 -0
- devagent_spatial/_resources/examples/make_examples.py +36 -0
- devagent_spatial/_resources/examples/single_floor.json +444 -0
- devagent_spatial/_resources/examples/v0771_training_wizard.json +11 -0
- devagent_spatial/_resources/examples/warehouse-3floor-standard-2d.json +708 -0
- devagent_spatial/_resources/examples/warehouse-operations-synthetic.json +1186 -0
- devagent_spatial/_resources/examples/warehouse-v07-lab-bindings-PENDING.json +372 -0
- devagent_spatial/_resources/examples/warehouse.json +708 -0
- devagent_spatial/_resources/examples/water.json +288 -0
- devagent_spatial/_resources/reference/r9-golden/REFERENCE_SHA256.json +13 -0
- devagent_spatial/_resources/reference/r9-golden/web/app.mjs +745 -0
- devagent_spatial/_resources/reference/r9-golden/web/index.html +213 -0
- devagent_spatial/_resources/reference/r9-golden/web/lab_panel.mjs +53 -0
- devagent_spatial/_resources/reference/r9-golden/web/model.mjs +367 -0
- devagent_spatial/_resources/reference/r9-golden/web/state_adapter.mjs +78 -0
- devagent_spatial/_resources/reference/r9-golden/web/styles.css +76 -0
- devagent_spatial/_resources/reference/r9-original/README_R9.md +27 -0
- devagent_spatial/_resources/reference/r9-original/SHA256SUMS.txt +63 -0
- devagent_spatial/_resources/reference/r9-original/SNAPSHOT_SHA256SUMS.txt +16 -0
- devagent_spatial/_resources/reference/r9-original/flow_routes.json +527 -0
- devagent_spatial/_resources/reference/r9-original/flow_sim.py +117 -0
- devagent_spatial/_resources/reference/r9-original/lab_control.py +73 -0
- devagent_spatial/_resources/reference/r9-original/web/app.mjs +745 -0
- devagent_spatial/_resources/reference/r9-original/web/index.html +213 -0
- devagent_spatial/_resources/reference/r9-original/web/lab_panel.mjs +53 -0
- devagent_spatial/_resources/reference/r9-original/web/model.mjs +367 -0
- devagent_spatial/_resources/reference/r9-original/web/state_adapter.mjs +78 -0
- devagent_spatial/_resources/reference/r9-original/web/styles.css +76 -0
- devagent_spatial/_resources/reference/r9-original/web/vendor/LICENSE-three.txt +21 -0
- devagent_spatial/_resources/reference/r9-original/web/vendor/SHA256SUMS.txt +4 -0
- devagent_spatial/_resources/reference/r9-original/web/vendor/addons/controls/OrbitControls.js +1860 -0
- devagent_spatial/_resources/reference/r9-original/web/vendor/three.core.js +58773 -0
- devagent_spatial/_resources/reference/r9-original/web/vendor/three.module.js +18251 -0
- devagent_spatial/_resources/reference/v8-original/README.md +36 -0
- devagent_spatial/_resources/reference/v8-original/SHA256SUMS.txt +12 -0
- devagent_spatial/_resources/reference/v8-original/model.py +124 -0
- devagent_spatial/_resources/reference/v8-original/run_demo.sh +4 -0
- devagent_spatial/_resources/reference/v8-original/server.py +100 -0
- devagent_spatial/_resources/reference/v8-original/tests/browser_smoke.py +50 -0
- devagent_spatial/_resources/reference/v8-original/tests/test_v8.py +144 -0
- devagent_spatial/_resources/reference/v8-original/topology.json +24 -0
- devagent_spatial/_resources/reference/v8-original/web/app.js +114 -0
- devagent_spatial/_resources/reference/v8-original/web/index.html +22 -0
- devagent_spatial/_resources/reference/v8-original/web/simulator.html +1 -0
- devagent_spatial/_resources/reference/v8-original/web/simulator.js +6 -0
- devagent_spatial/_resources/reference/v8-original/web/style.css +16 -0
- devagent_spatial/_resources/sample_customer_inputs/Plant_Equipment_Register.csv +4 -0
- devagent_spatial/_resources/sample_customer_inputs/Plant_Flow_Requirements.txt +5 -0
- devagent_spatial/_resources/sample_customer_inputs/Raw_PLC_Tag_Export.csv +4 -0
- devagent_spatial/_resources/templates/warehouse_connections.csv +12 -0
- devagent_spatial/_resources/templates/warehouse_equipment.csv +21 -0
- devagent_spatial/_resources/templates/warehouse_signals.csv +34 -0
- devagent_spatial/_resources/templates/water_connections.csv +7 -0
- devagent_spatial/_resources/templates/water_equipment.csv +10 -0
- devagent_spatial/_resources/templates/water_signals.csv +12 -0
- devagent_spatial/agent_harness.py +299 -0
- devagent_spatial/agent_runtime.py +314 -0
- devagent_spatial/contract_opc_fat.py +216 -0
- devagent_spatial/contract_opc_source.py +265 -0
- devagent_spatial/control_intents.py +38 -0
- devagent_spatial/customer_intake.py +235 -0
- devagent_spatial/engineering_expertise.py +114 -0
- devagent_spatial/generator.py +201 -0
- devagent_spatial/ignition_native.py +234 -0
- devagent_spatial/ignition_project.py +144 -0
- devagent_spatial/live_lab_binding.py +128 -0
- devagent_spatial/model.py +297 -0
- devagent_spatial/native_reference.py +69 -0
- devagent_spatial/opc_snapshot.py +87 -0
- devagent_spatial/operations.py +284 -0
- devagent_spatial/operations_capture.py +47 -0
- devagent_spatial/operations_lab.py +64 -0
- devagent_spatial/original_r9.py +169 -0
- devagent_spatial/original_v8.py +81 -0
- devagent_spatial/preflight.py +140 -0
- devagent_spatial/preview_simulation.py +189 -0
- devagent_spatial/project_package.py +101 -0
- devagent_spatial/qualification.py +152 -0
- devagent_spatial/strict_json.py +29 -0
- devagent_spatial/studio.py +894 -0
- devagent_spatial/studio_workflow.py +277 -0
- devagent_spatial/test_reporting.py +87 -0
- devagent_spatial/v076_opc_fat.py +180 -0
- devagent_spatial/v078_commands.py +277 -0
- devagent_spatial/v078_native_commands.py +161 -0
- devagent_spatial/v07_fat.py +110 -0
- devagent_spatial/v07_native.py +318 -0
- devagent_spatial/v083_native.py +349 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><meta name="color-scheme" content="dark"><title>DevAgent Spatial Operations — Concept Preview</title><link rel="stylesheet" href="./style.css"></head>
|
|
4
|
+
<body>
|
|
5
|
+
<div id="root">
|
|
6
|
+
<header class="top"><div><div class="eyebrow">DEVAGENT / SPATIAL OPERATIONS / CUSTOMER CONCEPT</div><h1 id="project-name">Industrial Facility</h1></div><div class="top-right"><strong>DESIGN SYSTEM V1</strong><span id="source-indicator" class="tag warn">PREVIEW / NO LIVE OPC UA</span><button type="button" id="alerts-toggle" class="alert-bell is-unknown" aria-haspopup="dialog" aria-controls="alerts-dialog" aria-label="Notifications — source not verified" title="Notifications — source not verified"><svg class="bell-icon" viewBox="0 0 24 24" aria-hidden="true" focusable="false"><path d="M18 8a6 6 0 0 0-12 0c0 7-3 8.5-3 9.5h18c0-1-3-2.5-3-9.5ZM10 21h4"/></svg><span id="alert-count" class="bell-badge is-unknown" aria-hidden="true">?</span></button><button type="button" id="engineering-toggle" class="engineering-link" aria-haspopup="dialog" aria-controls="engineering-dialog">ENGINEERING REVIEW</button></div></header>
|
|
7
|
+
<main>
|
|
8
|
+
<section class="metrics" aria-label="Overview metrics"><div class="metric"><small>ASSETS MODELED</small><strong id="m-assets">—</strong><span>customer equipment definition</span></div><div class="metric"><small>PROPOSED OPC UA SIGNALS</small><strong id="m-signals">—</strong><span>not live verified</span></div><div class="metric"><small>VERIFIED TAG MAPPINGS</small><strong>0</strong><span>live validation pending</span></div><div class="metric"><small>SAFETY / CONTROL AUTHORITY</small><strong>READ ONLY</strong><span>PLC writes disabled</span></div><div class="metric"><small>HMI STATUS</small><strong>PREVIEW</strong><span>not Ignition qualified</span></div></section>
|
|
9
|
+
<section class="ops-board" aria-label="Industrial operations KPIs">
|
|
10
|
+
<div class="ops-heading"><div><div class="eyebrow">OPERATIONAL INTELLIGENCE / SOURCE-QUALIFIED</div><b>System performance & alarms</b></div><div id="ops-mode" class="ops-mode">NO LIVE SOURCE · KPI UNAVAILABLE</div></div>
|
|
11
|
+
<div class="ops-metrics">
|
|
12
|
+
<div class="ops-metric"><small>EQUIPMENT RUNNING</small><strong id="kpi-running">N/A</strong><span id="kpi-running-note">Awaiting verified data</span></div>
|
|
13
|
+
<div class="ops-metric"><small>ACTIVE FAULTS</small><strong id="kpi-faults">N/A</strong><span id="kpi-faults-note">Unknown ≠ no faults</span></div>
|
|
14
|
+
<div class="ops-metric"><small>PHOTOEYES BLOCKED</small><strong id="kpi-blocked">N/A</strong><span id="kpi-blocked-note">No live source</span></div>
|
|
15
|
+
<div class="ops-metric"><small>NO_READ EVENTS</small><strong id="kpi-noread">N/A</strong><span id="kpi-noread-note">Source not verified</span></div>
|
|
16
|
+
<div class="ops-metric"><small>TOTAL SCANS</small><strong id="kpi-scans">N/A</strong><span id="kpi-scans-note">Source not configured</span></div>
|
|
17
|
+
<div class="ops-metric"><small>PARCELS IN TRANSIT</small><strong id="kpi-transit">N/A</strong><span id="kpi-transit-note">Source not configured</span></div>
|
|
18
|
+
<div class="ops-metric"><small>DELIVERED PARCELS</small><strong id="kpi-delivered">N/A</strong><span id="kpi-delivered-note">Source not configured</span></div>
|
|
19
|
+
<div class="ops-metric"><small>LAST SCAN RESULT</small><strong id="kpi-scanresult">N/A</strong><span id="kpi-scanresult-note">Source not connected</span></div>
|
|
20
|
+
<div class="ops-metric"><small>LAST BARCODE</small><strong id="kpi-barcode">N/A</strong><span id="kpi-barcode-note">Source not configured</span></div>
|
|
21
|
+
<div class="ops-metric"><small>SIGNAL QUALITY</small><strong id="kpi-quality">N/A</strong><span id="kpi-quality-note">0 verified mappings</span></div>
|
|
22
|
+
</div>
|
|
23
|
+
</section>
|
|
24
|
+
<section class="command" aria-label="Design overview"><div><b>Facility command center</b><span id="system-subtitle">Customer-configured facility</span></div><div class="command-buttons"><button class="muted-btn cmd-start" disabled title="No verified PLC write permission" aria-disabled="true">START</button><button class="muted-btn cmd-stop" disabled title="No verified PLC write permission" aria-disabled="true">STOP</button><button class="muted-btn cmd-reset" disabled title="No verified PLC write permission" aria-disabled="true">RESET</button><span class="tag warn" aria-label="No physical control authority">LOCKED · COMMANDS DISABLED</span></div></section>
|
|
25
|
+
<div class="workspace">
|
|
26
|
+
<section class="viewer-panel"><div class="panel-head"><div><div class="eyebrow">01 / SPATIAL FACILITY MAP</div><h2 id="viewer-title">Spatial material flow</h2><p id="viewer-description">Conceptual, interactive preview. Customer geometry must be reviewed.</p></div><span class="tag">NO PHYSICAL EQUIPMENT CONTROL</span></div>
|
|
27
|
+
<div class="viewer-toolbar"><div class="seg"><button id="view-fit" class="active">3D OVERVIEW</button><button id="view-top">TOP</button><button id="view-side">SIDE</button><button id="view-reset">RESET CAMERA</button></div><div class="seg"><label for="floor">FLOOR</label><select id="floor"><option value="all">ALL LEVELS</option></select></div></div>
|
|
28
|
+
<div id="view-stage" class="stage" tabindex="0" aria-label="Interactive industrial scene"><div id="scene-layer"></div><div class="stage-caption"><div class="eyebrow">OPERATIONAL DIGITAL TWIN / CONCEPT MODEL</div><strong id="scene-label">Spatial layout</strong><small>Orbit • drag · zoom • wheel · select • click</small></div><div id="layer-index" class="layer-index" aria-label="Facility floor navigation"><div class="eyebrow">3D LAYER INDEX</div><div id="layer-buttons"></div></div><div id="scene-engine" class="engine-tag" role="status">Loading renderer…</div><div class="stage-help">CONCEPTUAL GEOMETRY · SOLID TRANSITIONS = CONCEPTUAL ROUTES · DASHED LINES = LOGICAL FLOW ONLY · NOT AS-BUILT · NO LIVE PLC CONNECTION</div></div>
|
|
29
|
+
</section>
|
|
30
|
+
<aside class="inspector"><div class="panel-head inspector-head"><div><div class="eyebrow">02 / EQUIPMENT INSPECTOR</div><h2>Asset intelligence</h2><p>Select a machine in the spatial viewer</p></div></div><div class="inspector-body"><div class="eyebrow" id="selected-type">SELECTED EQUIPMENT</div><h2 id="selected-id">—</h2><p id="selected-name">Click an asset to inspect its proposed mappings.</p><div id="asset-meta" class="detail-grid"></div><div class="small-title">AVAILABLE SIGNALS · NOT VERIFIED</div><div id="selected-signals" class="signals-mini"></div><div class="note">Preview only · Signal values and machine states are not connected to a verified source.</div></div></aside>
|
|
31
|
+
</div>
|
|
32
|
+
<dialog class="alerts-dialog" id="alerts-dialog" aria-labelledby="alerts-title">
|
|
33
|
+
<div class="alerts-title"><div><div class="eyebrow">DEVAGENT / OPERATOR AWARENESS</div><h2 id="alerts-title">Alarm & Notification Center</h2><p id="alerts-source">NO LIVE SOURCE — current equipment alarm states unknown</p></div><button type="button" id="alerts-close">CLOSE ×</button></div>
|
|
34
|
+
<div class="alerts-summary"><b id="alerts-active">N/A active alarms</b><span id="alerts-evidence">No lab receipt loaded</span></div>
|
|
35
|
+
<div id="alerts-items" class="alerts-items" aria-live="polite"><p class="empty-alerts">No alarm history available. This does not mean the equipment is healthy.</p></div>
|
|
36
|
+
<p class="alerts-disclaimer">LAB REPLAY alerts are demonstration events only. This preview does not acknowledge alarms. It cannot reset a PLC fault or acknowledge an Ignition alarm.</p>
|
|
37
|
+
</dialog>
|
|
38
|
+
<dialog class="engineering-dialog" id="engineering-dialog" aria-labelledby="engineering-title"><div class="engineering-bar"><div><div class="eyebrow">DEVAGENT / ENGINEERING WORKSPACE</div><h2 id="engineering-title">Engineering mapping review</h2><p>Proposed mappings only. Read-only; live source verification and FAT are still pending.</p></div><button type="button" id="engineering-close" class="engineering-close">CLOSE ×</button></div><section class="contracts"><div class="contract-heading"><div><div class="eyebrow">03 / ENGINEERING CONTRACTS</div><h2>Proposed signal and mapping inventory</h2></div><span class="tag warn">ALL LIVE MAPPINGS: NOT VERIFIED</span></div><div class="table-scroll"><table><thead><tr><th>ASSET</th><th>ROLE</th><th>TYPE / UNIT</th><th>OPC UA SOURCE</th><th>QUALIFICATION</th></tr></thead><tbody id="signal-table"></tbody></table></div></section><section class="ops-review" hidden aria-hidden="true"><div class="eyebrow">04 / ISOLATED LAB FAT REPLAY · NO LIVE BINDINGS</div><h2>KPI and alarm logic review</h2><p>Import an independently generated operations receipt for this project's exact tag manifest. The browser only replays evidence; it never reads PLC tags or writes commands. Use <code>ops-demo</code> for synthetic demonstration, or <code>ops-evaluate</code> for approved lab observations.</p><div class="lab-tools"><label class="file-label" for="ops-upload">IMPORT READ-ONLY LAB RECEIPT</label><input id="ops-upload" type="file" accept="application/json,.json"><button id="ops-previous" disabled>◀ PREVIOUS</button><button id="ops-next" disabled>NEXT FRAME ▶</button></div><div id="ops-import-status" role="status">No receipt loaded. All operational KPI values remain N/A.</div><div class="ops-contract-summary" id="ops-contract-summary">Contract is static; Studio/FAT execution pending.</div></section></dialog>
|
|
39
|
+
<footer>DEVAGENT SPATIAL OPERATIONS • PREVIEW IS CONCEPTUAL • THIS IS NOT AN IGNITION EXPORT OR AN AS-BUILT ENGINEERING DRAWING</footer>
|
|
40
|
+
</main>
|
|
41
|
+
</div>
|
|
42
|
+
<script type="application/json" id="project-data">__EMBEDDED_PROJECT__</script>
|
|
43
|
+
<script type="application/json" id="operations-policy">__EMBEDDED_OPERATIONS_POLICY__</script>
|
|
44
|
+
<script type="module" src="./viewer.js"></script>
|
|
45
|
+
</body></html>
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { startThree } from './three_scene.js';
|
|
2
|
+
import { startFallback } from './fallback_scene.js';
|
|
3
|
+
import { installOperations } from './operations_ui.js';
|
|
4
|
+
import { startLabFeed } from './runtime_feed.js';
|
|
5
|
+
import { showDeviceControls } from './equipment_controls.mjs';
|
|
6
|
+
const model=JSON.parse(document.getElementById('project-data').textContent);
|
|
7
|
+
const controlPlan=JSON.parse(document.getElementById('control-plan').textContent);
|
|
8
|
+
const $=id=>document.getElementById(id);
|
|
9
|
+
const app={model,selected:null,floor:'all',scene:null};
|
|
10
|
+
document.body.classList.add('layout-'+model.layout);
|
|
11
|
+
document.body.dataset.palette=model.palette||'r9_cyan';
|
|
12
|
+
function setText(id,text){const node=$(id);if(node)node.textContent=String(text);}
|
|
13
|
+
setText('project-name',model.name);setText('m-assets',model.equipment.length);setText('m-signals',model.signals.length);
|
|
14
|
+
setText('system-subtitle',`${model.industry} • ${model.equipment.length} configured assets • ${model.layout.replaceAll('_',' ')}`);
|
|
15
|
+
setText('viewer-title',model.layout==='process_flow'?'Spatial process flow':model.layout==='machine_detail'?'Equipment-focused spatial view':'Spatial material flow');
|
|
16
|
+
setText('viewer-description',`${model.industry} · Interactive equipment overview`);
|
|
17
|
+
const floorCount=new Set(model.equipment.map(e=>e.floor)).size;
|
|
18
|
+
setText('scene-label',`${floorCount} ${floorCount===1?'FLOOR':'FLOORS'} • ${model.equipment.length} ASSETS`);
|
|
19
|
+
for(const f of [...new Set(model.equipment.map(e=>e.floor))].sort((a,b)=>a-b)){const opt=document.createElement('option');opt.value=String(f);opt.textContent=`FLOOR ${String(f).padStart(2,'0')}`;$('floor').append(opt);}
|
|
20
|
+
if(floorCount===1){$('floor').value=String(model.equipment[0].floor);$('floor').disabled=true;}
|
|
21
|
+
// R9-style floor index; always generated from the customer's actual floors.
|
|
22
|
+
const layerIndex=$('layer-index'),layerButtons=$('layer-buttons');
|
|
23
|
+
if(floorCount===1){layerIndex.hidden=true;}else{
|
|
24
|
+
for(const f of [...new Set(model.equipment.map(e=>e.floor))].sort((a,b)=>b-a)){
|
|
25
|
+
const count=model.equipment.filter(e=>e.floor===f).length;
|
|
26
|
+
const b=document.createElement('button');b.type='button';b.className='layer-option';
|
|
27
|
+
const tag=document.createElement('strong');tag.textContent=String(f).padStart(2,'0');
|
|
28
|
+
const desc=document.createElement('small');desc.textContent=`FLOOR ${f} · ${count} ASSETS`;
|
|
29
|
+
b.append(tag,desc);b.addEventListener('click',()=>{
|
|
30
|
+
$('floor').value=String(f);$('floor').dispatchEvent(new Event('change'));
|
|
31
|
+
});layerButtons.append(b);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function pair(label,value){const div=document.createElement('div');div.className='detail-row';const a=document.createElement('label');a.textContent=label;const b=document.createElement('strong');b.textContent=String(value);div.append(a,b);return div;}
|
|
36
|
+
const jump=$('equipment-jump');
|
|
37
|
+
if(jump){for(const floor of [...new Set(model.equipment.map(e=>e.floor))].sort((a,b)=>a-b)){
|
|
38
|
+
const group=document.createElement('optgroup');group.label=`FLOOR ${String(floor).padStart(2,'0')}`;
|
|
39
|
+
for(const e of model.equipment.filter(e=>e.floor===floor)){
|
|
40
|
+
const opt=document.createElement('option');opt.value=e.id;opt.textContent=`${e.id} · ${e.kind}`;group.append(opt);
|
|
41
|
+
}jump.append(group);
|
|
42
|
+
}jump.addEventListener('change',()=>{if(jump.value)selectAsset(jump.value);});}
|
|
43
|
+
function selectAsset(id){const e=model.equipment.find(x=>x.id===id);if(!e)return;app.selected=id;if(jump)jump.value=id;setText('selected-id',e.id);setText('selected-name',e.name);setText('selected-type',e.kind.toUpperCase());$('asset-meta').replaceChildren(pair('ZONE',e.zone||'—'),pair('FLOOR',e.floor),pair('STATUS','UNKNOWN'),pair('DATA QUALITY','UNKNOWN'));
|
|
44
|
+
const sig=model.signals.filter(s=>s.asset_id===id);if($('selected-parameters')){
|
|
45
|
+
const rows=[];
|
|
46
|
+
const add=(name,value)=>rows.push(pair(name,value));
|
|
47
|
+
if(['conveyor','sorter','spiral'].includes(e.kind)){
|
|
48
|
+
add('RUN FEEDBACK','SOURCE UNAVAILABLE');add('MOTOR FAULT','SOURCE UNAVAILABLE');
|
|
49
|
+
add('PE IN','NOT MAPPED');add('PE OUT','NOT MAPPED');
|
|
50
|
+
add('BELT SPEED (m/s)','NOT MAPPED');
|
|
51
|
+
}else if(e.kind==='photoeye'){
|
|
52
|
+
add('PE STATE','SOURCE UNAVAILABLE');add('PE COUNT','SOURCE UNAVAILABLE');
|
|
53
|
+
}else if(e.kind==='vfd'){
|
|
54
|
+
add('FREQUENCY (Hz)','SOURCE UNAVAILABLE');add('BELT SPEED','NOT MAPPED');
|
|
55
|
+
}else if(e.kind==='scanner'){
|
|
56
|
+
add('LAST SCAN','SOURCE UNAVAILABLE');add('NO_READ COUNT','SOURCE UNAVAILABLE');
|
|
57
|
+
}
|
|
58
|
+
const knownLabels=new Set(rows.map(r=>r.firstElementChild.textContent));
|
|
59
|
+
for(const s of sig){const label=s.role.replaceAll('_',' ').toUpperCase()+(s.unit?' ('+s.unit+')':'');
|
|
60
|
+
if(!knownLabels.has(label)){add(label,'UNKNOWN · SOURCE NOT VERIFIED');knownLabels.add(label);}}
|
|
61
|
+
$('selected-parameters').replaceChildren(...rows);
|
|
62
|
+
}
|
|
63
|
+
if(app.scene?.select)app.scene.select(id);
|
|
64
|
+
showDeviceControls(controlPlan,e,$('device-controls'));}
|
|
65
|
+
app.selectAsset=selectAsset;
|
|
66
|
+
const tbody=$('signal-table');if(tbody)for(const s of model.signals){const tr=document.createElement('tr');for(const v of [s.asset_id,s.role,`${s.datatype}${s.unit?' / '+s.unit:''}`,`${s.source.namespace_uri} · ${s.source.node_id}`,'NOT VERIFIED']){const td=document.createElement('td');td.textContent=v;if(v==='NOT VERIFIED')td.className='warning-text';tr.append(td);}tbody.append(tr);}
|
|
67
|
+
if(tbody&&!model.signals.length){const tr=document.createElement('tr');const td=document.createElement('td');td.colSpan=5;td.textContent='No signals provided. Add an OPC UA mapping contract to enable mapping review.';tr.append(td);tbody.append(tr);}
|
|
68
|
+
function attachControls(){for(const [name,fn] of Object.entries({ 'view-fit':()=>app.scene?.overview?.()||app.scene?.view('iso'),'view-top':()=>app.scene?.view('top'),'view-side':()=>app.scene?.view('side'),'view-reset':()=>app.scene?.overview?.()||app.scene?.view('iso')}))$(name).addEventListener('click',()=>{fn();document.querySelectorAll('.viewer-toolbar button').forEach(x=>x.classList.remove('active'));$(name).classList.add('active');});$('floor').addEventListener('change',e=>{app.floor=e.target.value;app.scene?.floor(app.floor);});}
|
|
69
|
+
attachControls();
|
|
70
|
+
// Engineering diagnostics belong only to the separate Studio Test Workspace.
|
|
71
|
+
try{app.scene=await startThree(model,$('scene-layer'),selectAsset);setText('scene-engine','3D VIEW');}
|
|
72
|
+
catch(err){console.warn('Three.js local engine unavailable. Schematic fallback:',err);app.scene=startFallback(model,$('scene-layer'),selectAsset);setText('scene-engine','3D NOT AVAILABLE · SCHEMATIC VIEW');}
|
|
73
|
+
if(model.equipment[0])selectAsset(model.equipment[0].id);
|
|
74
|
+
const operations=installOperations({model,selectAsset,scene:()=>app.scene,policy:JSON.parse($('operations-policy').textContent)});
|
|
75
|
+
const projectId=location.pathname.match(/^\/projects\/([a-z0-9-]+)\/viewer\/index\.html$/)?.[1];
|
|
76
|
+
// Existing buttons remain locked for every non-synthetic source.
|
|
77
|
+
function connectSyntheticOperator(pid){
|
|
78
|
+
const names=['start','stop','reset','ack'];const buttons=Object.fromEntries(names.map(x=>[x,$('op-cmd-'+x)]));
|
|
79
|
+
const badge=$('operator-authority');let busy=false;
|
|
80
|
+
const lock=()=>{for(const b of Object.values(buttons)){b.disabled=true;b.setAttribute('aria-disabled','true');}
|
|
81
|
+
badge.textContent='🔒 CONTROL LOCKED';badge.classList.remove('sim-linked');};
|
|
82
|
+
const sync=result=>{
|
|
83
|
+
if(busy)return;
|
|
84
|
+
const sim=result?.status==='PASS_SYNTHETIC_PREVIEW_ONLY'&&result?.source==='IN_MEMORY_SYNTHETIC_NOT_OPC';
|
|
85
|
+
if(!sim){lock();return;}
|
|
86
|
+
const fault=!!result.fault_asset,paused=!!result.paused;
|
|
87
|
+
const enabled={start:paused&&!fault,stop:!paused,reset:paused,ack:fault&&!result.acknowledged};
|
|
88
|
+
for(const n of names){buttons[n].disabled=!enabled[n];buttons[n].setAttribute('aria-disabled',String(!enabled[n]));}
|
|
89
|
+
badge.textContent='SIMULATOR LINKED · NO PLC';badge.classList.add('sim-linked');
|
|
90
|
+
};
|
|
91
|
+
for(const n of names)buttons[n].addEventListener('click',async()=>{
|
|
92
|
+
if(buttons[n].disabled||busy)return;
|
|
93
|
+
if(n==='reset'&&!confirm('Reset SYNTHETIC simulation? This clears demo fault and resets parcel position, not a PLC.'))return;
|
|
94
|
+
busy=true;for(const b of Object.values(buttons))b.disabled=true;
|
|
95
|
+
try{
|
|
96
|
+
const response=await fetch('/api/preview-sim/'+encodeURIComponent(pid)+'/operator/'+n,{method:'POST',
|
|
97
|
+
headers:{'Content-Type':'application/json','X-DevAgent-Operator':'synthetic-session-v1'},
|
|
98
|
+
body:JSON.stringify({confirm:'SYNTHETIC_OPERATOR_ONLY'})});
|
|
99
|
+
const data=await response.json();if(!response.ok)throw Error(data.reason||'OPERATOR_SIMULATION_HOLD');
|
|
100
|
+
badge.textContent='SIM '+n.toUpperCase()+' ACCEPTED · NOT PLC';
|
|
101
|
+
}catch(e){badge.textContent='SIM HOLD · '+String(e.message||e).slice(0,65);}
|
|
102
|
+
finally{busy=false;setTimeout(()=>{if(!busy)startOperatorStatus();},250);}
|
|
103
|
+
});
|
|
104
|
+
async function startOperatorStatus(){
|
|
105
|
+
try{const r=await fetch('/api/live-lab/'+encodeURIComponent(pid)+'/readings',{cache:'no-store'});
|
|
106
|
+
const d=await r.json();sync(d);}catch(_){lock();}
|
|
107
|
+
}
|
|
108
|
+
lock();return sync;
|
|
109
|
+
}
|
|
110
|
+
if(projectId){const operatorSync=connectSyntheticOperator(projectId);
|
|
111
|
+
startLabFeed({operations,projectId,onReading:operatorSync});}
|
|
112
|
+
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "devagent_spatial_v1",
|
|
3
|
+
"status": "LOCKED_R9_INSPIRED_LAYOUT_PALETTE_ONLY_V043",
|
|
4
|
+
"inspiration": "User-approved R9 R5 warehouse command-center screenshot, not a byte-copy of its Ignition project",
|
|
5
|
+
"palette": {
|
|
6
|
+
"background": "#07131f",
|
|
7
|
+
"panels": "#0e2638",
|
|
8
|
+
"deep_panel": "#0b1e2f",
|
|
9
|
+
"border": "#294b61",
|
|
10
|
+
"accent": "#58c1dc",
|
|
11
|
+
"text": "#ecf5ff",
|
|
12
|
+
"muted": "#82a6b9",
|
|
13
|
+
"warning": "#e6bd70"
|
|
14
|
+
},
|
|
15
|
+
"principles": [
|
|
16
|
+
"Spatial 3D-first",
|
|
17
|
+
"Right-side equipment inspector",
|
|
18
|
+
"Legible KPI cards",
|
|
19
|
+
"Obvious simulated/unverified markers",
|
|
20
|
+
"Responsive no clipped typography",
|
|
21
|
+
"No deceptive live values",
|
|
22
|
+
"Controls default disabled"
|
|
23
|
+
],
|
|
24
|
+
"layout_archetypes": [
|
|
25
|
+
"spatial_overview",
|
|
26
|
+
"process_flow",
|
|
27
|
+
"machine_detail",
|
|
28
|
+
"multi_zone"
|
|
29
|
+
],
|
|
30
|
+
"sizing": {
|
|
31
|
+
"viewport_min_height_px": 510,
|
|
32
|
+
"inspector_desktop_width_px": 274,
|
|
33
|
+
"minimum_action_height_px": 42
|
|
34
|
+
},
|
|
35
|
+
"golden_reference_status": "R9_R5_VISUAL_REFERENCE_ONLY_NATIVE_IGNITION_RESOURCE_NOT_ATTACHED",
|
|
36
|
+
"design_standard": "DevAgent Spatial Operations V1 / R9 reference principles",
|
|
37
|
+
"palette_rules": {
|
|
38
|
+
"default": "r9_cyan",
|
|
39
|
+
"allowed": [
|
|
40
|
+
"r9_cyan",
|
|
41
|
+
"steel_blue",
|
|
42
|
+
"teal",
|
|
43
|
+
"warm_amber"
|
|
44
|
+
],
|
|
45
|
+
"allowed_changes": [
|
|
46
|
+
"brand background",
|
|
47
|
+
"decorative panel tones",
|
|
48
|
+
"decorative accent",
|
|
49
|
+
"decorative outlines",
|
|
50
|
+
"conceptual scene lighting tint"
|
|
51
|
+
],
|
|
52
|
+
"immutable": [
|
|
53
|
+
"font family",
|
|
54
|
+
"type hierarchy",
|
|
55
|
+
"KPI grid",
|
|
56
|
+
"responsive panel hierarchy",
|
|
57
|
+
"3D-dominant viewport",
|
|
58
|
+
"right-side inspector on desktop",
|
|
59
|
+
"equipment selection behavior",
|
|
60
|
+
"engineering review separation",
|
|
61
|
+
"equipment topology",
|
|
62
|
+
"OPC identity",
|
|
63
|
+
"FAT state",
|
|
64
|
+
"disabled controls",
|
|
65
|
+
"semantic running/fault/unknown/warning interpretation"
|
|
66
|
+
],
|
|
67
|
+
"safety_semantics": {
|
|
68
|
+
"running": "label and verified feedback required",
|
|
69
|
+
"fault": "label and verified alarm required",
|
|
70
|
+
"unknown": "unknown quality explicitly indicated",
|
|
71
|
+
"preview": "no live machine-state claim",
|
|
72
|
+
"control_authority": "read_only_without_approval"
|
|
73
|
+
},
|
|
74
|
+
"color_contrast": "fixed dark backgrounds; light text; palette choices pre-reviewed for readability; browser accessibility verification pending"
|
|
75
|
+
},
|
|
76
|
+
"palettes": {
|
|
77
|
+
"r9_cyan": {
|
|
78
|
+
"name": "R9 Navy / Cyan",
|
|
79
|
+
"background": "#07131f",
|
|
80
|
+
"panel": "#0e2638",
|
|
81
|
+
"deep": "#0b1e2f",
|
|
82
|
+
"border": "#294b61",
|
|
83
|
+
"accent": "#58c1dc",
|
|
84
|
+
"muted": "#82a6b9",
|
|
85
|
+
"scene_bg": "#071827",
|
|
86
|
+
"control_active": "#18536c",
|
|
87
|
+
"stage_inner": "#12384c",
|
|
88
|
+
"stage_outer": "#081a2a"
|
|
89
|
+
},
|
|
90
|
+
"steel_blue": {
|
|
91
|
+
"name": "Graphite / Blue",
|
|
92
|
+
"background": "#0a121e",
|
|
93
|
+
"panel": "#152638",
|
|
94
|
+
"deep": "#0d1b2b",
|
|
95
|
+
"border": "#365573",
|
|
96
|
+
"accent": "#85c6ff",
|
|
97
|
+
"muted": "#9fb7cb",
|
|
98
|
+
"scene_bg": "#0a1727",
|
|
99
|
+
"control_active": "#224d7a",
|
|
100
|
+
"stage_inner": "#193750",
|
|
101
|
+
"stage_outer": "#081522"
|
|
102
|
+
},
|
|
103
|
+
"teal": {
|
|
104
|
+
"name": "Deep Teal / Mint",
|
|
105
|
+
"background": "#07191d",
|
|
106
|
+
"panel": "#102c31",
|
|
107
|
+
"deep": "#092328",
|
|
108
|
+
"border": "#35656a",
|
|
109
|
+
"accent": "#75dfce",
|
|
110
|
+
"muted": "#9abcc0",
|
|
111
|
+
"scene_bg": "#071c23",
|
|
112
|
+
"control_active": "#1a6467",
|
|
113
|
+
"stage_inner": "#164448",
|
|
114
|
+
"stage_outer": "#061a22"
|
|
115
|
+
},
|
|
116
|
+
"warm_amber": {
|
|
117
|
+
"name": "Graphite / Amber",
|
|
118
|
+
"background": "#17150f",
|
|
119
|
+
"panel": "#2b261b",
|
|
120
|
+
"deep": "#201d17",
|
|
121
|
+
"border": "#675c45",
|
|
122
|
+
"accent": "#f5c77b",
|
|
123
|
+
"muted": "#b8aa90",
|
|
124
|
+
"scene_bg": "#191c21",
|
|
125
|
+
"control_active": "#75602d",
|
|
126
|
+
"stage_inner": "#333a3e",
|
|
127
|
+
"stage_outer": "#151b23"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "devagent.device_command_contract.v078",
|
|
3
|
+
"model_sha256": "816c63dd2a7f59229474e5124bfb58a5b538d400b98231f55aa4b2346d947a0e",
|
|
4
|
+
"scope": "ISOLATED_FAKE_OPCUA_ONLY",
|
|
5
|
+
"asset_id": "CV101",
|
|
6
|
+
"kind": "conveyor",
|
|
7
|
+
"actions": [
|
|
8
|
+
"START",
|
|
9
|
+
"STOP",
|
|
10
|
+
"RESET"
|
|
11
|
+
],
|
|
12
|
+
"tag_paths": {
|
|
13
|
+
"request": "[DevAgentLabCommands]VirtualPLC/CV101/CommandRequest",
|
|
14
|
+
"ack_id": "[DevAgentLabCommands]VirtualPLC/CV101/AckId",
|
|
15
|
+
"result": "[DevAgentLabCommands]VirtualPLC/CV101/CommandResult",
|
|
16
|
+
"state": "[DevAgentLabCommands]VirtualPLC/CV101/State",
|
|
17
|
+
"run_feedback": "[DevAgentLabCommands]VirtualPLC/CV101/RunFeedback",
|
|
18
|
+
"fault": "[DevAgentLabCommands]VirtualPLC/CV101/Fault",
|
|
19
|
+
"permissive": "[DevAgentLabCommands]VirtualPLC/CV101/Permissive"
|
|
20
|
+
},
|
|
21
|
+
"simulated_namespace_uri": "urn:devagent:isolated:virtual-plc:v078:816c63dd2a7f5922",
|
|
22
|
+
"engineer": "",
|
|
23
|
+
"approval": "PENDING_LAB_REVIEW",
|
|
24
|
+
"timeout_ms": 2500,
|
|
25
|
+
"role": "Authenticated/Roles/DevAgentLabOperator",
|
|
26
|
+
"command_identity": "LAB_SYNTHETIC_NOT_CUSTOMER_TAG",
|
|
27
|
+
"production_mapping": null,
|
|
28
|
+
"production_authority": "NONE",
|
|
29
|
+
"note": "Explicit lab-only contract. No customer NodeIds or field authorization."
|
|
30
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"name": "Warehouse Line A - CV101 FAT Demo",
|
|
4
|
+
"industry": "Warehouse Automation",
|
|
5
|
+
"theme": "devagent_spatial_v1",
|
|
6
|
+
"palette": "r9_cyan",
|
|
7
|
+
"layout": "spatial_overview",
|
|
8
|
+
"description": "Training scenario for one receiving line: CV101 -> CV102 -> CV103, with PE101, PE102, VFD101 and SCN101. All OPC UA NodeIds below are DEMO PLACEHOLDERS, NOT VERIFIED PLC SOURCES. This build is for conceptual HMI and synthetic FAT only.",
|
|
9
|
+
"equipment": [
|
|
10
|
+
{
|
|
11
|
+
"id": "CV101",
|
|
12
|
+
"name": "Receiving Conveyor",
|
|
13
|
+
"kind": "conveyor",
|
|
14
|
+
"floor": 1,
|
|
15
|
+
"zone": "INFEED",
|
|
16
|
+
"position": {
|
|
17
|
+
"x": 0.0,
|
|
18
|
+
"y": 0.0,
|
|
19
|
+
"z": 0.0
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"id": "CV102",
|
|
24
|
+
"name": "Transfer Conveyor",
|
|
25
|
+
"kind": "conveyor",
|
|
26
|
+
"floor": 1,
|
|
27
|
+
"zone": "TRANSFER",
|
|
28
|
+
"position": {
|
|
29
|
+
"x": 6.0,
|
|
30
|
+
"y": 0.0,
|
|
31
|
+
"z": 0.0
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "CV103",
|
|
36
|
+
"name": "Outfeed Conveyor",
|
|
37
|
+
"kind": "conveyor",
|
|
38
|
+
"floor": 1,
|
|
39
|
+
"zone": "OUTFEED",
|
|
40
|
+
"position": {
|
|
41
|
+
"x": 12.0,
|
|
42
|
+
"y": 0.0,
|
|
43
|
+
"z": 0.0
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "PE101",
|
|
48
|
+
"name": "Receiving Photoeye",
|
|
49
|
+
"kind": "photoeye",
|
|
50
|
+
"floor": 1,
|
|
51
|
+
"zone": "INFEED",
|
|
52
|
+
"position": {
|
|
53
|
+
"x": 1.0,
|
|
54
|
+
"y": 0.0,
|
|
55
|
+
"z": 1.3
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"id": "PE102",
|
|
60
|
+
"name": "Outfeed Photoeye",
|
|
61
|
+
"kind": "photoeye",
|
|
62
|
+
"floor": 1,
|
|
63
|
+
"zone": "OUTFEED",
|
|
64
|
+
"position": {
|
|
65
|
+
"x": 13.0,
|
|
66
|
+
"y": 0.0,
|
|
67
|
+
"z": 1.3
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"id": "VFD101",
|
|
72
|
+
"name": "CV101 Drive",
|
|
73
|
+
"kind": "vfd",
|
|
74
|
+
"floor": 1,
|
|
75
|
+
"zone": "INFEED",
|
|
76
|
+
"position": {
|
|
77
|
+
"x": 0.0,
|
|
78
|
+
"y": 0.0,
|
|
79
|
+
"z": 2.5
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
"id": "SCN101",
|
|
84
|
+
"name": "Barcode Scanner",
|
|
85
|
+
"kind": "scanner",
|
|
86
|
+
"floor": 1,
|
|
87
|
+
"zone": "TRANSFER",
|
|
88
|
+
"position": {
|
|
89
|
+
"x": 7.0,
|
|
90
|
+
"y": 0.0,
|
|
91
|
+
"z": 2.0
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
],
|
|
95
|
+
"connections": [
|
|
96
|
+
{
|
|
97
|
+
"from": "CV101",
|
|
98
|
+
"to": "CV102"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"from": "CV102",
|
|
102
|
+
"to": "CV103"
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"signals": [
|
|
106
|
+
{
|
|
107
|
+
"id": "S_CV101_RUN",
|
|
108
|
+
"asset_id": "CV101",
|
|
109
|
+
"role": "run_feedback",
|
|
110
|
+
"datatype": "Boolean",
|
|
111
|
+
"unit": "",
|
|
112
|
+
"polarity": "active_high",
|
|
113
|
+
"source": {
|
|
114
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
115
|
+
"node_id": "Demo/CV101/RunFeedback"
|
|
116
|
+
},
|
|
117
|
+
"write_authorized": false
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"id": "S_CV101_FAULT",
|
|
121
|
+
"asset_id": "CV101",
|
|
122
|
+
"role": "fault",
|
|
123
|
+
"datatype": "Boolean",
|
|
124
|
+
"unit": "",
|
|
125
|
+
"polarity": "active_high",
|
|
126
|
+
"source": {
|
|
127
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
128
|
+
"node_id": "Demo/CV101/Fault"
|
|
129
|
+
},
|
|
130
|
+
"write_authorized": false
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "S_CV102_RUN",
|
|
134
|
+
"asset_id": "CV102",
|
|
135
|
+
"role": "run_feedback",
|
|
136
|
+
"datatype": "Boolean",
|
|
137
|
+
"unit": "",
|
|
138
|
+
"polarity": "active_high",
|
|
139
|
+
"source": {
|
|
140
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
141
|
+
"node_id": "Demo/CV102/RunFeedback"
|
|
142
|
+
},
|
|
143
|
+
"write_authorized": false
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"id": "S_CV102_FAULT",
|
|
147
|
+
"asset_id": "CV102",
|
|
148
|
+
"role": "fault",
|
|
149
|
+
"datatype": "Boolean",
|
|
150
|
+
"unit": "",
|
|
151
|
+
"polarity": "active_high",
|
|
152
|
+
"source": {
|
|
153
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
154
|
+
"node_id": "Demo/CV102/Fault"
|
|
155
|
+
},
|
|
156
|
+
"write_authorized": false
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"id": "S_CV103_RUN",
|
|
160
|
+
"asset_id": "CV103",
|
|
161
|
+
"role": "run_feedback",
|
|
162
|
+
"datatype": "Boolean",
|
|
163
|
+
"unit": "",
|
|
164
|
+
"polarity": "active_high",
|
|
165
|
+
"source": {
|
|
166
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
167
|
+
"node_id": "Demo/CV103/RunFeedback"
|
|
168
|
+
},
|
|
169
|
+
"write_authorized": false
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"id": "S_PE101_BLOCKED",
|
|
173
|
+
"asset_id": "PE101",
|
|
174
|
+
"role": "photoeye_blocked",
|
|
175
|
+
"datatype": "Boolean",
|
|
176
|
+
"unit": "",
|
|
177
|
+
"polarity": "active_high",
|
|
178
|
+
"source": {
|
|
179
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
180
|
+
"node_id": "Demo/PE101/Blocked"
|
|
181
|
+
},
|
|
182
|
+
"write_authorized": false
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"id": "S_PE102_BLOCKED",
|
|
186
|
+
"asset_id": "PE102",
|
|
187
|
+
"role": "photoeye_blocked",
|
|
188
|
+
"datatype": "Boolean",
|
|
189
|
+
"unit": "",
|
|
190
|
+
"polarity": "active_high",
|
|
191
|
+
"source": {
|
|
192
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
193
|
+
"node_id": "Demo/PE102/Blocked"
|
|
194
|
+
},
|
|
195
|
+
"write_authorized": false
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"id": "S_VFD101_FREQ",
|
|
199
|
+
"asset_id": "VFD101",
|
|
200
|
+
"role": "vfd_frequency",
|
|
201
|
+
"datatype": "Double",
|
|
202
|
+
"unit": "Hz",
|
|
203
|
+
"polarity": "",
|
|
204
|
+
"source": {
|
|
205
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
206
|
+
"node_id": "Demo/VFD101/Frequency"
|
|
207
|
+
},
|
|
208
|
+
"write_authorized": false
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
"id": "S_VFD101_FAULT",
|
|
212
|
+
"asset_id": "VFD101",
|
|
213
|
+
"role": "fault",
|
|
214
|
+
"datatype": "Boolean",
|
|
215
|
+
"unit": "",
|
|
216
|
+
"polarity": "active_high",
|
|
217
|
+
"source": {
|
|
218
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
219
|
+
"node_id": "Demo/VFD101/Fault"
|
|
220
|
+
},
|
|
221
|
+
"write_authorized": false
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"id": "S_SCN101_RESULT",
|
|
225
|
+
"asset_id": "SCN101",
|
|
226
|
+
"role": "scanner_result",
|
|
227
|
+
"datatype": "String",
|
|
228
|
+
"unit": "",
|
|
229
|
+
"polarity": "",
|
|
230
|
+
"source": {
|
|
231
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
232
|
+
"node_id": "Demo/SCN101/Result"
|
|
233
|
+
},
|
|
234
|
+
"write_authorized": false
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"id": "S_SCN101_NOREAD",
|
|
238
|
+
"asset_id": "SCN101",
|
|
239
|
+
"role": "no_read_count",
|
|
240
|
+
"datatype": "Int32",
|
|
241
|
+
"unit": "count",
|
|
242
|
+
"polarity": "",
|
|
243
|
+
"source": {
|
|
244
|
+
"namespace_uri": "urn:devagent:training:synthetic-warehouse:opcua",
|
|
245
|
+
"node_id": "Demo/SCN101/NoReadCount"
|
|
246
|
+
},
|
|
247
|
+
"write_authorized": false
|
|
248
|
+
}
|
|
249
|
+
],
|
|
250
|
+
"requirements": [
|
|
251
|
+
{
|
|
252
|
+
"id": "R001",
|
|
253
|
+
"text": "Operator must be able to click CV101 and see run feedback and fault status."
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"id": "R002",
|
|
257
|
+
"text": "Operator must be able to inspect photoeye PE101 Blocked/Clear status."
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"id": "R003",
|
|
261
|
+
"text": "Operator must be able to inspect VFD101 actual frequency in Hz if mapped."
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"id": "R004",
|
|
265
|
+
"text": "Unverified mappings and bad data quality must not be displayed as confirmed PLC values."
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"id": "R005",
|
|
269
|
+
"text": "Synthetic parcel test must not issue any PLC or OPC UA write commands."
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
}
|