Example #1
0
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()
Example #2
0
class DemoServer:
    def __init__(self):
        self.server = Server()

        self.server.set_endpoint('opc.tcp://0.0.0.0:51210/UA/SampleServer')
        self.server.set_server_name('Custom structure demo server')
        # idx name will be used later for creating the xml used in data type dictionary
        self._idx_name = 'http://examples.freeopcua.github.io'
        self.idx = self.server.register_namespace(self._idx_name)

        self.dict_builder = DataTypeDictionaryBuilder(self.server, self.idx,
                                                      self._idx_name,
                                                      'MyDictionary')

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        quit()

    def start_server(self):
        self.server.start()

    def create_structure(self, name):
        # save the created data type
        return self.dict_builder.create_data_type(name)

    def complete_creation(self):
        self.dict_builder.set_dict_byte_string()
Example #3
0
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()
Example #4
0
async def test_context_manager():
    # Context manager calls start() and stop()
    state = [0]

    async 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
    async with server:
        # test if server started
        assert 1 == state[0]
    # test if server stopped
    assert 2 == state[0]
    #-------------------------------------------------------------------------------
    # Import customobject type
    server.import_xml('customobject.xml')

    # get nodeid of custom object type by one of the following 3 ways:
    # 1) Use node ID
    # 2) Or Full path
    # 3) Or As child from parent
    myobject1_type_nodeid = ua.NodeId.from_string('ns=%d;i=2' % idx)
    myobject2_type_nodeid = server.get_root_node().get_child([
        "0:Types", "0:ObjectTypes", "0:BaseObjectType",
        "%d:MyCustomObjectType" % idx
    ]).nodeid
    myobject3_type_nodeid = server.get_node(
        ua.ObjectIds.BaseObjectType).get_child(["%d:MyCustomObjectType" % idx
                                                ]).nodeid

    # populating our address space
    myobj = objects.add_object(idx, "MyCustomObjectB", myobject3_type_nodeid)
    #-------------------------------------------------------------------------------

    # starting!
    server.start()

    try:
        while True:
            time.sleep(1)
    finally:
        # close connection, remove subcsriptions, etc
        server.stop()
