Commit e889b090 authored by Ivan Tyagov's avatar Ivan Tyagov

Erp5 opcua

See merge request nexedi/osie!33
parents ebe760bd 69143a1a
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/OPCUADocument_view</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<module>
<id>opcua_document_module</id>
<permission_list>
<permission type='tuple'>
<name>Access Transient Objects</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Access contents information</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Access session data</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add portal content</name>
<role>Assignor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Add portal folders</name>
<role>Assignor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Change local roles</name>
<role>Assignor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Copy or Move</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Delete objects</name>
<role>Assignor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>List folder contents</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>Modify portal content</name>
<role>Assignor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>View</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Manager</role>
</permission>
<permission type='tuple'>
<name>View History</name>
<role>Assignee</role>
<role>Assignor</role>
<role>Associate</role>
<role>Auditor</role>
<role>Author</role>
<role>Manager</role>
</permission>
</permission_list>
<portal_type>OPCUA Document Module</portal_type>
<title>OPCUA Documents</title>
</module>
\ No newline at end of file
<property_sheet_list>
<portal_type id="OPCUA Document">
<item>OPCUADocument</item>
</portal_type>
</property_sheet_list>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Base Type" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>content_icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>factory</string> </key>
<value> <string>addXMLObject</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>OPCUA Document</string> </value>
</item>
<item>
<key> <string>init_script</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>permission</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>type_class</string> </key>
<value> <string>XMLObject</string> </value>
</item>
<item>
<key> <string>type_interface</string> </key>
<value>
<tuple/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<workflow_chain>
<chain>
<type>OPCUA Document</type>
<workflow>edit_workflow, validation_workflow</workflow>
</chain>
</workflow_chain>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Property Sheet" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>OPCUA Documents\' property sheet.</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>OPCUADocument</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/multiple selection</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Contains a dictionary of OPC Ua nodes and their values.</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>node_dict_property</string> </value>
</item>
<item>
<key> <string>property_default</string> </key>
<value> <string>python: {}</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Folder" module="OFS.Folder"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>erp5_opcua</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""
OPCUA to ERP5 OPCUA Document setter / getter glue script.
"""
import json
from erp5.component.module.Log import log
def convertNodeValue(node_id, node_value):
"""
Based on node_id convert to proper Python type. Based on this format:
ns=<namespaceindex>;<type>=<value>
XXX: handle rest of datatypes!
"""
node_type = node_id.split(";")[1]
if node_type.startswith("s"):
node_value = str(node_value)
if node_type.startswith("i"):
node_value = int(node_value)
return node_value
# XXX: what should be the OPCUA container?
default_id = "1"
default_opcua_document = context.opcua_document_module.get(default_id, None)
if default_opcua_document is None:
context.opcua_document_module.newContent(portal_type = "OPCUA Document",
id = default_id)
# do selection of oepration in a REST fashion based in HTTP method
http_method = context.REQUEST.method
context.log(http_method)
if http_method == "GET":
# assume read request, return what was saved.
return json.dumps(default_opcua_document.getNodeDict())
elif http_method == "POST":
# assume write request
try:
data = context.REQUEST.data
except AttributeError as e:
log("Warning: 'data' is missing from request.")
raise e
else:
data = json.loads(data)
if 'node' in data.keys():
# log only set requests for now
node_id = data['node']
node_value = data['val']
# set to "ERP5 OPCUA Document" but only if it's not a None value
if node_value is not None and node_value != "None":
log("Set '%s' = '%s' to %s as %s" %(node_id, node_value, default_opcua_document, node_id))
node_dict = default_opcua_document.getNodeDict()
node_dict[node_id] = convertNodeValue(node_id, node_value)
default_opcua_document.setNodeDict(node_dict)
log("Changed = %s" %default_opcua_document.getNodeDict())
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="_reconstructor" module="copy_reg"/>
</klass>
<tuple>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
<global name="object" module="__builtin__"/>
<none/>
</tuple>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>*args, **kwargs</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>ERP5Site_handleOPCUARequest</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_doSelect</string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>OPCUADocumentModule_viewOPCUADocumentList</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>OPCUADocumentModule_viewOPCUADocumentList</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_list</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>OPCUA Document Module</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>portal_type</string>
<string>selection_name</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_list_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value>
<list>
<tuple>
<string>OPCUA Document</string>
<string>OPCUA Document</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>opcua_document_module_selection</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>OPCUA Document Module</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ERP5 Form" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Base_edit</string> </value>
</item>
<item>
<key> <string>action_title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<dictionary>
<item>
<key> <string>bottom</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list>
<string>my_title</string>
<string>my_node_dict</string>
</list>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>OPCUADocument_view</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>OPCUADocument_view</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_view</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>OPCUA Document</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>update_action</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>update_action_title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_node_dict</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_text_area_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Node Dictionary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
27-07-2023 Ivan
* initlal import of Levin's POC
\ No newline at end of file
erp5_base
\ No newline at end of file
Provides OPC UA communication for ERP5.
\ No newline at end of file
ivan
\ No newline at end of file
OPCUA Document | view
\ No newline at end of file
1
\ No newline at end of file
opcua_document_module
\ No newline at end of file
OPCUA Document
\ No newline at end of file
OPCUA Document | OPCUADocument
\ No newline at end of file
OPCUA Document | edit_workflow
OPCUA Document | validation_workflow
\ No newline at end of file
OPCUADocument
\ No newline at end of file
erp5_opcua
\ No newline at end of file
erp5_opcua
\ No newline at end of file
<?xml version='1.0' encoding='utf-8'?>
<UANodeSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:uax="http://opcfoundation.org/UA/2008/02/Types.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://opcfoundation.org/UA/2011/03/UANodeSet.xsd">
<NamespaceUris>
<Uri>http://erp5.com</Uri>
</NamespaceUris>
<Aliases>
<Alias Alias="Int64">i=8</Alias>
<Alias Alias="Organizes">i=35</Alias>
<Alias Alias="HasTypeDefinition">i=40</Alias>
<Alias Alias="HasComponent">i=47</Alias>
</Aliases>
<UAObject NodeId="ns=1;i=1" BrowseName="1:erp5-test-object-0" ParentNodeId="i=85">
<DisplayName>erp5-test-object-0</DisplayName>
<Description>erp5-test-object-0</Description>
<References>
<Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=2</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=2" BrowseName="1:erp5-variable" ParentNodeId="ns=1;i=1" DataType="Int64" AccessLevel="3" UserAccessLevel="3">
<DisplayName>erp5-variable</DisplayName>
<Description>erp5-variable</Description>
<References>
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=1</Reference>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>
<UAObject NodeId="ns=1;i=3" BrowseName="1:erp5-test-object-1" ParentNodeId="i=85">
<DisplayName>erp5-test-object-1</DisplayName>
<Description>erp5-test-object-1</Description>
<References>
<Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=4</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=4" BrowseName="1:erp5-variable" ParentNodeId="ns=1;i=3" DataType="Int64" AccessLevel="3" UserAccessLevel="3">
<DisplayName>erp5-variable</DisplayName>
<Description>erp5-variable</Description>
<References>
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=3</Reference>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>
<UAObject NodeId="ns=1;i=5" BrowseName="1:erp5-test-object-2" ParentNodeId="i=85">
<DisplayName>erp5-test-object-2</DisplayName>
<Description>erp5-test-object-2</Description>
<References>
<Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=6</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=6" BrowseName="1:erp5-variable" ParentNodeId="ns=1;i=5" DataType="Int64" AccessLevel="3" UserAccessLevel="3">
<DisplayName>erp5-variable</DisplayName>
<Description>erp5-variable</Description>
<References>
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=5</Reference>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>
<UAObject NodeId="ns=1;i=7" BrowseName="1:erp5-test-object-3" ParentNodeId="i=85">
<DisplayName>erp5-test-object-3</DisplayName>
<Description>erp5-test-object-3</Description>
<References>
<Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=8</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=8" BrowseName="1:erp5-variable" ParentNodeId="ns=1;i=7" DataType="Int64" AccessLevel="3" UserAccessLevel="3">
<DisplayName>erp5-variable</DisplayName>
<Description>erp5-variable</Description>
<References>
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=7</Reference>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>
<UAObject NodeId="ns=1;i=9" BrowseName="1:erp5-test-object-4" ParentNodeId="i=85">
<DisplayName>erp5-test-object-4</DisplayName>
<Description>erp5-test-object-4</Description>
<References>
<Reference ReferenceType="Organizes" IsForward="false">i=85</Reference>
<Reference ReferenceType="HasTypeDefinition">i=58</Reference>
<Reference ReferenceType="HasComponent">ns=1;i=10</Reference>
</References>
</UAObject>
<UAVariable NodeId="ns=1;i=10" BrowseName="1:erp5-variable" ParentNodeId="ns=1;i=9" DataType="Int64" AccessLevel="3" UserAccessLevel="3">
<DisplayName>erp5-variable</DisplayName>
<Description>erp5-variable</Description>
<References>
<Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=9</Reference>
<Reference ReferenceType="HasTypeDefinition">i=63</Reference>
</References>
</UAVariable>
</UANodeSet>
\ No newline at end of file
#!//usr/bin/python
"""
Basic OPC UA <-> HTTP gateway server.
"""
import sys
import asyncio
import asyncua
from dataclasses import dataclass, field
import json
import requests
import urllib
import argparse
import logging
import __main__
# command line handling
parser = argparse.ArgumentParser(description='Run OPCUA Server.')
a = parser.add_argument
a('--ip', help='The IP address on which the OPCUA Server runs', default="127.0.0.1")
a('--port', help='The port on which the OPCUA Server runs', default="4840")
a('--xml', help='Path of XML to configure Server. See asyncua doc for more details.', default=None)
a('--erp5-url', help='URL of ERP5 instance to which data shall be send.', default=None)
a('--erp5-username', help='Username of ERP5 instance to which data shall be send.', default=None)
a('--erp5-password', help='Password of ERP5 instance to which data shall be send.', default=None)
args = parser.parse_args()
ip = args.ip
port = args.port
xml = args.xml
erp5_url = args.erp5_url
erp5_username = args.erp5_username
erp5_password = args.erp5_password
ERP5_REQUEST_API = "ERP5Site_handleOPCUARequest"
# ERP5 backend storage for OPCUA Document
@dataclass(frozen=True)
class ERP5Handler(asyncua.common.subscription.SubHandler):
url: str
session: requests.Session = field(default_factory=requests.Session)
@property
def uri(self):
if self.url is not None:
return f"%s/%s" %(self.url, ERP5_REQUEST_API)
def call(self, http_method = "POST", **data):
params = urllib.parse.quote_plus(json.dumps({k: str(v) for k, v in data.items()}))
self.session.auth = (erp5_username, erp5_password)
if http_method == "POST":
self.session.post(f"{self.uri}?data={params}")
elif http_method == "GET":
return self.session.get(f"{self.uri}")
def datachange_notification(self, node, val, data):
self.call(node=node, val=val, data=data)
def event_notification(self, event):
self.call(event=event)
# init main ERP5 storage
erp5_handler = ERP5Handler(erp5_url)
class InternalSession(asyncua.server.internal_session.InternalSession):
async def read(self, params):
erp5_handler.call(params=params)
return await super().read(params)
# Start OPCUA Server
async def main():
_logger = logging.getLogger(__name__)
# setup our server
server = asyncua.Server()
await server.init()
server.set_endpoint(f"opc.tcp://{ip}:{port}/freeopcua/server/")
if xml is not None:
await server.import_xml(xml)
# read previous state as saved in ERP5 backend
erp5_json = erp5_handler.call(http_method="GET").json()
_logger.error(erp5_json)
for k,v in erp5_json.items():
# set
node = server.get_node(k)
_logger.debug("Init from ERP5. Set %s = %s at %s" %(k, v, node))
await node.write_value(v)
subscription = await server.create_subscription(1000, erp5_handler)
await subscription.subscribe_events()
nodes = await asyncua.common.ua_utils.get_nodes_of_namespace(server)
await subscription.subscribe_data_change(nodes)
def create_session(name,
user=asyncua.server.users.User(role=asyncua.server.users.UserRole.Anonymous),
external=False):
self = server.iserver
return InternalSession(self, self.aspace, self.subscription_service, name, user=user, external=external)
server.iserver.create_session = create_session
# start OPCUA server
_logger.info("Starting server!")
async with server:
while True:
await asyncio.sleep(1)
logging.basicConfig(level=logging.DEBUG)
asyncio.run(main(), debug=True)
if __name__ == '__main__':
sys.exit(__main__.main())
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment