Примеры кода

В данном разделе вы познакомитесь с менеджером API C# с помощью некоторых примеров исполняемого исходного кода. Полный исходный код примера приведен последним.

  1.  Создание нового менеджера

Следуйте инструкциям главы «Создание менеджера C# API» и удалите исходный код класса «Program». Теперь ваш класс должен выглядеть следующим образом:

using System;
using System.Threading.Tasks;
namespace GettingStarted
{
  class Samples
  {
    static OaManager _managerInstance = null;
    public Samples()
    {
      PrintSampleUsage();
    }
    public void PrintSampleUsage()
    {
      Console.Clear();
      Console.WriteLine("Нажмите клавиши 1 – 9, чтобы запустить соответствующий пример кода:");
      Console.WriteLine("1     Создать новый менеджер");
      Console.WriteLine("2     Установить соединение");
      Console.WriteLine("3     Считать текущее значение из "КАСКАД Цифра"  (синхронно и асинхронно)");
      Console.WriteLine("4     Асинхронно записать значение в "КАСКАД Цифра"");
      Console.WriteLine("5     Запросить изменения значений");
      Console.WriteLine("6     Создать точку данных");
      Console.WriteLine("7     Запросить текущие алармы с использованием выражения SELECT");
      Console.WriteLine("8     Запросить исторические значения");
      Console.WriteLine("9     Полный пример");
      Приставка.WriteLine ("ESC   Выхов");
    }
  }
}
  1. Подключение

В следующем примере устанавливается соединение с проектом «КАСКАД Цифра» с помощью заданных программных аргументов, предоставляемых командной строкой. Скопируйте исходный код в пустой проект.

class Program
using System;
using System.Threading.Tasks;
namespace GettingStarted
{
  class Samples
  {
    static OaManager _managerInstance = null;
    public Samples()
    {
      PrintSampleUsage();
    }
    public void PrintSampleUsage()
    {
      Console.Clear();
      Console.WriteLine("Нажмите клавиши 1 – 9, чтобы запустить соответствующий пример кода:");
      Console.WriteLine("1     Создать новый менеджер");
      Console.WriteLine("2     Установить соединение");
      Console.WriteLine("3     Считать текущее значение из "КАСКАД Цифра"  (синхронно и асинхронно)");
      Console.WriteLine("4     Асинхронно записать значение в "КАСКАД Цифра"");
      Console.WriteLine("5     Запросить изменения значений");
      Console.WriteLine("6     Создать точку данных");
      Console.WriteLine("7     Запросить текущие алармы с использованием выражения SELECT");
      Console.WriteLine("8     Запросить исторические значения");
      Console.WriteLine("9     Полный пример");
      Приставка.WriteLine ("ESC   Выхов");
    }
    // Пример 1: создание объекта менеджера
    public OaManager ManagerInstance
    {
      get
      {
        // Шаблон проектирования "Одиночка" (Синглтон) гарантирует, что будет создан только один объект менеджера
        if (_managerInstance == null)
          _managerInstance = OaSdk.CreateManager();
        return _managerInstance;
      }
    }
    // Пример 2: установка соединения с проектом "КАСКАД Цифра"
    public async Task<int>EstablishConection(string[] args)
    {
      // Инициализация конфигурации менеджера
      ManagerInstance.Init(ManagerSettings.DefaultApiSettings, args);
      // Запуск менеджера
      await ManagerInstance.StartAsync();
      // Сообщение о подключении. Консольный вывод идет прямо в средство просмотра журналов "КАСКАД Цифра"
      Console.WriteLine("Connection to project established");
      return 1;
    }
  }
}
  1.  Чтение текущих значений «КАСКАД Цифра»

В первом примере считывается текущее значение с помощью синхронной версии функции GetDpValue() из подключенного проекта «КАСКАД Цифра». Запустите пример, скопировав код в класс Program, и вызовите ReadValuesExample() из функции main ().

// Пример 3: считывание текущего значения из "КАСКАД Цифра"
    public void ReadValuesExample()
    {
      // Получение доступа к ProcessValues
      OaProcessValues valueAccess = ManagerInstance.ProcessValues;
      // Вызов GetDpValue через объект "Access"
      OaDpValueItem myFloatItem = valueAccess.GetDpValue("ExampleDP_Arg1.");
      // Чтение свойства DpValue из экземпляра OaDpValue
      double myFloatVal1 = myFloatItem.DpValue;
      // Это также можно было бы сделать в одной строке с
      double myFloatVal2 = valueAccess.GetDpValue("ExampleDP_Arg1.").DpValue;
      // Чтение более одного значения
      string[] myValuesToRead = { "ExampleDP_Arg1.", "ExampleDP_AlertHdl1." };
      var myResultCollection = valueAccess.GetDpValue(myValuesToRead);
      // Проход циклом по всем ответам
      foreach (var item in myResultCollection)
      {
        Console.WriteLine(item.DpValue.ToString());
      }
    }

Второй фрагмент демонстрирует считывание текущего значения с помощью асинхронной версии функции GetDpValue() из подключенного проекта «КАСКАД Цифра». Запустите пример, скопировав код в класс Program и вызвав ReadValuesExampleAsync().Wait() из функции main().

// Пример 3b: асинхронное считывание текущих значений из "КАСКАД Цифра"
    public async Task ReadValuesExampleAsync()
    {
      // Получение доступа к ProcessValues
      OaProcessValues valueAccess = ManagerInstance.ProcessValues;
      // Вызов GetDpValue через объект "Access"
      OaDpValueItem myFloatItem = await valueAccess.GetDpValueAsync("ExampleDP_Arg1.");
      // Чтение свойства DpValue из экземпляра OaDpValue
      double myFloatVal1 = myFloatItem.DpValue;
      // Без await асинхронное значение возвращает объект Task, который можно было бы ожидать позже
      Task<OaDpValueItem> myTaskToWait = valueAccess.GetDpValueAsync("ExampleDP_Arg1.");
      // Здесь можно сделать какие-то действия, пока идет ожидание значения
      Console.WriteLine("Во время ожидания ожидания можно сделать какие-то действия");
      // Дождитесь результата и получите значение результата напрямую 
      var myFloatIVal2 = (await myTaskToWait).DpValue;
    }
  1.    Запись значений в «КАСКАД Цифра»

Следующий код демонстрирует запись значения float 4.2 в точку данных «ExampleDP_Arg1.” Запустите пример, скопировав код в класс Program и вызвав WriteValuesExampleAsync().Wait() из функции main ().

// Пример 4. Запись значений в "КАСКАД Цифра"
    public async Task WriteValuesExampleAsync()
    {
      // Получение доступа к ProcessValues
      OaProcessValues valueAccess = ManagerInstance.ProcessValues;
      // Вызов SetDpValue через объект "Access". SetDpValue ждет ответа от
      // менеджера событий
      await valueAccess.SetDpValueAsync("ExampleDP_Arg1.", 4.2);
      // Вызов FireDpValue. FireDpValue не ждет ответа от менеджера событий 
      // (поэтому асинхронный вариант не нужен)
      valueAccess.FireDpValue("ExampleDP_Arg1.", 77.2);
      // Установить набор значений с определенным временем
      await valueAccess.SetDpValueAsync(DateTime.Now.AddSeconds(2),
      new Tuple<string, OaVariant>("ExampleDP_Arg1.", (double)7.7),
      new Tuple<string, OaVariant>("ExampleDP_AlertHdl1.", (bool)false));
    }
  1.  Запрос изменений значений

