devagent-ignition 0.1.2__tar.gz → 0.1.4__tar.gz
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_ignition-0.1.2 → devagent_ignition-0.1.4}/PKG-INFO +2 -1
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/SHA256SUMS.txt +4 -4
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/v076_fat_ui.js +6 -3
- devagent_ignition-0.1.4/devagent_spatial/__init__.py +1 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/studio.py +10 -7
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v076_opc_fat.py +24 -5
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/pyproject.toml +2 -2
- devagent_ignition-0.1.2/devagent_spatial/__init__.py +0 -1
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/.gitignore +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/README.md +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/RELEASE_MANIFEST.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/SOURCE_PROVENANCE.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/agent.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator.css +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator_2d.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator_original_r9.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator_original_v8.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator_r9_diagnostics.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator_scene.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/creator_ui.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/customer_documents.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/equipment_controls.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/facility2d.css +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/facility2d_app.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/facility2d_core.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/facility2d_simulation.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/facility2d_viewer.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/fallback_scene.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/flow_geometry.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/harness.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/live_design_review.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/operations_ui.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/operator_viewer.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/project_package.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/r9_transport.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/runtime_feed.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/studio.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/style.css +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/test_workspace.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/three_scene.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/unified_engineer.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/v078_command_ui.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/viewer.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/assets/viewer.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/design-system.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_hmi.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/agent_harness.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/agent_runtime.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/contract_opc_fat.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/contract_opc_source.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/control_intents.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/customer_intake.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/engineering_expertise.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/generator.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/ignition_native.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/ignition_project.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/live_lab_binding.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/model.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/native_reference.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/opc_snapshot.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/operations.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/operations_capture.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/operations_lab.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/original_r9.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/original_v8.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/preflight.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/preview_simulation.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/project_package.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/qualification.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/strict_json.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/studio_workflow.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/test_reporting.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v078_commands.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v078_native_commands.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v07_fat.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v07_native.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v083_native.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/CV101-command-contract-PENDING.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/cv101_guided.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/make_examples.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/single_floor.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/v0771_training_wizard.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse-3floor-standard-2d.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse-operations-synthetic.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse-v07-lab-bindings-PENDING.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/water.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/REFERENCE_SHA256.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/app.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/index.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/lab_panel.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/model.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/state_adapter.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/styles.css +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/README_R9.md +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/SHA256SUMS.txt +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/SNAPSHOT_SHA256SUMS.txt +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/flow_routes.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/flow_sim.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/lab_control.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/app.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/index.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/lab_panel.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/model.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/state_adapter.mjs +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/styles.css +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/LICENSE-three.txt +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/SHA256SUMS.txt +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/addons/controls/OrbitControls.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/three.core.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/three.module.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/README.md +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/SHA256SUMS.txt +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/model.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/run_demo.sh +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/server.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/tests/browser_smoke.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/tests/test_v8.py +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/topology.json +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/web/app.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/web/index.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/web/simulator.html +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/web/simulator.js +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/web/style.css +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/sample_customer_inputs/Plant_Equipment_Register.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/sample_customer_inputs/Plant_Flow_Requirements.txt +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/sample_customer_inputs/Raw_PLC_Tag_Export.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/templates/warehouse_connections.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/templates/warehouse_equipment.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/templates/warehouse_signals.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/templates/water_connections.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/templates/water_equipment.csv +0 -0
- {devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/templates/water_signals.csv +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: devagent-ignition
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.4
|
|
4
4
|
Summary: Offline industrial HMI engineering and Ignition Perspective candidate tools (production deployment not qualified)
|
|
5
5
|
Project-URL: Repository, https://github.com/tomha85/devagent-ignition
|
|
6
6
|
Project-URL: Documentation, https://github.com/tomha85/devagent-ignition#readme
|
|
@@ -13,6 +13,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
14
|
Classifier: Topic :: Scientific/Engineering
|
|
15
15
|
Requires-Python: <3.14,>=3.13
|
|
16
|
+
Requires-Dist: asyncua==2.1.0
|
|
16
17
|
Description-Content-Type: text/markdown
|
|
17
18
|
|
|
18
19
|
# DevAgent
|
|
@@ -93,13 +93,13 @@ c9f87624386bbe84ab7d71f93708f00f91a69e0d9693738cfee51913e5831fdf assets/style.c
|
|
|
93
93
|
fd0d07ddec872de25c4e485573d5aa5b0c7a2c3137a93e65c6406b637fad7ad7 assets/test_workspace.html
|
|
94
94
|
d7b86f7cf6d22e08f2fe00c593db9d20ddf9e46bdb945781d8afea7af3ff2688 assets/three_scene.js
|
|
95
95
|
af23f86ef51e18dfc94355e77fe9fb52570db14466d05d6dadededf17458fe25 assets/unified_engineer.js
|
|
96
|
-
|
|
96
|
+
531c378fe3aae0c1d0686da48d7a4eba371ca7641b343b952dc8448f1cf65dc1 assets/v076_fat_ui.js
|
|
97
97
|
d009f79a79ed1278911c81818b97a7dbce72464b599bb00f6116b81e1b1f9b5c assets/v078_command_ui.js
|
|
98
98
|
9d95941755b73fc16aaa0ef8af0550ee64f15d60d6f3792eb00d82844a48a75b assets/viewer.html
|
|
99
99
|
600d23649659fd9b435e6b828a5b191b95cae721784b2eed4d7594b783b56681 assets/viewer.js
|
|
100
100
|
54ee77ca35589b06bd093204c9e5b28eabb69a8b2158ef1be5897386d3676c3f design-system.json
|
|
101
101
|
287744606d4ec09533bb0af2ab6c1e059e614a7d87bc8c365d0f1e16c646bff8 devagent_hmi.py
|
|
102
|
-
|
|
102
|
+
68111b0efc782cc83c0354c9251e9d107bbcad03835629f9dbc84b4bf103bee0 devagent_spatial/__init__.py
|
|
103
103
|
a6b1a2a97e2ec31e2de7f4c576b9482f66d3aa7fb356b06f0475bcd221dd8116 devagent_spatial/agent_harness.py
|
|
104
104
|
a54c22bb64e5ff6b8d720bc44a73d851388f3f55adcba0f5f17098349895f2a4 devagent_spatial/agent_runtime.py
|
|
105
105
|
f57e58f596ab5395b5a9692158cca43866de32ec9f8d07bdec363a36610e3d2b devagent_spatial/contract_opc_fat.py
|
|
@@ -124,10 +124,10 @@ d013f40d6a913126b7466fccfb97617f249e655ce1d5183d8d21e47f81a7e2d4 devagent_spati
|
|
|
124
124
|
b63c232a9218a6c7dc350f8510af0ccb9d7af61b6ffbc448918ae0a4beaef07d devagent_spatial/project_package.py
|
|
125
125
|
74cbfb179c33304851dade43687d6ff7075d72305e696dab7d5de126b0ec253e devagent_spatial/qualification.py
|
|
126
126
|
05b93e0f13f2e59251bed066975944a3a21f084a6447ea5607c8620c0e489aef devagent_spatial/strict_json.py
|
|
127
|
-
|
|
127
|
+
050f4c23b07ae54367626777a50c771233bae60c0217f3f74c5c6f08d6c5348e devagent_spatial/studio.py
|
|
128
128
|
7f58410cba0fd20fbeb9be75b0afdad2bb443eb361eb510a9fd78d250145e21e devagent_spatial/studio_workflow.py
|
|
129
129
|
e8058af1dbe09d877700144b41451440c0fee4602fffcf658b497b34efe9b30b devagent_spatial/test_reporting.py
|
|
130
|
-
|
|
130
|
+
4a712465d91b0c93a4d0d13569dc6fb96b5d7ec7cef7da3d643fc56768c257b1 devagent_spatial/v076_opc_fat.py
|
|
131
131
|
ae48eeebcc0e1df2a93bca41d6344c17c66b19ef8b492f6af41d7cdd554b863f devagent_spatial/v078_commands.py
|
|
132
132
|
ba2b1147d1871266c6150e229a35fc4132ab492860d2fae40ccc8a31f1424db6 devagent_spatial/v078_native_commands.py
|
|
133
133
|
4269e8b41f06982b99ac6f0d6d7a2a027e3bb24456f5752c1f6fb8f879f72ae2 devagent_spatial/v07_fat.py
|
|
@@ -26,13 +26,16 @@ button.addEventListener('click',async()=>{
|
|
|
26
26
|
finally{clearTimeout(timeout);}
|
|
27
27
|
const result=await response.json();
|
|
28
28
|
if(response.ok&&result.status==='PASS_LAB_OPC_PROTOCOL_ONLY'){
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
const scope=result.test_scope==='SYNTHETIC_TRANSPORT_ONLY_NO_CUSTOMER_SIGNALS'
|
|
30
|
+
? 'Transport-only synthetic equipment probes; NO customer signal mappings or device behaviors verified. '
|
|
31
|
+
: 'Synthetic protocol exercise of declared signal definitions; physical mappings NOT VERIFIED. ';
|
|
32
|
+
state.textContent=scope+'OPC UA: '+result.cases_passed+'/'+result.cases_planned+
|
|
33
|
+
' TCP readbacks PASS. Ignition HMI FAT: NOT VERIFIED. Production: HOLD. ';
|
|
31
34
|
if(result.report_url){const link=document.createElement('a');link.href=result.report_url;
|
|
32
35
|
link.target='_blank';link.rel='noopener';link.textContent='Open lab evidence ↗';state.append(link);}
|
|
33
36
|
}else{
|
|
34
37
|
state.textContent='HOLD '+(result.reason||result.status||'UNKNOWN')+
|
|
35
|
-
'.
|
|
38
|
+
'. Synthetic OPC UA FAT did not complete; no PASS was recorded.';
|
|
36
39
|
}
|
|
37
40
|
}catch(e){state.textContent='HOLD: fake OPC UA protocol test unavailable. No FAT PASS.';}
|
|
38
41
|
finally{busy=false;button.disabled=false;}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '0.1.4'
|
|
@@ -265,10 +265,10 @@ class StudioHandler(BaseHTTPRequestHandler):
|
|
|
265
265
|
opc_report=re.fullmatch(r'/api/v076-opc/([a-z0-9-]{1,100})/report/([0-9a-f]{12})',path)
|
|
266
266
|
if opc_report:
|
|
267
267
|
pid,rid=opc_report.groups()
|
|
268
|
-
from .studio_workflow import load_project,LabHold
|
|
268
|
+
from .studio_workflow import load_project,LabHold,project_lab_dir
|
|
269
269
|
try:
|
|
270
270
|
load_project(self.server.workspace,pid)
|
|
271
|
-
file=self.server.workspace
|
|
271
|
+
file=project_lab_dir(self.server.workspace,pid)/'opc-fat'/('lab-opc-v076-'+rid+'.json')
|
|
272
272
|
if not file.is_file() or file.stat().st_size>3_000_000:
|
|
273
273
|
return self.output(404,{'status':'HOLD','reason':'REPORT_NOT_FOUND'})
|
|
274
274
|
return self.output(200,strict_loads(file.read_text(encoding='utf8')))
|
|
@@ -277,10 +277,10 @@ class StudioHandler(BaseHTTPRequestHandler):
|
|
|
277
277
|
cmd_report=re.fullmatch(r'/api/v078-command/([a-z0-9-]{1,100})/report/([0-9a-f]{12})',path)
|
|
278
278
|
if cmd_report:
|
|
279
279
|
pid,rid=cmd_report.groups()
|
|
280
|
-
from .studio_workflow import load_project,LabHold
|
|
280
|
+
from .studio_workflow import load_project,LabHold,project_lab_dir
|
|
281
281
|
try:
|
|
282
282
|
load_project(self.server.workspace,pid)
|
|
283
|
-
file=self.server.workspace
|
|
283
|
+
file=project_lab_dir(self.server.workspace,pid)/'command-fat'/('lab-command-v078-'+rid+'.json')
|
|
284
284
|
if not file.is_file() or file.is_symlink() or file.stat().st_size>400_000:
|
|
285
285
|
return self.output(404,{'status':'HOLD','reason':'COMMAND_FAT_REPORT_NOT_FOUND'})
|
|
286
286
|
return self.output(200,strict_loads(file.read_text(encoding='utf8')))
|
|
@@ -557,7 +557,8 @@ class StudioHandler(BaseHTTPRequestHandler):
|
|
|
557
557
|
model,c,port=4899,confirm=LAB_CONFIRM),timeout=45))
|
|
558
558
|
rid=secrets.token_hex(6)
|
|
559
559
|
from .v076_opc_fat import save_new
|
|
560
|
-
|
|
560
|
+
from .studio_workflow import project_lab_dir
|
|
561
|
+
save_new(project_lab_dir(self.server.workspace,pid)/'command-fat'/('lab-command-v078-'+rid+'.json'),result)
|
|
561
562
|
public={'status':result['status'],'cases_checked':result['case_count'],
|
|
562
563
|
'report_url':f'/api/v078-command/{pid}/report/{rid}',
|
|
563
564
|
'gateway':'NOT_VERIFIED','physical_plc':'NOT_VERIFIED','production':'HOLD'}
|
|
@@ -587,11 +588,13 @@ class StudioHandler(BaseHTTPRequestHandler):
|
|
|
587
588
|
raise LabHold('LAB_BUSY')
|
|
588
589
|
try:
|
|
589
590
|
import asyncio
|
|
590
|
-
result=asyncio.run(asyncio.wait_for(run_loopback_fat(model,port=4898),timeout=50))
|
|
591
|
+
result=asyncio.run(asyncio.wait_for(run_loopback_fat(model,port=4898,allow_transport_only=not bool(model['signals'])),timeout=50))
|
|
591
592
|
rid=secrets.token_hex(6)
|
|
592
|
-
|
|
593
|
+
from .studio_workflow import project_lab_dir
|
|
594
|
+
save_new(project_lab_dir(self.server.workspace,pid)/'opc-fat'/('lab-opc-v076-'+rid+'.json'),result)
|
|
593
595
|
result={'status':result['status'],'cases_passed':result['cases_passed'],
|
|
594
596
|
'cases_planned':result['cases_planned'],
|
|
597
|
+
'test_scope':result.get('test_scope','UNSPECIFIED'),
|
|
595
598
|
'report_url':f'/api/v076-opc/{pid}/report/{rid}',
|
|
596
599
|
'gateway':'NOT_VERIFIED','production':'HOLD'}
|
|
597
600
|
return self.output(200 if result['status']=='PASS_LAB_OPC_PROTOCOL_ONLY' else 422,result)
|
|
@@ -26,12 +26,19 @@ class LabHold(ValueError):pass
|
|
|
26
26
|
def model_hash(model):
|
|
27
27
|
return hashlib.sha256(json.dumps(model,sort_keys=True,ensure_ascii=False,separators=(',',':')).encode()).hexdigest()
|
|
28
28
|
|
|
29
|
-
def lab_manifest(model):
|
|
29
|
+
def lab_manifest(model, *, allow_transport_only=False):
|
|
30
30
|
"""Generate a separate synthetic mapping, never overwrite customer OPC identities."""
|
|
31
31
|
if qualify(model)['status']=='HOLD':raise LabHold('ENGINEERING_MODEL_HOLD')
|
|
32
32
|
signals=model['signals']
|
|
33
|
-
if not signals:raise LabHold('LAB_HAS_NO_DECLARED_SIGNALS')
|
|
34
33
|
if len(signals)>MAX_LAB_SIGNALS:raise LabHold('LAB_LIMIT_200_SIGNALS')
|
|
34
|
+
# No customer OPC mapping? Probe protocol transport using explicit, synthetic
|
|
35
|
+
# equipment-identity fixtures only. This is NOT a photoeye, VFD, run/fault,
|
|
36
|
+
# scanner or other operational signal test.
|
|
37
|
+
transport_only=not signals and allow_transport_only is True
|
|
38
|
+
if not signals and not transport_only:
|
|
39
|
+
raise LabHold('LAB_HAS_NO_DECLARED_SIGNALS')
|
|
40
|
+
if transport_only and not model['equipment']:
|
|
41
|
+
raise LabHold('LAB_HAS_NO_EQUIPMENT_FOR_SYNTHETIC_PROBE')
|
|
35
42
|
digest=model_hash(model)
|
|
36
43
|
uri=LAB_URI_PREFIX+digest[:16]
|
|
37
44
|
rows=[]
|
|
@@ -45,7 +52,18 @@ def lab_manifest(model):
|
|
|
45
52
|
'production_namespace_uri':None,'production_node_id':None,
|
|
46
53
|
'binding_review':'PENDING_ENGINEER_REVIEW',
|
|
47
54
|
'source':'GENERATED_SYNTHETIC_LAB_NOT_CUSTOMER_MAPPING'})
|
|
55
|
+
if transport_only:
|
|
56
|
+
for equipment in model['equipment'][:MAX_LAB_SIGNALS]:
|
|
57
|
+
eid=equipment['id']
|
|
58
|
+
rows.append({'signal_id':'LAB_PROBE_'+eid,'equipment_id':eid,
|
|
59
|
+
'role':'lab_transport_probe','datatype':'Boolean',
|
|
60
|
+
'lab_namespace_uri':uri,'lab_node_id':'LAB/PROBE/'+eid,
|
|
61
|
+
'ignition_lab_tag_path':None,
|
|
62
|
+
'production_namespace_uri':None,'production_node_id':None,
|
|
63
|
+
'binding_review':'NOT_A_PHYSICAL_MAPPING',
|
|
64
|
+
'source':'GENERATED_SYNTHETIC_TRANSPORT_PROBE_ONLY'})
|
|
48
65
|
return {'schema':'devagent.opc.synthetic_manifest.v076','status':'PLAN_ONLY_NOT_EXECUTED',
|
|
66
|
+
'test_scope':'SYNTHETIC_TRANSPORT_ONLY_NO_CUSTOMER_SIGNALS' if transport_only else 'SYNTHETIC_DECLARED_SIGNAL_PROTOCOL',
|
|
49
67
|
'model_sha256':digest,'lab_namespace_uri':uri,'signals':rows,
|
|
50
68
|
'physical_mapping':'NOT_VERIFIED','ignition_binding':'NOT_CONFIGURED',
|
|
51
69
|
'production_release':'HOLD','write_authority':'DISABLED'}
|
|
@@ -91,14 +109,14 @@ def _verified_phase(manifest,step,readbacks):
|
|
|
91
109
|
'actual_value_recorded':False})
|
|
92
110
|
return cases,failures
|
|
93
111
|
|
|
94
|
-
async def run_loopback_fat(model,port:int=4898):
|
|
112
|
+
async def run_loopback_fat(model,port:int=4898,*,allow_transport_only=False):
|
|
95
113
|
"""Create OPC UA server on loopback, stimulate synthetic signals, read with a client.
|
|
96
114
|
|
|
97
115
|
All nodes are read-only to clients; writes only occur from this server process.
|
|
98
116
|
Does not import to Ignition or touch any customer PLC. Returns fail-closed.
|
|
99
117
|
"""
|
|
100
118
|
if type(port) is not int or not 1024<=port<=65535:raise LabHold('LAB_PORT_INVALID')
|
|
101
|
-
manifest=lab_manifest(model)
|
|
119
|
+
manifest=lab_manifest(model,allow_transport_only=allow_transport_only)
|
|
102
120
|
try:
|
|
103
121
|
from asyncua import Client, Server, ua
|
|
104
122
|
except ImportError as exc:raise LabHold('ASYNCUA_NOT_INSTALLED') from exc
|
|
@@ -158,6 +176,7 @@ async def run_loopback_fat(model,port:int=4898):
|
|
|
158
176
|
return {'schema':'devagent.fat.lab_run.v076',
|
|
159
177
|
'status':'PASS_LAB_OPC_PROTOCOL_ONLY' if passed else 'FAIL_LAB_OPC_PROTOCOL',
|
|
160
178
|
'model_sha256':manifest['model_sha256'],
|
|
179
|
+
'test_scope':manifest['test_scope'],
|
|
161
180
|
'lab_namespace_uri':manifest['lab_namespace_uri'],
|
|
162
181
|
'opc_endpoint_scope':'LOOPBACK_ONLY','source':'SYNTHETIC_NOT_CUSTOMER',
|
|
163
182
|
'cases_planned':len(manifest['signals'])*3,
|
|
@@ -169,7 +188,7 @@ async def run_loopback_fat(model,port:int=4898):
|
|
|
169
188
|
'ignition_gateway':'NOT_VERIFIED','perspective_hmi':'NOT_VERIFIED',
|
|
170
189
|
'physical_mapping':'NOT_VERIFIED','production_release':'HOLD',
|
|
171
190
|
'recorded_utc':dt.datetime.now(dt.timezone.utc).isoformat(),
|
|
172
|
-
'qualification_boundary':'OPC protocol synthetic fixtures only; no machine process, Ignition FAT or PLC proof.'}
|
|
191
|
+
'qualification_boundary':'OPC protocol synthetic fixtures only; no machine process, signal mapping, Ignition FAT or PLC proof.'}
|
|
173
192
|
|
|
174
193
|
def save_new(path:Path,data:dict):
|
|
175
194
|
path=Path(path)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "devagent-ignition"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.4"
|
|
8
8
|
description = "Offline industrial HMI engineering and Ignition Perspective candidate tools (production deployment not qualified)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.13,<3.14"
|
|
@@ -18,7 +18,7 @@ classifiers = [
|
|
|
18
18
|
"Operating System :: POSIX :: Linux",
|
|
19
19
|
"Topic :: Scientific/Engineering",
|
|
20
20
|
]
|
|
21
|
-
dependencies = []
|
|
21
|
+
dependencies = ["asyncua==2.1.0"]
|
|
22
22
|
|
|
23
23
|
[project.urls]
|
|
24
24
|
Repository = "https://github.com/tomha85/devagent-ignition"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '0.1.2'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/engineering_expertise.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/devagent_spatial/v078_native_commands.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/CV101-command-contract-PENDING.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse-3floor-standard-2d.json
RENAMED
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse-operations-synthetic.json
RENAMED
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/examples/warehouse-v07-lab-bindings-PENDING.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/REFERENCE_SHA256.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-golden/web/state_adapter.mjs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/SNAPSHOT_SHA256SUMS.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/state_adapter.mjs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/SHA256SUMS.txt
RENAMED
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/three.core.js
RENAMED
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/r9-original/web/vendor/three.module.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/tests/browser_smoke.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/reference/v8-original/web/simulator.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{devagent_ignition-0.1.2 → devagent_ignition-0.1.4}/sample_customer_inputs/Raw_PLC_Tag_Export.csv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|