В MasterSCADA есть штатные средства для работы с архивами – у модуля «Расчет» (и аналогично у «События») есть функции для работы с архивами (интеграл, сумма значений, мгновенное значение, пробег), также с помощью редактора отчетов можно выполнять обработку и выдачу значений архива. Но «Расчет» может не удовлетворить гибкостью, а редактор отчетов выведет результат в собственном окне, что может не подойти если значение нужно передать в дерево объектов для дальнейшей обработки. В таком случае на выручку придет «Скрипт C#».
В качестве примера напишем скрипт, который будет производить поиск максимального значения за заданный интервал времени, и выдавать на выход значение и его метку времени.
Сначала подготовим необходимые для отладки компоненты. Добавим в объект команду, включим у нее архивацию и наполним ее данными. Например, получится вот такой набор данных:



public partial class ФБ : ScriptBase { bool? M=false; public override void Execute() |
Теперь уже в методе Execute, приступим к проверке.
public partial class ФБ : ScriptBase { bool? M=false; public override void Execute() { if (Найти==true && M==false) { } M=Найти; } } |
if (Найти==true && M==false && Начало.HasValue && Конец.HasValue && Конец>Начало) |
var elem = HostFB.InputGroup.GetPin("Вход").TreePinHlp; |
HostFB – это обращение к текущему ФБ (то есть скрипту), InputGroup – к входной группе ФБ. Затем следует метод GetPin, в качестве аргумента которому передается имя входа, который вас интересует. TreePinHlp – это как раз конечный интерфейс, который нам нужно получить чтобы потом получить доступ к архиву входа.
var elem = HostFB.InputGroup.GetPin("Вход").TreePinHlp; var k=elem.DataArchiveItem; |
Теперь объявим локальные переменные для поиска – начало и конец.
DateTime EndTime=Конец.Value.ToUniversalTime(); DateTime StartTime=Начало.Value.ToUniversalTime(); |
Теперь выполним выборку из архива:
var mas=k.Read(StartTime, EndTime, false); |
Теперь обработаем архив:
var mas=k.Read(StartTime, EndTime, false); double? Val=null; DateTime? TimeStamp=null; foreach (var element in mas) { if (Val.HasValue==false || Convert.ToDouble(element.Value)>Val.Value) { Val=Convert.ToDouble(element.Value); TimeStamp=element.Time.ToLocalTime(); } } Значение=Val; МеткаВремени=TimeStamp; |
Затем происходит перебор значений в цикле. В качестве цикла используется foreach– данный цикл перебирает массив mas, и каждое значение массива кладет в переменную element (тип PinValue), в которому можно обратится в теле цикла.
Затем мы проверяем – если значение Val пустое (то есть не имеет значение и равно Null) или новое значение из массива больше сохраненного ранее значения Val, то мы сохраняем в Val значения элемента массива (свойство Value), а в переменную TimeStamp – метку времени элемента (свойство Time), предварительно приведя его из UTC в локальное время с помощью метода ToLocalTime. Свойство element.Value имеет тип object, поэтому чтобы присвоить его переменной Val, сначала делается приведение с помощью метода Convert.ToDouble.
После того как перебор массива закончился, найденные значения записываются на выходы скрипта. Итоговый код выглядит так:
public partial class ФБ : ScriptBase { bool? M=false; public override void Execute() { if (Найти==true && M==false && Начало.HasValue && Конец.HasValue && Конец>Начало) { var elem = HostFB.InputGroup.GetPin("Вход").TreePinHlp; var k=elem.DataArchiveItem; DateTime EndTime=Конец.Value.ToUniversalTime(); DateTime StartTime=Начало.Value.ToUniversalTime(); var mas=k.Read(StartTime, EndTime, false); double? Val=null; DateTime? TimeStamp=null; foreach (var element in mas) { if (Val.HasValue==false || Convert.ToDouble(element.Value)>Val.Value) { Val=Convert.ToDouble(element.Value); TimeStamp=element.Time.ToLocalTime(); } } Значение=Val; МеткаВремени=TimeStamp; } M=Найти; } } |
Данный код можно использовать в качестве основы собственных скриптов анализа архива. Фактически анализ происходит в цикле foreach – можно легко видоизменить алгоритм поиска под собственную задачу.
Проверим работу скрипта. Запустим режим исполнения, зададим значения переменным «Начало» и «Конец» и запустим поиск сигналом на входе «Найти».

Если нужно определить также и признак качества найденного значения, то для этого используется свойство element.Quality, которое содержит ряд свойств – isBad (плохой признак качества), isGood (хороший признак качества), isUncertain (неопределенное значение).
Скачать пример скрипта можно по ссылке.