Example #6
0
    async def start(self):

      node_obj = {}
      variable_obj = {}

      # Data Type Mappings (OPCUA Datatypes to IoT Central Datatypes)
      variant_type = VariantType(self.logger)
      
      # OPCUA Server Setup
      # Here we setup the Server and add discovery
      try:

        # configure the endpoint
        opc_url = self.config["ServerUrlPattern"].format(ip = self.config["IPAddress"], port = self.config["Port"])
        
        if not self.whatif:
          
          # init the server
          opc_server = Server()
          await opc_server.init()
          
          # set the endpoint and name
          opc_server.set_endpoint(opc_url)
          opc_server.set_server_name(self.config["ServerDiscoveryName"])
          
          # set discovery
          await opc_server.set_application_uri(self.config["ApplicationUri"])

        log_msg = "[SERVER CONFIG] ENDPOINT: {ep} APPLICATION URI: {au} APPLICATION NAME: {an}"
        self.logger.info(log_msg.format(ep = opc_url, au = self.config["ApplicationUri"], an = self.config["ServerDiscoveryName"]))

        # Setup root for Map Telemetry
        self.map_telemetry = self.create_map_telemetry(self.config["NameSpace"], self.config["DeviceCapabilityModelId"])

      except Exception as ex:
        self.logger.error("[ERROR] %s" % ex)
        self.logger.error("[TERMINATING] We encountered an error in OPCUA Server Setup" )
        return

      # OPCUA Server Setup Nodes
      # Here we setup the Nodes and Variables
      try:

        # Set NameSpace
        namespace = self.config["NameSpace"]
        self.logger.info("[NAMESPACE] %s" % namespace)
        
        if not self.whatif:
          id_namespace = await opc_server.register_namespace(namespace)

        node_count = 0

        # Create our Nodes and Parameters
        for node in self.nodes:

          # Add Node and Begin Populating our Address Space
          if not self.whatif:
            
            # Create Node
            node_obj[node["Name"]] = await opc_server.nodes.objects.add_object(id_namespace, node["Name"])
            self.logger.info("[NODE ID] %s" % node_obj[node["Name"]])
            
            # Setup nodes for Map Telemetry
            self.map_telemetry["Nodes"].append(self.create_map_telemetry_node(node["Name"], str(node_obj[node["Name"]]), node["InterfacelId"], node["InterfaceInstanceName"]))

          for variable in node["Variables"]:
            
            variable_name = variable["DisplayName"]
            telemetry_name = variable["TelemetryName"]
            range_value = variable["RangeValues"][0]
            opc_variant_type = variant_type.map_variant_type(variable["IoTCDataType"])
            log_msg = "[SETUP VARIABLE] NODE NAME: {nn} DISPLAY NAME: {dn} TELEMETRY NAME: {tn} RANGE VALUE: {rv} " \
              "IoTC TYPE: {it} OPC VARIANT TYPE {ovt} OPC DATA TYPE {odt}"
            self.logger.info(log_msg.format(nn = node["Name"], dn = variable["DisplayName"], vn = variable["TelemetryName"], \
              tn = variable["TelemetryName"], rv = variable["RangeValues"][0], it = variable["IoTCDataType"], \
                ovt = opc_variant_type, odt = opc_variant_type))

            if not self.whatif:
              
              # Create Node Variable
              nodeObject = await node_obj[node["Name"]].add_variable(id_namespace, telemetry_name, range_value)
              await nodeObject.set_writable()
              variable_obj[telemetry_name] = nodeObject
              self.map_telemetry_nodes_variables.append(self.create_map_telemetry_variable(variable_name, telemetry_name, str(variable_obj[telemetry_name]), variable["IoTCDataType"]))

          if not self.whatif:
            self.map_telemetry["Nodes"][node_count]["Variables"] = copy.copy(self.map_telemetry_nodes_variables)
            self.logger.info("[MAP] %s" % self.map_telemetry)
            self.map_telemetry_nodes_variables =  []
          
          node_count += 1

        if not self.whatif:
          self.update_map_telemetry()
            
      except Exception as ex:
        self.logger.error("[ERROR] %s" % ex)
        self.logger.error("[TERMINATING] We encountered an error in OPCUA Server Setup for the Nodes and Variables" )
        return
      
      # Start the server and save the address space
      try:
        
        if not self.whatif and self.cache_addr_space == "save":
          filename = Path(self.config["CacheAddrSpaceFileName"])
          opc_server.start()
          opc_server.iserver.dump_address_space(filename)
          opc_server.stop()
          self.logger.info("[CACHE ADDRESS SPACE] Saved and Server Terminated. Now run with -c load")
          return

      except Exception as ex:
          self.logger.error("[ERROR] %s" % ex)
          self.logger.error("[TERMINATING] We encountered an error in OPCUA Server Setup for the Nodes and Variables" )
          return

      # We start the server loop if we are not in WhatIf and the CacheAddrSpace
      # is null (not set) or load. If it was load, we pulled it from the cache on
      # server init()...
      if not self.whatif and (self.cache_addr_space == None or self.cache_addr_space == "load"):
        
        self.logger.info("[STARTING SERVER] %s" % opc_url)
        
        if self.cache_addr_space == "load":
          filename = Path(self.config["CacheAddrSpaceFileName"])
          opc_server.iserver.load_address_space(filename)
          self.logger.info("[CACHE ADDRESS SPACE] Loaded Address Space Cache from %s" % filename)

        opc_server.start()

        async with opc_server:
          while True:
            await asyncio.sleep(self.config["ServerFrequencyInSeconds"])
            for node in self.nodes:
              temp_dict = self.nodes_dict[node["Name"]]
              temp_dict_counter = self.nodes_dict_counter[node["Name"]]
              
              for variable in node["Variables"]:
                count = temp_dict_counter[variable["TelemetryName"]]
                sequence_count = temp_dict[variable["TelemetryName"]]

                if count > (sequence_count - 1):
                  count = 0              

                # Choose the next value in the telemetry sequence for the variable
                self.nodes_dict_counter[node["Name"]][variable["TelemetryName"]] = (count + 1)
                value = variable["RangeValues"][count]
                
                if not self.whatif:
                  await variable_obj[variable["TelemetryName"]].write_value(value)
                
                log_msg = "[LOOP] {nn} {tn} {vw} {tc} SEQ({sc}) CUR({cc})"
                self.logger.info(log_msg.format(nn = node["Name"], tn = variable["TelemetryName"], vw = value, tc = count, sc = temp_dict[variable["TelemetryName"]], cc = temp_dict_counter[variable["TelemetryName"]]))

      else:
        
          while True:
            await asyncio.sleep(self.config["ServerFrequencyInSeconds"])
            for node in self.nodes:
              temp_dict = self.nodes_dict[node["Name"]]
              temp_dict_counter = self.nodes_dict_counter[node["Name"]]
              
              for variable in node["Variables"]:
                count = temp_dict_counter[variable["TelemetryName"]]
                sequence_count = temp_dict[variable["TelemetryName"]]

                if count > (sequence_count - 1):
                  count = 0              

                # Choose the next value in the telemetry sequence for the variable
                self.nodes_dict_counter[node["Name"]][variable["TelemetryName"]] = (count + 1)
                value = variable["RangeValues"][count]
                log_msg = "[LOOP] {nn} {tn} {vw} {tc} SEQ({sc}) CUR({cc})"
                self.logger.info(log_msg.format(nn = node["Name"], tn = variable["TelemetryName"], vw = value, tc = count, sc = temp_dict[variable["TelemetryName"]], cc = temp_dict_counter[variable["TelemetryName"]]))


      return