C# чтение и запись на сервере opc ua, просмотр всех узлов, чтение и запись узлов — АСУ ТП: сообщество инженеров

C# чтение и запись на сервере opc ua, просмотр всех узлов, чтение и запись узлов

Коротко о статье

В статье приведены примеры использования библиотеки OpcUaHelper.dll для работы с узлами OPC UA сервера на C#: подключение, просмотр узлов, чтение и запись значений. Материал охватывает одиночные и пакетные операции, а также чтение по подписке.

Главное
  • Для работы устанавливается пакет OpcUaHelper через NuGet и подключается пространство имён using OpcUaHelper.
  • В качестве тестового OPC UA сервера используется симулятор Codesys 3.5 с настроенным OPC UA сервером.
  • Браузер узлов Node browser позволяет получить конфигурацию сервера и адреса узлов.
  • Экземпляр OpcUaClient подключается к серверу асинхронно и отключается при закрытии формы.
  • Чтение реализуется одиночным методом ReadNode, пакетным ReadNodes и подпиской через AddSubscription.
  • Запись выполняется методом WriteNodes для нескольких узлов одновременно.
Термины и технологии
  • OPC UA
  • OpcUaHelper.dll
  • OpcUaClient
  • Node browser
  • Codesys 3.5
  • NodeId
  • DataValue
  • MonitoredItem

Кому полезно: Инженерам АСУ ТП и разработчикам на C#, работающим с OPC UA серверами.

Первоисточник: digielectric.ru

Выжимка составлена редакцией сайта с помощью ИИ по тексту статьи.

OPC UA [унифицированная архитектура OPC] является относительно новой и достаточно распространенной технологией «общения» между машинами. В данной статье приведу примеры того, как можно использовать методы, предоставляемы библиотекой классов OpcUaHelper.dll для осуществления операций с узлами сервера.

Предварительная подготовка

В диспетчере пакетов NuGet установите пакет OpcUaHelper, затем подключите пространство имен следующим образом:

using OpcUaHelper;

Подготовка сервера OPC UA

Для проведения тестов можно использовать любой Opc Ua сервер. В случае, если Opc Ua сервер отсутствует, можно создать тестовое скрипт на Python. Я, в качестве Opc Ua сервера использую симулятор Codesys 3.5. Скачать проект для CodeSys 3.5 SP20 с настроенным Opc Ua сервером можно здесь.

Node browser

Для проведения тестов можно использовать любой Opc Ua сервер. В случае, если Opc Ua сервер отсутствует, можно создать тестовое скрипт на Python. Я, в качестве Opc Ua сервера использую симулятор Codesys 3.5. Скачать проект для CodeSys 3.5 SP20 с настроенным Opc Ua сервером можно здесь.

При помощи браузера узлов Node browser можно получить данные о конфигурации сервера. Это позволит создать карту узлов Opc Ua сервера, узнать об адресах узлов сервера.

private void btnShowBrowse_Click(object sender, EventArgs e)
{
   using (FormBrowseServer form = new FormBrowseServer())
   {
      form.ShowDialog();
   }
}

Создание экземпляра Opc Ua клиента

//Экземпляр Opc Ua сервера
private OpcUaClient opcUaClient = new OpcUaClient();
 
//Асинхронный метод, вызываемый при загрузке формы
//В методе осуществляется подключение к Opc Ua серверу: opc.tcp://127.0.0.1:4840/Opc
private async void Form1_Load(object sender, EventArgs e)
{
  //Авторизация (при необходимости)
  opcUaClient.UserIdentity = new Opc.Ua.UserIdentity("ВАШ ЛОГИН", "ВАШ ПАРОЛЬ");

  //Подключение к серверу
  await opcUaClient.ConnectServer("opc.tcp://127.0.0.1:4840/MyFirstOpc");
}
 
//Метод, вызываемый при закрытии формы
//В методе осуществляется отключение от Opc Ua сервера
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
  opcUaClient.Disconnect();
}

Просмотр локально зарегистрированных серверов

//Метод, вызываемый при нажатии на кнопку = Просмотр зарегистрированных Opc Ua серверов
private void btnDiscoverServer_Click( object sender, EventArgs e )
{
   // Получение адреса зарегистрированного сервера
   string endpointUrl = new Opc.Ua.Client.Controls.DiscoverServerDlg( ).ShowDialog( opcUaClient.AppConfig, null );
   
   // Получить адрес, зарегистрированный другими серверами. Обратите внимание, что политика безопасности IP должна быть настроена правильно
   // string endpointUrl = new Opc.Ua.Client.Controls.DiscoverServerDlg( ).ShowDialog( opcUaClient.AppConfig, "192.168.0.100" );
 
   if (!string.IsNullOrEmpty( endpointUrl ))
   {
       // Получить адрес сервера, которым нужно управлять
   }
}

Операция одиночного чтения узла

/// <summary>
/// Операция чтения узла
/// </summary>
private void btnReadSingleNode_Click(object sender, EventArgs e)
{
    try
    {
        float value = opcUaClient.ReadNode<float>("ns=2;s=VibroSensors!AxX");
        MessageBox.Show ($"Уровень жидкости в резервуаре: {value} %");
    }
    catch(Exception ex)
    {
        MessageBox.Show ($"{ex.Message}}");
    }
}

Операция пакетного чтения узлов

/// <summary>
/// Операция пакетного чтения узлов с неизвестными типами
/// </summary>
private void btnReadNodesAsUnknowTypes_Click(object sender, EventArgs e)
{
    try
    {
        // Инициализация списка с узлами, значение которых необходимо прочитать
        List<NodeId> nodeList = new List<NodeId>( )
        {
            new NodeId ("ns=2;s=VibroSensors!AxX"),
            new NodeId ("ns=2;s=VibroSensors!AxY"),
            new NodeId ("ns=2;s=VibroSensors!AxZ")
        };

        // Пакетное чтение значений выбранных узлов
        List<DataValue> uDataValues = opcUaClient.ReadNodes(nodeList.ToArray());

        // В данном цикле получение прочитанного значения узла
        // в виде object
        foreach (var dataValue in uDataValues)
        {
            object value = dataValue.WrappedValue.Value;
            // ВАШ КОД ...
        }
 
    }
    catch (Exception ex)
    {
        ClientUtils.HandleException( this.Text, ex );
    }
}

/// <summary>
/// Операция пакетного чтения узлов с определенными (известными) типами данных
/// </summary>
private void btnReadNodesAsKnowTypes_Click(object sender, EventArgs e)
{
    try
    {
        // Если типы значений, которые вы читаете в пакетах, одинаковы, например, float, то есть удобный способ
        List<string> tags = new List<string>( )
        {
            "ns=2;s=VibroSensors!AxX",
            "ns=2;s=VibroSensors!AxY",
            "ns=2;s=VibroSensors!AxZ"
        };
 
        // Значения определены в порядке
        List<float> values = opcUaClient.ReadNodes<float>( tags.ToArray() );
 
    }
    catch (Exception ex)
    {
      ClientUtils.HandleException( this.Text, ex );
    }
}

Операция чтения узла по подписке

/// <summary>
/// Обработка нажатия кнопки - подвисаться
/// </summary>
 private void btnSubscribe_Click( object sender, EventArgs e )
 {
    OpcUaClient.AddSubscription("AxX", "ns=2;s=VibroSensors!AxX", SubCallback);
}
 
/// <summary>
/// Функция Callback
/// </summary>
private void SubCallback(string key, MonitoredItem monitoredItem, MonitoredItemNotificationEventArgs args )
{
    if (InvokeRequired)
    {
        Invoke( new Action<string, MonitoredItem, MonitoredItemNotificationEventArgs>(SubCallback), key, monitoredItem, args );
        return;
    }
 
    // Обработка события по ключу
    if (key == "AxX")
    {
        MonitoredItemNotification notification = args.NotificationValue as MonitoredItemNotification;
        if (notification != null)
        {
            txbVibroAxX.Text = notification.Value.WrappedValue.Value.ToString( );
        }
    }
}

Операция одиночной записи узла

/// <summary>
/// Операция чтения узла
/// </summary>
private void btnReadSingleNode_Click(object sender, EventArgs e)
{
    try
    {
        float value = opcUaClient.ReadNode<float>("ns=2;s=VibroSensors!AxX");
        MessageBox.Show ($"Уровень жидкости в резервуаре: {value} %");
    }
    catch(Exception ex)
    {
        MessageBox.Show ($"{ex.Message}}");
    }
}

Операция пакетной записи узлов

/// <summary>
/// Пакетная запись значений в узлы
/// </summary>
private void btnWriteMultiNodes_Click(object sender, EventArgs e)
{
    // Определение имен узлов, в которые
    // необходимо записать значения
    string[] nodes = new string[]
    {
        "ns=2;s=VibroSensors!AxX",
        "ns=2;s=VibroSensors!AllSensors"
    };

    object[] data = new object[]
    {
        4, new float[]{2.1, 2.0, 1.9, 1.98, 1.99, 2.05}
    };
 
    // Запись данных в узлы Opc Ua сервера 

  bool result = opcUaClient.WriteNodes(nodes, data);

Источник: https://digielectric.ru/Articles/OpcUaDotNet

Оставьте комментарий

Войти

Зарегистрироваться

Сбросить пароль

Пожалуйста, введите ваше имя пользователя или эл. адрес, вы получите письмо со ссылкой для сброса пароля.

Прокрутить вверх