Следующий пример демонстрирует оформление подписки на изменения значений и меток времени точек данных «ExampleDP_Arg1.» и «ExampleDP_Arg2.”. Запустите пример, скопировав код в класс Program и вызвав SubscribeOnValueChangesExampleAsync().Wait() из функции main ().

 // Пример 5: запрос изменений значений
    public async Task SubscribeOnValueChangesExampleAsync()
    {
      // Получение доступа к ProcessValues
      OaProcessValues valueAccess = ManagerInstance.ProcessValues;
      // Создать объект "Subscription" 
      OaDpValueSubscription mySubscription = valueAccess.CreateDpValueSubscription();
      // Добавить точки данных для подписки на них
      mySubscription.AddDp("ExampleDP_Arg1.");
      mySubscription.AddDp("ExampleDP_Arg1.:_online.._stime");
      mySubscription.AddDp("ExampleDP_Arg2.");
      mySubscription.AddDp("ExampleDP_Arg2.:_online.._stime");
      // Определите функцию делегата для события изменения значения. Можно сделать так, как показано здесь.
      //Либо в виде лямбда-функции, либо в виде отдельной функции
      mySubscription.SingleValueChanged += (vcsender, vce) =>
      {
        if (vce.IsAnswer)
          Console.WriteLine("Первый ответ: " + vce.Value.DpValue.ToString());
        else
          Console.WriteLine("Измененное значение: " + vce.Value.DpValue.ToString());
      };
      // Если FireChangedEventForAnswer имеет значение true, то ValueChangedEvent также срабатывает для первого ответа
      mySubscription.FireChangedEventForAnswer = true;
      // Активируйте подписку и в качестве дополнительной опции дождитесь первого ответа в качестве результирующего значения
      var FirstAnswerItem = await mySubscription.StartAsync();
      // Измените значение одного DPE, чтобы вызвать событие подписки
      await valueAccess.SetDpValueAsync("ExampleDP_Arg1.", 100.1);
      await mySubscription.StopAsync();
    }
  1.  Создание точки данных

Следующий код демонстрирует создание новой точки данных «myNewTestDp». Если точка данных уже существует, она автоматически удаляется. Запустите пример, скопировав код в класс Program и вызвав ModifyDataModelExample().Wait() из функции main ().

    // Пример 6: Создание точки данных
    public async Task ModifyDataModelExample()
    {
      // Получение доступа к ProcessModel
      OaProcessModel dataModel = ManagerInstance.ProcessModel;
      // Проверьте, существует ли уже точка данных "myNewTestDp", и в этом случае удалите ее
      if (await dataModel.IsDpPathExistingAsync("myNewTestDp"))
        await dataModel.DeleteDpAsync("myNewTestDp");
      // Создание "myNewTestDp"
      await dataModel.CreateDpAsync("myNewTestDp", "ExampleDP_Float");
    }
  1.  Запрос текущих алармов с использованием выражения SELECT

Этот фрагмент кода запрашивает текущие алармы. Запустите пример, скопировав код в класс Program и вызвав AlertQuerySubscriptionExample().Wait() из функции main ().

// Пример 7: запрос текущих алармов с использованием выражения SELECT
    EventHandler<OaQuerySubscriptionChangedEventArgs> myAlertChangedEvent = delegate (object sender, OaQuerySubscriptionChangedEventArgs args)
    {
      for (int iLoop = 0; iLoop < args.Result.GetRecordCount(); iLoop++)
      {
        var atime = args.Result.GetData(iLoop, 1);
        var avalue = args.Result.GetData(iLoop, 2);
        Console.WriteLine("Запись " + iLoop + ": Время аларма: " + atime.ToString() + "значение: " + avalue.ToString());
      }
    };
    public async Task AlertQuerySubscriptionExample()
    {
      // Получение доступа к алармам
      var alerts = ManagerInstance.Alerts;
      // Создание подписки AlertQuerySubscription
      var alertSubscription = alerts.CreateAlertQuerySubscription();
      // Настройка AlertQuerySubscription;
      // Установите AlertChangedEvent, назначив обработчик SystemEventHandler;
      alertSubscription.ValueChanged += myAlertChangedEvent;
      // Триггер ChangedEvent также сработает и для первого ответа
      alertSubscription.FireChangedEventForAnswer = true;
      // Ниже будет задана строка запроса
      alertSubscription.SetQuery("SELECT ALERT '_alert_hdl.._value' FROM '*.**'");
      // Запуск AlertQuerySubscription
      await alertSubscription.StartAsync();
    }
  1.  Запрос исторических значений

