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,36 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
root=Path(__file__).parent
|
|
4
|
+
warehouse_assets=[
|
|
5
|
+
('INFEED01','Receiving infeed','conveyor',1,-18,0,0),('CV101','Line conveyor 101','conveyor',1,-11,0,0),('DWS01','Dimension-weight-scan','scanner',1,-7,0,-2),('PE101','Infeed photoeye','photoeye',1,-10,0,2),('CV102','Main feed conveyor','conveyor',1,-4,0,0),('SPIRAL01','Spiral ascent 1','spiral',1,2,0,2),('CV201','Sorter infeed','conveyor',2,6,8,0),('SORT201','Crossbelt sorter','sorter',2,13,8,1),('CV202','Exit chute left','conveyor',2,20,8,-5),('CV203','Exit chute right','conveyor',2,20,8,6),('PE201','Sorter entry photoeye','photoeye',2,10,8,-2),('SCN201','Destination scanner','scanner',2,16,8,-2),('SPIRAL02','Spiral ascent 2','spiral',2,24,8,2),('CV301','Upper receiving conveyor','conveyor',3,22,16,0),('CV302','Upper distribution','conveyor',3,15,16,-2),('CV303','Outbound line','conveyor',3,8,16,-6),('PE301','Outbound photoeye','photoeye',3,5,16,-5),('VFD101','Conveyor motor drive','vfd',1,-13,0,4),('VFD201','Sorter motor drive','vfd',2,11,8,5),('VFD301','Outbound drive','vfd',3,12,16,3),]
|
|
6
|
+
equipment=[{'id':i,'name':name,'kind':kind,'floor':f,'zone':f'ZONE-F{f}', 'position':{'x':x,'y':y,'z':z}} for i,name,kind,f,x,y,z in warehouse_assets]
|
|
7
|
+
links=[('INFEED01','CV101'),('CV101','CV102'),('CV102','SPIRAL01'),('SPIRAL01','CV201'),('CV201','SORT201'),('SORT201','CV202'),('SORT201','CV203'),('CV203','SPIRAL02'),('SPIRAL02','CV301'),('CV301','CV302'),('CV302','CV303')]
|
|
8
|
+
signals=[]
|
|
9
|
+
def add(eid, role, dt, suffix, unit='',polarity=''):
|
|
10
|
+
signals.append({'id':f'S_{eid}_{role}'.upper(),'asset_id':eid,'role':role,'datatype':dt,'unit':unit,'polarity':polarity,
|
|
11
|
+
'source':{'namespace_uri':'urn:customer:warehouse:opc:preview','node_id':f'Line01/{eid}/{suffix}'}})
|
|
12
|
+
for e in ['INFEED01','CV101','CV102','CV201','SORT201','CV202','CV203','CV301','CV302','CV303']:
|
|
13
|
+
add(e,'run_feedback','Boolean','RunFeedback',polarity='active_high')
|
|
14
|
+
add(e,'fault','Boolean','MotorFault',polarity='active_high')
|
|
15
|
+
for e in ['PE101','PE201','PE301']:
|
|
16
|
+
add(e,'photoeye_blocked','Boolean','Blocked',polarity='active_high')
|
|
17
|
+
add(e,'photoeye_count','Int32','EdgeCount',unit='count')
|
|
18
|
+
for e in ['DWS01','SCN201']:
|
|
19
|
+
add(e,'scanner_result','String','LastResult')
|
|
20
|
+
add(e,'no_read_count','Int32','NoReadCount',unit='count')
|
|
21
|
+
for e in ['VFD101','VFD201','VFD301']:
|
|
22
|
+
add(e,'vfd_frequency','Double','ActualHz',unit='Hz')
|
|
23
|
+
req=[{'id':'REQ001','text':'Each conveyor must show verified run feedback and fault state.'},{'id':'REQ002','text':'Scanner NO_READ events must be traceable to a specific scanner.'},{'id':'REQ003','text':'Three-floor topology and spiral transfer must be reviewed against approved drawings.'}]
|
|
24
|
+
warehouse={'schema_version':1,'name':'North Distribution Warehouse','industry':'Warehouse automation', 'theme':'devagent_spatial_v1','layout':'spatial_overview','description':'Three-floor material flow with sortation, scanner stations and vertical spirals. Concept reference; coordinates require approval.','equipment':equipment,'connections':[{'from':a,'to':b} for a,b in links], 'signals':signals,'requirements':req}
|
|
25
|
+
(root/'warehouse.json').write_text(json.dumps(warehouse,indent=2)+'\n')
|
|
26
|
+
water_assets=[('TANK01','Raw-water holding tank','tank',1,-15,0,-3),('PUMP01','Lift pump 1','pump',1,-9,0,-3),('VALVE01','Isolation valve','valve',1,-5,0,-3),('FILTER01','Primary filter vessel','tank',1,0,0,-3),('PUMP02','Treatment feed pump','pump',1,5,0,-3),('TANK02','Clear-water storage tank','tank',1,12,0,-3),('VFD01','Lift pump frequency drive','vfd',1,-9,0,2),('VFD02','Treatment pump drive','vfd',1,5,0,2),('VALVE02','Outlet valve','valve',1,16,0,-3)]
|
|
27
|
+
eq2=[{'id':i,'name':n,'kind':k,'floor':f,'zone':'WATER-PROCESS', 'position':{'x':x,'y':y,'z':z}} for i,n,k,f,x,y,z in water_assets]
|
|
28
|
+
s2=[]
|
|
29
|
+
def add2(id,role,dt,unit='',polarity=''):
|
|
30
|
+
s2.append({'id':f'S_{id}_{role}'.upper(),'asset_id':id,'role':role,'datatype':dt,'unit':unit,'polarity':polarity,'source':{'namespace_uri':'urn:customer:waterplant:opc:preview','node_id':f'WaterProcess/{id}/{role}'}})
|
|
31
|
+
for id in ('PUMP01','PUMP02'):add2(id,'run_feedback','Boolean',polarity='active_high');add2(id,'fault','Boolean',polarity='active_high')
|
|
32
|
+
for id in ('TANK01','TANK02','FILTER01'):add2(id,'tank_level','Double',unit='%')
|
|
33
|
+
for id in ('VFD01','VFD02'):add2(id,'vfd_frequency','Double',unit='Hz')
|
|
34
|
+
for id in ('VALVE01','VALVE02'):add2(id,'valve_open','Boolean')
|
|
35
|
+
water={'schema_version':1,'name':'West Water Process','industry':'Water treatment','theme':'devagent_spatial_v1','layout':'process_flow','description':'Pump, filtration and storage process. Concept representation — not a validated P&ID.', 'equipment':eq2,'connections':[{'from':a,'to':b} for a,b in zip(['TANK01','PUMP01','VALVE01','FILTER01','PUMP02','TANK02'],['PUMP01','VALVE01','FILTER01','PUMP02','TANK02','VALVE02'])], 'signals':s2,'requirements':[{'id':'REQ101','text':'Pump run feedback must be independently verified from OPC UA.'},{'id':'REQ102','text':'Tank level units and range must be verified against source configuration.'}]}
|
|
36
|
+
(root/'water.json').write_text(json.dumps(water,indent=2)+'\n')
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema_version": 1,
|
|
3
|
+
"name": "Smart Warehouse Single Floor",
|
|
4
|
+
"industry": "Warehouse Automation",
|
|
5
|
+
"theme": "devagent_spatial_v1",
|
|
6
|
+
"layout": "spatial_overview",
|
|
7
|
+
"description": "Single-floor parcel sorting. Geometry conceptual; OPC tags are examples only.",
|
|
8
|
+
"equipment": [
|
|
9
|
+
{
|
|
10
|
+
"id": "CV101",
|
|
11
|
+
"name": "Receiving Conveyor",
|
|
12
|
+
"kind": "conveyor",
|
|
13
|
+
"floor": 1,
|
|
14
|
+
"zone": "ZONE_F1",
|
|
15
|
+
"position": {
|
|
16
|
+
"x": -12.0,
|
|
17
|
+
"y": 0.0,
|
|
18
|
+
"z": 0.0
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "CV102",
|
|
23
|
+
"name": "Scanner Infeed",
|
|
24
|
+
"kind": "conveyor",
|
|
25
|
+
"floor": 1,
|
|
26
|
+
"zone": "ZONE_F1",
|
|
27
|
+
"position": {
|
|
28
|
+
"x": -7.0,
|
|
29
|
+
"y": 0.0,
|
|
30
|
+
"z": 0.0
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "SORT101",
|
|
35
|
+
"name": "Parcel Sorter",
|
|
36
|
+
"kind": "sorter",
|
|
37
|
+
"floor": 1,
|
|
38
|
+
"zone": "ZONE_F1",
|
|
39
|
+
"position": {
|
|
40
|
+
"x": -2.0,
|
|
41
|
+
"y": 0.0,
|
|
42
|
+
"z": 0.0
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"id": "CV103",
|
|
47
|
+
"name": "Shipping Branch A",
|
|
48
|
+
"kind": "conveyor",
|
|
49
|
+
"floor": 1,
|
|
50
|
+
"zone": "ZONE_F1",
|
|
51
|
+
"position": {
|
|
52
|
+
"x": 4.0,
|
|
53
|
+
"y": 0.0,
|
|
54
|
+
"z": -4.0
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"id": "CV104",
|
|
59
|
+
"name": "Shipping Branch B",
|
|
60
|
+
"kind": "conveyor",
|
|
61
|
+
"floor": 1,
|
|
62
|
+
"zone": "ZONE_F1",
|
|
63
|
+
"position": {
|
|
64
|
+
"x": 4.0,
|
|
65
|
+
"y": 0.0,
|
|
66
|
+
"z": 4.0
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"id": "CV105",
|
|
71
|
+
"name": "Outbound A",
|
|
72
|
+
"kind": "conveyor",
|
|
73
|
+
"floor": 1,
|
|
74
|
+
"zone": "ZONE_F1",
|
|
75
|
+
"position": {
|
|
76
|
+
"x": 10.0,
|
|
77
|
+
"y": 0.0,
|
|
78
|
+
"z": -4.0
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "CV106",
|
|
83
|
+
"name": "Outbound B",
|
|
84
|
+
"kind": "conveyor",
|
|
85
|
+
"floor": 1,
|
|
86
|
+
"zone": "ZONE_F1",
|
|
87
|
+
"position": {
|
|
88
|
+
"x": 10.0,
|
|
89
|
+
"y": 0.0,
|
|
90
|
+
"z": 4.0
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "PE101",
|
|
95
|
+
"name": "Receiving Photoeye",
|
|
96
|
+
"kind": "photoeye",
|
|
97
|
+
"floor": 1,
|
|
98
|
+
"zone": "ZONE_F1",
|
|
99
|
+
"position": {
|
|
100
|
+
"x": -10.0,
|
|
101
|
+
"y": 0.0,
|
|
102
|
+
"z": 2.0
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"id": "PE102",
|
|
107
|
+
"name": "Sorter Entry Photoeye",
|
|
108
|
+
"kind": "photoeye",
|
|
109
|
+
"floor": 1,
|
|
110
|
+
"zone": "ZONE_F1",
|
|
111
|
+
"position": {
|
|
112
|
+
"x": -3.0,
|
|
113
|
+
"y": 0.0,
|
|
114
|
+
"z": 2.0
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"id": "SCN101",
|
|
119
|
+
"name": "Barcode Scanner",
|
|
120
|
+
"kind": "scanner",
|
|
121
|
+
"floor": 1,
|
|
122
|
+
"zone": "ZONE_F1",
|
|
123
|
+
"position": {
|
|
124
|
+
"x": -6.0,
|
|
125
|
+
"y": 0.0,
|
|
126
|
+
"z": -2.0
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"id": "VFD101",
|
|
131
|
+
"name": "Receiving Conveyor Drive",
|
|
132
|
+
"kind": "vfd",
|
|
133
|
+
"floor": 1,
|
|
134
|
+
"zone": "ZONE_F1",
|
|
135
|
+
"position": {
|
|
136
|
+
"x": -12.0,
|
|
137
|
+
"y": 0.0,
|
|
138
|
+
"z": 4.0
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"connections": [
|
|
143
|
+
{
|
|
144
|
+
"from": "CV101",
|
|
145
|
+
"to": "CV102"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"from": "CV102",
|
|
149
|
+
"to": "SORT101"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"from": "SORT101",
|
|
153
|
+
"to": "CV103"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"from": "SORT101",
|
|
157
|
+
"to": "CV104"
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"from": "CV103",
|
|
161
|
+
"to": "CV105"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"from": "CV104",
|
|
165
|
+
"to": "CV106"
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
"signals": [
|
|
169
|
+
{
|
|
170
|
+
"id": "S_CV101_RUN_FEEDBACK",
|
|
171
|
+
"asset_id": "CV101",
|
|
172
|
+
"role": "run_feedback",
|
|
173
|
+
"datatype": "Boolean",
|
|
174
|
+
"unit": "",
|
|
175
|
+
"polarity": "active_high",
|
|
176
|
+
"source": {
|
|
177
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
178
|
+
"node_id": "Line1/CV101/run_feedback"
|
|
179
|
+
},
|
|
180
|
+
"write_authorized": false
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"id": "S_CV101_FAULT",
|
|
184
|
+
"asset_id": "CV101",
|
|
185
|
+
"role": "fault",
|
|
186
|
+
"datatype": "Boolean",
|
|
187
|
+
"unit": "",
|
|
188
|
+
"polarity": "active_high",
|
|
189
|
+
"source": {
|
|
190
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
191
|
+
"node_id": "Line1/CV101/fault"
|
|
192
|
+
},
|
|
193
|
+
"write_authorized": false
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
"id": "S_CV102_RUN_FEEDBACK",
|
|
197
|
+
"asset_id": "CV102",
|
|
198
|
+
"role": "run_feedback",
|
|
199
|
+
"datatype": "Boolean",
|
|
200
|
+
"unit": "",
|
|
201
|
+
"polarity": "active_high",
|
|
202
|
+
"source": {
|
|
203
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
204
|
+
"node_id": "Line1/CV102/run_feedback"
|
|
205
|
+
},
|
|
206
|
+
"write_authorized": false
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"id": "S_SORT101_RUN_FEEDBACK",
|
|
210
|
+
"asset_id": "SORT101",
|
|
211
|
+
"role": "run_feedback",
|
|
212
|
+
"datatype": "Boolean",
|
|
213
|
+
"unit": "",
|
|
214
|
+
"polarity": "active_high",
|
|
215
|
+
"source": {
|
|
216
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
217
|
+
"node_id": "Line1/SORT101/run_feedback"
|
|
218
|
+
},
|
|
219
|
+
"write_authorized": false
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"id": "S_SORT101_FAULT",
|
|
223
|
+
"asset_id": "SORT101",
|
|
224
|
+
"role": "fault",
|
|
225
|
+
"datatype": "Boolean",
|
|
226
|
+
"unit": "",
|
|
227
|
+
"polarity": "active_high",
|
|
228
|
+
"source": {
|
|
229
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
230
|
+
"node_id": "Line1/SORT101/fault"
|
|
231
|
+
},
|
|
232
|
+
"write_authorized": false
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"id": "S_CV103_RUN_FEEDBACK",
|
|
236
|
+
"asset_id": "CV103",
|
|
237
|
+
"role": "run_feedback",
|
|
238
|
+
"datatype": "Boolean",
|
|
239
|
+
"unit": "",
|
|
240
|
+
"polarity": "active_high",
|
|
241
|
+
"source": {
|
|
242
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
243
|
+
"node_id": "Line1/CV103/run_feedback"
|
|
244
|
+
},
|
|
245
|
+
"write_authorized": false
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"id": "S_CV104_RUN_FEEDBACK",
|
|
249
|
+
"asset_id": "CV104",
|
|
250
|
+
"role": "run_feedback",
|
|
251
|
+
"datatype": "Boolean",
|
|
252
|
+
"unit": "",
|
|
253
|
+
"polarity": "active_high",
|
|
254
|
+
"source": {
|
|
255
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
256
|
+
"node_id": "Line1/CV104/run_feedback"
|
|
257
|
+
},
|
|
258
|
+
"write_authorized": false
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"id": "S_CV105_RUN_FEEDBACK",
|
|
262
|
+
"asset_id": "CV105",
|
|
263
|
+
"role": "run_feedback",
|
|
264
|
+
"datatype": "Boolean",
|
|
265
|
+
"unit": "",
|
|
266
|
+
"polarity": "active_high",
|
|
267
|
+
"source": {
|
|
268
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
269
|
+
"node_id": "Line1/CV105/run_feedback"
|
|
270
|
+
},
|
|
271
|
+
"write_authorized": false
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
"id": "S_CV106_RUN_FEEDBACK",
|
|
275
|
+
"asset_id": "CV106",
|
|
276
|
+
"role": "run_feedback",
|
|
277
|
+
"datatype": "Boolean",
|
|
278
|
+
"unit": "",
|
|
279
|
+
"polarity": "active_high",
|
|
280
|
+
"source": {
|
|
281
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
282
|
+
"node_id": "Line1/CV106/run_feedback"
|
|
283
|
+
},
|
|
284
|
+
"write_authorized": false
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"id": "S_PE101_PHOTOEYE_BLOCKED",
|
|
288
|
+
"asset_id": "PE101",
|
|
289
|
+
"role": "photoeye_blocked",
|
|
290
|
+
"datatype": "Boolean",
|
|
291
|
+
"unit": "",
|
|
292
|
+
"polarity": "active_high",
|
|
293
|
+
"source": {
|
|
294
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
295
|
+
"node_id": "Line1/PE101/photoeye_blocked"
|
|
296
|
+
},
|
|
297
|
+
"write_authorized": false
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
"id": "S_PE101_PHOTOEYE_COUNT",
|
|
301
|
+
"asset_id": "PE101",
|
|
302
|
+
"role": "photoeye_count",
|
|
303
|
+
"datatype": "Int32",
|
|
304
|
+
"unit": "count",
|
|
305
|
+
"polarity": "",
|
|
306
|
+
"source": {
|
|
307
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
308
|
+
"node_id": "Line1/PE101/photoeye_count"
|
|
309
|
+
},
|
|
310
|
+
"write_authorized": false
|
|
311
|
+
},
|
|
312
|
+
{
|
|
313
|
+
"id": "S_PE102_PHOTOEYE_BLOCKED",
|
|
314
|
+
"asset_id": "PE102",
|
|
315
|
+
"role": "photoeye_blocked",
|
|
316
|
+
"datatype": "Boolean",
|
|
317
|
+
"unit": "",
|
|
318
|
+
"polarity": "active_high",
|
|
319
|
+
"source": {
|
|
320
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
321
|
+
"node_id": "Line1/PE102/photoeye_blocked"
|
|
322
|
+
},
|
|
323
|
+
"write_authorized": false
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
"id": "S_PE102_PHOTOEYE_COUNT",
|
|
327
|
+
"asset_id": "PE102",
|
|
328
|
+
"role": "photoeye_count",
|
|
329
|
+
"datatype": "Int32",
|
|
330
|
+
"unit": "count",
|
|
331
|
+
"polarity": "",
|
|
332
|
+
"source": {
|
|
333
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
334
|
+
"node_id": "Line1/PE102/photoeye_count"
|
|
335
|
+
},
|
|
336
|
+
"write_authorized": false
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"id": "S_SCN101_SCANNER_RESULT",
|
|
340
|
+
"asset_id": "SCN101",
|
|
341
|
+
"role": "scanner_result",
|
|
342
|
+
"datatype": "String",
|
|
343
|
+
"unit": "",
|
|
344
|
+
"polarity": "",
|
|
345
|
+
"source": {
|
|
346
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
347
|
+
"node_id": "Line1/SCN101/scanner_result"
|
|
348
|
+
},
|
|
349
|
+
"write_authorized": false
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
"id": "S_SCN101_SCANNER_BARCODE",
|
|
353
|
+
"asset_id": "SCN101",
|
|
354
|
+
"role": "scanner_barcode",
|
|
355
|
+
"datatype": "String",
|
|
356
|
+
"unit": "",
|
|
357
|
+
"polarity": "",
|
|
358
|
+
"source": {
|
|
359
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
360
|
+
"node_id": "Line1/SCN101/scanner_barcode"
|
|
361
|
+
},
|
|
362
|
+
"write_authorized": false
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"id": "S_SCN101_SCAN_COUNT",
|
|
366
|
+
"asset_id": "SCN101",
|
|
367
|
+
"role": "scan_count",
|
|
368
|
+
"datatype": "Int32",
|
|
369
|
+
"unit": "count",
|
|
370
|
+
"polarity": "",
|
|
371
|
+
"source": {
|
|
372
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
373
|
+
"node_id": "Line1/SCN101/scan_count"
|
|
374
|
+
},
|
|
375
|
+
"write_authorized": false
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"id": "S_SCN101_NO_READ_COUNT",
|
|
379
|
+
"asset_id": "SCN101",
|
|
380
|
+
"role": "no_read_count",
|
|
381
|
+
"datatype": "Int32",
|
|
382
|
+
"unit": "count",
|
|
383
|
+
"polarity": "",
|
|
384
|
+
"source": {
|
|
385
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
386
|
+
"node_id": "Line1/SCN101/no_read_count"
|
|
387
|
+
},
|
|
388
|
+
"write_authorized": false
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
"id": "S_VFD101_VFD_FREQUENCY",
|
|
392
|
+
"asset_id": "VFD101",
|
|
393
|
+
"role": "vfd_frequency",
|
|
394
|
+
"datatype": "Double",
|
|
395
|
+
"unit": "Hz",
|
|
396
|
+
"polarity": "",
|
|
397
|
+
"source": {
|
|
398
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
399
|
+
"node_id": "Line1/VFD101/vfd_frequency"
|
|
400
|
+
},
|
|
401
|
+
"write_authorized": false
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"id": "S_VFD101_RUN_FEEDBACK",
|
|
405
|
+
"asset_id": "VFD101",
|
|
406
|
+
"role": "run_feedback",
|
|
407
|
+
"datatype": "Boolean",
|
|
408
|
+
"unit": "",
|
|
409
|
+
"polarity": "active_high",
|
|
410
|
+
"source": {
|
|
411
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
412
|
+
"node_id": "Line1/VFD101/run_feedback"
|
|
413
|
+
},
|
|
414
|
+
"write_authorized": false
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
"id": "S_VFD101_FAULT",
|
|
418
|
+
"asset_id": "VFD101",
|
|
419
|
+
"role": "fault",
|
|
420
|
+
"datatype": "Boolean",
|
|
421
|
+
"unit": "",
|
|
422
|
+
"polarity": "active_high",
|
|
423
|
+
"source": {
|
|
424
|
+
"namespace_uri": "urn:example:warehouse:onefloor:opcua",
|
|
425
|
+
"node_id": "Line1/VFD101/fault"
|
|
426
|
+
},
|
|
427
|
+
"write_authorized": false
|
|
428
|
+
}
|
|
429
|
+
],
|
|
430
|
+
"requirements": [
|
|
431
|
+
{
|
|
432
|
+
"id": "R001",
|
|
433
|
+
"text": "Display exactly one floor"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"id": "R002",
|
|
437
|
+
"text": "All signal mappings require verified OPC UA source identity"
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"id": "R003",
|
|
441
|
+
"text": "No generated control writes allowed"
|
|
442
|
+
}
|
|
443
|
+
]
|
|
444
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Smart Parcel Distribution Center - 3 Floors",
|
|
3
|
+
"industry": "Warehouse Automation",
|
|
4
|
+
"layout": "spatial_overview",
|
|
5
|
+
"palette": "r9_cyan",
|
|
6
|
+
"description": "Three-floor parcel distribution training demonstration with two inbound docks, sorter/chute branches and inter-floor spirals. Demonstrate continuous conceptual transport along declared belts and transfer surfaces, smooth path curves through sorter branches and spiral transition, separate parcel IDs at completion, clear status provenance. Do NOT fabricate real PLC mappings, belt speeds, PE-to-belt associations, sensor states, barcode decisions, mechanical clearance or FAT PASS. Test-only synthetic data.\n",
|
|
7
|
+
"equipment_csv": "id,name,kind,floor,zone,x,y,z\nIN_DOCK01,Receiving Dock 1,room,1,RECEIVING,-22,0,-9\nIN_DOCK02,Receiving Dock 2,room,1,RECEIVING,-22,0,8\nCV101,Dock 1 Receiving Conveyor,conveyor,1,RECEIVING,-15,0,-9\nCV102,Dock 2 Receiving Conveyor,conveyor,1,RECEIVING,-15,0,8\nCV103,Receiving Merge Conveyor,conveyor,1,MERGE,-7,0,0\nPE101,Receiving Photoeye,photoeye,1,RECEIVING,-12,0,-7\nSCN101,Parcel Barcode Scanner,scanner,1,MERGE,-4,0,2\nVFD101,Floor 1 Conveyor Drive,vfd,1,MERGE,-7,0,3\nSORT101,Floor 1 Sorter,sorter,1,SORTATION,0,0,0\nCHUTE101,Floor 1 Outbound Chute,junction,1,OUTBOUND,6,0,-7\nOUT_DOCK01,Shipping Dock 1,room,1,OUTBOUND,12,0,-7\nSPIRAL12,Transfer Spiral Floor 1 to 2,spiral,1,TRANSFER,7,0,8\nCV201,Floor 2 Infeed Conveyor,conveyor,2,SORTATION,-3,8,1\nPE201,Floor 2 Photoeye,photoeye,2,SORTATION,-2,8,3\nVFD201,Floor 2 Drive,vfd,2,SORTATION,0,8,5\nSORT201,Floor 2 Sorter,sorter,2,SORTATION,3,8,1\nCHUTE201,Floor 2 Outbound Chute,junction,2,OUTBOUND,9,8,-6\nOUT_DOCK02,Shipping Dock 2,room,2,OUTBOUND,14,8,-6\nSPIRAL23,Transfer Spiral Floor 2 to 3,spiral,2,TRANSFER,9,8,8\nCV301,Floor 3 Distribution Conveyor,conveyor,3,DISTRIBUTION,-3,16,1\nPE301,Floor 3 Photoeye,photoeye,3,DISTRIBUTION,0,16,3\nVFD301,Floor 3 Drive,vfd,3,DISTRIBUTION,-1,16,5\nSORT301,Floor 3 Sorter,sorter,3,SORTATION,4,16,1\nCHUTE301,Floor 3 Outbound Chute,junction,3,OUTBOUND,10,16,-6\nOUT_DOCK03,Shipping Dock 3,room,3,OUTBOUND,15,16,-6\n",
|
|
8
|
+
"connections_csv": "from,to\nIN_DOCK01,CV101\nIN_DOCK02,CV102\nCV101,CV103\nCV102,CV103\nCV103,SORT101\nSORT101,CHUTE101\nCHUTE101,OUT_DOCK01\nSORT101,SPIRAL12\nSPIRAL12,CV201\nCV201,SORT201\nSORT201,CHUTE201\nCHUTE201,OUT_DOCK02\nSORT201,SPIRAL23\nSPIRAL23,CV301\nCV301,SORT301\nSORT301,CHUTE301\nCHUTE301,OUT_DOCK03\n",
|
|
9
|
+
"signals_csv": "id,asset_id,role,datatype,namespace_uri,node_id,unit,polarity\nS_CV101_RUN_FEEDBACK,CV101,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV101/run_feedback,,active_high\nS_CV101_FAULT,CV101,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV101/fault,,active_high\nS_CV102_RUN_FEEDBACK,CV102,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV102/run_feedback,,active_high\nS_CV102_FAULT,CV102,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV102/fault,,active_high\nS_CV103_RUN_FEEDBACK,CV103,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV103/run_feedback,,active_high\nS_CV103_FAULT,CV103,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV103/fault,,active_high\nS_CV201_RUN_FEEDBACK,CV201,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV201/run_feedback,,active_high\nS_CV201_FAULT,CV201,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV201/fault,,active_high\nS_CV301_RUN_FEEDBACK,CV301,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV301/run_feedback,,active_high\nS_CV301_FAULT,CV301,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/CV301/fault,,active_high\nS_SORT101_RUN_FEEDBACK,SORT101,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SORT101/run_feedback,,active_high\nS_SORT101_FAULT,SORT101,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SORT101/fault,,active_high\nS_SORT201_RUN_FEEDBACK,SORT201,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SORT201/run_feedback,,active_high\nS_SORT201_FAULT,SORT201,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SORT201/fault,,active_high\nS_SORT301_RUN_FEEDBACK,SORT301,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SORT301/run_feedback,,active_high\nS_SORT301_FAULT,SORT301,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SORT301/fault,,active_high\nS_SPIRAL12_RUN_FEEDBACK,SPIRAL12,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SPIRAL12/run_feedback,,active_high\nS_SPIRAL12_FAULT,SPIRAL12,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SPIRAL12/fault,,active_high\nS_SPIRAL23_RUN_FEEDBACK,SPIRAL23,run_feedback,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SPIRAL23/run_feedback,,active_high\nS_SPIRAL23_FAULT,SPIRAL23,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SPIRAL23/fault,,active_high\nS_PE101_PHOTOEYE_BLOCKED,PE101,photoeye_blocked,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/PE101/photoeye_blocked,,active_high\nS_PE201_PHOTOEYE_BLOCKED,PE201,photoeye_blocked,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/PE201/photoeye_blocked,,active_high\nS_PE301_PHOTOEYE_BLOCKED,PE301,photoeye_blocked,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/PE301/photoeye_blocked,,active_high\nS_VFD101_VFD_FREQUENCY,VFD101,vfd_frequency,Double,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/VFD101/vfd_frequency,Hz,\nS_VFD101_FAULT,VFD101,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/VFD101/fault,,active_high\nS_VFD201_VFD_FREQUENCY,VFD201,vfd_frequency,Double,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/VFD201/vfd_frequency,Hz,\nS_VFD201_FAULT,VFD201,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/VFD201/fault,,active_high\nS_VFD301_VFD_FREQUENCY,VFD301,vfd_frequency,Double,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/VFD301/vfd_frequency,Hz,\nS_VFD301_FAULT,VFD301,fault,Boolean,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/VFD301/fault,,active_high\nS_SCN101_SCANNER_RESULT,SCN101,scanner_result,String,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SCN101/scanner_result,,\nS_SCN101_NO_READ_COUNT,SCN101,no_read_count,Int32,urn:devagent:training:three-floor:synthetic-inputs,TRAINING_ONLY/SCN101/no_read_count,count,\n",
|
|
10
|
+
"requirements": "Operator can navigate Floor 1, Floor 2, and Floor 3 and identify equipment by asset ID.\nOperator can click each conveyor to view declared Run Feedback, Fault and source quality.\nOperator can inspect each photoeye Blocked/Clear and quality; do not assume PE IN/OUT equipment association.\nOperator can inspect VFD frequency in Hz only where a valid source is declared.\nOperator can inspect scanner last result and NO_READ counter with source provenance.\nOperator can identify sorters, outbound chutes, and material-flow branches on every floor.\nUnknown physical mappings must display UNKNOWN or NOT MAPPED, never fabricated operating state.\nCreate simulation tests for declared material-flow paths with independent expected outputs.\nCreate explicit HOLD tests for barcode destination-based sorter routing until routing logic exists.\nRun isolated fake OPC UA datatype and quality readback without production PLC writes.\nGenerate required FAT inventory and evidence; simulation does not qualify real Ignition or PLC.\nHMI must use professional industrial 2D design, with an R9 3D alternative.\nContinuous synthetic parcel trajectories through CV101->CV103->SORT101->SPIRAL12->CV201, with no teleportation; invalid transport paths must HOLD.\nShow declared sorter branch material flow, with unknown barcode destination routing explicitly NOT VERIFIED.\nSmooth belt-to-belt transfer and inter-floor transition are conceptual geometry only, not proof of safe physical clearances.\n"
|
|
11
|
+
}
|