Как отобразить события на каждую метку времени

Top  Previous  Next

 

В списке полей редактора отчетов данные из архива ошибок хранятся в узле Архив ошибок точки учета, а данные из архива событий устройства хранятся в узле Устройство->Архив событий устройства.

Архив ошибок и архив событий это наборы записей с полями:

Example_DeviceEvent_FieldList

 

Архив ошибок связан с опрашиваемой точкой учета. Записи архива ошибок содержат дату/время начала метки времени DateTime, к которой относится ошибка.

Архив событий связан с опрашиваемым устройством, тепловые вводы которого могут быть подключены к разным точкам учета. Записи архива событий содержат дату/время начала StartDateTime  и окончания EndDateTime события, а также номер теплового ввода HeatLeadIn, к которому подключена  точка учета.

В редакторе отчетов информация по ошибкам и событиям на каждую метку времени хранится в полях DeviceErrorCodes, DeviceErrorDurations, DeviceEventCodes, DeviceEventDurations.

ПРИМЕЧАНИЕ. Чтобы при формировании отчета была доступна информация о событиях устройства, необходимо в параметрах автоопроса или в параметрах ручного опроса выбрать загрузку архива событий.

Архив ошибок, если он есть,  заполняется автоматически при опросе точки учета.

За период одной метки времени могут происходить события относящиеся к разным типам, поэтому для каждого события указываются тип архива, номер теплового ввода, номер канала и код события.

В полях DeviceErrorCodes и DeviceEventCodes информация хранится в виде строки с разделителями:

архив1|ввод1|канал1|код1; ... архивN|вводN|каналN|кодN.

В полях DeviceErrorDurations и DeviceEventDurations информация хранится в виде строки с разделителями:

архив1|ввод1|канал1|код1|длительность1; ... архивN|вводN|каналN|кодN|длительностьN

Длительность указывается в секундах.

Коды событий зависят от модели устройства и описываются в руководстве по эксплуатации прибора.

Если при формировании отчета для каждой метки времени требуется выводить информацию о типе архива, коде и длительности события, то это выполняется в скриптах обработчика Перед печатью для ячеек связанных с полем DeviceEventCodes или DeviceEventDurations.

 

Рассмотрим использование полей DeviceEventCodes и DeviceEventDurations для архива событий на примере отчетной формы для точки учета c прибором КМ-5.

Использование полей DeviceErrorCodes и DeviceErrorDurations для архива ошибок выполняется аналогично.

ШАГ 1. Создайте отчетную форму для точки учета.

ШАГ 2. Добавьте колонку в секции PageHeader и Detail. Добавленную колонку секции Detail назовите EventArchive.

ШАГ 3. Свяжите добавленную колонку EventArchive с полем DeviceEventCodes из узла Архив потреблений и интеграторов.

Example_DeviceEvent_Step3

 

ШАГ 4. Добавьте в секцию Detail ячейку с именем EventDuration. Свойству Видимость для этой ячейки задайте значение Нет. Эта ячейка нужна только для доступа к полю DeviceEventDurations.

ШАГ 5. Свяжите ячейку EventDuration с полем DeviceEventDurations.

ШАГ 6. Для вывода расшифровки кодов событий для каждого типа архива положите на форму в секцию ReportFooter поле DeviceEventDescription из узла Устройство.

Example_DeviceEvent_EventDecriptions

 

Для отображения длительностей для групп событий добавьте в секцию ReportFooter таблицу. Задайте наименования ячеек как показано на рисунке для групп событий обозначенных символами U, E, D, g, G, *

Example_DeviceEvent_EventPeriods

Ячейку с длительностью отчетного периода свяжите с полем RequestedInterval из узла Рассчитанные значения->Суммарные потребления по системам снабжения за отчетный период, а ячейку с длительностью периода имеющихся данных с полем ExistingInterval.

 

Example_DeviceEvent_EventPeriods_Intervals

ШАГ 7. В окне свойств колонки EventArchive в разделе Скрипты добавьте новый обработчик события Перед печатью.

 

Example_DeviceEvent_Step4

 

ШАГ 8. Откроется редактор скриптов, в котором будет пустая заготовка обработчика Перед печатью c именем EventArchive_BeforePrint().

Перед обработчиком EventArchive_BeforePrint() добавьте массивы для хранения групп кодов событий и переменные для хранения длительностей соответствующих периодов:

// Код периода отключения питания

int[] codes_U = {122};

 

// Длительность отключения питания

double period_U = 0;

 

 

// Код периода t1-t2 < min

int[] codes_D = {96};

 

// Длительность периода t1-t2 < min

double period_D = 0;

 

 

// Коды функционального отказа

int[] codes_E = {61, 64, 65, 66, 67, 68, 69, 71, 73, 74, 76, 79, 81, 88, 90, 91, 93, 94, 106, 114, 119, 120, 121};

 

// Длительность функционального отказа

double period_E = 0;

 

 

// Коды периода G > max

int[] codes_G = {82, 85};

 

// Длительность периода G > max

double period_G = 0;

 

 

// Коды периода G < min

int[] codes_g = {84, 87};

 

// Длительность периода G < min

double period_g = 0;

 

 

// Длительность периода для прочих кодов

double period_other = 0;

 

В метод EventArchive_BeforePrint() обработчика добавьте код, в котором формируется отображаемое значение ячейки EventArchive.

// Формирует текст для колонки 'Архив событий'

// Эта колонка связана с полем DeviceEventCodes, в котором события записаны в виде строки:

// архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN

private void EventArchive_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 

{

 // Строка с информацией о событиях. 

 // Формат строки: архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN.

 string eventCodesString = ((XRLabel)sender).Text;

 

 if (String.IsNullOrEmpty(eventCodesString))

         return;

 

 // Получаем массив типов архива и кодов событий:

 // eventCodesString - строка с форматом: архив1|ввод1|канал1|код1; архив2|ввод2|канал2|код2; ... архивN|вводN|каналN|кодN

 string[] eventCodes =  eventCodesString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries);

 

 // Формируем обозначения для групп событий и типов архивов

 string eventCodesSymbol = String.Empty;

 foreach (string eventCodeInfo in eventCodes)

 {

         // Получаем информация по событию в виде строки: архив|ввод|канал|код

         string[] eventInfo = (eventCodeInfo.Trim()).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);

 

         // Код типа архива 

         int archiveType = -1;

         if (!String.IsNullOrEmpty(eventInfo[0].Trim()))

                 archiveType = Convert.ToInt32(eventInfo[0]);

 

         // Номер теплового ввода 

         int heatLeadIn = -1;

         if (!String.IsNullOrEmpty(eventInfo[1].Trim()))

                 heatLeadIn = Convert.ToInt32(eventInfo[1]);

 

         // Номер канала 

         int channelNumber = -1;

         if (!String.IsNullOrEmpty(eventInfo[2].Trim()))

                 channelNumber = Convert.ToInt32(eventInfo[2]);

 

         // Код события

         int code = -1;

         if (!String.IsNullOrEmpty(eventInfo[3].Trim()))

                 code = Convert.ToInt32(eventInfo[3]);

 

         // Формируем символьное отображение набора событий в зависимости от кода события

 

         // Период отключения питания

         if (Array.Exists(codes_U, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("U") == -1)

                 eventCodesSymbol += "U";

 

         // Период t1-t2 < min

         else if (Array.Exists(codes_D, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("D") == -1)

                 eventCodesSymbol += "D";

 

         // Период функционального отказа

         else if (Array.Exists(codes_E, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("E") == -1)

                 eventCodesSymbol += "E";

 

         // Период G > max

         else if (Array.Exists(codes_G, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("G") == -1)

                 eventCodesSymbol += "G";

 

         // Период G < min

         if (Array.Exists(codes_g, delegate(int c) { return (c == code); }) && eventCodesSymbol.IndexOf("g") == -1)

                 eventCodesSymbol += "g";

 

         // Период прочих кодов

         else if (eventCodesSymbol.IndexOf("*") == -1)

                 eventCodesSymbol += "*";

 }

 

 // Задаем текст отображаемый в ячейке EventArchive

 ((XRLabel)sender).Text = eventCodesSymbol;

}

 

 

ШАГ 9. В окне свойств ячейки EventDuration в разделе Скрипты добавьте новый обработчик Перед печатью с именем EventsDuration_BeforePrint.

В метод EventsDuration_BeforePrint() обработчика добавьте код, в котором формируются суммарные длительности для групп событий:

// Формируем суммарные длительности для групп событий

// Ячейка EventsDuration связана с полем DeviceEventDuration, в котором события записаны в виде строки:

// архив1|ввод1|канал1|код1|длительность1; архив2|ввод2|канал2|код2|длительность2; ... архивN|вводN|каналN|кодN|длительностьN

// Ячейка EventsDuration нужна только для расчета суммарных длительностей, поэтому ее можно сделать невидимой установив свойство Видимость = Нет

private void EventDuration_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 

{

 // Получаем содержимое ячейки.

 string eventDurationString = ((XRLabel)sender).Text;

 

 if (String.IsNullOrEmpty(eventDurationString))

         return;

 

 // Получаем массив кодов и длительностей событий

 // Каждый элемент мвссива - это строка формата: архив|ввод|канал|код|длительность

 string[] eventDurations =  eventDurationString.Split(new string[]{";"}, StringSplitOptions.RemoveEmptyEntries);

 

 // Перебираем события и формируем суммарные длительности         

 foreach (string eventDuration in eventDurations)

 {

         // eventDuration - строка c форматом: архив|ввод|канал|код|длительность

         string[] codeDuration = (eventDuration.Trim()).Split(new string[]{"|"}, StringSplitOptions.RemoveEmptyEntries);

         

         // Код типа архива 

         int archiveType = -1;

         if (!String.IsNullOrEmpty(codeDuration[0].Trim()))

                 archiveType = Convert.ToInt32(codeDuration[0]);

 

         // Номер теплового ввода 

         int heatLeadIn = -1;

         if (!String.IsNullOrEmpty(codeDuration[1].Trim()))

                 heatLeadIn = Convert.ToInt32(codeDuration[1]);

 

         // Номер канала 

         int channelNumber = -1;

         if (!String.IsNullOrEmpty(codeDuration[2].Trim()))

                 channelNumber = Convert.ToInt32(codeDuration[2]);

 

         // Код события

         int code = -1;

         if (!String.IsNullOrEmpty(codeDuration[3].Trim()))

                 code = Convert.ToInt32(codeDuration[3]);

 

         // Длительность события в секундах

         double duration = 0;

         if (!String.IsNullOrEmpty(codeDuration[4].Trim()))

                 duration = Convert.ToDouble(codeDuration[4]);

 

         // Переводим длительность события из секунд в доли часа

         duration = duration / 3600D;

 

         // Период отключения питания

         if (Array.Exists(codes_U, delegate(int c) { return (c == code); }))

                 period_U += duration;

 

         // Период t1-t2 < min

         else if (Array.Exists(codes_D, delegate(int c) { return (c == code); }))

                 period_D += duration;

 

         // Период функционального отказа

         else if (Array.Exists(codes_E, delegate(int c) { return (c == code); }))

                 period_E += duration;

 

         // Период G > max

         else if (Array.Exists(codes_G, delegate(int c) { return (c == code); }))

                 period_G += duration;

 

         // Период G < min

         else if (Array.Exists(codes_g, delegate(int c) { return (c == code); }))

                 period_g += duration;

 

         // Период прочих кодов

         else 

                 period_other += duration;

 }

}

 

ШАГ 10. Для всех ячеек с длительностями групп событий в добавленной таблице в секции ReportFooter в разделе Скрипты добавьте обработчик Перед печатью c именем Period_BeforePrint.

В метод Period_BeforePrint() обработчика добавьте код, в котором заполняются ячейки с суммарными длительностями для групп событий:

 

// Отображаем суммарные длительности периодов групп событий

private void Period_BeforePrint(object sender, System.Drawing.Printing.PrintEventArgs e) 

{

 XRTableCell cell= ((XRTableCell)sender);

 

 double period = 0;

 switch (cell.Name)

 {

         case "Period_U":        // Период отключения питания

                 period = period_U;

                 break;

 

         case "Period_D":        // Период t1-t2 < min

                 period = period_D;

                 break;

 

         case "Period_E":        // Период функционального отказа

                 period = period_E;

                 break;

 

         case "Period_Gmax":        // Период G > max

                 period = period_G;

                 break;

 

         case "Period_Gmin":        // Период G < min

                 period = period_g;

                 break;

 

         case "Period_Other":        // Период прочие

                 period = period_other;

                 break;

 }

 

 cell.Text = String.Format("{0:F4}", period);

}

 

ШАГ 11. Сохраните  отчетную форму.

Если сформировать отчет по созданной отчетной форме, то он будет выглядеть так:

Example_DeviceEvent_ReportResult

chapterup Наверх