Код запрашивает исторические значения в определенном временном диапазоне. Запустите пример, скопировав код в класс Program и вызвав QueryHistoricalValuesExample().Wait() из функции main ().

// Пример 8: запрос исторических значений
    public async Task QueryHistoricalValuesExample()
    {
      // Получение доступа к ValueHistory
      var histAccess = ManagerInstance.ValueHistory;
      DateTime tStart = DateTime.Now; // запоминаем начальное время
      // Сымитируем 5 значений с помощью SetValue
      for (int i = 1; i <= 5; i++)
      {
        // использование ProcessValues напрямую без временной переменной
        ManagerInstance.ProcessValues.SetDpValue("ExampleDP_Rpt1.", (double)i);
      }
      DateTime tEnd = DateTime.Now; // remember the end time
      // Запрос исторических данных
      var myResult = await histAccess.GetDpValuePeriodAsync(tStart, tEnd, "ExampleDP_Rpt1.");
      foreach (var TimedValue in myResult)
      {
        Console.WriteLine("Получено: " + TimedValue.DpName.ToString() +
                           " Значение: " + TimedValue.DpValue.ToString() +
                           " Метка времени: " + TimedValue.SourceTime.ToString());
      }
    }
  1. Полный пример

Следующий пример содержит все ранее перечисленные блоки кода:

// Пример 9: полный
public void CompleteSample(string[] args)
    {
      // Получение локальной ссылки на объект менеджера
      OaManager myManager = ManagerInstance;
      // Инициализация конфигурации менеджера
      myManager.Init(ManagerSettings.DefaultApiSettings, args);
      // Запуск менеджера и подключение к проекту OA с заданной конфигурацией
      myManager.Start();
      // Чтение из конфигурационного файла секции myCsTest. 
      // ReadString(section, key, defaultval)
      OaConfigurationFile file = new OaConfigurationFile();
      string dpNameSet = file.ReadString("myCsTest", "dpNameSet", "ExampleDP_Arg2.");
      string dpNameConnect = file.ReadString("myCsTest", "dpNameConnect", "ExampleDP_Arg1.");
      // Получение доступа к ProcessValues
      var valueAccess = myManager.ProcessValues;
      // Создание объекта подписки
      var mySubscription = valueAccess.CreateDpValueSubscription();
      // Добавление точки данных для подписки
      mySubscription.AddDp(dpNameConnect);
      // Определение лямбда-функции для события изменения значения. Может быть сделано в виде отдельной функции
      mySubscription.SingleValueChanged += (vcsender, vce) =>
      {
        // В случае ошибки vce.Value может быть null 
        if (vce.Value == null)
          return;
        Console.WriteLine("Полученное значение: " + vce.Value.DpValue.ToString() + " для DPE: " + vce.Value.DpName.ToString());
        //Установить полученное значение для DPE с помощью dpNameSet
        valueAccess.SetDpValue(dpNameSet, vce.Value.DpValue.ToDouble());
        Console.WriteLine("Установлено значение: " + vce.Value.DpValue.ToString() + "в DPE: " + dpNameSet);
      };
      // Если FireChangedEventForAnswer имеет значение true, то ValueChangedEvent также срабатывает для первого ответа
      mySubscription.FireChangedEventForAnswer = true;
      // Активируйте подписку и в качестве дополнительной опции дождитесь первого ответа в качестве результирующего значения
      mySubscription.StartAsync();
    }
  }
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *