РЕЖИМ РАБОТЫ:  9.00 - 18.00 ПН - ПТ СБ, ВС - выходные дни
Оплата Доставка

ФБ "Скрипт C#" и его использование в MasterSCADA. Управление трендом – задающий график

ФБ "Скрипт C#" и его использование в MasterSCADA. Управление трендом – задающий график

Иногда перед разработчиками систем автоматизации встает необходимость использования задающего графика. Например – необходимо чтобы процесс шел по строго определенному графику, заданному оператору. При этом необходимо видеть оба графика – эталонный и реальный, на одном тренде. В данной статьей мы рассмотрим создание скрипта для формирования такого графика.

Задающий график создается в тренде, на продвинутом уровне при активной панели настроек. Выберем – Задание таблицей
На тренд добавится перо.
Теперь наша задача управлять данным пером – создать в нем нужные точки. Для этой цели мы будем использовать Скрипт. Для примера мы будем формировать график за сутки по 5 точками.
В дереве объектов разместим команду типа «Время» - «День», с ее помощью мы будем создавать за какой день нужно построить график. Дискретной командой «Сформировать» мы будем выполнять формирование точек пера.

Также разместим в дереве 5 одинаковых объектов – Координата 1Координата 5. В них мы создадим команду типа Время – X, и аналоговая – Y. Также добавим значение Подпись – в нем мы дадим имя каждой точке («Точка 1» - «Точка 5»).

У объектов сделаем изображения объектов, в котором расположим подпись и команды X и Y. Из данных изображений скомпонуем таблицу. В итоге мнемосхема будет выглядеть примерно так.

Теперь перейдем к скрипту. Создадим у скрипта набор входов и выходов - входные сигналы даты формирования, сигнала для формирования, значения координат точек, и выходы – начало и конец для управления трендом (их мы свяжем с параметрами тренда Дата С и Дата по), и выход ошибки.

Установим связи в дереве:

И на мнемосхеме:
Теперь приступим к коду скрипта.

Формирование координат пера мы будем выполнять по сигналу на входе Применить. При этом добавим контроль что все входы имеют значения – в противном случае выдадим ошибку и выйдем из скрипта.
if (Применить==true && M==false) 
 { 
 if (!День.HasValue || !X1.HasValue || !X2.HasValue || !X3.HasValue || !X4.HasValue || !X5.HasValue ||
  !Y1.HasValue || !Y2.HasValue || !Y3.HasValue || !Y4.HasValue || !Y5.HasValue) 
  {
Ошибка="Не заданы все параметры";
return;
  }
}
 M=Применить;  
После проверки, определить начало текущего дня, и запишем на выходы Начало и Конец.
DateTime Start=День.Value.Date;    
Начало=Start;
Конец=Start.AddDays(1);
Ранее, в одной статей, мы уже рассматривали как обратится к тренду, расположенному на мнемосхеме.
var проект = HostFB.TreeItemHlp.Project;        
 //получаем корневой объект
 var объект = (ITreeItemHlp)HostFB.TreeItemHlp.Parent;        
 //получаем тренд         
  RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate
  {
     foreach (Trend trend in проект.GetService<TrendService>().Opened)
     {            
     var host = trend.Host as System.Windows.Forms.Control;            
     if (host!=null)
         {
         Object name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME);
         if (name.ToString()!=ИМЯ_ТРЕНДА || trend.Attribute.TreeItem.ID!=объект.ID || trend.Attribute.DisplayName!=ИМЯ_ОКНА) continue;  
         //Теперь можно работать с трендом                
 
         }                
 }     
 }));   

Ранее, в одной статей, мы уже рассматривали как обратится к тренду, расположенному на мнемосхеме.
var проект = HostFB.TreeItemHlp.Project;        
 //получаем корневой объект
 var объект = (ITreeItemHlp)HostFB.TreeItemHlp.Parent;        
 //получаем тренд         
  RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate
  {
     foreach (Trend trend in проект.GetService<TrendService>().Opened)
     {            
     var host = trend.Host as System.Windows.Forms.Control;            
     if (host!=null)
         {
         Object name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME);
         if (name.ToString()!=ИМЯ_ТРЕНДА || trend.Attribute.TreeItem.ID!=объект.ID || trend.Attribute.DisplayName!=ИМЯ_ОКНА) continue;  
         //Теперь можно работать с трендом                
 
         }                
 }     
 }));   

Итак, теперь можно работать с трендом. Начнем с того, что получим перо «Задающий график». Ранее мы уже получали коллекцию перьев с помощью метода:
var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.Graph2D>().ToList();

Здесь все почти тоже самое, только используется тип пера не Graph2D, а UserGraph2D.
var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.UserGraph2D>().ToList();     

Продолжим – получим нулевой перо (оно у нас единственное). Затем, чтобы обратится к таблице пера (мы добавили перо с формированием по таблице) обратимся к свойству XMLTableValues. В данное свойство нужно записать коллекцию, с координатами. Каждая координата – это точка, структура Poing (описание).
//получаем нулевое перо
           var param=list[0];                            
           param.XMLTableValues = new GraphFigureCollection
                  {
                      new GraphFigure
                          {
              Coords = new CoordCollection
                                   {
                                    new Coord {Logic = new Point((Start.Date+X1.Value.TimeOfDay).ToOADate(), Y1.Value)},
                                       new Coord {Logic = new Point((Start.Date+X2.Value.TimeOfDay).ToOADate(), Y2.Value)},
                                       new Coord {Logic = new Point((Start.Date+X3.Value.TimeOfDay).ToOADate(), Y3.Value)},
                                       new Coord {Logic = new Point((Start.Date+X4.Value.TimeOfDay).ToOADate(), Y4.Value)},
                                       new Coord {Logic = new Point((Start.Date+X5.Value.TimeOfDay).ToOADate(), Y5.Value)},
 
                                   }
                          }
                   };



В строке Start.Date+X5.Value.TimeOfDay происходит сложение даты (начала дня), и заданной пользователем координаты времени (дата отбрасывается). Затем с помощью метода ToOADate происходит преобразование формата DateTime в переменную Double, которую требует структура Point.

Наш скрипт готов. Итоговый вариант выглядит следующим образом:
 public partial class ФБ : ScriptBase
{
bool? M=false;
string ИМЯ_ТРЕНДА = "Тренд";    
string ИМЯ_ОКНА = "Мнемосхема";    
    public override void Execute()
    {
     
    if (Применить==true && M==false) 
    { 
    if (!День.HasValue || !X1.HasValue || !X2.HasValue || !X3.HasValue || !X4.HasValue || !X5.HasValue ||
     !Y1.HasValue || !Y2.HasValue || !Y3.HasValue || !Y4.HasValue || !Y5.HasValue) 
     {
   Ошибка="Не заданы все параметры";
   return;
     }
    DateTime Start=День.Value.Date;    
    Начало=Start;
    Конец=Start.AddDays(1);
     //System.Diagnostics.Debug.Assert(false);
        //Ссылка на текущий проект        
        var проект = HostFB.TreeItemHlp.Project;        
        //получаем корневой объект
        var объект = (ITreeItemHlp)HostFB.TreeItemHlp.Parent;        
        //получаем тренд         
         RTManager.Instance.ThreadHolder.BeginInvoke(new ThreadStart(delegate
         {
            foreach (Trend trend in проект.GetService<TrendService>().Opened)
            {            
            var host = trend.Host as System.Windows.Forms.Control;            
            if (host!=null)
                {
                Object name = WinFormsControlBase.GetAmbientProperty(host, WindowlessControlBase.DISPID.DISPID_AMBIENT_NAME);
                if (name.ToString()!=ИМЯ_ТРЕНДА || trend.Attribute.TreeItem.ID!=объект.ID || trend.Attribute.DisplayName!=ИМЯ_ОКНА) continue;  
                //получаем коллекцию перьев                
                var list = trend.Settings.Objects.OfType<MasterSCADA.Graph.Objects.UserGraph2D>().ToList();     
                //получаем нулевое перо
                var param=list[0];                            
                param.XMLTableValues = new GraphFigureCollection
                       {
                           new GraphFigure
                               {
                   Coords = new CoordCollection
                                        {
                                         new Coord {Logic = new Point((Start.Date+X1.Value.TimeOfDay).ToOADate(), Y1.Value)},
                                            new Coord {Logic = new Point((Start.Date+X2.Value.TimeOfDay).ToOADate(), Y2.Value)},
                                            new Coord {Logic = new Point((Start.Date+X3.Value.TimeOfDay).ToOADate(), Y3.Value)},
                                            new Coord {Logic = new Point((Start.Date+X4.Value.TimeOfDay).ToOADate(), Y4.Value)},
                                            new Coord {Logic = new Point((Start.Date+X5.Value.TimeOfDay).ToOADate(), Y5.Value)},
 
                                        }
                               }
                        };
                }                
        }     
        }));         
    }
    M=Применить;        
    }
}

Проверим работу в режиме исполнения – выберем любую из дат, и запустим формирование координат.
Пример с готовым скриптом можно скачать по данной ссылке.