ФБ «Скрипт C#» и его использование в MasterSCADA. Определение выходных дней

ФБ «Скрипт C#» и его использование в MasterSCADA. Определение выходных дней

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

Поскольку перечень выходных и праздничных дней может меняться, нами был разработан специальный контрол, который позволяет гибко настроить рабочий календарь. Данный контрол находится на закладке «Элементы диалога» и называется «Календарь рабочих дней».
В данном случае календарь развернут на весь год. При необходимости можно уменьшить его изменив размерность в свойствах.
Помимо размерности в настройках календаря есть поле «Путь к файлу с исключительными датами». Прежде чем изучать данную настройку, запустим режим исполнения и посмотрим работу контрола.

В контроле жирным шрифтом выделены выходные дни, а обычным – рабочие. Вызвав контекстное меню любого дня можно указать является ли день рабочим или не рабочим.
Это можно делать как для одного дня, так и для нескольких – их можно выделять мышью.
Таким образом составляются исключения. После отметки всех дней в контекстное меню выберите Сохранить. Произойдет сохранение всех исключительных дат в файл – чтобы система могла потом загрузить их.
Итак, настройка «Путь к файлу с исключительными датами» определяет имя файла, в котором будут хранится исключения. Можно указать статичный путь, а можно динамизировать его – используя вход динамизации. Мы будем именно динамизировать – с помощью скрипта мы сформируем путь к файлу и передадим в контрол. Это нужно чтобы и скрипт и контрол гарантировано работали с одним и тем же файлом.
Добавим в дерево объектов Скрипт, назовем его Рабочий день. Добавим в него вход Дата – на него мы будем подавать дату, которую хотим проверить. Добавим выходы Рабочий день и Путь, на первый будет подавать Истина если день является рабочим, а на второй мы подадим путь файла, который потом пустим в контрол.
Приступим к созданию кода.
Начнем с формирования пути файла. Мы будем хранить файл с исключениями в папке текущего объекта. В методе Start, возьмем свойство родительского объекта FolderPath и добавим имя файла – savedays.xml

public override void Start()
    {    
    //инициализация при старте режима исполнения
    Путь = HostFB.TreeItemHlp.Parent.FolderPath+"savedays.xml"; //путь сохранения файла 
    }  


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

Для этого сначала подключим сборку (dll библиотеку) к нашему скрипту - MasterSCADA.RT.dll. Это делается на закладке Настройки.
На вкладке «Код» в секции using добавим обращение к данной сборке:
using MasterSCADA.RT.Controls.WorkDays;

Теперь приступим к написанию. Приведем код полностью, а потом разберем его построчно.
   public override void Execute()
   { 
   //если на входе Дата есть значение
 if (Дата.HasValue)
  {
  var date=Дата.Value.Date; //получение значения даты   
  //считывание массива выходных дней
  DateTime[] daysOff = WorkDaysService.Load(Путь).GetDaysOff(date,date);
  //если записей нет - текущий день рабочий
  if (daysOff.Length==0) Рабочий_день=true;
  //если есть хотя одна запись то текущий день выходной
  else Рабочий_день=false;
     }
} 


Сначала в методе Execute, мы проверяем наличие значения у входа Дата, в противном случае мы потом получим ошибку.
Если значение есть, то берем от него только дату – используем свойство Date.
Главной строчкой здесь является:
DateTime[] daysOff = WorkDaysService.Load(Путь).GetDaysOff(date,date);
Именно здесь и происходит считывание файла и анализ даты. WorkDaysService – это класс контрола. Метод Load, производит загрузку указанного файла (путь к которому мы сформировали заранее). Затем вызывается метод GetDaysOff. В качестве аргументов ему передаются две даты – начало и конец интервала. Метод возвращает массив значения DateTime (то есть массив дат), которые являются выходными. В нашем случае мы проверяем только одну дату, поэтому начало и конец у нас совпадают и равны переменной date.
Затем мы проверяем длину нашего массив. Если массив пуст и его длина равно нулю, значит наш день не является выходным, в этом случае в переменную Рабочий_день записывается True, в противном случае записывается False.
Пример с готовым скриптом можно скачать по данной ссылке.

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

/products/?category=1300