Skip to content
Snippets Groups Projects
Commit 409ab032 authored by Jan David Mol's avatar Jan David Mol
Browse files

Split off helper functions into separate files

parent 96ed3b95
No related branches found
No related tags found
No related merge requests found
......@@ -25,121 +25,13 @@ import sys
import opcua
import traceback
import numpy
import time
from threading import Thread
from functools import wraps
import socket
from wrappers import only_when_on, fault_on_error
from opcua_connection import OPCUAConnection
__all__ = ["RCUSCC", "main"]
def only_when_on(func):
"""
Wrapper to return None when the device isn't in ON state.
If in ON state, calls & returns the wrapped function.
"""
@wraps(func)
def when_on_wrapper(self, *args, **kwargs):
if self.get_state() != DevState.ON:
return None
return func(self, *args, **kwargs)
return when_on_wrapper
def fault_on_error(func):
"""
Wrapper to catch exceptions. Sets the device in a FAULT state if any occurs.
"""
@wraps(func)
def error_wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except Exception as e:
self.error_stream("Function failed. Trace: %s", traceback.format_exc())
self.Fault()
return None
return error_wrapper
class OPCUAConnection(Thread):
"""
Connects to OPC-UA in the foreground or background, and sends HELLO
messages to keep a check on the connection. On connection failure, reconnects once.
"""
def __init__(self, client, on_func, fault_func, streams, try_interval=2):
super().__init__(daemon=True)
self.client = client
self.on_func = on_func
self.fault_func = fault_func
self.try_interval = try_interval
self.streams = streams
self.stopping = False
self.connected = False
def _servername(self):
return self.client.server_url.geturl()
def connect(self):
try:
self.streams.debug_stream("Connecting to server %s", self._servername())
self.client.connect()
self.connected = True
self.streams.debug_stream("Connected to server. Initialising.")
return True
except socket.error as e:
self.streams.error_stream("Could not connect to server %s: %s", self._servername(), e)
return False
def disconnect(self):
self.connected = False # always force a reconnect, regardless of a successful disconnect
try:
self.client.disconnect()
except Exception as e:
self.streams.error_stream("Disconnect from OPC-UA server %s failed: %s", self._servername(), e)
def run(self):
while not self.stopping:
# keep trying to connect
if not self.connected:
if self.connect():
self.on_func()
else:
# we retry only once, to catch exotic network issues. if the infra or hardware is down,
# our device cannot help, and must be reinitialised after the infra or hardware is fixed.
self.fault_func()
return
# keep checking if the connection is still alive
try:
while not self.stopping:
self.client.send_hello()
time.sleep(self.try_interval)
except Exception as e:
self.streams.error_stream("Lost connection to server %s: %s", self._servername(), e)
# technically, we may not have dropped the connection, but encounter a different error. so explicitly disconnect.
self.disconnect()
# signal that we're disconnected
self.fault_func()
def stop(self):
"""
Stop connecting & disconnect. Can take a few seconds for the timeouts to hit.
"""
self.stopping = True
self.join()
self.disconnect()
class RCUSCC(Device):
"""
......
from threading import Thread
import socket
import time
__all__ = ["OPCUAConnection"]
class OPCUAConnection(Thread):
"""
Connects to OPC-UA in the foreground or background, and sends HELLO
messages to keep a check on the connection. On connection failure, reconnects once.
"""
def __init__(self, client, on_func, fault_func, streams, try_interval=2):
super().__init__(daemon=True)
self.client = client
self.on_func = on_func
self.fault_func = fault_func
self.try_interval = try_interval
self.streams = streams
self.stopping = False
self.connected = False
def _servername(self):
return self.client.server_url.geturl()
def connect(self):
try:
self.streams.debug_stream("Connecting to server %s", self._servername())
self.client.connect()
self.connected = True
self.streams.debug_stream("Connected to server. Initialising.")
return True
except socket.error as e:
self.streams.error_stream("Could not connect to server %s: %s", self._servername(), e)
return False
def disconnect(self):
self.connected = False # always force a reconnect, regardless of a successful disconnect
try:
self.client.disconnect()
except Exception as e:
self.streams.error_stream("Disconnect from OPC-UA server %s failed: %s", self._servername(), e)
def run(self):
while not self.stopping:
# keep trying to connect
if not self.connected:
if self.connect():
self.on_func()
else:
# we retry only once, to catch exotic network issues. if the infra or hardware is down,
# our device cannot help, and must be reinitialised after the infra or hardware is fixed.
self.fault_func()
return
# keep checking if the connection is still alive
try:
while not self.stopping:
self.client.send_hello()
time.sleep(self.try_interval)
except Exception as e:
self.streams.error_stream("Lost connection to server %s: %s", self._servername(), e)
# technically, we may not have dropped the connection, but encounter a different error. so explicitly disconnect.
self.disconnect()
# signal that we're disconnected
self.fault_func()
def stop(self):
"""
Stop connecting & disconnect. Can take a few seconds for the timeouts to hit.
"""
self.stopping = True
self.join()
self.disconnect()
from tango import DevState
from functools import wraps
import traceback
__all__ = ["only_when_on", "fault_on_error"]
def only_when_on(func):
"""
Wrapper to return None when the device isn't in ON state.
If in ON state, calls & returns the wrapped function.
"""
@wraps(func)
def when_on_wrapper(self, *args, **kwargs):
if self.get_state() != DevState.ON:
return None
return func(self, *args, **kwargs)
return when_on_wrapper
def fault_on_error(func):
"""
Wrapper to catch exceptions. Sets the device in a FAULT state if any occurs.
"""
@wraps(func)
def error_wrapper(self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except Exception as e:
self.error_stream("Function failed. Trace: %s", traceback.format_exc())
self.Fault()
return None
return error_wrapper
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment