Commit 52c805fd authored by Philipp's avatar Philipp

Accessing webportal as client not server.

parent 31045f10
...@@ -5,6 +5,7 @@ Basic OPC UA <-> HTTP gateway server. ...@@ -5,6 +5,7 @@ Basic OPC UA <-> HTTP gateway server.
import sys import sys
import asyncio import asyncio
from asyncua import Client, ua
import asyncua import asyncua
from dataclasses import dataclass, field from dataclasses import dataclass, field
import json import json
...@@ -13,6 +14,7 @@ import urllib ...@@ -13,6 +14,7 @@ import urllib
import argparse import argparse
import logging import logging
import __main__ import __main__
import random
# command line handling # command line handling
parser = argparse.ArgumentParser(description='Run OPCUA Server.') parser = argparse.ArgumentParser(description='Run OPCUA Server.')
...@@ -35,6 +37,9 @@ erp5_url = args.erp5_url ...@@ -35,6 +37,9 @@ erp5_url = args.erp5_url
erp5_username = args.erp5_username erp5_username = args.erp5_username
erp5_password = args.erp5_password erp5_password = args.erp5_password
ERP5_REQUEST_API = "ERP5Site_handleOPCUARequest" ERP5_REQUEST_API = "ERP5Site_handleOPCUARequest"
read_backend = False
bool_server = False
bool_client = True
# ERP5 backend storage for OPCUA Document # ERP5 backend storage for OPCUA Document
@dataclass(frozen=True) @dataclass(frozen=True)
...@@ -61,9 +66,9 @@ class ERP5Handler(asyncua.common.subscription.SubHandler): ...@@ -61,9 +66,9 @@ class ERP5Handler(asyncua.common.subscription.SubHandler):
self.session.auth = (erp5_username, erp5_password) self.session.auth = (erp5_username, erp5_password)
if http_method == "POST": if http_method == "POST":
self.session.post(f"{self.uri}?data={params}") self.session.post(f"{self.uri}?data={params}")
elif http_method == "GET": elif http_method == "GET":
return self.session.get(f"{self.uri}") return self.session.get(f"{self.uri}")
def datachange_notification(self, node, val, data): def datachange_notification(self, node, val, data):
self.call(node=node, val=val, data=data) self.call(node=node, val=val, data=data)
...@@ -83,46 +88,115 @@ class InternalSession(asyncua.server.internal_session.InternalSession): ...@@ -83,46 +88,115 @@ class InternalSession(asyncua.server.internal_session.InternalSession):
# Start OPCUA Server # Start OPCUA Server
async def main(): async def main():
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
if bool_client:
# setup our server #VariantType=<VariantType.Boolean
server = asyncua.Server() #VariantType=<VariantType.Int64
await server.init() # Example of creating and sending data to the HTTP backend
def send_custom_data(node, val, data_type):
if bool(int(ipv6_enabled)): custom_data = {
server.set_endpoint(f"opc.tcp://[{ipv6}]:{port}/freeopcua/server/") 'node': node,
#else: 'val': val,
# server.set_endpoint(f"opc.tcp://{ipv4}:{port}/freeopcua/server/") 'data': data_type
}
if xml is not None: # Send the data to the ERP5 backend
await server.import_xml(xml) erp5_handler.call(http_method="POST", **custom_data)
_logger.info("Sent custom data to ERP5 backend")
# read previous state as saved in ERP5 backend # FHI Server
erp5_json = erp5_handler.call(http_method="GET").json() ipv6 = "2001:67c:1254:108:404e::a"
_logger.error(erp5_json) url = f"opc.tcp://[{ipv6}]:{port}/PwDC"
for k,v in erp5_json.items(): _logger.info("Connecting to %s ...", url)
# set async with Client(url=url, timeout=2) as client:
node = server.get_node(k) while True:
_logger.debug("Init from ERP5. Set %s = %s at %s" %(k, v, node)) await asyncio.sleep(1)
await node.write_value(v) # Get the root node
root = client.get_root_node()
subscription = await server.create_subscription(1000, erp5_handler)
await subscription.subscribe_events() # Get the objects node
nodes = await asyncua.common.ua_utils.get_nodes_of_namespace(server) objects = await root.get_child("0:Objects")
await subscription.subscribe_data_change(nodes)
# Get the Powerfuse object
def create_session(name, powerfuse_obj = await objects.get_child("1:Powerfuse")
user=asyncua.server.users.User(role=asyncua.server.users.UserRole.Anonymous),
external=False): # Get the variables
self = server.iserver machine_status_rot = await powerfuse_obj.get_child("1:Powerfuse_Maschinenstatus_Status_Rot")
return InternalSession(self, self.aspace, self.subscription_service, name, user=user, external=external) machine_status_gelb = await powerfuse_obj.get_child("1:Powerfuse_Maschinenstatus_Status_Gelb")
server.iserver.create_session = create_session # Read values
value_rot = await machine_status_rot.read_value()
# start OPCUA server value_gelb = await machine_status_gelb.read_value()
_logger.info("Starting server!") _logger.info(f"Initial values: Rot={value_rot}, Gelb={value_gelb}")
async with server:
while True: # Write values
await asyncio.sleep(1) await machine_status_rot.write_value(True)
await machine_status_gelb.write_value(False)
# Start sending custom data in the background
send_custom_data(node = "Powerfuse_Maschinenstatus_Status_Rot",
val = value_rot,
data_type = "VariantType=<VariantType.String")
if bool_server:
# setup our server
server = asyncua.Server()
await server.init()
if bool(int(ipv6_enabled)):
# todo change name of /freeopcua/server
_logger.debug(f"Setting endpoint to: opc.tcp://[{ipv6}]:{port}/freeopcua/server/")
server.set_endpoint(f"opc.tcp://[{ipv6}]:{port}/freeopcua/server/")
#else:
# server.set_endpoint(f"opc.tcp://{ipv4}:{port}/freeopcua/server/")
if xml is not None:
await server.import_xml(xml)
# read previous state as saved in ERP5 backend
#todo: BadNodeIdUnknown is due to the fact that when the server is started the node is not yet created - first create node than read it from backend
if read_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
# Example of creating and sending data to the HTTP backend
async def send_custom_data():
while True:
# Create your custom data
custom_data = {
'node': 'ns=2;s=MyCustomNode',
'val': random.randint(0, 19),
'data': 'VariantType=<VariantType.Int64'
}
# Send the data to the ERP5 backend
erp5_handler.call(http_method="POST", **custom_data)
_logger.info("Sent custom data to ERP5 backend")
await asyncio.sleep(10) # Wait for 10 seconds before sending next data
# Start sending custom data in the background
asyncio.create_task(send_custom_data())
# start OPCUA server
_logger.info("Starting server!")
async with server:
# End creating nodes for
while True:
await asyncio.sleep(1)
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
asyncio.run(main(), debug=True) asyncio.run(main(), debug=True)
......
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