Exemplo n.º 1
0
    address_space = server.register_namespace("http://andreas-heine.net/UA")

    uri = "urn:opcua:python:server"
    server.set_application_uri(uri)

    server.load_certificate("certificate.pem")
    server.load_private_key("key.pem")
    server.set_security_policy([
        # ua.SecurityPolicyType.NoSecurity,
        # ua.SecurityPolicyType.Basic128Rsa15_Sign,
        # ua.SecurityPolicyType.Basic128Rsa15_SignAndEncrypt,
        # ua.SecurityPolicyType.Basic256Sha256_Sign,
        ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt
    ])
    policyIDs = ["Username"]
    server.set_security_IDs(policyIDs)
    server.user_manager.set_user_manager(user_manager)
    """
    OPC-UA-Modeling
    """
    root_node = server.get_root_node()
    object_node = server.get_objects_node()
    server_node = server.get_server_node()

    try:
        server.import_xml("custom_nodes.xml")
    except FileNotFoundError:
        pass
    except Exception as e:
        print(e)
Exemplo n.º 2
0
    def __init__(self, name, shared):
        super().__init__(name, shared)
        self.logger = logging.getLogger(self.name)
        self.logger.info("init")

        self.shared.config.set_hidden_value(self.name, "user")
        self.shared.config.set_hidden_value(self.name, "password")
        self.shared.config.set_hidden_value(self.name, "password_hash")

        def config(key, val):
            return self.shared.config.config(self.name, key, val)

        endpoint = config("endpoint", "no_endpoint")
        certificate = config("certificate", "")
        private_key = config("private_key", "")
        uri = config("uri", "http://examples.freeopcua.github.io")
        root_object_name = config("root_object_name", "TEST")
        separator = config("separator", ".")
        namespace = config("namespace", 2)

        self.oldnew = config("oldnew_comparision", 0)

        admin_username = config("user", "admin")
        admin_password = config("password", "admin")
        admin_password_hash = config("password_hash", "").replace("$$", "$")

        security_ids = []
        anonymous_on = config("anonymous_on", 0)
        username_on = config("username_on", 1)
        certificate_on = config("certificate_basic256sha256_on", 0)

        if anonymous_on:
            security_ids.append("Anonymous")
        if username_on:
            security_ids.append("Username")
        if certificate_on:
            security_ids.append("Basic256Sha256")

        security_policy = []

        if config("nosecurity_on", 1):
            security_policy.append(ua.SecurityPolicyType.NoSecurity)
        if config("basic128rsa15_sign_on", 0):
            security_policy.append(ua.SecurityPolicyType.Basic128Rsa15_Sign)
        if config("basic128rsa15_signandencrypt_on", 0):
            security_policy.append(
                ua.SecurityPolicyType.Basic128Rsa15_SignAndEncrypt)
        if config("basic256_sign_on", 0):
            security_policy.append(ua.SecurityPolicyType.Basic256_Sign)
        if config("basic256_signandencrypt_on", 0):
            security_policy.append(
                ua.SecurityPolicyType.Basic256_SignAndEncrypt)
        if config("basic256sha256_sign_on", 1):
            security_policy.append(ua.SecurityPolicyType.Basic256Sha256_Sign)
        if config("basic256sha256_signandencrypt_on", 1):
            security_policy.append(
                ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt)

        initial_values_is_quality_good = config(
            "initial_values_is_quality_good", 0)

        if anonymous_on:
            server = Server()
        else:
            server = Server(iserver=CustomInternalServer())
            server.iserver.set_parent(server)

        server.set_endpoint(endpoint)
        server.allow_remote_admin(False)

        if certificate and private_key:
            server.load_certificate(str(certificate))
            server.load_private_key(str(private_key))

        if security_ids:
            server.set_security_IDs(security_ids)

        if security_policy:
            server.set_security_policy(security_policy)

        def custom_user_manager(isession, userName, password):
            if userName != admin_username:
                return False
            if admin_password_hash:
                if werkzeug.security.check_password_hash(
                        admin_password_hash, password):
                    return True
            else:
                # fallback to plaintext
                if password == admin_password:
                    return True
            return False

        if username_on:
            server.user_manager.set_user_manager(custom_user_manager)

        idx = server.register_namespace(uri)
        objects = server.get_objects_node()
        root = objects.add_object(idx, root_object_name)

        self.server = server
        self.objects = objects
        self.root = root
        self.sep = separator
        self.ns = namespace
        self.items = []

        if initial_values_is_quality_good:
            self.initial_status_code = ua.StatusCodes.Good
        else:
            self.initial_status_code = ua.StatusCodes.BadWaitingForInitialData
