Commit b068e4cb authored by Levin Zimmermann's avatar Levin Zimmermann

component/opcua-server: notify erp5 if datachange

parent 5f8dc534
......@@ -3,7 +3,10 @@ parts = opcua-server
[opcua-server]
recipe = zc.recipe.egg
eggs = asyncua
eggs =
asyncua
# To send data to erp5
requests
egg-versions =
asyncua = 1.0.1
sortedcontainers = 2.4.0
......@@ -12,27 +15,44 @@ egg-versions =
python-dateutil = 2.8.2:whl
entry-points = ${:_buildout_section_name_}=__main__:main
initialization =
# ######################
# #################################
# Configure
import argparse
parser = argparse.ArgumentParser(description='Run OPCUA Server.')
parser.add_argument(
'--ip', help='The IP address on which the OPCUA Server runs', default="127.0.0.1"
)
parser.add_argument(
'--port', help='The port on which the OPCUA Server runs', default="2262"
)
parser.add_argument(
'--xml',
help='Path of XML to configure Server. See asyncua doc for more details.',
default=None
)
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="2262")
a('--xml', help='Path of XML to configure Server. See asyncua doc for more details.', default=None)
a('--erp5-ip', help='IP of ERP5 instance to which data shall be send.', default=None)
a('--erp5-port', help='Port of ERP5 instance to which data shall be send.', default=None)
args = parser.parse_args()
ip, port, xml = args.ip, args.port, args.xml
# ######################
ip, port, xml, erp5_ip, erp5_port = args.ip, args.port, args.xml, args.erp5_ip, args.erp5_port
# #################################
# Define ERP5Handler
from dataclasses import dataclass, field
import json
import requests
import urllib
from asyncua.common.subscription import SubHandler
@dataclass(frozen=True)
class ERP5Handler(SubHandler):
ip: str
port: str
session: requests.Session = field(default_factory=requests.Session)
@property
def uri(self):
return f"http://{self.ip}:{self.port}/erp5/opcua_test"
def call(self, **data):
params = urllib.parse.quote_plus(json.dumps({k: str(v) for k, v in data.items()}))
self.session.post(f"{self.uri}?data={params}")
def datachange_notification(self, node, val, data):
self.call(node=node, val=val, data=data)
# #################################
# Start OPCUA Server
import asyncio
import logging
from asyncua import Server
from asyncua.common.ua_utils import get_nodes_of_namespace
async def main():
_logger = logging.getLogger(__name__)
# setup our server
......@@ -41,6 +61,13 @@ initialization =
server.set_endpoint(f"opc.tcp://{ip}:{port}/freeopcua/server/")
if xml is not None:
await server.import_xml(xml)
if erp5_ip is not None and erp5_port is not None:
erp5_handler = ERP5Handler(erp5_ip, erp5_port)
subscription = await server.create_subscription(1000, erp5_handler)
await subscription.subscribe_events()
nodes = await get_nodes_of_namespace(server)
await subscription.subscribe_data_change(nodes)
_logger.info("Added subscription for erp5 handler.")
_logger.info("Starting server!")
async with server:
while True:
......
......@@ -2,6 +2,9 @@
{# port is hard coded here + in stack/erp5/haproxy.cfg.in #}
{% set port = 2262 %}
{% set opcua_server_config = parameter_dict["opcua_server_config_xml"] %}
{# erp5 port hard coded for now. #}
{# see https://lab.nexedi.com/nexedi/slapos/blob/a729a677/stack/erp5/instance-erp5.cfg.in#L310 #}
{% set erp5_port = "2200" %}
[buildout]
extends = {{ template_monitor }}
......@@ -22,5 +25,5 @@ var = ${buildout:directory}/var
[opcua-server]
recipe = slapos.cookbook:wrapper
command-line =
{{ bin_directory }}/opcua-server --ip {{ ipv4 }} --port {{ port }} --xml {{ opcua_server_config }}
{{ bin_directory }}/opcua-server --ip {{ ipv4 }} --port {{ port }} --xml {{ opcua_server_config }} --erp5-ip {{ ipv4 }} --erp5-port {{ erp5_port }}
wrapper-path = ${directory:service-on-watch}/opcua-server
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