def test_context_manager(self): """ Context manager calls start() and stop() """ state = [0] def increment_state(self, *args, **kwargs): state[0] += 1 # create server and replace instance methods with dummy methods server = Server() server.start = increment_state.__get__(server) server.stop = increment_state.__get__(server) assert state[0] == 0 with server: # test if server started self.assertEqual(state[0], 1) # test if server stopped self.assertEqual(state[0], 2)
class HelloServer: def __init__(self, endpoint, name, model_filepath): self.server = Server() # This need to be imported at the start or else it will overwrite the data self.server.import_xml(model_filepath) self.server.set_endpoint(endpoint) self.server.set_server_name(name) objects = self.server.get_objects_node() freeopcua_namespace = self.server.get_namespace_index("urn:freeopcua:python:server") hellower = objects.get_child("0:Hellower") hellower_say_hello = hellower.get_child("0:SayHello") self.server.link_method(hellower_say_hello, say_hello_xml) hellower.add_method( freeopcua_namespace, "SayHello2", say_hello, [ua.VariantType.Boolean], [ua.VariantType.String]) hellower.add_method( freeopcua_namespace, "SayHelloArray", say_hello_array, [ua.VariantType.Boolean], [ua.VariantType.String]) def __enter__(self): self.server.start() return self.server def __exit__(self, exc_type, exc_val, exc_tb): self.server.stop()
class TestClient(unittest.TestCase, CommonTests): ''' Run common tests on client side Of course we need a server so we start a server in another process using python Process module Tests that can only be run on client side must be defined here ''' @classmethod def setUpClass(self): # start our own server self.srv = Server() self.srv.set_endpoint('opc.tcp://localhost:%d' % port_num1) add_server_methods(self.srv) self.srv.start() # start client self.clt = Client('opc.tcp://localhost:%d' % port_num1) self.clt.connect() self.opc = self.clt @classmethod def tearDownClass(self): self.clt.disconnect() # stop the server in its own process self.srv.stop() def test_service_fault(self): request = ua.ReadRequest() request.TypeId = ua.FourByteNodeId(999) # bad type! with self.assertRaises(Exception): self.clt.bclient._send_request(request)
def start(self, host, port): self.set_endpoint("opc.tcp://" + str(host) + ":" + str(port) + "/ua/server/") logger.info('OPCUA server started on: %s', (host, port)) Server.start(self) # Subscription Handler handler = SubHandler() sub = self.create_subscription(500, handler) for ua_variable in self.variables: sub.subscribe_data_change(ua_variable)
class TestRefsWidget(unittest.TestCase): def setUp(self): self.server = Server() self.server.set_endpoint("opc.tcp://0.0.0.0:48409/freeopcua/server/") self.server.start() self.widget = RefsWidget(QTableView()) def tearDown(self): self.server.stop() def test_1(self): o = self.server.nodes.objects self.widget.show_refs(o)
def test_port_in_use(self): server1 = Server() server1.set_endpoint('opc.tcp://localhost:{0:d}'.format(port_num + 1)) server1.start() server2 = Server() server2.set_endpoint('opc.tcp://localhost:{0:d}'.format(port_num + 1)) try: server2.start() except Exception: pass server1.stop() server2.stop()
class TestServer(unittest.TestCase, CommonTests): ''' Run common tests on server side Tests that can only be run on server side must be defined here ''' @classmethod def setUpClass(self): self.srv = Server() self.srv.set_endpoint('opc.tcp://localhost:%d' % port_num2) add_server_methods(self.srv) self.srv.start() self.opc = self.srv @classmethod def tearDownClass(self): self.srv.stop() def test_register_namespace(self): uri = 'http://mycustom.Namespace.com' idx1 = self.opc.register_namespace(uri) idx2 = self.opc.get_namespace_index(uri) self.assertEqual(idx1, idx2) def test_register_use_namespace(self): uri = 'http://my_very_custom.Namespace.com' idx = self.opc.register_namespace(uri) root = self.opc.get_root_node() myvar = root.add_variable(idx, 'var_in_custom_namespace', [5]) myid = myvar.nodeid self.assertEqual(idx, myid.NamespaceIndex) def test_server_method(self): def func(parent, variant): variant.Value *= 2 return [variant] o = self.opc.get_objects_node() v = o.add_method(3, 'Method1', func, [ua.VariantType.Int64], [ua.VariantType.Int64]) result = o.call_method(v, ua.Variant(2.1)) self.assertEqual(result, 4.2) def test_xml_import(self): self.srv.import_xml("tests/custom_nodes.xml") o = self.opc.get_objects_node() v = o.get_child(["MyXMLFolder", "MyXMLObject", "MyXMLVariable"]) val = v.get_value() self.assertEqual(val, "StringValue")
class TestCmdLines(unittest.TestCase): ''' Test command lines ''' @classmethod def setUpClass(self): self.srv = Server() self.srv_url = 'opc.tcp://localhost:%d' % port_num self.srv.set_endpoint(self.srv_url) objects = self.srv.get_objects_node() obj = objects.add_object(4, "directory") var = obj.add_variable(4, "variable", 1.999) var2 = obj.add_variable(4, "variable2", 1.777) var2.set_writable() self.srv.start() def test_uals(self): s = subprocess.check_output(["python", "tools/uals", "--url", self.srv_url]) self.assertIn(b"i=85", s) self.assertNotIn(b"i=89", s) self.assertNotIn(b"1.999", s) s = subprocess.check_output(["python", "tools/uals", "--url", self.srv_url, "-d", "3"]) self.assertIn(b"1.999", s) def test_uaread(self): s = subprocess.check_output(["python", "tools/uaread", "--url", self.srv_url, "--path", "0:Objects,4:directory,4:variable"]) self.assertIn(b"1.999", s) def test_uawrite(self): s = subprocess.check_output(["python", "tools/uawrite", "--url", self.srv_url, "--path", "0:Objects,4:directory,4:variable2", "1.789"]) s = subprocess.check_output(["python", "tools/uaread", "--url", self.srv_url, "--path", "0:Objects,4:directory,4:variable2"]) self.assertIn(b"1.789", s) self.assertNotIn(b"1.999", s) def test_uadiscover(self): s = subprocess.check_output(["python", "tools/uadiscover", "--url", self.srv_url]) self.assertIn(b"opc.tcp://localhost", s) self.assertIn(b"FreeOpcUa", s) self.assertIn(b"urn:freeopcua:python:server", s) @classmethod def tearDownClass(self): self.srv.stop()
class TestClient(unittest.TestCase): def setUp(self): self.server = Server() url = "opc.tcp://localhost:48400/freeopcua/server/" self.server.set_endpoint(url) self.server.start() self.client = Window() self.client.ui.addrComboBox.setCurrentText(url) self.client.connect() def tearDown(self): self.client.disconnect() self.server.stop() def get_attr_value(self, text): idxlist = self.client.attrs_ui.model.match(self.client.attrs_ui.model.index(0, 0), Qt.DisplayRole, text, 1, Qt.MatchExactly | Qt.MatchRecursive) idx = idxlist[0] idx = idx.sibling(idx.row(), 1) item = self.client.attrs_ui.model.itemFromIndex(idx) return item.data(Qt.UserRole).value def test_select_objects(self): objects = self.server.nodes.objects self.client.tree_ui.set_current_node("Objects") self.assertEqual(objects, self.client.tree_ui.get_current_node()) self.assertGreater(self.client.attrs_ui.model.rowCount(), 6) print("REF COUNT", self.client.refs_ui.model.rowCount()) self.assertGreater(self.client.refs_ui.model.rowCount(), 1) data = self.get_attr_value("NodeId") self.assertEqual(data, objects.nodeid) def test_select_server_node(self): self.client.tree_ui.set_current_node("Objects") self.client.tree_ui.expand_current_node() # must be expanded to load children server_node = self.server.nodes.server self.client.tree_ui.set_current_node("Server") self.assertEqual(server_node, self.client.tree_ui.get_current_node()) self.assertGreater(self.client.attrs_ui.model.rowCount(), 6) self.assertGreater(self.client.refs_ui.model.rowCount(), 10) data = self.get_attr_value("NodeId") self.assertEqual(data, server_node.nodeid)
class TestServer(unittest.TestCase, CommonTests): """ Run common tests on server side Tests that can only be run on server side must be defined here """ @classmethod def setUpClass(self): self.srv = Server() self.srv.set_endpoint("opc.tcp://localhost:%d" % port_num2) add_server_methods(self.srv) self.srv.start() self.opc = self.srv @classmethod def tearDownClass(self): self.srv.stop() def test_register_namespace(self): uri = "http://mycustom.Namespace.com" idx1 = self.opc.register_namespace(uri) idx2 = self.opc.get_namespace_index(uri) self.assertEqual(idx1, idx2) def test_register_use_namespace(self): uri = "http://my_very_custom.Namespace.com" idx = self.opc.register_namespace(uri) root = self.opc.get_root_node() myvar = root.add_variable(idx, "var_in_custom_namespace", [5]) myid = myvar.nodeid self.assertEqual(idx, myid.NamespaceIndex) def test_server_method(self): def func(parent, variant): variant.Value *= 2 return [variant] o = self.opc.get_objects_node() v = o.add_method(3, "Method1", func, [ua.VariantType.Int64], [ua.VariantType.Int64]) result = o.call_method(v, ua.Variant(2.1)) self.assertEqual(result, 4.2)
def mymain(): # setup our server server = Server() server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/") # setup our own namespace, not really necessary but should as spec uri = "http://examples.freeopcua.github.io" idx = server.register_namespace(uri) # get Objects node, this is where we should put our nodes objects = server.get_objects_node() # populating our address space myobj = objects.add_object(idx, "MyObject") myvar = myobj.add_variable(idx, "MyVariable", 6.7) myvar.set_writable() # Set MyVariable to be writable by clients # starting! server.start() server.stop()
class ServerPython(object): def __init__(self): self._server = None self.nodes = None self.get_node = None self.get_namespace_array = None def start_server(self, endpoint): logger.info("Starting python-opcua server") self._server = Server() self._server.set_endpoint(endpoint) self._server.set_server_name("OpcUa Modeler Server") self.nodes = self._server.nodes self.get_node = self._server.get_node self.get_namespace_array = self._server.get_namespace_array self.load_type_definitions = self._server.load_type_definitions self.load_enums = self._server.load_enums # now remove freeopcua namespace, not necessary when modeling and # ensures correct idx for exported nodesets ns_node = self._server.get_node(ua.NodeId(ua.ObjectIds.Server_NamespaceArray)) nss = ns_node.get_value() ns_node.set_value(nss[:1]) self._server.start() def stop_server(self): if self._server is not None: self._server.stop() self._server = None self.get_node = None self.get_namespace_array = None def import_xml(self, path): return self._server.import_xml(path) def export_xml(self, nodes, uris, path): exp = XmlExporter(self._server) exp.build_etree(nodes, uris=uris) exp.write_xml(path)
class TestServer(unittest.TestCase, CommonTests): ''' Run common tests on server side Tests that can only be run on server side must be defined here ''' @classmethod def setUpClass(self): self.srv = Server() self.srv.set_endpoint('opc.tcp://localhost:%d' % port_num2) add_server_methods(self.srv) self.srv.start() self.opc = self.srv self.discovery = Server() self.discovery.set_application_uri("urn:freeopcua:python:discovery") self.discovery.set_endpoint('opc.tcp://localhost:%d' % port_discovery) self.discovery.start() @classmethod def tearDownClass(self): self.srv.stop() self.discovery.stop() def test_discovery(self): client = Client(self.discovery.endpoint.geturl()) client.connect() servers = client.find_servers() new_app_uri = "urn:freeopcua:python:server::test_discovery" self.srv.application_uri = new_app_uri self.srv.register_to_discovery(self.discovery.endpoint.geturl(), 1) time.sleep(0.1) # let server register registration new_servers = client.find_servers() self.assertEqual(len(new_servers) - len(servers) , 1) self.assertFalse(new_app_uri in [s.ApplicationUri for s in servers]) self.assertTrue(new_app_uri in [s.ApplicationUri for s in new_servers]) client.disconnect() """ # not sure if this test is necessary, and there is a lot repetition with previous test def test_discovery_server_side(self): servers = self.discovery.find_servers() self.assertEqual(len(servers), 1) self.srv.register_to_discovery(self.discovery.endpoint.geturl(), 1) time.sleep(1) # let server register registration servers = self.discovery.find_servers() print("SERVERS 2", servers) self.assertEqual(len(servers), 2) """ #def test_register_server2(self): #servers = self.opc.register_server() def test_register_namespace(self): uri = 'http://mycustom.Namespace.com' idx1 = self.opc.register_namespace(uri) idx2 = self.opc.get_namespace_index(uri) self.assertEqual(idx1, idx2) def test_register_use_namespace(self): uri = 'http://my_very_custom.Namespace.com' idx = self.opc.register_namespace(uri) root = self.opc.get_root_node() myvar = root.add_variable(idx, 'var_in_custom_namespace', [5]) myid = myvar.nodeid self.assertEqual(idx, myid.NamespaceIndex) def test_server_method(self): def func(parent, variant): variant.Value *= 2 return [variant] o = self.opc.get_objects_node() v = o.add_method(3, 'Method1', func, [ua.VariantType.Int64], [ua.VariantType.Int64]) result = o.call_method(v, ua.Variant(2.1)) self.assertEqual(result, 4.2) def test_xml_import(self): self.srv.import_xml("tests/custom_nodes.xml") o = self.opc.get_objects_node() v = o.get_child(["MyXMLFolder", "MyXMLObject", "MyXMLVariable"]) val = v.get_value() self.assertEqual(val, "StringValue")
class AdminTestClient(unittest.TestCase, CommonTests): ''' Run common tests on client side Of course we need a server so we start a server in another process using python Process module Tests that can only be run on client side must be defined here ''' @classmethod def setUpClass(self): # start our own server self.srv = Server() self.srv.set_endpoint('opc.tcp://*****:*****@localhost:%d' % port_num1) self.clt.connect() self.opc = self.clt # start anonymous client self.ro_clt = Client('opc.tcp://localhost:%d' % port_num1) self.ro_clt.connect() @classmethod def tearDownClass(self): #stop our clients self.ro_clt.disconnect() self.clt.disconnect() # stop the server self.srv.stop() def test_service_fault(self): request = ua.ReadRequest() request.TypeId = ua.FourByteNodeId(999) # bad type! with self.assertRaises(Exception): self.clt.bclient._send_request(request) def test_objects_anonymous(self): objects = self.ro_clt.get_objects_node() with self.assertRaises(Exception): objects.set_attribute(ua.AttributeIds.WriteMask, ua.DataValue(999)) with self.assertRaises(Exception): f = objects.add_folder(3, 'MyFolder') def test_folder_anonymous(self): objects = self.clt.get_objects_node() f = objects.add_folder(3, 'MyFolderRO') f_ro = self.ro_clt.get_node(f.nodeid) self.assertEqual(f, f_ro) with self.assertRaises(Exception): f2 = f_ro.add_folder(3, 'MyFolder2') def test_variable_anonymous(self): objects = self.clt.get_objects_node() v = objects.add_variable(3, 'MyROVariable', 6) v.set_value(4) #this should work v_ro = self.ro_clt.get_node(v.nodeid) with self.assertRaises(Exception): v_ro.set_value(2) self.assertEqual(v_ro.get_value(), 4) v.set_writable(True) v_ro.set_value(2) #now it should work self.assertEqual(v_ro.get_value(), 2) v.set_writable(False) with self.assertRaises(Exception): v_ro.set_value(9) self.assertEqual(v_ro.get_value(), 2)
class SimulatedController(Server): """Simulated controller with OPC UA server for testing. class attributes added to opcua.Server: _server _nodes """ def __init__(self, parameter_file): """Create a Fake OPC UA server with updating nodes. Arguments parameter_file (str): Filename for the service parameters. """ super(SimulatedController, self).__init__() self._server = None self._nodes = dict() self._params = self._get_parameters(parameter_file) def _get_parameters(self, config_file): """Read and parse the yaml file containing the configuration parameters to start the services. Arguments config_file (str): Filename containing parameters formatted as yaml. returns (dict): Parameters. """ params = helper_functions.yaml_to_dict(config_file) logger.info("retrieved service parameters from file") return params def _create_nodes(self, idx, nodes): """Create nodes defined by params. """ for node_obj, node_group in nodes.items(): obj = self._server.nodes.objects.add_object(idx, node_obj) for name, attr in node_group.items(): node = obj.add_variable(idx, name, attr["value"], getattr(ua.VariantType, attr["type"])) node.set_writable( ) if attr["writable"] else node.set_read_only() self._nodes[name] = node def run(self): """Instantiate and run server """ logger.info("starting OPC service") params = self._params self._server = Server() self._server.set_endpoint(params["endpoint"]) self._server.set_server_name(params["name"]) idx = self._server.register_namespace(params["uri"]) self._create_nodes(idx, params["nodes"]) self._server.start() self._start_simulations() def _start_simulations(self): """Start the simulations for the various nodes. """ logger.info("starting simulation threads") try: watchdog = threading.Thread( target=self._update_WATCHDOG_CONTROLLER, daemon=True) watchdog.start() for i in range(10): logger.info("set flow") self._nodes["SET_FLOWRATE_CONTROLLER"].set_value(random() * 1000) sleep(2) logger.info("start") self._nodes["STOP_CONTROLLER"].set_value(False) self._nodes["START_CONTROLLER"].set_value(True) sleep(10) logger.info("stop") self._nodes["START_CONTROLLER"].set_value(False) self._nodes["STOP_CONTROLLER"].set_value(True) logger.info("complete") except KeyboardInterrupt: logger.info("KeyboardInterrupt") finally: # run the server indefinetely for evaluation try: while True: pass except KeyboardInterrupt: pass self._server.stop() logger.info("shutdown") def _update_WATCHDOG_CONTROLLER(self): """Watchdog thread""" logger.info("starting WATCHDOG_CONTROLLER thread") while True: self._nodes["WATCHDOG_CONTROLLER"].set_value( not self._nodes["WATCHDOG_CONTROLLER"].get_value()) sleep(5)
def main(): logging.basicConfig(level=logging.WARN) logger = logging.getLogger("opcua.server.internal_subscription") logger.setLevel(logging.DEBUG) # setup our server server = Server() server.set_endpoint( Commons.OPC_ENDPOINT ) # setup our own namespace, not really necessary but should as spec server_namespace = Commons.OPC_NAMESPACE address_space = server.register_namespace( server_namespace ) # get Objects node, this is where we should put our custom stuff objects_node = server.get_objects_node() # populating our address space ChargeControllerObject = objects_node.add_object(address_space, Commons.MY_OBJECT_NAME) RelayBoxObject = objects_node.add_object(address_space, "RelayBox") panelVoltage = ChargeControllerObject.add_variable( address_space, "panelVoltage", 0.0 ) panelCurrent = ChargeControllerObject.add_variable( address_space, "panelCurrent", 0.0 ) batteryVoltage = ChargeControllerObject.add_variable( address_space, "batteryVoltage", 0.0 ) batteryCurrent = ChargeControllerObject.add_variable( address_space, "batteryCurrent", 0.0 ) loadVoltage = ChargeControllerObject.add_variable( address_space, "loadVoltage", 0.0 ) loadCurrent = ChargeControllerObject.add_variable( address_space, "loadCurrent", 0.0 ) inPower = ChargeControllerObject.add_variable( address_space, "inPower", 0.0 ) outPower = ChargeControllerObject.add_variable( address_space, "outPower", 0.0 ) batteryStatus = ChargeControllerObject.add_variable( address_space, "batteryStatus", "" ) batteryCapacity = ChargeControllerObject.add_variable( address_space, "batteryCapacity", 0.0 ) batteryTemperature = ChargeControllerObject.add_variable( address_space, "batteryTemperature", 0.0 ) ## To make them writable by the clients """ panelVoltage.set_writable() panelCurrent.set_writable() batteryCurrent.set_writable() batteryVoltage.set_writable() loadVoltage.set_writable() loadCurrent.set_writable() inPower.set_writable() outPower.set_writable() batteryStatus.set_writable() batteryCapacity.set_writable() batteryTemperature.set_writable() """ ### Creating a custom EVENT eventType = server.create_custom_event_type( address_space, Commons.MY_FIRST_EVENT_NAME, ua.ObjectIds.BaseEventType, [ ('batteryVoltage', ua.VariantType.Float), ('outputsEnabled', ua.VariantType.Boolean), ] ) myEventGenerator = server.get_event_generator(eventType, ChargeControllerObject) ##creating an array plug_A_current_array = ChargeControllerObject.add_variable(address_space, "plug_A_current_array", [6.7, 7.9]) # the variable could be hard typed plug_B_current_array = ChargeControllerObject.add_variable(address_space, "plug_B_current_array", ua.Variant([], ua.VariantType.Float)) ## creating a property prop_charge_controller_producer = ChargeControllerObject.add_property(address_space, "charge_controller_producer", "Epever") prop_charge_controller_model = ChargeControllerObject.add_property(address_space, "charge_controller_model", "Tracer 2210A MPPT") prop_panel = ChargeControllerObject.add_property(address_space, "panel_info", "12V 100 W") prop_battery = ChargeControllerObject.add_property(address_space, "battery_info", "Bosch 12V") ## Two different methods definitions # First plugs_control_node = RelayBoxObject.add_method(address_space, "set_plug_state", set_plug_state, [ua.VariantType.Boolean], [ua.VariantType.Boolean]) # Second inarg = ua.Argument() inarg.Name = "inverter_state" inarg.DataType = ua.NodeId(ua.ObjectIds.Boolean) inarg.ValueRank = -1 inarg.ArrayDimensions = [] inarg.Description = ua.LocalizedText("Boolean inverter state") outarg = ua.Argument() outarg.Name = "Result" outarg.DataType = ua.NodeId(ua.ObjectIds.Boolean) outarg.ValueRank = -1 outarg.ArrayDimensions = [] outarg.Description = ua.LocalizedText("Final Inverter State") inverter_control_node = RelayBoxObject.add_method(address_space, "set_inverter_state", set_inverter_state, [inarg], [outarg]) # starting! server.start() print( "Server starting ...") # creating my machinery objects chargeController = cc.EpeverChargeController(produce_dummy_data = DUMMY_DATA) outputsEnabled = True try: while True: time.sleep(1) data = chargeController.readAllData() panelVoltage.set_value( data['panelVoltage'] ) panelCurrent.set_value( data['panelCurrent'] ) batteryVoltage.set_value( data['batteryVoltage'] ) batteryCurrent.set_value( data['batteryCurrent'] ) loadVoltage.set_value( data['loadVoltage'] ) loadCurrent.set_value( data['loadCurrent'] ) inPower.set_value( data['inPower'] ) outPower.set_value( data['outPower'] ) batteryStatus.set_value( data['batteryStatus'] ) batteryCapacity.set_value( data['batteryCapacity'] ) batteryTemperature.set_value( data['batteryTemperature'] ) if data['batteryVoltage'] < LOW_BATTERY_VOLTAGE and outputsEnabled: outputsEnabled = False; myEventGenerator.event.Message = ua.LocalizedText("Battery Voltage is too low. Outputs will be disconnected") myEventGenerator.event.batteryVoltage = ua.Variant(float(data['panelVoltage']), ua.VariantType.Float) myEventGenerator.event.outputsEnabled = ua.Variant( outputsEnabled , ua.VariantType.Boolean) myEventGenerator.event.Severity = ua.Variant( 1 , ua.VariantType.Int32) myEventGenerator.trigger() elif data['batteryVoltage'] > LOW_BATTERY_VOLTAGE and not outputsEnabled: outputsEnabled = True; myEventGenerator.event.Message = ua.LocalizedText("Battery Voltage is normal. Outputs will be activated") myEventGenerator.event.batteryVoltage = ua.Variant(float(data['panelVoltage']), ua.VariantType.Float) myEventGenerator.event.outputsEnabled = ua.Variant( outputsEnabled , ua.VariantType.Boolean) myEventGenerator.event.Severity = ua.Variant( 1 , ua.VariantType.Int32) myEventGenerator.trigger() ## update array variables burst = [random.random() for _ in range(1024)] plug_A_current_array.set_value(burst) plug_B_current_array.set_value(burst) embed() finally: # close connection, remove subcsriptions, etc server.stop()
class MyRevPiOpcuaServerApp: def __init__(self): """Init MyRevPiApp class.""" self.main_state = False self.state_1_on = False self.state_2_on = False self.trigger = 0 self.trigger_system_on_trigger = 1 self.trigger_system_off_trigger = 2 self.trigger_door_outside_open = 3 self.trigger_door_outside_close = 4 self.trigger_door_inside_open = 5 self.trigger_door_inside_close = 6 # self.system_on_time # self.system_off_time # self.system_delta_time = 0.0 # self.system_running_time = 0.0 self.system_sum_time = 0 self.door_count = 0 self.door_outside_time_opened = 0.0 self.door_outside_time_closed = 0.0 self.door_outside_delta_time_open = 0.0 self.door_outside_sum_time_open = 0.0 self.door_inside_time_opened = 0.0 self.door_inside_time_closed = 0.0 self.door_inside_delta_time_open = 0.0 self.door_inside_sum_time_open = 0.0 self.open_percentage = 0 self.door_open_time = 0.0 self.door_outside_share_percentage = 50 # = door_outside/(door_outside+door_inside)time print("put all switches in off mode") # Instantiate RevPiModIO self.rpi = revpimodio2.RevPiModIO(autorefresh=True) # standard cycletime on Core-3 is 20 (msec), by uncommenting next line you extend it to 50 msec # might be needed if once more print statements are used in event handlers # self.rpi.cycletime = 50 # Handle SIGINT / SIGTERM to exit program cleanly self.rpi.handlesignalend(self.cleanup_revpi) # Register event to toggle output O_1 with input I_1 self.rpi.io.main_switch.reg_event(self.event_main_on, edge=revpimodio2.RISING) self.rpi.io.main_switch.reg_event(self.event_main_off, edge=revpimodio2.FALLING) # Register event to toggle output O_3 with input I_3 self.rpi.io.switch_1.reg_event(self.event_switch_1_on, edge=revpimodio2.RISING) self.rpi.io.switch_1.reg_event(self.event_switch_1_off, edge=revpimodio2.FALLING) # Register event to toggle output O_5 with input I_5 self.rpi.io.switch_2.reg_event(self.event_switch_2_on, edge=revpimodio2.RISING) self.rpi.io.switch_2.reg_event(self.event_switch_2_off, edge=revpimodio2.FALLING) self.rpi.core.a1green.value = True # program is loaded and active self.rpi.core.a1red.value = False self.rpi.core.a2green.value = False self.rpi.core.a2red.value = False self.rpi.io.main_relay.value = False # O 1 (output 1) right side connector on DIO is odd input/output nr self.rpi.io.relay_1.value = False # O 3 self.rpi.io.relay_2.value = False # O 5 print( 'starting OPC server on core-3: (url 0.0.0.0 (192.168.1.3 or 192.168.0.3 or 10.0.0.3 or 10.0.1.3):4840)' ) self.opc_server = Server(shelffile="/home/pi/RevPi-OPC-Server") # shelffile is trick with freeopcua to speedup loading of xml object base self.opc_url = "opc.tcp://0.0.0.0:4840" self.opc_server.set_endpoint(self.opc_url) # TODO security print('starting OPC server .. (namespace)') self.opc_name = "RevPi-opcua-server" self.addspace = self.opc_server.register_namespace(self.opc_name) print('starting OPC server ... (variables)') self.opc_node = self.opc_server.get_objects_node() self.param = self.opc_node.add_object(self.addspace, "Parameters") self.opc_time = self.param.add_variable(self.addspace, "Time", 0) # opc i=2 self.opc_trigger = self.param.add_variable(self.addspace, "Trigger", 0) # opc i=3 self.opc_warehouse_state = self.param.add_variable( self.addspace, "System state", 0) # opc i=4 self.opc_door_outside = self.param.add_variable( self.addspace, "Outside door", 0) # opc i=5 self.opc_door_inside = self.param.add_variable(self.addspace, "Inside door", 0) # opc i=6 self.opc_open_percentage = self.param.add_variable( self.addspace, "Door open %", 0.0) # opc i=7 self.opc_door_outside_share_percentage = self.param.add_variable( self.addspace, "Outside/Inside share", 0.0) self.opc_time.set_writable() self.opc_trigger.set_writable() self.opc_warehouse_state.set_writable() self.opc_door_outside.set_writable() self.opc_door_inside.set_writable() self.opc_open_percentage.set_writable() self.opc_door_outside_share_percentage.set_writable() self.opc_server.start() print("OPC UA Server started at {}".format(self.opc_url)) def cleanup_revpi(self): """Cleanup function to leave the RevPi in a defined state, stop opc server and exit.""" self.rpi.core.a1green.value = False self.rpi.core.a1red.value = False self.rpi.io.main_relay.value = False self.rpi.io.relay_1.value = False self.rpi.io.relay_2.value = False self.rpi = revpimodio2.RevPiModIO(autorefresh=False) self.opc_server.stop() print("exit") # self.master.destroy() exit(1) def event_main_on(self, ioname, iovalue): """Called if main_switch goes to True.""" # Switch on/off output O_1 self.rpi.io.main_relay.value = True self.main_state = True self.system_on_time = time.time() self.trigger = self.trigger_system_on_trigger def event_main_off(self, ioname, iovalue): """Called if main_switch goes to false.""" # Switch on/off output O_1 self.rpi.io.main_relay.value = False self.rpi.io.relay_1.value = False self.rpi.io.relay_2.value = False self.main_state = False self.system_off_time = time.time() self.system_delta_time = self.system_off_time - self.system_on_time self.system_sum_time = self.system_sum_time + self.system_delta_time print("system delta: ", int(self.system_delta_time), "sec system sum: ", int(self.system_sum_time), ' sec') if self.state_1_on: self.door_outside_time_closed = time.time() self.door_outside_delta_time_open = self.door_outside_time_closed - self.door_outside_time_opened self.door_outside_sum_time_open = self.door_outside_sum_time_open + self.door_outside_delta_time_open elif self.state_2_on: self.door_inside_time_closed = time.time() self.door_inside_delta_time_open = self.door_inside_time_closed - self.door_inside_time_opened self.door_inside_sum_time_open = self.door_inside_sum_time_open + self.door_inside_delta_time_open self.trigger = self.trigger_system_off_trigger def event_switch_1_on(self, ioname, iovalue): """Called if I_3 goes to True.""" if self.main_state and not self.state_2_on: self.rpi.io.relay_1.value = True self.state_1_on = True self.door_outside_time_opened = time.time() self.trigger = self.trigger_door_outside_open def event_switch_1_off(self, ioname, iovalue): """Called if I_3 goes to false.""" if self.main_state: self.rpi.io.relay_1.value = False self.state_1_on = False self.door_count = self.door_count + 1 # self.door_outside_time_closed = time.time() # self.door_outside_delta_time_open = self.door_outside_time_closed - self.door_outside_time_opened # self.door_outside_sum_time_open = self.door_outside_sum_time_open + self.door_outside_delta_time_open # print("outside delta: ", int(self.door_outside_delta_time_open), # "sec outside sum: ", int(self.door_outside_sum_time_open), ' sec') self.door_outside_sum_time_open = \ self.door_outside_sum_time_open + time.time() - self.door_outside_time_opened self.trigger = self.trigger_door_outside_close def event_switch_2_on(self, ioname, iovalue): """Called if I_5 goes to True.""" if self.main_state and not self.state_1_on: self.rpi.io.relay_2.value = True self.state_2_on = True self.door_inside_time_opened = time.time() self.trigger = self.trigger_door_inside_open def event_switch_2_off(self, ioname, iovalue): """Called if I_5 goes to False.""" if self.main_state: self.rpi.io.relay_2.value = False self.state_2_on = False self.door_count = self.door_count + 1 # self.door_inside_time_closed = time.time() # self.door_inside_delta_time_open = self.door_inside_time_closed - self.door_inside_time_opened # self.door_inside_sum_time_open = self.door_inside_sum_time_open + self.door_inside_delta_time_open # print("inside delta: ", int(self.door_inside_delta_time_open), # "sec inside sum: ", int(self.door_inside_sum_time_open), ' sec') self.door_inside_sum_time_open = self.door_inside_sum_time_open + time.time( ) - self.door_inside_time_opened self.trigger = self.trigger_door_inside_close def start(self): """Start event system and own cyclic loop.""" # Start event system without blocking here self.rpi.mainloop(blocking=False) # My own loop to do some work next to the event system. We will stay # here till self.rpi.exitsignal.wait returns True after SIGINT/SIGTERM while not self.rpi.exitsignal.wait(1): # Switch on / off green part of LED A1 to signal to user that PLC runs self.rpi.core.a1green.value = not self.rpi.core.a1green.value self.opc_time.set_value(datetime.datetime.now()) self.opc_trigger.set_value(self.trigger) if self.trigger == self.trigger_system_on_trigger or self.trigger == self.trigger_system_off_trigger: self.opc_warehouse_state.set_value(self.main_state) if self.trigger == self.trigger_door_outside_open or self.trigger == self.trigger_door_outside_close: self.opc_door_outside.set_value(self.state_1_on) if self.trigger == self.trigger_door_inside_open or self.trigger == self.trigger_door_inside_close: self.opc_door_inside.set_value(self.state_2_on) # needed to update system on time while no event takes place if self.main_state: self.system_delta_time = time.time() - self.system_on_time self.system_running_time = self.system_sum_time + self.system_delta_time else: self.system_running_time = self.system_sum_time self.door_open_time = self.door_outside_sum_time_open + self.door_inside_sum_time_open if self.system_running_time == 0.0: # if 0 then main has not been switched on yet self.open_percentage = 0 else: self.open_percentage = (self.door_open_time / self.system_running_time) * 100 # print("door open time: ", int(self.door_open_time), # " system on time: ", int(self.system_running_time), ' sec') if self.door_open_time == 0.0: # if 0 then main has not been switched on yet self.door_outside_share_percentage = 50 # if 0, avoid DIV by Zero, and start at 50/50% else: self.door_outside_share_percentage = ( self.door_outside_sum_time_open / self.door_open_time) * 100 self.opc_open_percentage.set_value(self.open_percentage) self.opc_door_outside_share_percentage.set_value( self.door_outside_share_percentage)
kgu = objects.add_object(ns, "KGU") newval = [] value = 1 # for name in all_data: # value = kgu.add_variable(ns, name, 0.0) for name in all_data: if name.find('k1') == 0: value = kgu.add_variable(ns2, name, 0.0) else: value = kgu.add_variable(ns1, name, 0.0) all_vars[name] = value print(all_vars) vvars = kgu.get_variables() print(type(vvars).__name__) for i in vvars: # print((i.get_display_name().Text)) print(str(i.get_browse_name())) print('res =============') get_websrv = threading.Thread(target=getHTTP, args=()) get_websrv.start() server.start() V = 220.0 while True: time.sleep(1.33) server.stop()
def run_OPCUA_server_start(): print("Starting OPC UA SERVER %s:%s" % (OPCUA_HOST, OPCUA_PORT)) # setup our server server = Server() server.set_endpoint("opc.tcp://%s:%s/freeopcua/server/" % (OPCUA_HOST, OPCUA_PORT)) # setup our own namespace, not really necessary but should as spec uri = "http://examples.freeopcua.github.io" idx = server.register_namespace(uri) # get Objects node, this is where we should put our nodes objects = server.get_objects_node() # populating our address space imms = objects.add_object(idx, "IMMS") imms_date = imms.add_variable(idx, "DATE", 0, varianttype=ua.VariantType.Double) imms_date.set_writable() imms_time = imms.add_variable(idx, "TIME", "", varianttype=ua.VariantType.String) imms_time.set_writable() imms_ActSimPara1 = imms.add_variable(idx, "ActSimPara1", 0, varianttype=ua.VariantType.Double) imms_ActSimPara1.set_writable() imms_ActSimPara2 = imms.add_variable(idx, "ActSimPara2", 0, varianttype=ua.VariantType.Double) imms_ActSimPara2.set_writable() imms_ActCntCyc = imms.add_variable(idx, "ActCntCyc", 0, varianttype=ua.VariantType.Double) imms_ActCntCyc.set_writable() imms_ActCntPrt = imms.add_variable(idx, "ActCntPrt", 0, varianttype=ua.VariantType.Double) imms_ActCntPrt.set_writable() imms_ActStsMach = imms.add_variable(idx, "ActStsMach", "", varianttype=ua.VariantType.String) imms_ActStsMach.set_writable() imms_ActTimCyc = imms.add_variable(idx, "ActTimCyc", 5, varianttype=ua.VariantType.Double) imms_ActTimCyc.set_writable() imms_SetCntMld = imms.add_variable(idx, "SetCntMld", 0, varianttype=ua.VariantType.Double) imms_SetCntMld.set_writable() imms_SetCntPrt = imms.add_variable(idx, "SetCntPrt", 0, varianttype=ua.VariantType.Double) imms_SetCntPrt.set_writable() imms_SetTimCyc = imms.add_variable(idx, "SetTimCyc", 0, varianttype=ua.VariantType.Double) imms_SetTimCyc.set_writable() # starting! server.start()
ua.SecurityPolicyType.NoSecurity, ua.SecurityPolicyType.Basic128Rsa15_SignAndEncrypt, ua.SecurityPolicyType.Basic128Rsa15_Sign, ua.SecurityPolicyType.Basic256_SignAndEncrypt, ua.SecurityPolicyType.Basic256_Sign ]) # setup our own namespace, not really necessary but should as spec URI = "http://examples.freeopcua.github.io" IDX = SERVER.register_namespace(URI) # get Objects node, this is where we should put our nodes OBJECTS = SERVER.get_objects_node() IDX = 5 # populating our address space CHOCOOBJ = OBJECTS.add_object(IDX, "Chocolate") TEMPVAR = CHOCOOBJ.add_variable("ns=5;s=temperature", "Float", 0.0) TEMPVAR.set_writable() # Set MyVariable to be writable by clients # starting! SERVER.start() try: COUNT = 0 while True: time.sleep(1) COUNT += 0.1 TEMPVAR.set_value(COUNT) finally: #close connection, remove subcsriptions, etc SERVER.stop()
class TestClient(unittest.TestCase, CommonTests, SubscriptionTests): ''' Run common tests on client side Of course we need a server so we start also start a server Tests that can only be run on client side must be defined in this class ''' @classmethod def setUpClass(self): # start our own server self.srv = Server() self.srv.set_endpoint('opc.tcp://*****:*****@localhost:%d' % port_num1, timeout=10) self.clt.connect() self.opc = self.clt # start anonymous client self.ro_clt = Client('opc.tcp://localhost:%d' % port_num1) self.ro_clt.connect() @classmethod def tearDownClass(self): #stop our clients self.ro_clt.disconnect() self.clt.disconnect() # stop the server self.srv.stop() def test_service_fault(self): request = ua.ReadRequest() request.TypeId = ua.FourByteNodeId(999) # bad type! with self.assertRaises(ua.UaStatusCodeError): self.clt.uaclient._uasocket.send_request(request) def test_objects_anonymous(self): objects = self.ro_clt.get_objects_node() with self.assertRaises(ua.UaStatusCodeError): objects.set_attribute(ua.AttributeIds.WriteMask, ua.DataValue(999)) with self.assertRaises(ua.UaStatusCodeError): f = objects.add_folder(3, 'MyFolder') def test_folder_anonymous(self): objects = self.clt.get_objects_node() f = objects.add_folder(3, 'MyFolderRO') f_ro = self.ro_clt.get_node(f.nodeid) self.assertEqual(f, f_ro) with self.assertRaises(ua.UaStatusCodeError): f2 = f_ro.add_folder(3, 'MyFolder2') def test_variable_anonymous(self): objects = self.clt.get_objects_node() v = objects.add_variable(3, 'MyROVariable', 6) v.set_value(4) #this should work v_ro = self.ro_clt.get_node(v.nodeid) with self.assertRaises(ua.UaStatusCodeError): v_ro.set_value(2) self.assertEqual(v_ro.get_value(), 4) v.set_writable(True) v_ro.set_value(2) #now it should work self.assertEqual(v_ro.get_value(), 2) v.set_writable(False) with self.assertRaises(ua.UaStatusCodeError): v_ro.set_value(9) self.assertEqual(v_ro.get_value(), 2) def test_context_manager(self): """ Context manager calls connect() and disconnect() """ state = [0] def increment_state(self, *args, **kwargs): state[0] += 1 # create client and replace instance methods with dummy methods client = Client('opc.tcp://dummy_address:10000') client.connect = increment_state.__get__(client) client.disconnect = increment_state.__get__(client) assert state[0] == 0 with client: # test if client connected self.assertEqual(state[0], 1) # test if client disconnected self.assertEqual(state[0], 2)
class TestServer(unittest.TestCase, CommonTests, SubscriptionTests): ''' Run common tests on server side Tests that can only be run on server side must be defined here ''' @classmethod def setUpClass(self): self.srv = Server() self.srv.set_endpoint('opc.tcp://localhost:%d' % port_num) add_server_methods(self.srv) self.srv.start() self.opc = self.srv self.discovery = Server() self.discovery.set_application_uri("urn:freeopcua:python:discovery") self.discovery.set_endpoint('opc.tcp://localhost:%d' % port_discovery) self.discovery.start() @classmethod def tearDownClass(self): self.srv.stop() self.discovery.stop() def test_discovery(self): client = Client(self.discovery.endpoint.geturl()) client.connect() try: servers = client.find_servers() new_app_uri = "urn:freeopcua:python:server:test_discovery" self.srv.application_uri = new_app_uri self.srv.register_to_discovery(self.discovery.endpoint.geturl(), 0) time.sleep(0.1) # let server register registration new_servers = client.find_servers() self.assertEqual(len(new_servers) - len(servers) , 1) self.assertFalse(new_app_uri in [s.ApplicationUri for s in servers]) self.assertTrue(new_app_uri in [s.ApplicationUri for s in new_servers]) finally: client.disconnect() def test_find_servers2(self): client = Client(self.discovery.endpoint.geturl()) client.connect() try: servers = client.find_servers() new_app_uri1 = "urn:freeopcua:python:server:test_discovery1" self.srv.application_uri = new_app_uri1 self.srv.register_to_discovery(self.discovery.endpoint.geturl(), period=0) new_app_uri2 = "urn:freeopcua:python:test_discovery2" self.srv.application_uri = new_app_uri2 self.srv.register_to_discovery(self.discovery.endpoint.geturl(), period=0) time.sleep(0.1) # let server register registration new_servers = client.find_servers() self.assertEqual(len(new_servers) - len(servers) , 2) self.assertFalse(new_app_uri1 in [s.ApplicationUri for s in servers]) self.assertFalse(new_app_uri2 in [s.ApplicationUri for s in servers]) self.assertTrue(new_app_uri1 in [s.ApplicationUri for s in new_servers]) self.assertTrue(new_app_uri2 in [s.ApplicationUri for s in new_servers]) # now do a query with filer new_servers = client.find_servers(["urn:freeopcua:python:server"]) self.assertEqual(len(new_servers) - len(servers) , 0) self.assertTrue(new_app_uri1 in [s.ApplicationUri for s in new_servers]) self.assertFalse(new_app_uri2 in [s.ApplicationUri for s in new_servers]) # now do a query with filer new_servers = client.find_servers(["urn:freeopcua:python"]) self.assertEqual(len(new_servers) - len(servers) , 2) self.assertTrue(new_app_uri1 in [s.ApplicationUri for s in new_servers]) self.assertTrue(new_app_uri2 in [s.ApplicationUri for s in new_servers]) finally: client.disconnect() """ # not sure if this test is necessary, and there is a lot repetition with previous test def test_discovery_server_side(self): servers = self.discovery.find_servers() self.assertEqual(len(servers), 1) self.srv.register_to_discovery(self.discovery.endpoint.geturl(), 1) time.sleep(1) # let server register registration servers = self.discovery.find_servers() print("SERVERS 2", servers) self.assertEqual(len(servers), 2) """ #def test_register_server2(self): #servers = self.opc.register_server() def test_register_namespace(self): uri = 'http://mycustom.Namespace.com' idx1 = self.opc.register_namespace(uri) idx2 = self.opc.get_namespace_index(uri) self.assertEqual(idx1, idx2) def test_register_use_namespace(self): uri = 'http://my_very_custom.Namespace.com' idx = self.opc.register_namespace(uri) root = self.opc.get_root_node() myvar = root.add_variable(idx, 'var_in_custom_namespace', [5]) myid = myvar.nodeid self.assertEqual(idx, myid.NamespaceIndex) def test_server_method(self): def func(parent, variant): variant.Value *= 2 return [variant] o = self.opc.get_objects_node() v = o.add_method(3, 'Method1', func, [ua.VariantType.Int64], [ua.VariantType.Int64]) result = o.call_method(v, ua.Variant(2.1)) self.assertEqual(result, 4.2) def test_xml_import(self): self.srv.import_xml("tests/custom_nodes.xml") o = self.opc.get_objects_node() v = o.get_child(["MyXMLFolder", "MyXMLObject", "MyXMLVariable"]) val = v.get_value() self.assertEqual(val, "StringValue") def test_historize_variable(self): o = self.opc.get_objects_node() var = o.add_variable(3, "test_hist", 1.0) self.srv.iserver.enable_history_data_change(var, timedelta(days=1)) time.sleep(1) var.set_value(2.0) var.set_value(3.0) self.srv.iserver.disable_history_data_change(var) def test_historize_events(self): srv_node = self.srv.get_node(ua.ObjectIds.Server) srvevgen = self.srv.get_event_generator() self.srv.iserver.enable_history_event(srv_node, period=None) srvevgen.trigger(message="Message") self.srv.iserver.disable_history_event(srv_node) def test_references_for_added_nodes_method(self): objects = self.opc.get_objects_node() o = objects.add_object(3, 'MyObject') nodes = objects.get_referenced_nodes(refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Forward, includesubtypes=False) self.assertTrue(o in nodes) nodes = o.get_referenced_nodes(refs=ua.ObjectIds.Organizes, direction=ua.BrowseDirection.Inverse, includesubtypes=False) self.assertTrue(objects in nodes) self.assertEqual(o.get_parent(), objects) self.assertEqual(o.get_type_definition(), ua.ObjectIds.BaseObjectType) @uamethod def callback(parent): return m = o.add_method(3, 'MyMethod', callback) nodes = o.get_referenced_nodes(refs=ua.ObjectIds.HasComponent, direction=ua.BrowseDirection.Forward, includesubtypes=False) self.assertTrue(m in nodes) nodes = m.get_referenced_nodes(refs=ua.ObjectIds.HasComponent, direction=ua.BrowseDirection.Inverse, includesubtypes=False) self.assertTrue(o in nodes) self.assertEqual(m.get_parent(), o) # This should work for following BaseEvent tests to work (maybe to write it a bit differentlly since they are not independent) def test_get_event_from_type_node_BaseEvent(self): ev = opcua.common.events.get_event_obj_from_type_node(opcua.Node(self.opc.iserver.isession, ua.NodeId(ua.ObjectIds.BaseEventType))) check_base_event(self, ev) def test_get_event_from_type_node_Inhereted_AuditEvent(self): ev = opcua.common.events.get_event_obj_from_type_node(opcua.Node(self.opc.iserver.isession, ua.NodeId(ua.ObjectIds.AuditEventType))) self.assertIsNot(ev, None) # we did not receive event self.assertIsInstance(ev, BaseEvent) self.assertIsInstance(ev, AuditEvent) self.assertEqual(ev.EventType, ua.NodeId(ua.ObjectIds.AuditEventType)) self.assertEqual(ev.Severity, 1) self.assertEqual(ev.ActionTimeStamp, None) self.assertEqual(ev.Status, False) self.assertEqual(ev.ServerId, None) self.assertEqual(ev.ClientAuditEntryId, None) self.assertEqual(ev.ClientUserId, None) def test_eventgenerator_default(self): evgen = self.opc.get_event_generator() check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_BaseEvent_object(self): evgen = self.opc.get_event_generator(BaseEvent()) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_BaseEvent_Node(self): evgen = self.opc.get_event_generator(opcua.Node(self.opc.iserver.isession, ua.NodeId(ua.ObjectIds.BaseEventType))) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_BaseEvent_NodeId(self): evgen = self.opc.get_event_generator(ua.NodeId(ua.ObjectIds.BaseEventType)) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_BaseEvent_ObjectIds(self): evgen = self.opc.get_event_generator(ua.ObjectIds.BaseEventType) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_BaseEvent_Identifier(self): evgen = self.opc.get_event_generator(2041) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_sourceServer_Node(self): evgen = self.opc.get_event_generator(source=opcua.Node(self.opc.iserver.isession, ua.NodeId(ua.ObjectIds.Server))) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_sourceServer_NodeId(self): evgen = self.opc.get_event_generator(source=ua.NodeId(ua.ObjectIds.Server)) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_sourceServer_ObjectIds(self): evgen = self.opc.get_event_generator(source=ua.ObjectIds.Server) check_eventgenerator_BaseEvent(self, evgen) check_eventgenerator_SourceServer(self, evgen) def test_eventgenerator_sourceMyObject(self): objects = self.opc.get_objects_node() o = objects.add_object(3, 'MyObject') evgen = self.opc.get_event_generator(source=o) check_eventgenerator_BaseEvent(self, evgen) check_event_generator_object(self, evgen, o) def test_eventgenerator_source_collision(self): objects = self.opc.get_objects_node() o = objects.add_object(3, 'MyObject') event = BaseEvent(sourcenode=o.nodeid) evgen = self.opc.get_event_generator(event, ua.ObjectIds.Server) check_eventgenerator_BaseEvent(self, evgen) check_event_generator_object(self, evgen, o) def test_eventgenerator_InheritedEvent(self): evgen = self.opc.get_event_generator(ua.ObjectIds.AuditEventType) check_eventgenerator_SourceServer(self, evgen) ev = evgen.event self.assertIsNot(ev, None) # we did not receive event self.assertIsInstance(ev, BaseEvent) self.assertIsInstance(ev, AuditEvent) self.assertEqual(ev.EventType, ua.NodeId(ua.ObjectIds.AuditEventType)) self.assertEqual(ev.Severity, 1) self.assertEqual(ev.ActionTimeStamp, None) self.assertEqual(ev.Status, False) self.assertEqual(ev.ServerId, None) self.assertEqual(ev.ClientAuditEntryId, None) self.assertEqual(ev.ClientUserId, None) def test_create_custom_event_type_ObjectId(self): etype = self.opc.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) check_custom_event_type(self, etype) def test_create_custom_event_type_NodeId(self): etype = self.opc.create_custom_event_type(2, 'MyEvent', ua.NodeId(ua.ObjectIds.BaseEventType), [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) check_custom_event_type(self, etype) def test_create_custom_event_type_Node(self): etype = self.opc.create_custom_event_type(2, 'MyEvent', opcua.Node(self.opc.iserver.isession, ua.NodeId(ua.ObjectIds.BaseEventType)), [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) check_custom_event_type(self, etype) def test_get_event_from_type_node_CustomEvent(self): etype = self.opc.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) ev = opcua.common.events.get_event_obj_from_type_node(etype) check_custom_event(self, ev, etype) self.assertEqual(ev.PropertyNum, None) self.assertEqual(ev.PropertyString, None) def test_eventgenerator_customEvent(self): etype = self.opc.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) evgen = self.opc.get_event_generator(etype, ua.ObjectIds.Server) check_eventgenerator_CustomEvent(self, evgen, etype) check_eventgenerator_SourceServer(self, evgen) self.assertEqual(evgen.event.PropertyNum, None) self.assertEqual(evgen.event.PropertyString, None) def test_eventgenerator_double_customEvent(self): event1 = self.opc.create_custom_event_type(3, 'MyEvent1', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) event2 = self.opc.create_custom_event_type(4, 'MyEvent2', event1, [('PropertyBool', ua.VariantType.Boolean), ('PropertyInt', ua.VariantType.Int32)]) evgen = self.opc.get_event_generator(event2, ua.ObjectIds.Server) check_eventgenerator_CustomEvent(self, evgen, event2) check_eventgenerator_SourceServer(self, evgen) # Properties from MyEvent1 self.assertEqual(evgen.event.PropertyNum, None) self.assertEqual(evgen.event.PropertyString, None) # Properties from MyEvent2 self.assertEqual(evgen.event.PropertyBool, None) self.assertEqual(evgen.event.PropertyInt, None) def test_eventgenerator_customEvent_MyObject(self): objects = self.opc.get_objects_node() o = objects.add_object(3, 'MyObject') etype = self.opc.create_custom_event_type(2, 'MyEvent', ua.ObjectIds.BaseEventType, [('PropertyNum', ua.VariantType.Float), ('PropertyString', ua.VariantType.String)]) evgen = self.opc.get_event_generator(etype, o) check_eventgenerator_CustomEvent(self, evgen, etype) check_event_generator_object(self, evgen, o) self.assertEqual(evgen.event.PropertyNum, None) self.assertEqual(evgen.event.PropertyString, None)
class ServerOPC(): def __init__(self, sensori): self.keys=c_gpio.led_dict.keys() self.sensori=sensori self.__led=c_gpio.led_dict self.init_server() def init_server(self): print("inizio settaggio server") self.server=Server() #self.server.set_endpoint("opc.tcp://192.168.1.250:4840") self.server.set_endpoint("opc.tcp://0.0.0.0:4840") self.server.set_server_name("DomoticProject") #carico il certificato e la chiave privata global base_path file_path_cert=(base_path / "../config/certificati/my_cert.der").resolve() file_path_key=(base_path / "../config/certificati/my_private_key.pem").resolve() self.server.load_certificate(file_path_cert) self.server.load_private_key(file_path_key) self.server.set_security_policy([ ua.SecurityPolicyType.NoSecurity, ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt, ua.SecurityPolicyType.Basic256Sha256_Sign ]) #setup namespace uri="Domotic" self.idx=self.server.register_namespace(uri) self.objects=self.server.get_objects_node() #per contenere le info dei sensori self.sensors_o=self.objects.add_object(self.idx, "Sensori") self.temperatura_s=self.sensors_o.add_variable(self.idx, "Temperatura", 0.00) self.counterbagno_s=self.sensors_o.add_variable(self.idx, "Counter Bagno", 0) self.countersalotto_s=self.sensors_o.add_variable(self.idx, "Counter Salotto", 0) #per contenere le info dei led self.luci_o=self.objects.add_object(self.idx, "Luci") self.luci_o_dict={} for x in self.keys: self.luci_o_dict[x]=self.luci_o.add_variable(self.idx, "Luce "+x, False) self.luci_o_dict[x].set_writable() #per contenere i metodi self.method_o=self.objects.add_object(self.idx, "Metodi") inarg=ua.Argument() inarg.Name="stanza" inarg.DataType=ua.NodeId(ua.ObjectIds.String) inarg.ValueRank=-1 inarg.ArrayDimensions=[] inarg.Description=ua.LocalizedText("stanza su cui applicare il metodo ['salotto', 'camera', 'bagno', 'ingresso']") self.mymethod1=self.method_o.add_method(self.idx, "Accendi luce", self.accendi_luce, [inarg]) self.mymethod2=self.method_o.add_method(self.idx, "Spegni luce", self.spegni_luce, [inarg]) print("server settato") def run(self): print("start server") self.server.start() try: while True: val=ua.Variant(self.sensori["temperatura"], ua.VariantType.Float) val=ua.DataValue(val) val.SourceTimestamp=datetime.utcnow() val.ServerTimestamp=datetime.utcnow() self.temperatura_s.set_data_value(val) val2=ua.Variant(self.sensori["counter_bagno"], ua.VariantType.UInt16) val2=ua.DataValue(val2) val2.SourceTimestamp=datetime.utcnow() val2.ServerTimestamp=datetime.utcnow() self.counterbagno_s.set_data_value(val2) val3=ua.Variant(self.sensori["counter_salotto"], ua.VariantType.UInt16) val3=ua.DataValue(val3) val3.SourceTimestamp=datetime.utcnow() val3.ServerTimestamp=datetime.utcnow() self.countersalotto_s.set_data_value(val3) for x in self.keys: pin=self.__led[x] status=gpio.input(pin) var=ua.Variant(status, ua.VariantType.Boolean) s=ua.DataValue(var) s.SourceTimestamp=datetime.utcnow() s.ServerTimestamp=datetime.utcnow() self.luci_o_dict[x].set_value(s) time.sleep(1) finally: self.server.stop() @uamethod def accendi_luce(self, parent, stanza): pin=self.__led[stanza] if stanza=="salotto": s=gpio.input(2) gpio.output(2, 1) gpio.output(pin, 0) else: gpio.output(pin, 1) @uamethod def spegni_luce(self, parent, stanza): pin=self.__led[stanza] if stanza=="salotto": s=gpio.input(2) gpio.output(2, 0) gpio.output(pin, 1) else: gpio.output(pin, 0)
def uaserver(): parser = argparse.ArgumentParser(description="Run an example OPC-UA server. By importing xml definition and using uawrite command line, it is even possible to expose real data using this server") # we setup a server, this is a bit different from other tool so we do not reuse common arguments parser.add_argument("-u", "--url", help="URL of OPC UA server, default is opc.tcp://0.0.0.0:4840", default='opc.tcp://0.0.0.0:4840', metavar="URL") parser.add_argument("-v", "--verbose", dest="loglevel", choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], default='WARNING', help="Set log level") parser.add_argument("-x", "--xml", metavar="XML_FILE", help="Populate address space with nodes defined in XML") parser.add_argument("-p", "--populate", action="store_true", help="Populate address space with some sample nodes") parser.add_argument("-c", "--disable-clock", action="store_true", help="Disable clock, to avoid seeing many write if debugging an application") parser.add_argument("-s", "--shell", action="store_true", help="Start python shell instead of randomly changing node values") parser.add_argument("--certificate", help="set server certificate") parser.add_argument("--private_key", help="set server private key") args = parser.parse_args() logging.basicConfig(format="%(levelname)s: %(message)s", level=getattr(logging, args.loglevel)) server = Server() server.set_endpoint(args.url) if args.certificate: server.load_certificate(args.certificate) if args.private_key: server.load_private_key(args.private_key) server.disable_clock(args.disable_clock) server.set_server_name("FreeOpcUa Example Server") if args.xml: server.import_xml(args.xml) if args.populate: @uamethod def multiply(parent, x, y): print("multiply method call with parameters: ", x, y) return x * y uri = "http://examples.freeopcua.github.io" idx = server.register_namespace(uri) objects = server.get_objects_node() myobj = objects.add_object(idx, "MyObject") mywritablevar = myobj.add_variable(idx, "MyWritableVariable", 6.7) mywritablevar.set_writable() # Set MyVariable to be writable by clients myvar = myobj.add_variable(idx, "MyVariable", 6.7) myarrayvar = myobj.add_variable(idx, "MyVarArray", [6.7, 7.9]) myprop = myobj.add_property(idx, "MyProperty", "I am a property") mymethod = myobj.add_method(idx, "MyMethod", multiply, [ua.VariantType.Double, ua.VariantType.Int64], [ua.VariantType.Double]) server.start() try: if args.shell: embed() elif args.populate: count = 0 while True: time.sleep(1) myvar.set_value(math.sin(count / 10)) myarrayvar.set_value([math.sin(count / 10), math.sin(count / 100)]) count += 1 else: while True: time.sleep(1) finally: server.stop() sys.exit(0)
class TestAttrsWidget(unittest.TestCase): def setUp(self): self.server = Server() self.server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/") self.server.start() self.widget = AttrsWidget(QTreeView()) def tearDown(self): self.server.stop() def find_item(self, text): idxlist = self.widget.model.match(self.widget.model.index(0, 0), Qt.DisplayRole, text, 1, Qt.MatchExactly | Qt.MatchRecursive) idx = idxlist[0] return idx def modify_item(self, text, val, match_to_use=0): """ modify the current item and set its displayed value to 'val' """ idxlist = self.widget.model.match(self.widget.model.index(0, 0), Qt.DisplayRole, text, match_to_use + 1, Qt.MatchExactly | Qt.MatchRecursive) if not idxlist: raise RuntimeError("Item with text '{}' not found".format(text)) idx = idxlist[match_to_use] self.widget.view.setCurrentIndex(idx) idx = idx.sibling(idx.row(), 1) self.widget.view.edit(idx) editor = self.widget.view.focusWidget() if not editor: print(app.focusWidget()) print("NO EDITOR WIDGET") #QTest.keyClick(self.widget.view, Qt.Key_Return) from IPython import embed embed() raise RuntimeError("Could not get editor widget!, it does not have the focus") if hasattr(editor, "_current_node"): editor._current_node = val elif hasattr(editor, "setCurrentText"): editor.setCurrentText(val) else: editor.setText(val) self.widget.view.commitData(editor) self.widget.view.closeEditor(editor, QAbstractItemDelegate.NoHint) self.widget.view.reset() def modify_value(self, val): self.modify_item("Value", val, 1) def test_display_objects_node(self): objects = self.server.nodes.objects self.widget.show_attrs(objects) self.modify_item("BrowseName", "5:titi") self.assertEqual(objects.get_browse_name().to_string(), "5:titi") self.modify_item("BrowseName", "0:Objects") # restore states for other tests def test_display_var_double(self): objects = self.server.nodes.objects myvar = objects.add_variable(1, "myvar1", 9.99, ua.VariantType.Double) self.widget.show_attrs(myvar) self.modify_value("8.45") self.assertEqual(myvar.get_value(), 8.45) def test_display_var_bytes(self): objects = self.server.nodes.objects myvar = objects.add_variable(1, "myvar_bytes", b"jkl", ua.VariantType.ByteString) self.widget.show_attrs(myvar) self.modify_value("titi") self.assertEqual(myvar.get_value(), b"titi") def test_change_data_type(self): objects = self.server.nodes.objects myvar = objects.add_variable(1, "myvar1", 9.99, ua.VariantType.Double) self.widget.show_attrs(myvar) dtype = myvar.get_data_type() self.assertEqual(dtype, ua.NodeId(ua.ObjectIds.Double)) new_dtype = ua.NodeId(ua.ObjectIds.String) self.modify_item("DataType", self.server.get_node(new_dtype)) self.assertEqual(myvar.get_data_type(), new_dtype) # now try to write a value which is a string self.modify_value("mystring") self.assertEqual(myvar.get_value(), "mystring") def test_change_value_rank(self): # need to find a way to modify combo box with QTest objects = self.server.nodes.objects myvar = objects.add_variable(1, "myvar1", 9.99, ua.VariantType.Double) self.widget.show_attrs(myvar) rank = myvar.get_value_rank() self.modify_item("ValueRank", "ThreeDimensions") self.assertEqual(myvar.get_value_rank(), ua.ValueRank.ThreeDimensions)
class TestCryptoConnect(unittest.TestCase): ''' Test connectino with a server supporting crypto ''' @classmethod def setUpClass(self): # start our own server self.srv_crypto = Server() self.uri_crypto = 'opc.tcp://localhost:%d' % port_num1 self.srv_crypto.set_endpoint(self.uri_crypto) # load server certificate and private key. This enables endpoints # with signing and encryption. self.srv_crypto.load_certificate("examples/certificate-example.der") self.srv_crypto.load_private_key("examples/private-key-example.pem") self.srv_crypto.start() # start a server without crypto self.srv_no_crypto = Server() self.uri_no_crypto = 'opc.tcp://localhost:%d' % port_num2 self.srv_no_crypto.set_endpoint(self.uri_no_crypto) self.srv_no_crypto.start() @classmethod def tearDownClass(self): # stop the server self.srv_no_crypto.stop() self.srv_crypto.stop() def test_nocrypto(self): clt = Client(self.uri_no_crypto) clt.connect() try: clt.get_objects_node().get_children() finally: clt.disconnect() def test_nocrypto_feil(self): clt = Client(self.uri_no_crypto) with self.assertRaises(ua.UaError): clt.set_security_string("Basic256,Sign,examples/certificate-example.der,examples/private-key-example.pem") def test_basic256(self): clt = Client(self.uri_crypto) try: clt.set_security_string("Basic256,Sign,examples/certificate-example.der,examples/private-key-example.pem") clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect() def test_basic256_encrypt(self): clt = Client(self.uri_crypto) try: clt.set_security_string("Basic256,SignAndEncrypt,examples/certificate-example.der,examples/private-key-example.pem") clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect() def test_basic128Rsa15(self): clt = Client(self.uri_crypto) try: clt.set_security_string("Basic128Rsa15,Sign,examples/certificate-example.der,examples/private-key-example.pem") clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect() def test_basic128Rsa15_encrypt(self): clt = Client(self.uri_crypto) try: clt.set_security_string("Basic128Rsa15,SignAndEncrypt,examples/certificate-example.der,examples/private-key-example.pem") clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect() def test_basic256_encrypt_success(self): clt = Client(self.uri_crypto) try: clt.set_security(security_policies.SecurityPolicyBasic256, 'examples/certificate-example.der', 'examples/private-key-example.pem', None, ua.MessageSecurityMode.SignAndEncrypt ) clt.connect() self.assertTrue(clt.get_objects_node().get_children()) finally: clt.disconnect() def test_basic256_encrypt_feil(self): # FIXME: how to make it feil??? clt = Client(self.uri_crypto) with self.assertRaises(ua.UaError): clt.set_security(security_policies.SecurityPolicyBasic256, 'examples/certificate-example.der', 'examples/private-key-example.pem', None, ua.MessageSecurityMode.None_ )
def run(nodejson, endpoint, namespace, description): # now setup our server server = Server() #server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/") server.set_endpoint(endpoint) server.set_server_name(description) # setup our own namespace uri = namespace idx = server.register_namespace(uri) # get Objects node, this is where we should put our custom stuff objects = server.get_objects_node() variables = {} nodeId = 5 def add_variable(f, vals, nodeId): for x in vals: k = x if isinstance(x, str) or isinstance(x, unicode) else x.keys()[0] #v = f.add_variable("ns=6;i=600%d" % nodeId, k, ua.Variant([], ua.VariantType.Float)) v = f.add_variable("ns=6;i=600%d" % nodeId, x, ua.Variant([], ua.VariantType.Float)) # nodeid, browsename, value, [variant type] #v = f.add_variable("ns=6;s=%s" % x, x, ua.Variant([], ua.VariantType.Float)) v.set_writable() variables[k] = v nodeId = nodeId+1 return nodeId def add_folder(p, pid, val, nodeId): for n, v in val.items(): mf = p.add_folder("ns=%d;i=%d00%d" % (pid, pid, nodeId), n) #mf = p.add_folder("ns=%d;s=%s" % (pid, n), n) if isinstance(v, list) or isinstance(v, tuple): nodeId = add_variable(mf, v, nodeId+1) else: nodeId = add_folder(mf, pid+1, v, nodeId+1) return nodeId # populating our address space add_folder(objects, 5, nodejson, nodeId) ''' myobj = objects.add_object(idx, "MyObject") myvar = myobj.add_variable(idx, "MyVariable", 6.7) myvar.set_writable() # Set MyVariable to be writable by clients myarrayvar = myobj.add_variable(idx, "myarrayvar", [6.7, 7.9]) myarrayvar = myobj.add_variable(idx, "myStronglytTypedVariable", ua.Variant([], ua.VariantType.UInt32)) myprop = myobj.add_property(idx, "myproperty", "I am a property") mymethod = myobj.add_method(idx, "mymethod", func, [ua.VariantType.Int64], [ua.VariantType.Boolean]) inargx = ua.Argument() inargx.Name = "x" inargx.DataType = ua.NodeId(ua.ObjectIds.Int64) inargx.ValueRank = -1 inargx.ArrayDimensions = [] inargx.Description = ua.LocalizedText("First number x") inargy = ua.Argument() inargy.Name = "y" inargy.DataType = ua.NodeId(ua.ObjectIds.Int64) inargy.ValueRank = -1 inargy.ArrayDimensions = [] inargy.Description = ua.LocalizedText("Second number y") outarg = ua.Argument() outarg.Name = "Result" outarg.DataType = ua.NodeId(ua.ObjectIds.Int64) outarg.ValueRank = -1 outarg.ArrayDimensions = [] outarg.Description = ua.LocalizedText("Multiplication result") multiply_node = myobj.add_method(idx, "multiply", multiply, [inargx, inargy], [outarg]) ''' # starting! server.start() #print("Available loggers are: ", logging.Logger.manager.loggerDict.keys()) return server, variables
myarrayvar = myobj.add_variable(idx, "myarrayvar", [6.7, 7.9]) myarrayvar = myobj.add_variable(idx, "myStronglytTypedVariable", ua.Variant([], ua.VariantType.UInt32)) myprop = myobj.add_property(idx, "myproperty", "I am a property") mymethod = myobj.add_method(idx, "mymethod", func, [ua.VariantType.Int64], [ua.VariantType.Boolean]) multiply_node = myobj.add_method(idx, "multiply", multiply, [ua.VariantType.Int64, ua.VariantType.Int64], [ua.VariantType.Int64]) # import some nodes from xml server.import_xml("custom_nodes.xml") # creating a default event object # The event object automatically will have members for all events properties # you probably want to create a custom event type, see other examples myevgen = server.get_event_generator() myevgen.event.Severity = 300 # starting! server.start() print("Available loggers are: ", logging.Logger.manager.loggerDict.keys()) try: # enable following if you want to subscribe to nodes on server side #handler = SubHandler() #sub = server.create_subscription(500, handler) #handle = sub.subscribe_data_change(myvar) # trigger event, all subscribed clients wil receive it mydevice_var.set_value("Running") myevgen.trigger(message="This is BaseEvent") embed() finally: server.stop()
class MyGroveOpcTerminalApp: def __init__(self): self.warehouse_state = False self.door_outside_state = False self.door_inside_state = False self.warehouse_button = GroveLedButton(5) self.door_outside_button = GroveLedButton(18) self.door_inside_button = GroveLedButton(16) self.warehouse_button.on_press = self.on_press_main self.door_outside_button.on_press = self.on_press_door_outside self.door_inside_button.on_press = self.on_press_door_inside self.warehouse_relay = GroveRelay(22) self.door_outside_relay = GroveRelay(26) self.door_inside_relay = GroveRelay(24) self.time_stamp = datetime.now() self.temperature_doors = Factory.getTemper("MCP9808-I2C", 0x18) self.temperature_doors.resolution(Temper.RES_1_16_CELSIUS) self.temperature_warehouse = Factory.getTemper("MCP9808-I2C", 0x19) self.temperature_warehouse.resolution(Temper.RES_1_16_CELSIUS) self.temperature_outdoor = Factory.getTemper("NTC-ADC", 0x00, 2) # 2 implies on the grove base hat board port A2, top row, last port) self.warehouse_air_quality = GroveAirQualitySensor(6) # 6 implies on the grove base hat board port A6, middle row, last port # print('{} Celsius warehouse temperature'.format(self.temperature_warehouse.temperature)) # print('{} Celsius outside temperature'.format(int(self.temperature_outdoor.temperature))) # print('{} Air Quality (carbon monoxide & other gasses'.format(self.warehouse_air_quality.value)) print('starting OPC server ') self.opc_server = Server(shelffile="/home/pi/grove-opc-server") #shelffile is trick with freeopcua to speedup loading of xml object base self.opc_url = "opc.tcp://0.0.0.0:4840" self.opc_server.set_endpoint(self.opc_url) print('starting OPC server ..') self.opc_name = "Grove-opcua-server" self.addspace = self.opc_server.register_namespace(self.opc_name) print('starting OPC server ...') self.opc_node = self.opc_server.get_objects_node() self.param = self.opc_node.add_object(self.addspace, "Parameters") self.opc_time = self.param.add_variable(self.addspace, "Time", 0) self.opc_temperature_w = self.param.add_variable(self.addspace, "Temperature warehouse", 0.0) self.opc_temperature_d = self.param.add_variable(self.addspace, "Temperature door-lock", 0.0) self.opc_temperature_o = self.param.add_variable(self.addspace, "Temperature outdoor", 0.0) self.opc_warehouse_air = self.param.add_variable(self.addspace, "Warehouse air", 0.0) self.opc_trigger = self.param.add_variable(self.addspace, "Trigger", 0) self.opc_warehouse_state = self.param.add_variable(self.addspace, "Warehouse state", 0) self.opc_door_outside = self.param.add_variable(self.addspace, "Outside door", 0) self.opc_door_inside = self.param.add_variable(self.addspace, "Inside door", 0) self.opc_time.set_read_only() self.opc_temperature_w.set_read_only() self.opc_temperature_d.set_read_only() self.opc_temperature_o.set_read_only() self.opc_warehouse_air.set_read_only() self.opc_trigger.set_read_only() self.opc_warehouse_state.set_read_only() self.opc_door_outside.set_read_only() self.opc_door_inside.set_read_only() print('starting OPC server .....') self.opc_server.start() print("OPC UA Server started at {}".format(self.opc_url)) print() print(" T = temperature Celsius") print("time trigger warehouse outside-door inside-door Q-air T-outdoor T-doors T-warehouse") def closeapp(self): self.warehouse_relay.off() self.door_outside_relay.off() self.door_inside_relay.off() self.warehouse_button.led_off() self.door_outside_button.led_off() self.door_inside_button.led_off() self.opc_server.stop() print("exit") # self.master.destroy() exit(1) def update_opc(self, trigger): self.time_stamp = datetime.now() self.opc_time.set_value(self.time_stamp) self.opc_temperature_w.set_value(self.temperature_warehouse.temperature) self.opc_temperature_d.set_value(self.temperature_doors.temperature) self.opc_temperature_o.set_value(int(self.temperature_outdoor.temperature)) self.opc_warehouse_air.set_value(self.warehouse_air_quality.value) self.opc_trigger.set_value(trigger) self.opc_warehouse_state.set_value(self.warehouse_state) self.opc_door_outside.set_value(self.door_outside_state) self.opc_door_inside.set_value(self.door_inside_state) print('{} '.format(self.time_stamp.strftime("%X")), trigger, " ", int(self.warehouse_state), " ", int(self.door_outside_state), " ", int(self.door_inside_state), " ", self.warehouse_air_quality.value, " ", int(self.temperature_outdoor.temperature), " ", self.temperature_doors.temperature, " ", self.temperature_warehouse.temperature) def on_press_main(self): if self.warehouse_state: self.warehouse_state = False self.door_outside_state = False self.door_inside_state = False self.warehouse_relay.off() self.door_outside_relay.off() self.door_inside_relay.off() self.warehouse_button.led_off() self.door_outside_button.led_off() self.door_inside_button.led_off() else: self.warehouse_state = True self.warehouse_relay.on() self.warehouse_button.led_on() self.update_opc(1) def on_press_door_outside(self): if self.warehouse_state: if self.door_outside_state: self.door_outside_state = False self.door_outside_relay.off() self.door_outside_button.led_off() else: if not self.door_inside_state: self.door_outside_state = True self.door_outside_relay.on() self.door_outside_button.led_on() self.update_opc(2) def on_press_door_inside(self): if self.warehouse_state: if self.door_inside_state: self.door_inside_state = False self.door_inside_relay.off() self.door_inside_button.led_off() else: if not self.door_outside_state: self.door_inside_state = True self.door_inside_relay.on() self.door_inside_button.led_on() self.update_opc(3) # start function is for terminal-mode, not usable in windows mode, there we use the widget.after method def start(self): """Start event system and own cyclic loop.""" while True: try: # dirty temp (client changes every 5 sec opc_warehouse_state) if self.opc_warehouse_state.get_value(): self.warehouse_button.led_on() else: self.warehouse_button.led_off() time.sleep(5) self.update_opc(0) except KeyboardInterrupt: self.closeapp()