Exemplo n.º 3
0
    def serverLoop(self):

        self.log.Info(self.opcInfoList)

        # setup our server
        server = Server()
        server.set_endpoint("opc.tcp://" + self.get_local_ip("eth0") +
                            ":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)

        server.user_manager.set_user_manager(self.user_manager)
        server.set_security_IDs("Username")

        # get Objects node, this is where we should put our nodes
        objects = server.get_objects_node()

        # populating our address space
        obj_modbusDevInfoList = objects.add_object(idx,
                                                   "obj_modbusDevInfoList")
        obj_opcInfoList = objects.add_object(idx, "obj_opcInfoList")
        obj_lzbusIpInfoList = objects.add_object(idx, "obj_lzbusIpInfoList")
        obj_snmpInfoList = objects.add_object(idx, "obj_snmpInfoList")

        obj_dev1 = objects.add_object(idx, "obj_173_12_10_138")
        obj_dev2 = objects.add_object(idx, "obj_173_12_10_139")

        v_modbusDevInfoList = obj_modbusDevInfoList.add_variable(
            idx, "v_modbusDevInfoList", "")
        v_opcInfoList = obj_opcInfoList.add_variable(idx, "v_opcInfoList", "")
        v_lzbusIpInfoList = obj_lzbusIpInfoList.add_variable(
            idx, "v_lzbusIpInfoList", "")
        v_snmpInfoList = obj_snmpInfoList.add_variable(idx, "v_snmpInfoList",
                                                       "")

        d1_ip = obj_dev1.add_variable(idx, "ID", "173.12.10.138")
        d1_type = obj_dev1.add_variable(idx, "TYPE", "1")
        d1_powerstatus = obj_dev1.add_variable(idx, "POWERSTAUS", "on")
        d1_netstatus = obj_dev1.add_variable(idx, "NETSTATUS", "on")
        d1_cpu1_per = obj_dev1.add_variable(idx, "CPU1_PER", "70")
        d1_cpu2_per = obj_dev1.add_variable(idx, "CPU2_PER", "50")
        d1_cpu3_per = obj_dev1.add_variable(idx, "CPU3_PER", "30")
        d1_cpu4_per = obj_dev1.add_variable(idx, "CPU4_PER", "10")
        d1_mem_total = obj_dev1.add_variable(idx, "MEM_TOTAL", "82300000")
        d1_disk_total = obj_dev1.add_variable(idx, "DISK_TOTAL", "70")

        d2_type = obj_dev2.add_variable(idx, "TYPE", "1")
        d2_powerstatus = obj_dev2.add_variable(idx, "POWERSTAUS", "on")
        d2_netstatus = obj_dev2.add_variable(idx, "NETSTATUS", "on")
        d2_cpu1_per = obj_dev2.add_variable(idx, "CPU1_PER", "70")
        d2_cpu2_per = obj_dev2.add_variable(idx, "CPU2_PER", "50")
        d2_cpu3_per = obj_dev2.add_variable(idx, "CPU3_PER", "30")
        d2_cpu4_per = obj_dev2.add_variable(idx, "CPU4_PER", "10")
        d2_mem_total = obj_dev2.add_variable(idx, "MEM_TOTAL", "82300000")
        d2_disk_total = obj_dev2.add_variable(idx, "DISK_TOTAL", "70")

        # starting!
        server.start()

        while True:
            dateInfo = datetime.datetime.now().strftime('%Y-%m-%d %H-%M-%S')
            v_modbusDevInfoList.set_value(json.dumps(self.modbusDevInfoList))
            v_opcInfoList.set_value(json.dumps(self.opcInfoList))
            v_lzbusIpInfoList.set_value(json.dumps(self.lzbusIpInfoList))
            v_snmpInfoList.set_value(json.dumps(self.snmpInfoList))

            d1_ip.set_value("173.12.10.138")
            d1_type.set_value("1")
            d1_powerstatus.set_value("on")
            d1_netstatus.set_value("on")
            d1_cpu1_per.set_value("70")
            d1_cpu2_per.set_value("50")
            d1_cpu3_per.set_value("30")
            d1_cpu4_per.set_value("10")
            d1_mem_total.set_value("82300000")
            d1_disk_total.set_value("70")

            d2_type.set_value("1")
            d2_powerstatus.set_value("on")
            d2_netstatus.set_value("on")
            d2_cpu1_per.set_value("70")
            d2_cpu2_per.set_value("50")
            d2_cpu3_per.set_value("30")
            d2_cpu4_per.set_value("10")
            d2_mem_total.set_value("82300000")
            d2_disk_total.set_value("70")

            time.sleep(60)
class CustomServer(object):
    def __init__(self):
        self.SERVER_ENDPOINT = os.environ.get("SERVER_ENDPOINT")
        self.NAMESPACE = os.environ.get("NAMESPACE")
        self.SERVER_NAME = os.environ.get("SERVER_NAME")
        self.ENABLE_CERTIFICATE = bool(
            strtobool(os.environ.get("ENABLE_CERTIFICATE")))

        # setup our server
        self.server = Server()
        self.server.set_endpoint(self.SERVER_ENDPOINT)
        self.server.set_server_name(self.SERVER_NAME)

        # set the security endpoints for identification of clients
        if self.ENABLE_CERTIFICATE:
            # load server certificate and private key. This enables endpoints with signing and encryption.
            self.CERTIFICATE_PATH_SERVER_CERT = os.path.dirname(
                os.getcwd()) + os.environ.get("CERTIFICATE_PATH_SERVER_CERT")
            self.CERTIFICATE_PATH_SERVER_PRIVATE_KEY = os.path.dirname(
                os.getcwd()) + os.environ.get(
                    "CERTIFICATE_PATH_SERVER_PRIVATE_KEY")
            self.server.load_certificate(self.CERTIFICATE_PATH_SERVER_CERT)
            self.server.load_private_key(
                self.CERTIFICATE_PATH_SERVER_PRIVATE_KEY)

            # set all possible endpoint policies for clients to connect through
            self.server.set_security_policy([
                # ua.SecurityPolicyType.NoSecurity,
                ua.SecurityPolicyType.Basic256Sha256_SignAndEncrypt,
                # ua.SecurityPolicyType.Basic256Sha256_Sign,
            ])

            self.server.set_security_IDs(["Username", "Basic256Sha256"])
        else:
            self.server.set_security_policy([ua.SecurityPolicyType.NoSecurity])
            self.server.set_security_IDs(["Anonymous", "Username"])

        # set the user_manager function
        self.server.user_manager.set_user_manager(user_manager)

        # setup our own namespace, not really necessary but should as spec
        uri = self.NAMESPACE
        self.idx = self.server.register_namespace(uri)

        # get important nodes
        self.root = self.server.get_root_node()
        self.obj = self.server.get_objects_node()

        self.init_methods()

    def init_methods(self):
        # method: ADD_OBJECTS_DIR
        inarg1 = ua.Argument()
        inarg1.Name = "objects folder"
        inarg1.DataType = ua.NodeId(ua.ObjectIds.String)  # String
        inarg1.ValueRank = -1
        inarg1.ArrayDimensions = []
        inarg1.Description = ua.LocalizedText("Name the new objects folder")

        method_node = self.obj.add_method(self.idx, "ADD_NEW_OBJECTS_FOLDER",
                                          self.add_objects_subfolder, [inarg1])

        # method: ADD_OPC_TAG
        inarg1 = ua.Argument()
        inarg1.Name = "opctag"
        inarg1.DataType = ua.NodeId(ua.ObjectIds.String)  # String
        inarg1.ValueRank = -1
        inarg1.ArrayDimensions = []
        inarg1.Description = ua.LocalizedText("Name new OPC variable")

        inarg2 = ua.Argument()
        inarg2.Name = "variant_type"
        inarg2.DataType = ua.NodeId(ua.ObjectIds.String)  # String
        inarg2.ValueRank = -1
        inarg2.ArrayDimensions = []
        inarg2.Description = ua.LocalizedText("Type of variable")

        inarg3 = ua.Argument()
        inarg3.Name = "parent_node"
        inarg3.DataType = ua.NodeId(ua.ObjectIds.String)  # String
        inarg3.ValueRank = -1
        inarg3.ArrayDimensions = []
        inarg3.Description = ua.LocalizedText(
            "Type in the name of the parent node the new variable should assigned to"
        )

        method_node = self.obj.add_method(self.idx, "ADD_OPC_TAG",
                                          self.register_opc_tag,
                                          [inarg1, inarg2, inarg3])

        # method: SET_PV_LIMIT
        inarg1 = ua.Argument()
        inarg1.Name = "active_power_setpoint"
        inarg1.DataType = ua.NodeId(ua.ObjectIds.Int32)  # Integer
        inarg1.ValueRank = -1
        inarg1.ArrayDimensions = []
        inarg1.Description = ua.LocalizedText(
            "Type in active power setpoint in percent [0 ... 100]")

        inarg2 = ua.Argument()
        inarg2.Name = "parent_node"
        inarg2.DataType = ua.NodeId(ua.ObjectIds.String)  # String
        inarg2.ValueRank = -1
        inarg2.ArrayDimensions = []
        inarg2.Description = ua.LocalizedText(
            "Type in the name of the parent node")

        method_node = self.obj.add_method(self.idx, "SET_PV_LIMIT",
                                          self.set_pv_active_power_setpoint,
                                          [inarg1, inarg2])

        # method: RUN_ONLINE_GRID_PROTECTION
        inarg1 = ua.Argument()
        inarg1.Name = "On/Off"
        inarg1.DataType = ua.NodeId(ua.ObjectIds.Int32)  # Integer
        inarg1.ValueRank = -1
        inarg1.ArrayDimensions = []
        inarg1.Description = ua.LocalizedText(
            "Type in 1 to RUN or 0 to STOP ONLINE_GRID_PROTECTION")

        inarg2 = ua.Argument()
        inarg2.Name = "parent_node"
        inarg2.DataType = ua.NodeId(ua.ObjectIds.String)  # String
        inarg2.ValueRank = -1
        inarg2.ArrayDimensions = []
        inarg2.Description = ua.LocalizedText(
            "Type in the name of the parent node")

        method_node = self.obj.add_method(self.idx,
                                          "RUN_ONLINE_GRID_PROTECTION",
                                          self.run_online_grid_protection,
                                          [inarg1, inarg2])

    @uamethod
    def add_objects_subfolder(self, parent, dir_name):
        # check if old dir with dir_name exists. if so then delete this dir first
        try:
            obj = self.root.get_child(
                ["0:Objects", ("{}:" + dir_name).format(self.idx)])
            self.server.delete_nodes([obj], True)
        except BadNoMatch:
            print(DateHelper.get_local_datetime(),
                  "There is no old folder with the name: " + dir_name)

        folder = self.obj.add_folder(self.idx, dir_name)
        print(DateHelper.get_local_datetime(), "Add subfolder: " + dir_name)

    @uamethod
    def register_opc_tag(self,
                         parent,
                         opctag,
                         variant_type="Float",
                         parent_node=""):
        # Object "parent_node":
        try:
            obj = self.root.get_child(
                ["0:Objects", ("{}:" + parent_node).format(self.idx)])
        except BadNoMatch:
            print(
                DateHelper.get_local_datetime(),
                "register_opc_tag(): OPCUA_server_dir the variables should be assigned to, doesn't exists."
            )
            raise

        var = ua.Variant(0, strings_to_vartyps(variant_type))
        mvar = obj.add_variable(self.idx, opctag.strip(), var)
        mvar.set_writable()
        print(
            DateHelper.get_local_datetime(), "Add variable: " + opctag +
            " of type " + variant_type + " @node " + parent_node)

    @uamethod
    def set_pv_active_power_setpoint(self, parent, setpoint, parent_node=""):
        try:
            obj = self.root.get_child(
                ["0:Objects", ("{}:" + parent_node).format(self.idx)])
        except BadNoMatch:
            print(
                DateHelper.get_local_datetime(),
                "set_pv_active_power_setpoint(): assign new value to node failed."
            )
            raise

        for mvar in obj.get_variables():
            if "PV" and "CTRL" in mvar.get_browse_name().Name:
                variant_type = mvar.get_data_value().Value.VariantType
                mvar.set_value(clamp(setpoint, 0, 100), variant_type)
                print(
                    DateHelper.get_local_datetime(),
                    "Set Value of node " + mvar.get_browse_name().Name +
                    " to " + str(clamp(setpoint, 0, 100)))

    @uamethod
    def run_online_grid_protection(self, parent, setpoint, parent_node=""):
        try:
            obj = self.root.get_child(
                ["0:Objects", ("{}:" + parent_node).format(self.idx)])
        except BadNoMatch:
            print(DateHelper.get_local_datetime(),
                  "run_online_grid_protection(): Change in On/Off failed.")
            raise

        for mvar in obj.get_variables():
            if "RUN_ONLINE_GRID_PROTECTION" in mvar.get_browse_name().Name:
                variant_type = mvar.get_data_value().Value.VariantType
                mvar.set_value(clamp(setpoint, 0, 1), variant_type)
                print(
                    DateHelper.get_local_datetime(),
                    "Change status of online grid protection to " +
                    str(clamp(setpoint, 0, 1)))

    def start(self):
        self.server.start()
        print(DateHelper.get_local_datetime(), self.__class__.__name__,
              " successful started")

    def stop(self):
        self.server.stop()
        print(DateHelper.get_local_datetime(), self.__class__.__name__,
              " successful stopped")