Интерпретация прогноза - разбор реальных данных от фреймворка

This commit is contained in:
Mikhail Chechnev 2025-04-10 02:13:34 +03:00
parent c9015e3d16
commit 07976cbe82
7 changed files with 543 additions and 362 deletions

View File

@ -191,11 +191,23 @@ create or replace package UDO_PKG_EQUIPDS as
COUT out clob -- Сериализованная таблица данных COUT out clob -- Сериализованная таблица данных
); );
/* Извлечение описания из данных прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ /* Цвет прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
procedure CMMLH_PARSE_FORECAST function CMMLH_FORECAST_COLOR
( (
CFORECAST in clob, -- Данные прогноза NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
NFORECAST out number -- Значение прогноза NVALUE in number :=0 -- Значение для подсветки
) return varchar2; -- Запрошенное значение в зависимости от режима
/* Карточка прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
procedure CMMLH_FORECAST_CARD
(
NEQUIPDSCMMLH in number, -- Рег. номер записи истории запросов модели
DFORECAST_DATE in date, -- Дата получения прогноза
NFORECAST_DAYS in number, -- Прогнозное количество дней до выхода из строя (на дату прогноза)
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
SFORECAST_DESC out varchar2, -- Краткое описание прогноза
SFORECAST_DESC_COLOR out varchar2, -- Цвет заливки прогноза
CFORECAST out clob -- Данные детальной карточки прогноза
); );
/* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */ /* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */
@ -1480,26 +1492,228 @@ create or replace package body UDO_PKG_EQUIPDS as
COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1); COUT := PKG_P8PANELS_VISUAL.TDG_TO_XML(RDATA_GRID => RDG, NINCLUDE_DEF => 1);
end CMML_LIST_BY_EQCONFIG; end CMML_LIST_BY_EQCONFIG;
/* Извлечение описания из данных прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ /* Цвет прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
procedure CMMLH_PARSE_FORECAST function CMMLH_FORECAST_COLOR
( (
CFORECAST in clob, -- Данные прогноза NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
NFORECAST out number -- Значение прогноза NVALUE in number :=0 -- Значение для подсветки
) return varchar2 -- Запрошенное значение в зависимости от режима
is
begin
/* Работаем от режима */
case NMODE
/* Для подсказки в колонке таблицы */
when 0 then
return '<b style="color:red">Опасность</b> - вероятность сбоя более 60%.<br>' || '<b style="color:orange">Внимание</b> - вероятность сбоя от 30% до 60%<br>' || '<b style="color:green">В норме</b> - вероятность сбоев менее 30%';
/* Для колонки таблицы */
when 1 then
begin
if (NVALUE < 30) then
return 'success';
else
if ((NVALUE >= 30) and (NVALUE < 60)) then
return 'warning';
else
return 'error';
end if;
end if;
end;
/* Для карточки детализации */
when 2 then
begin
if (NVALUE < 30) then
return 'success.main';
else
if ((NVALUE >= 30) and (NVALUE < 60)) then
return 'warning.main';
else
return 'error.main';
end if;
end if;
end;
/* Неверный режим */
else
return null;
end case;
end CMMLH_FORECAST_COLOR;
/* Карточка прогноза "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
procedure CMMLH_FORECAST_CARD
(
NEQUIPDSCMMLH in number, -- Рег. номер записи истории запросов модели
DFORECAST_DATE in date, -- Дата получения прогноза
NFORECAST_DAYS in number, -- Прогнозное количество дней до выхода из строя (на дату прогноза)
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
SFORECAST_DESC out varchar2, -- Краткое описание прогноза
SFORECAST_DESC_COLOR out varchar2, -- Цвет заливки прогноза
CFORECAST out clob -- Данные детальной карточки прогноза
) )
is is
XDOC PKG_XPATH.TDOCUMENT; -- Десериализованный демо-прогноз RCMMLH UDO_T_EQUIPDSCMMLH%rowtype; -- Запись истории запросов модели
XROOT PKG_XPATH.TNODE; -- Корневой элемент данных NCUR integer; -- Курсор документа для результата
XDOC PKG_XMAKE.TNODE; -- Документ для результата
XROOT PKG_XMAKE.TNODE; -- Содержимое корневого узла документа
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
CCHART clob; -- Сериализованный график
NBREAKDOWN_PROB PKG_STD.TNUMBER; -- Вероятность выхода из строя
NBREAKDOWN_PROB_CUR PKG_STD.TNUMBER; -- Вероятность выхода из строя (для текущей позиции графика ТО и ремонтов/рем. ведомости)
DNEXT_REPAIR PKG_STD.TLDATE; -- Дата ближайшего ТО и ремонта по графику/рем. ведомости
NFORECAST_DAYS_NOW PKG_STD.TNUMBER; -- Количество дней до выхода из строя согласно прогнозу, но от текущей даты
begin begin
/* Разбираем демо-даные */ /* Считаем запись истории запросов к модели */
XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CFORECAST); RCMMLH := UDO_PKG_EQUIPDS_BASE.CMMLH_GET(NFLAG_SMART => 0, NRN => NEQUIPDSCMMLH);
/* Извлекаем корневой элемент */ /* Проноз есть */
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC); if ((DFORECAST_DATE is not null) and (NFORECAST_DAYS is not null)) then
/* Читаем прогноз */ /* Вычислим сколько осталось до выхода из строя от текущей даты */
NFORECAST := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/NFORECAST')); NFORECAST_DAYS_NOW := UDO_PKG_EQUIPDS_BASE.CMMLH_FORECAST_DAYS_NOW(DFORECAST_DATE => DFORECAST_DATE,
exception NFORECAST_DAYS => NFORECAST_DAYS);
when others then /* Вычислим вероятность выхода из строя до даты ближайшего ТО/ремонта по графику или рем. ведомости с учётом прогноза */
null; DNEXT_REPAIR := UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_GEN_NXTRPR(NEQCONFIG => RCMMLH.EQCONFIG);
end CMMLH_PARSE_FORECAST; NBREAKDOWN_PROB := UDO_PKG_EQUIPDS_BASE.CMMLH_RUL_BREAKDOWN_PROB(DFORECAST_DATE => DFORECAST_DATE,
NFORECAST_DAYS => NFORECAST_DAYS,
DDATE => DNEXT_REPAIR);
/* Открываем документ */
NCUR := PKG_XMAKE.OPEN_CURSOR();
/* Заполним дату прогноза */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'SFORECAST_DATE',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => TO_CHAR(DFORECAST_DATE,
'dd.mm.yyyy'))));
/* Заполним прогнозное количество дней до выхода из стороя на эту дату */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'NFORECAST_DAYS',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
NVALUE => NFORECAST_DAYS)));
/* Заполним прогнозную дату выхода из стороя */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'SFORECAST_DATE_CALC',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => TO_CHAR(DFORECAST_DATE +
NFORECAST_DAYS,
'dd.mm.yyyy'))));
/* Заполним текущую дату */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'SFORECAST_DATE_NOW',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => TO_CHAR(sysdate,
'dd.mm.yyyy'))));
/* Заполним прогнозное количество дней до выхода из стороя на текущую дату */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'NFORECAST_DAYS_NOW',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
NVALUE => NFORECAST_DAYS_NOW)));
/* Заполним код задачи прогнозирования */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'STASK',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, SVALUE => STASK)));
/* Заполним наименование задачи прогнозирования */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'STASK_NAME',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => UDO_PKG_EQUIPDS_BASE.CMML_TASK_NAME(STASK => STASK))));
/* Заполним дату следующего ТО и ремонта */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'DNEXT_REPAIR',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
DVALUE => DNEXT_REPAIR)));
/* Если есть запланированные графики ТО и ремонта или ремонтные ведомости */
if (DNEXT_REPAIR is not null) then
/* Строим график вероятностей выхода из строя опираясь на них */
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_LINE,
STITLE => 'Прогноз с учётом графика ТО и ремонтов/ремонтных ведомостей',
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_TOP);
/* Сформируем набор данных */
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Вероятность перехода в критическое состояние (%)');
/* Обходим ближайшие 5 позиций графика ТО и ремонтов или ремонтных ведомостей */
for C in (select ROWNUM,
D.DDATEPRD_BEG
from (select T.DDATEPRD_BEG
from (select P.DATEPRD_BEG DDATEPRD_BEG
from EQTCHSRV P
where P.EQCONFIG_TECH = RCMMLH.EQCONFIG
and P.DATEPRD_BEG >= sysdate
union
select R.DATEPLAN_BEG DDATEPRD_BEG
from EQRPSHEETS R
where R.EQCONFIG = RCMMLH.EQCONFIG
and R.DATEPLAN_BEG >= sysdate) T
order by T.DDATEPRD_BEG) D
where ROWNUM <= 5)
loop
/* Добавим метку для графика */
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => TO_CHAR(C.DDATEPRD_BEG, 'dd.mm.yyyy'));
/* Считаем вероятность выхода из строя в эту дату */
NBREAKDOWN_PROB_CUR := UDO_PKG_EQUIPDS_BASE.CMMLH_RUL_BREAKDOWN_PROB(DFORECAST_DATE => DFORECAST_DATE,
NFORECAST_DAYS => NFORECAST_DAYS,
DDATE => C.DDATEPRD_BEG);
/* Если ещё не фиксировали вероятность для первой даты - сделаем это */
if (NBREAKDOWN_PROB is null) then
NBREAKDOWN_PROB := NBREAKDOWN_PROB_CUR;
end if;
/* Добавим элемент в набор данных */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => NBREAKDOWN_PROB_CUR);
end loop;
/* Добавим набор данных в график */
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
/* Сериализуем график */
CCHART := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
end if;
/* Заполним вероятность выхода из стороя до ближайшего ТО с учётом прогноза */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'NBREAKDOWN_PROB',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
NVALUE => NBREAKDOWN_PROB)));
/* Заполним цвет вероятности выхода из стороя до ближайшего ТО с учётом прогноза */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'SBREAKDOWN_PROB_COLOR',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => CMMLH_FORECAST_COLOR(NMODE => 2,
NVALUE => NBREAKDOWN_PROB))));
/* Добавляем график в ответ */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'XCHART',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, LCVALUE => CCHART)));
/* Формируем XML-представление ответа */
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XROOT);
/* Конвертируем в CLOB */
CFORECAST := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
ITYPE => PKG_XMAKE.CONTENT_,
RNODE => XDOC,
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
SENCODING => PKG_XHEADER.ENCODING_UTF_,
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
/* Закрываем документ */
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
/* Возвращаем значение краткого описания прогноза */
SFORECAST_DESC := TO_CHAR(NFORECAST_DAYS_NOW) || 'Д / ' || TO_CHAR(ROUND(NBREAKDOWN_PROB)) || '%';
/* Возвращаем значение цвета заливки описания прогноза */
SFORECAST_DESC_COLOR := CMMLH_FORECAST_COLOR(NMODE => 1, NVALUE => NBREAKDOWN_PROB);
end if;
end CMMLH_FORECAST_CARD;
/* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */ /* Список "Выборки данных оборудования (классы оборудования, модели, история запросов)" по единице оборудования */
procedure CMMLH_LIST_BY_EQCONFIG procedure CMMLH_LIST_BY_EQCONFIG
@ -1544,11 +1758,10 @@ create or replace package body UDO_PKG_EQUIPDS as
SNAME => 'STO_FORECAST_DESC', SNAME => 'STO_FORECAST_DESC',
SCAPTION => 'Прогноз', SCAPTION => 'Прогноз',
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR, SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_STR,
SHINT => '<b>Формат прогноза:</b> "XXЕИ / YY%", где<br>' || SHINT => '<b>Формат прогноза:</b> "XXД / YY%", где<br>' ||
'<b>XXЕИ</b> - время до перехода в критическое состояние в ЕИ ресурса единицы оборудования (часы/дни/месяцы/рабочие циклы и т.п.)<br>' || '<b>XXД</b> - время (в днях, от текущей даты) до перехода в критическое состояние<br>' ||
'<b>YY%</b> - вероятность перехода в критическое состояние до следующего ТО и ремонта<br><br>' || '<b>YY%</b> - вероятность перехода в критическое состояние до следующего ТО и ремонта<br><br>' ||
'<b>Цвет прогноза:</b><br>' || '<b>Цвет прогноза:</b><br>' || CMMLH_FORECAST_COLOR(NMODE => 0));
UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 0));
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'STO_FORECAST_DESC_COLOR', SNAME => 'STO_FORECAST_DESC_COLOR',
SCAPTION => 'Цвет прогноза', SCAPTION => 'Цвет прогноза',
@ -1574,7 +1787,8 @@ create or replace package body UDO_PKG_EQUIPDS as
ML.PRECISION NEQUIPDSCMML_PRECISION, ML.PRECISION NEQUIPDSCMML_PRECISION,
DM.MEAS_MNEMO SDICMUNTS, DM.MEAS_MNEMO SDICMUNTS,
T.FORECAST BFORECAST, T.FORECAST BFORECAST,
null NFORECAST, T.FORECAST_DATE DFORECAST_DATE,
T.FORECAST_DAYS NFORECAST_DAYS,
null STO_FORECAST_DESC, null STO_FORECAST_DESC,
null STO_FORECAST_DESC_COLOR, null STO_FORECAST_DESC_COLOR,
null STO_FORECAST null STO_FORECAST
@ -1590,19 +1804,14 @@ create or replace package body UDO_PKG_EQUIPDS as
and CM.DICMUNTS = DM.RN and CM.DICMUNTS = DM.RN
order by T.RN desc) order by T.RN desc)
loop loop
/* Извлекаем данные из прогноза фреймворка */
CMMLH_PARSE_FORECAST(CFORECAST => BLOB2CLOB(LBDATA => C.BFORECAST), NFORECAST => C.NFORECAST);
/* Формируем данные карточки прогноза для конкретного тех. объекта */ /* Формируем данные карточки прогноза для конкретного тех. объекта */
UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_CRD(NEQCONFIG => NEQCONFIG, CMMLH_FORECAST_CARD(NEQUIPDSCMMLH => C.NRN,
DFORECAST_DATE => C.DRQ_DATE, DFORECAST_DATE => C.DFORECAST_DATE,
NFORECAST => C.NFORECAST, NFORECAST_DAYS => C.NFORECAST_DAYS,
SDICMUNTS => C.SDICMUNTS,
STASK => C.SEQUIPDSCMML_TASK, STASK => C.SEQUIPDSCMML_TASK,
COUT => C.STO_FORECAST);
/* Извлекаем прогноз и цвет для видимой колонки таблицы из карточки прогноза для конкретного тех. объекта */
UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_CRDP(CFORECAST => C.STO_FORECAST,
SFORECAST_DESC => C.STO_FORECAST_DESC, SFORECAST_DESC => C.STO_FORECAST_DESC,
SFORECAST_DESC_COLOR => C.STO_FORECAST_DESC_COLOR); SFORECAST_DESC_COLOR => C.STO_FORECAST_DESC_COLOR,
CFORECAST => C.STO_FORECAST);
/* Добавляем колонки с данными */ /* Добавляем колонки с данными */
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NRN', NVALUE => C.NRN, BCLEAR => true);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRQ_AUTHID', SVALUE => C.SRQ_AUTHID); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'SRQ_AUTHID', SVALUE => C.SRQ_AUTHID);

View File

@ -44,6 +44,24 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
DDATASET_TS in date -- Время формирования данных DDATASET_TS in date -- Время формирования данных
) return varchar2; -- Наименование выборки ) return varchar2; -- Наименование выборки
/* Сериализация описания параметров выборки для прогноза */
procedure UTL_FORECAST_RQ_MAKE_CFG
(
DBEG in date, -- Дата "С"
DEND in date, -- Дата "По"
NINTERVAL in number, -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
CRQ_CFG out clob -- Сериализованное описание параметров выборки для прогноза
);
/* Десериализация описания параметров выборки для прогноза */
procedure UTL_FORECAST_RQ_PARSE_CFG
(
CRQ_CFG in clob, -- Сериализованное описание параметров выборки для прогноза
DBEG out date, -- Дата "С"
DEND out date, -- Дата "По"
NINTERVAL out number -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
);
/* Считывание записи "Выборки данных оборудования" по регистрационному номеру */ /* Считывание записи "Выборки данных оборудования" по регистрационному номеру */
function GET function GET
( (
@ -293,13 +311,12 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
function CMML_USERPROCS_FRCST_DATA_HINT function CMML_USERPROCS_FRCST_DATA_HINT
return varchar2; -- Подсказка для процедуры формирования данных для прогноза return varchar2; -- Подсказка для процедуры формирования данных для прогноза
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */ /* Считывание записи "Выборки данных оборудования (классы оборудования, модели, история запросов)" по регистрационному номеру */
function CMML_RUL_BREAKDOWN_PROB function CMMLH_GET
( (
NFORECAST in number, -- RUL-прогноз (интервалов до перехода в предельное состояние) NFLAG_SMART in number, -- Признак выдачи сообщения об ошибке (0 - выдавать, 1 - не выдавать)
DFORECAST_DATE in date, -- Дата прогноза NRN in number -- Регистрационный номер
DDATE in date -- Дата на ) return UDO_T_EQUIPDSCMMLH%rowtype; -- Запись итории прогонозов модели
) return number; -- Значение вероятности
/* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ /* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
procedure CMMLH_INS procedure CMMLH_INS
@ -322,9 +339,27 @@ create or replace package UDO_PKG_EQUIPDS_BASE as
procedure CMMLH_SET_FORECAST procedure CMMLH_SET_FORECAST
( (
NRN in number, -- Регистрационный номер NRN in number, -- Регистрационный номер
BFORECAST in blob -- Данные прогноза BFORECAST in blob, -- Данные прогноза
DFORECAST_DATE in date, -- Дата прогноза
NFORECAST_DAYS in number -- Прогноз (дней до выхода из строя на дату прогноза)
); );
/* Вычисление количества дней до выхода из строя от даты */
function CMMLH_FORECAST_DAYS_NOW
(
DFORECAST_DATE in date, -- Дата прогноза
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
DDATE in date := sysdate -- Дата (не задана - текущая)
) return number; -- Количество дней до выхода из строя
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */
function CMMLH_RUL_BREAKDOWN_PROB
(
DFORECAST_DATE in date, -- Дата прогноза
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
DDATE in date -- Дата на
) return number; -- Значение вероятности
end UDO_PKG_EQUIPDS_BASE; end UDO_PKG_EQUIPDS_BASE;
/ /
create or replace package body UDO_PKG_EQUIPDS_BASE as create or replace package body UDO_PKG_EQUIPDS_BASE as
@ -390,6 +425,74 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
return '' || TO_CHAR(NDATASET_ID) || ' от ' || TO_CHAR(DDATASET_TS, 'dd.mm.yyyy hh24:mi:ss'); return '' || TO_CHAR(NDATASET_ID) || ' от ' || TO_CHAR(DDATASET_TS, 'dd.mm.yyyy hh24:mi:ss');
end UTL_DATASET_MAKE_NAME; end UTL_DATASET_MAKE_NAME;
/* Сериализация описания параметров выборки для прогноза */
procedure UTL_FORECAST_RQ_MAKE_CFG
(
DBEG in date, -- Дата "С"
DEND in date, -- Дата "По"
NINTERVAL in number, -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
CRQ_CFG out clob -- Сериализованное описание параметров выборки для прогноза
)
is
XDOC integer; -- Курсор для XML
XRESULT PKG_XMAKE.TNODE; -- XML-документ
begin
/* Проверим параметры */
if (DBEG is null) then
P_EXCEPTION(0, 'Не указана дата начала выборки для прогноза.');
end if;
if (DEND is null) then
P_EXCEPTION(0, 'Не указана дата окончания выборки для прогноза.');
end if;
if ((NINTERVAL is null) or (NINTERVAL <= 0)) then
P_EXCEPTION(0,
'Не указана или указана неверно длина интервала измерений выборки для прогноза.');
end if;
/* Создаём документ */
XDOC := PKG_XMAKE.OPEN_CURSOR();
/* Формируем документ */
XRESULT := PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
SNAME => 'XDATA',
RNODE00 => PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
SNAME => 'DBEG',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XDOC, DVALUE => DBEG)),
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
SNAME => 'DEND',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XDOC, DVALUE => DEND)),
RNODE02 => PKG_XMAKE.ELEMENT(ICURSOR => XDOC,
SNAME => 'NINTERVAL',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => XDOC,
NVALUE => NINTERVAL)));
/* Сериализуем */
CRQ_CFG := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => XDOC, ITYPE => PKG_XMAKE.CONTENT_, RNODE => XRESULT);
/* Освобождаем документ */
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => XDOC);
end UTL_FORECAST_RQ_MAKE_CFG;
/* Десериализация описания параметров выборки для прогноза */
procedure UTL_FORECAST_RQ_PARSE_CFG
(
CRQ_CFG in clob, -- Сериализованное описание параметров выборки для прогноза
DBEG out date, -- Дата "С"
DEND out date, -- Дата "По"
NINTERVAL out number -- Длина интервала (в днях, если меньше дня, то дробное - 1/24 для часа, например)
)
is
XDOC PKG_XPATH.TDOCUMENT; -- XML-документ
XROOT PKG_XPATH.TNODE; -- Корневой элемент
begin
/* Разбираем документ */
XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CRQ_CFG);
/* Находим корень */
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
/* Читаем параметры */
DBEG := PKG_XPATH.VALUE_DATE(RNODE => XROOT, SPATTERN => 'XDATA/DBEG');
DEND := PKG_XPATH.VALUE_DATE(RNODE => XROOT, SPATTERN => 'XDATA/DEND');
NINTERVAL := PKG_XPATH.VALUE_NUM(RNODE => XROOT, SPATTERN => 'XDATA/NINTERVAL');
/* Освобождаем документ */
PKG_XPATH.FREE(RDOCUMENT => XDOC);
end UTL_FORECAST_RQ_PARSE_CFG;
/* Считывание записи "Выборки данных оборудования" по регистрационному номеру */ /* Считывание записи "Выборки данных оборудования" по регистрационному номеру */
function GET function GET
( (
@ -1235,40 +1338,25 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
'идентификаторы файлового буфера с подготовленными данными (CSV), описанием структуры данных (XML) и описанием параметров запроса (XML) для интерпретации прогноза соответственно.'; 'идентификаторы файлового буфера с подготовленными данными (CSV), описанием структуры данных (XML) и описанием параметров запроса (XML) для интерпретации прогноза соответственно.';
end CMML_USERPROCS_FRCST_DATA_HINT; end CMML_USERPROCS_FRCST_DATA_HINT;
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */ /* Считывание записи "Выборки данных оборудования (классы оборудования, модели, история запросов)" по регистрационному номеру */
function CMML_RUL_BREAKDOWN_PROB function CMMLH_GET
( (
NFORECAST in number, -- RUL-прогноз (интервалов до перехода в предельное состояние) NFLAG_SMART in number, -- Признак выдачи сообщения об ошибке (0 - выдавать, 1 - не выдавать)
DFORECAST_DATE in date, -- Дата прогноза NRN in number -- Регистрационный номер
DDATE in date -- Дата на ) return UDO_T_EQUIPDSCMMLH%rowtype -- Запись итории прогонозов модели
) return number -- Значение вероятности
is is
NRES PKG_STD.TNUMBER; -- Буфер для результата RES UDO_T_EQUIPDSCMMLH%rowtype; -- Буфер для результата
begin begin
/* Проверим параметры */ /* Считывание записи */
if ((NFORECAST is null) or (DFORECAST_DATE is null) or (DDATE is null) or (DDATE < DFORECAST_DATE) or begin
(DFORECAST_DATE > sysdate) or (DDATE < sysdate)) then select T.* into RES from UDO_T_EQUIPDSCMMLH T where T.RN = NRN;
return null; exception
end if; when NO_DATA_FOUND then
/* Проверяем пограничные значения */ PKG_MSG.RECORD_NOT_FOUND(NFLAG_SMART => NFLAG_SMART, NDOCUMENT => NRN, SUNIT_TABLE => 'UDO_T_EQUIPDSCMMLH');
if (NFORECAST = 0) or ((DDATE - sysdate) = 0) then end;
return 100; /* Возврат результата */
end if; return RES;
if (sysdate + NFORECAST > DDATE) then end CMMLH_GET;
return 0;
end if;
/* Вычисляем */
NRES := 100 - ROUND((NFORECAST - (TRUNC(sysdate) - TRUNC(DFORECAST_DATE))) / (DDATE - sysdate) * 100);
/* Корректируем флуктуации */
if (NRES > 100) then
NRES := 100;
end if;
if (NRES < 0) then
NRES := 0;
end if;
/* Возвращаем результат */
return NRES;
end CMML_RUL_BREAKDOWN_PROB;
/* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ /* Базовое добавление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
procedure CMMLH_INS procedure CMMLH_INS
@ -1286,9 +1374,9 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
NRN := GEN_ID(); NRN := GEN_ID();
/* Добавляем запись */ /* Добавляем запись */
insert into UDO_T_EQUIPDSCMMLH insert into UDO_T_EQUIPDSCMMLH
(RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST) (RN, PRN, EQCONFIG, RQ_AUTHID, RQ_DATE, RQ, FORECAST, FORECAST_DATE, FORECAST_DAYS)
values values
(NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null); (NRN, NPRN, NEQCONFIG, SRQ_AUTHID, DRQ_DATE, BRQ, null, null, null);
end CMMLH_INS; end CMMLH_INS;
/* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */ /* Базовое удаление "Выборки данных оборудования (классы оборудования, модели, история запросов)" */
@ -1306,13 +1394,71 @@ create or replace package body UDO_PKG_EQUIPDS_BASE as
procedure CMMLH_SET_FORECAST procedure CMMLH_SET_FORECAST
( (
NRN in number, -- Регистрационный номер NRN in number, -- Регистрационный номер
BFORECAST in blob -- Данные прогноза BFORECAST in blob, -- Данные прогноза
DFORECAST_DATE in date, -- Дата прогноза
NFORECAST_DAYS in number -- Прогноз (дней до выхода из строя на дату прогноза)
) )
is is
begin begin
/* Установим данные ответа */ /* Установим данные прогноза */
update UDO_T_EQUIPDSCMMLH T set T.FORECAST = BFORECAST where T.RN = NRN; update UDO_T_EQUIPDSCMMLH T
set T.FORECAST = BFORECAST,
T.FORECAST_DATE = DFORECAST_DATE,
T.FORECAST_DAYS = NFORECAST_DAYS
where T.RN = NRN;
end CMMLH_SET_FORECAST; end CMMLH_SET_FORECAST;
/* Вычисление количества дней до выхода из строя от даты */
function CMMLH_FORECAST_DAYS_NOW
(
DFORECAST_DATE in date, -- Дата прогноза
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
DDATE in date := sysdate -- Дата (не задана - текущая)
) return number -- Количество дней до выхода из строя
is
NRES PKG_STD.TNUMBER; -- Буфер для результата
begin
/* От прогнозной даты выхода из строя (дата прогноза + дней до перехода в предельное состояние от неё) отнимем текущую дату */
NRES := ROUND((DFORECAST_DATE + NFORECAST_DAYS) - COALESCE(DDATE, sysdate));
/* Если дело прошлое - скажем, что осталось 0 дней */
if (NRES < 0) then
NRES := 0;
end if;
/* Вренём результат */
return NRES;
end CMMLH_FORECAST_DAYS_NOW;
/* Вычисление вероятности выхода из строя на дату по RUL-прогнозу */
function CMMLH_RUL_BREAKDOWN_PROB
(
DFORECAST_DATE in date, -- Дата прогноза
NFORECAST_DAYS in number, -- RUL-прогноз (дней до перехода в предельное состояние от даты прогноза)
DDATE in date -- Дата на
) return number -- Значение вероятности
is
NRES PKG_STD.TNUMBER; -- Буфер для результата
begin
/* Проверим параметры */
if ((NFORECAST_DAYS is null) or (DFORECAST_DATE is null) or (DDATE is null) or (DDATE < DFORECAST_DATE) or
(DFORECAST_DATE > sysdate) or (DDATE < sysdate)) then
return null;
end if;
/* Проверяем пограничные значения */
if ((NFORECAST_DAYS = 0) or ((DDATE - sysdate) = 0)) then
return 100;
end if;
/* Вычисляем */
NRES := 100 - ROUND((NFORECAST_DAYS - (TRUNC(sysdate) - TRUNC(DFORECAST_DATE))) / (DDATE - sysdate) * 100);
/* Корректируем флуктуации */
if (NRES > 100) then
NRES := 100;
end if;
if (NRES < 0) then
NRES := 0;
end if;
/* Возвращаем результат */
return NRES;
end CMMLH_RUL_BREAKDOWN_PROB;
end UDO_PKG_EQUIPDS_BASE; end UDO_PKG_EQUIPDS_BASE;
/ /

View File

@ -592,6 +592,8 @@ is
SERR_NTF_MAIL => null, SERR_NTF_MAIL => null,
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO, NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE, NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
NTIMEOUT_CONN => null,
NTIMEOUT_ASYNCH => null,
NFORCE_UPDATE => NFORCE_UPDATE, NFORCE_UPDATE => NFORCE_UPDATE,
NRN => NEXSSERVICEFN); NRN => NEXSSERVICEFN);
@ -623,6 +625,8 @@ is
SERR_NTF_MAIL => null, SERR_NTF_MAIL => null,
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO, NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE, NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
NTIMEOUT_CONN => null,
NTIMEOUT_ASYNCH => null,
NFORCE_UPDATE => NFORCE_UPDATE, NFORCE_UPDATE => NFORCE_UPDATE,
NRN => NEXSSERVICEFN); NRN => NEXSSERVICEFN);
/* Загрузка функции сервиса обмена */ /* Загрузка функции сервиса обмена */
@ -640,6 +644,8 @@ is
SERR_NTF_MAIL => null, SERR_NTF_MAIL => null,
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO, NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE, NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
NTIMEOUT_CONN => null,
NTIMEOUT_ASYNCH => null,
NFORCE_UPDATE => NFORCE_UPDATE, NFORCE_UPDATE => NFORCE_UPDATE,
NRN => NEXSSERVICEFN); NRN => NEXSSERVICEFN);
@ -671,6 +677,8 @@ is
SERR_NTF_MAIL => null, SERR_NTF_MAIL => null,
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO, NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE, NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
NTIMEOUT_CONN => null,
NTIMEOUT_ASYNCH => null,
NFORCE_UPDATE => NFORCE_UPDATE, NFORCE_UPDATE => NFORCE_UPDATE,
NRN => NEXSSERVICEFN); NRN => NEXSSERVICEFN);
/* Загрузка функции сервиса обмена */ /* Загрузка функции сервиса обмена */
@ -688,6 +696,8 @@ is
SERR_NTF_MAIL => null, SERR_NTF_MAIL => null,
NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO, NAUTH_ONLY => PKG_EXS.NAUTH_ONLY_NO,
NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE, NSAVE_QUEUE => PKG_EXS.NFN_SAVE_QUEUE,
NTIMEOUT_CONN => null,
NTIMEOUT_ASYNCH => null,
NFORCE_UPDATE => NFORCE_UPDATE, NFORCE_UPDATE => NFORCE_UPDATE,
NRN => NEXSSERVICEFN); NRN => NEXSSERVICEFN);

View File

@ -54,6 +54,12 @@ create or replace package UDO_PKG_EQUIPTCF as
NIDENT out number -- Идентификатор списка NIDENT out number -- Идентификатор списка
); );
/* Получение даты следующего ремонта по ремонтной ведомости или графику ТО и ремонтов (что раньше) технического объекта */
function EQCONFIG_THOBJ_GEN_NXTRPR
(
NEQCONFIG in number -- Рег. номер технического объекта
) return date; -- Дата ближайшего ремонта
/* Формирование карточки технического объекта */ /* Формирование карточки технического объекта */
procedure EQCONFIG_THOBJ_CARD procedure EQCONFIG_THOBJ_CARD
( (
@ -96,32 +102,6 @@ create or replace package UDO_PKG_EQUIPTCF as
CFORECAST in clob := null -- Данные прогноза CFORECAST in clob := null -- Данные прогноза
); );
/* Формирование цвета прогноза для технического объекта */
function EQCONFIG_THOBJ_FORECAST_CLR
(
NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
NVALUE in number :=0 -- Значение для подсветки
) return varchar2; -- Запрошенное значение в зависимости от режима
/* Формирование детальной карточки прогноза для технического объекта */
procedure EQCONFIG_THOBJ_FORECAST_CRD
(
NEQCONFIG in number, -- Рег. номер позиции состава оборудования
DFORECAST_DATE in date, -- Дата получения прогноза
NFORECAST in number, -- Прогнозное значение, полученное от фреймворка
SDICMUNTS in varchar2, -- Единица измерения выборки
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
COUT out clob -- Данные детальной карточки прогноза
);
/* Извлечение сведений из детальной карточки прогноза для технического объекта */
procedure EQCONFIG_THOBJ_FORECAST_CRDP
(
CFORECAST in clob, -- Данные детальной карточки прогноза
SFORECAST_DESC out varchar2, -- Описание прогноза
SFORECAST_DESC_COLOR out varchar2 -- Цвет заливки прогноза
);
/* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */ /* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
( (
@ -413,7 +393,7 @@ text="Проверка прав доступа при формировании
SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB, SDATA_TYPE => PKG_P8PANELS_VISUAL.SDATA_TYPE_NUMB,
BORDER => true, BORDER => true,
BFILTER => true, BFILTER => true,
SHINT => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 0)); SHINT => UDO_PKG_EQUIPDS.CMMLH_FORECAST_COLOR(NMODE => 0));
PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG, PKG_P8PANELS_VISUAL.TDG_ADD_COL_DEF(RDATA_GRID => RDG,
SNAME => 'SBREAKDOWN_PROB_COLOR', SNAME => 'SBREAKDOWN_PROB_COLOR',
SCAPTION => 'Цвет вероятности выхода из строя', SCAPTION => 'Цвет вероятности выхода из строя',
@ -526,7 +506,7 @@ text="Проверка прав доступа при формировании
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NBREAKDOWN_PROB', NVALUE => NBREAKDOWN_PROB); PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, SNAME => 'NBREAKDOWN_PROB', NVALUE => NBREAKDOWN_PROB);
PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW, PKG_P8PANELS_VISUAL.TDG_ROW_ADD_COL(RROW => RDG_ROW,
SNAME => 'SBREAKDOWN_PROB_COLOR', SNAME => 'SBREAKDOWN_PROB_COLOR',
SVALUE => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 1, NVALUE => NBREAKDOWN_PROB)); SVALUE => UDO_PKG_EQUIPDS.CMMLH_FORECAST_COLOR(NMODE => 1, NVALUE => NBREAKDOWN_PROB));
/* Добавляем строку в таблицу */ /* Добавляем строку в таблицу */
PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW); PKG_P8PANELS_VISUAL.TDG_ADD_ROW(RDATA_GRID => RDG, RROW => RDG_ROW);
end loop; end loop;
@ -850,7 +830,7 @@ text="Проверка прав доступа при формировании
into NCNT into NCNT
from FILE_BUFFER T from FILE_BUFFER T
where T.IDENT = NREQUEST_CONFIG_IDENT where T.IDENT = NREQUEST_CONFIG_IDENT
and T.BDATA is not null; and T.DATA is not null;
exception exception
when others then when others then
P_EXCEPTION(0, P_EXCEPTION(0,
@ -933,30 +913,73 @@ text="Проверка прав доступа при формировании
) )
is is
NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели NEQUIPDSCMMLH PKG_STD.TREF; -- Рег. номер истории запросов модели
BRQ blob; -- Описание параметров запроса на прогноз CRQ clob; -- Описание параметров запроса на прогноз
DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза (последняя)
NFORECAST_DAYS PKG_STD.TNUMBER; -- Прогноз (дней до выхода из строя на дату прогноза)
DBEG PKG_STD.TLDATE; -- Дата окончания интервала сбора данных для прогноза
DEND PKG_STD.TLDATE; -- Дата начала интервала сбора данных для прогноза
NINTERVAL PKG_STD.TLNUMBER; -- Размер (в днях) интервала измерения
XFORECAST PKG_XPATH.TDOCUMENT; -- XML-документ прогноза
XROOT PKG_XPATH.TNODE; -- Корневой элемент документа прогноза
XFCTS PKG_XPATH.TNODES; -- Массив предсказаний
XLAST_FCT PKG_XPATH.TNODE; -- Последний элемент массива предсказаний
NLAST PKG_STD.TNUMBER; -- Номер последней позиции массива предсказаний
NLAST_INTERVALS PKG_STD.TLNUMBER; -- Значение (количество интервалов измерения до выхода из строя) последней записи массива предсказаний
begin begin
/* Считаем параметры сделанного запроса */ /* Считаем параметры сделанного запроса */
begin begin
select T.BDATA select T.DATA
into BRQ into CRQ
from FILE_BUFFER T from FILE_BUFFER T
where T.IDENT = NREQUEST_CONFIG_IDENT where T.IDENT = NREQUEST_CONFIG_IDENT
and T.BDATA is not null; and T.DATA is not null;
exception exception
when NO_DATA_FOUND then when NO_DATA_FOUND then
P_EXCEPTION(0, 'Параметры запроса на прогнозирование не определёны.'); P_EXCEPTION(0,
'Параметры запроса на прогнозирование не определёны.');
when TOO_MANY_ROWS then when TOO_MANY_ROWS then
P_EXCEPTION(0, 'Параметры запроса на прогнозирование определёны неоднозначно.'); P_EXCEPTION(0,
'Параметры запроса на прогнозирование определёны неоднозначно.');
end; end;
/* Добавляем запись истории запросов */ /* Добавляем запись истории запросов */
UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML, UDO_PKG_EQUIPDS_BASE.CMMLH_INS(NPRN => NEQUIPDSCMML,
NEQCONFIG => NEQCONFIG, NEQCONFIG => NEQCONFIG,
SRQ_AUTHID => UTILIZER(), SRQ_AUTHID => UTILIZER(),
DRQ_DATE => sysdate, DRQ_DATE => sysdate,
BRQ => BRQ, BRQ => CLOB2BLOB(LCDATA => CRQ),
NRN => NEQUIPDSCMMLH); NRN => NEQUIPDSCMMLH);
/* Пробуем разобрать прогноз */
begin
/* Читаем параметры с которыми делался прогноз */
UDO_PKG_EQUIPDS_BASE.UTL_FORECAST_RQ_PARSE_CFG(CRQ_CFG => CRQ,
DBEG => DBEG,
DEND => DEND,
NINTERVAL => NINTERVAL);
/* Разбираем данные прогноза */
XFORECAST := PKG_XPATH.PARSE_FROM_BLOB(LBXML => BASE64_DECODE(LCSRCE => CFORECAST));
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XFORECAST);
XFCTS := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/XFORECAST');
/* Читаем последнее значение из массива предсказаний (оно соответствует дате окончания из параметров прогноза) */
NLAST := PKG_XPATH.COUNT_NODES(RNODES => XFCTS);
XLAST_FCT := PKG_XPATH.ITEM_NODE(RNODES => XFCTS, INUMBER => NLAST);
NLAST_INTERVALS := TO_CHAR(PKG_XPATH.VALUE(RNODE => XLAST_FCT, SPATTERN => 'SVALUE'));
if (NLAST_INTERVALS < 0) then
NLAST_INTERVALS := 0;
end if;
/* Освобождаем документ */
PKG_XPATH.FREE(RDOCUMENT => XFORECAST);
/* Сформируем дату прогноза и количество дней до выхода из строя на эту дату */
DFORECAST_DATE := DEND;
NFORECAST_DAYS := NINTERVAL * NLAST_INTERVALS;
exception
when others then
null;
end;
/* Сохраним данные прогноза */ /* Сохраним данные прогноза */
UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH, BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST)); UDO_PKG_EQUIPDS_BASE.CMMLH_SET_FORECAST(NRN => NEQUIPDSCMMLH,
BFORECAST => BASE64_DECODE(LCSRCE => CFORECAST),
DFORECAST_DATE => DFORECAST_DATE,
NFORECAST_DAYS => NFORECAST_DAYS);
/* Подчистим буферы */ /* Подчистим буферы */
EQCONFIG_THOBJ_FORECAST_BCLR(NDATASET_IDENT => NDATASET_IDENT, EQCONFIG_THOBJ_FORECAST_BCLR(NDATASET_IDENT => NDATASET_IDENT,
NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT, NDATASET_CONFIG_IDENT => NDATASET_CONFIG_IDENT,
@ -971,228 +994,6 @@ text="Проверка прав доступа при формировании
raise; raise;
end EQCONFIG_THOBJ_FORECAST_EPLG; end EQCONFIG_THOBJ_FORECAST_EPLG;
/* Формирование цвета прогноза для технического объекта */
function EQCONFIG_THOBJ_FORECAST_CLR
(
NMODE in number := 0, -- Режим работы (0 - для подсказки в колонке таблицы, 1 - для колонки таблицы, 2 - для карточки детализации
NVALUE in number :=0 -- Значение для подсветки
) return varchar2 -- Запрошенное значение в зависимости от режима
is
begin
/* Работаем от режима */
case NMODE
/* Для подсказки в колонке таблицы */
when 0 then
return '<b style="color:red">Опасность</b> - вероятность сбоя более 60%.<br>' || '<b style="color:orange">Внимание</b> - вероятность сбоя от 30% до 60%<br>' || '<b style="color:green">В норме</b> - вероятность сбоев менее 30%';
/* Для колонки таблицы */
when 1 then
begin
if (NVALUE < 30) then
return 'success';
else
if ((NVALUE >= 30) and (NVALUE < 60)) then
return 'warning';
else
return 'error';
end if;
end if;
end;
/* Для карточки детализации */
when 2 then
begin
if (NVALUE < 30) then
return 'success.main';
else
if ((NVALUE >= 30) and (NVALUE < 60)) then
return 'warning.main';
else
return 'error.main';
end if;
end if;
end;
/* Неверный режим */
else
return null;
end case;
end EQCONFIG_THOBJ_FORECAST_CLR;
/* Формирование детальной карточки прогноза для технического объекта */
procedure EQCONFIG_THOBJ_FORECAST_CRD
(
NEQCONFIG in number, -- Рег. номер позиции состава оборудования
DFORECAST_DATE in date, -- Дата получения прогноза
NFORECAST in number, -- Прогнозное значение, полученное от фреймворка
SDICMUNTS in varchar2, -- Единица измерения выборки
STASK in varchar2, -- Задача (см. константы UDO_PKG_EQUIPDS_BASE.CMML_TASK_*)
COUT out clob -- Данные детальной карточки прогноза
)
is
NCUR integer; -- Курсор документа для результата
XDOC PKG_XMAKE.TNODE; -- Документ для результата
XROOT PKG_XMAKE.TNODE; -- Содержимое корневого узла документа
RCH PKG_P8PANELS_VISUAL.TCHART; -- График
RCH_DS PKG_P8PANELS_VISUAL.TCHART_DATASET; -- Набор данных
CCHART clob; -- Сериализованный график
NBREAKDOWN_PROB PKG_STD.TNUMBER; -- Вероятность выхода из строя
NBREAKDOWN_PROB_CUR PKG_STD.TNUMBER; -- Вероятность выхода из строя (для текущей позиции графика ТО и ремонтов/рем. ведомости)
DNEXT_REPAIR PKG_STD.TLDATE; -- Дата ближайшего ТО и ремонта по графику/рем. ведомости
begin
/* Вычислим вероятность выхода из строя до даты ближайшего ТО/ремонта по графику или рем. ведомости с учётом прогноза */
DNEXT_REPAIR := EQCONFIG_THOBJ_GEN_NXTRPR(NEQCONFIG => NEQCONFIG);
if (DNEXT_REPAIR is null) then
NBREAKDOWN_PROB := 100;
else
if (sysdate + NFORECAST > DNEXT_REPAIR) then
NBREAKDOWN_PROB := 0;
end if;
end if;
/* Открываем документ */
NCUR := PKG_XMAKE.OPEN_CURSOR();
/* Заполним единицу измерения */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'SDICMUNTS',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, SVALUE => SDICMUNTS)));
/* Заполним прогноз */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'NFORECAST',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, NVALUE => NFORECAST)));
/* Заполним код задачи прогнозирования */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'STASK',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, SVALUE => STASK)));
/* Заполним наименование задачи прогнозирования */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'STASK_NAME',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => UDO_PKG_EQUIPDS_BASE.CMML_TASK_NAME(STASK => STASK))));
/* Заполним дату следующего ТО и ремонта */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'DNEXT_REPAIR',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
DVALUE => DNEXT_REPAIR)));
/* Если есть запланированные графики ТО и ремонта или ремонтные ведомости */
if (DNEXT_REPAIR is not null) then
/* Строим график вероятностей выхода из строя опираясь на них */
RCH := PKG_P8PANELS_VISUAL.TCHART_MAKE(STYPE => PKG_P8PANELS_VISUAL.SCHART_TYPE_LINE,
STITLE => 'Прогноз с учётом графика ТО и ремонтов/ремонтных ведомостей',
SLGND_POS => PKG_P8PANELS_VISUAL.SCHART_LGND_POS_TOP);
/* Сформируем набор данных */
RCH_DS := PKG_P8PANELS_VISUAL.TCHART_DATASET_MAKE(SCAPTION => 'Вероятность перехода в критическое состояние (%)');
/* Обходим ближайшие 5 позиций графика ТО и ремонтов или ремонтных ведомостей */
for C in (select ROWNUM,
D.DDATEPRD_BEG
from (select T.DDATEPRD_BEG
from (select P.DATEPRD_BEG DDATEPRD_BEG
from EQTCHSRV P
where P.EQCONFIG_TECH = NEQCONFIG
and P.DATEPRD_BEG >= sysdate
union
select R.DATEPLAN_BEG DDATEPRD_BEG
from EQRPSHEETS R
where R.EQCONFIG = NEQCONFIG
and R.DATEPLAN_BEG >= sysdate) T
order by T.DDATEPRD_BEG) D
where ROWNUM <= 5)
loop
/* Добавим метку для графика */
PKG_P8PANELS_VISUAL.TCHART_ADD_LABEL(RCHART => RCH, SLABEL => TO_CHAR(C.DDATEPRD_BEG, 'dd.mm.yyyy'));
/* Считаем вероятность выхода из строя в эту дату */
NBREAKDOWN_PROB_CUR := UDO_PKG_EQUIPDS_BASE.CMML_RUL_BREAKDOWN_PROB(NFORECAST => NFORECAST,
DFORECAST_DATE => DFORECAST_DATE,
DDATE => C.DDATEPRD_BEG);
/* Если ещё не фиксировали вероятность для первой даты - сделаем это */
if (NBREAKDOWN_PROB is null) then
NBREAKDOWN_PROB := NBREAKDOWN_PROB_CUR;
end if;
/* Добавим элемент в набор данных */
PKG_P8PANELS_VISUAL.TCHART_DATASET_ADD_ITEM(RDATASET => RCH_DS, NVALUE => NBREAKDOWN_PROB_CUR);
end loop;
/* Добавим набор данных в график */
PKG_P8PANELS_VISUAL.TCHART_ADD_DATASET(RCHART => RCH, RDATASET => RCH_DS);
/* Сериализуем график */
CCHART := PKG_P8PANELS_VISUAL.TCHART_TO_XML(RCHART => RCH, NINCLUDE_DEF => 1);
end if;
/* Заполним вероятность выхода из стороя до ближайшего ТО с учётом прогноза */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'NBREAKDOWN_PROB',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
NVALUE => NBREAKDOWN_PROB)));
/* Заполним цвет вероятности выхода из стороя до ближайшего ТО с учётом прогноза */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'SBREAKDOWN_PROB_COLOR',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR,
SVALUE => EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 2,
NVALUE => NBREAKDOWN_PROB))));
/* Добавляем график в ответ */
XROOT := PKG_XMAKE.CONCAT(ICURSOR => NCUR,
RNODE00 => XROOT,
RNODE01 => PKG_XMAKE.ELEMENT(ICURSOR => NCUR,
SNAME => 'XCHART',
RVALUE00 => PKG_XMAKE.VALUE(ICURSOR => NCUR, LCVALUE => CCHART)));
/* Формируем XML-представление ответа */
XDOC := PKG_XMAKE.ELEMENT(ICURSOR => NCUR, SNAME => 'XDATA', RNODE00 => XROOT);
/* Конвертируем в CLOB */
COUT := PKG_XMAKE.SERIALIZE_TO_CLOB(ICURSOR => NCUR,
ITYPE => PKG_XMAKE.CONTENT_,
RNODE => XDOC,
RHEADER => PKG_XHEADER.WRAP_ALL(SVERSION => PKG_XHEADER.VERSION_1_0_,
SENCODING => PKG_XHEADER.ENCODING_UTF_,
SSTANDALONE => PKG_XHEADER.STANDALONE_YES_));
/* Закрываем документ */
PKG_XMAKE.CLOSE_CURSOR(ICURSOR => NCUR);
end EQCONFIG_THOBJ_FORECAST_CRD;
/* Извлечение сведений из детальной карточки прогноза для технического объекта */
procedure EQCONFIG_THOBJ_FORECAST_CRDP
(
CFORECAST in clob, -- Данные детальной карточки прогноза
SFORECAST_DESC out varchar2, -- Описание прогноза
SFORECAST_DESC_COLOR out varchar2 -- Цвет заливки прогноза
)
is
XDOC PKG_XPATH.TDOCUMENT; -- Десериализованный демо-прогноз
XROOT PKG_XPATH.TNODE; -- Корневой элемент данных
SDICMUNTS PKG_STD.TSTRING; -- Единица измерения выборки
NFORECAST PKG_STD.TNUMBER; -- Прогноз по заданной задаче
NBREAKDOWN_PROB PKG_STD.TNUMBER; -- Вероятность выхода из строя
begin
/* Разбираем демо-даные */
XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => CFORECAST);
/* Извлекаем корневой элемент */
XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
/* Читаем единицу измерения */
SDICMUNTS := PKG_XPATH.VALUE(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/SDICMUNTS'));
/* Читаем прогноз */
NFORECAST := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT, SPATTERN => 'XDATA/NFORECAST'));
/* Читаем вероятность выхода из строя */
NBREAKDOWN_PROB := PKG_XPATH.VALUE_NUM(RNODE => PKG_XPATH.SINGLE_NODE(RPARENT_NODE => XROOT,
SPATTERN => 'XDATA/NBREAKDOWN_PROB'));
/* Проноз есть */
if (NFORECAST is not null) then
/* Возвращаем значение описания */
SFORECAST_DESC := TO_CHAR(ROUND(NFORECAST)) || SDICMUNTS || ' / ' || TO_CHAR(ROUND(NBREAKDOWN_PROB)) || '%';
/* Возвращаем значение цвета заливки описания прогноза */
SFORECAST_DESC_COLOR := EQCONFIG_THOBJ_FORECAST_CLR(NMODE => 1, NVALUE => NBREAKDOWN_PROB);
end if;
exception
when others then
null;
end EQCONFIG_THOBJ_FORECAST_CRDP;
/* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */ /* Вероятность выхода единицы оборудования из строя с учётом графика ТО и ремонтов и RUL-прогноза */
function EQCONFIG_THOBJ_TCHSRV_BRKDPROB function EQCONFIG_THOBJ_TCHSRV_BRKDPROB
( (
@ -1201,7 +1002,7 @@ text="Проверка прав доступа при формировании
is is
NRES PKG_STD.TNUMBER; -- Буфер для результата NRES PKG_STD.TNUMBER; -- Буфер для результата
DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза DFORECAST_DATE PKG_STD.TLDATE; -- Дата прогноза
NFORECAST PKG_STD.TNUMBER; -- Значение самго свежего прогноза модели NFORECAST_DAYS PKG_STD.TNUMBER; -- Значение самго свежего прогноза модели
DCALC_DATE PKG_STD.TLDATE; -- Дата расчета вероятности DCALC_DATE PKG_STD.TLDATE; -- Дата расчета вероятности
begin begin
/* Определим дату ближайшего ТО или ремонта */ /* Определим дату ближайшего ТО или ремонта */
@ -1209,8 +1010,8 @@ text="Проверка прав доступа при формировании
/* Если дата есть */ /* Если дата есть */
if (DCALC_DATE is not null) then if (DCALC_DATE is not null) then
/* Вынем самый свежий прогноз */ /* Вынем самый свежий прогноз */
for C in (select T.RQ_DATE DFORECAST_DATE, for C in (select T.FORECAST_DATE DFORECAST_DATE,
T.FORECAST T.FORECAST_DAYS NFORECAST_DAYS
from UDO_T_EQUIPDSCMMLH T, from UDO_T_EQUIPDSCMMLH T,
UDO_T_EQUIPDSCMML CMML UDO_T_EQUIPDSCMML CMML
where T.EQCONFIG = NEQCONFIG where T.EQCONFIG = NEQCONFIG
@ -1219,13 +1020,13 @@ text="Проверка прав доступа при формировании
order by T.RQ_DATE desc) order by T.RQ_DATE desc)
loop loop
DFORECAST_DATE := C.DFORECAST_DATE; DFORECAST_DATE := C.DFORECAST_DATE;
UDO_PKG_EQUIPDS.CMMLH_PARSE_FORECAST(CFORECAST => BLOB2CLOB(LBDATA => C.FORECAST), NFORECAST => NFORECAST); NFORECAST_DAYS := C.NFORECAST_DAYS;
exit; exit;
end loop; end loop;
/* Если есть и прогноз */ /* Если есть и прогноз */
if (NFORECAST is not null) then if (NFORECAST_DAYS is not null) then
NRES := UDO_PKG_EQUIPDS_BASE.CMML_RUL_BREAKDOWN_PROB(NFORECAST => NFORECAST, NRES := UDO_PKG_EQUIPDS_BASE.CMMLH_RUL_BREAKDOWN_PROB(DFORECAST_DATE => DFORECAST_DATE,
DFORECAST_DATE => DFORECAST_DATE, NFORECAST_DAYS => NFORECAST_DAYS,
DDATE => DCALC_DATE); DDATE => DCALC_DATE);
end if; end if;
end if; end if;
@ -1325,7 +1126,6 @@ text="Проверка прав доступа при формировании
SEQTECSRVKIND in varchar2, -- Вид ремонта SEQTECSRVKIND in varchar2, -- Вид ремонта
DPLANDATE_FROM in date, -- Плановая дата начала ремонта DPLANDATE_FROM in date, -- Плановая дата начала ремонта
NIDENT out number -- Идентификатор списка сформированных ведомостей NIDENT out number -- Идентификатор списка сформированных ведомостей
) )
is is
NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации NCOMPANY PKG_STD.TREF := GET_SESSION_COMPANY(); -- Рег. номер организации
@ -1372,8 +1172,8 @@ text="Проверка прав доступа при формировании
SNUMB => SNUMB, SNUMB => SNUMB,
DDOCDATE => sysdate, DDOCDATE => sysdate,
SJURPERSONS => SJURPERSONS, SJURPERSONS => SJURPERSONS,
DPLANDATE_FROM => DPLANDATE_FROM, DPLANDATE_FROM => TRUNC(DPLANDATE_FROM),
DPLANDATE_TO => DPLANDATE_FROM, DPLANDATE_TO => (TRUNC(DPLANDATE_FROM) + 1) - 1/24/60,
SCURRENCY => SCURRENCY, SCURRENCY => SCURRENCY,
NCOURSE => 1, NCOURSE => 1,
SEQTECSRVKIND => SEQTECSRVKIND, SEQTECSRVKIND => SEQTECSRVKIND,

View File

@ -9,6 +9,7 @@ create or replace procedure UDO_P_EQCONFIG_DATASET_MAKE
NREQUEST_CONFIG_IDENT out number -- Идентификатор буфера описания запроса NREQUEST_CONFIG_IDENT out number -- Идентификатор буфера описания запроса
) )
is is
CREQUEST_CONFIG clob; -- Буфер для описания запроса
begin begin
/* НАЧАЛО: Временная заглушка с отладочными данными (удалить) */ /* НАЧАЛО: Временная заглушка с отладочными данными (удалить) */
/* create table UDO_T_FILE_BUFFER as select * from FILE_BUFFER; */ /* create table UDO_T_FILE_BUFFER as select * from FILE_BUFFER; */
@ -25,6 +26,13 @@ begin
P_FILE_BUFFER_INSERT(NIDENT => NDATASET_IDENT, CFILENAME => C.FILENAME, CDATA => C.DATA, BLOBDATA => C.BDATA); P_FILE_BUFFER_INSERT(NIDENT => NDATASET_IDENT, CFILENAME => C.FILENAME, CDATA => C.DATA, BLOBDATA => C.BDATA);
end if; end if;
end loop; end loop;
/* Сформируем описание параметров выборки (ПРИ УДАЛЕНИИ ЗАГЛУШКИ ЭТО НАДО ОСТАВИТЬ) */
NREQUEST_CONFIG_IDENT := GEN_IDENT();
UDO_PKG_EQUIPDS_BASE.UTL_FORECAST_RQ_MAKE_CFG(DBEG => DBEG, DEND => DEND, NINTERVAL => 1, CRQ_CFG => CREQUEST_CONFIG);
P_FILE_BUFFER_INSERT(NIDENT => NREQUEST_CONFIG_IDENT,
CFILENAME => TO_CHAR(NREQUEST_CONFIG_IDENT) || '.xml',
CDATA => CREQUEST_CONFIG,
BLOBDATA => null);
return; return;
/* КОНЕЦ: Временная заглушка с отладочными данными (удалить) */ /* КОНЕЦ: Временная заглушка с отладочными данными (удалить) */
/* Обратимся к еденице оборудования */ /* Обратимся к еденице оборудования */

View File

@ -15,6 +15,10 @@ create table UDO_T_EQUIPDSCMMLH
RQ blob, RQ blob,
/* Данные прогноза */ /* Данные прогноза */
FORECAST blob, FORECAST blob,
/* Дата прогноза (последняя) */
FORECAST_DATE date default null,
/* Прогноз (дней до выхода из строя на дату прогноза) */
FORECAST_DAYS number(17) default null,
/* Ключи */ /* Ключи */
constraint UDO_C_EQUIPDSCMMLH_RN_PK primary key (RN), constraint UDO_C_EQUIPDSCMMLH_RN_PK primary key (RN),
constraint UDO_C_EQUIPDSCMMLH_PRN_FK foreign key (PRN) references UDO_T_EQUIPDSCMML(RN), constraint UDO_C_EQUIPDSCMMLH_PRN_FK foreign key (PRN) references UDO_T_EQUIPDSCMML(RN),

View File

@ -241,7 +241,7 @@ const ForecastTab = ({ onGoToAdmin }) => {
} catch (e) { } catch (e) {
throw new Error("Неожиданный ответ системы прогнозирования: ответ неверного формата."); throw new Error("Неожиданный ответ системы прогнозирования: ответ неверного формата.");
} }
if (response) { if (responseJson) {
if (responseJson?.status && responseJson.status == "ERR") if (responseJson?.status && responseJson.status == "ERR")
throw new Error(`Ошибка формирования прогноза: ${responseJson.message}`); throw new Error(`Ошибка формирования прогноза: ${responseJson.message}`);
if (responseJson?.forecast && Array.isArray(responseJson?.forecast)) { if (responseJson?.forecast && Array.isArray(responseJson?.forecast)) {
@ -254,7 +254,10 @@ const ForecastTab = ({ onGoToAdmin }) => {
NEQCONFIG: techObj.id, NEQCONFIG: techObj.id,
NEQUIPDSCMML: model.NRN, NEQUIPDSCMML: model.NRN,
CFORECAST: { CFORECAST: {
VALUE: object2Base64XML(responseJson, { arrayNodeName: "forecast" }), VALUE: object2Base64XML(
{ XDATA: { XFORECAST: responseJson.forecast.map(f => ({ STIME: f.time, SVALUE: f.value })) } },
{ arrayNodeName: "XFORECAST" }
),
SDATA_TYPE: SERV_DATA_TYPE_CLOB SDATA_TYPE: SERV_DATA_TYPE_CLOB
} }
}, },
@ -269,10 +272,11 @@ const ForecastTab = ({ onGoToAdmin }) => {
hideLoader(); hideLoader();
showMsgErr(e.message); showMsgErr(e.message);
executeStored({ executeStored({
stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_EPLG", stored: "UDO_PKG_EQUIPTCF.EQCONFIG_THOBJ_FORECAST_BCLR",
args: { args: {
NDATASET_IDENT: res.outParameters.NDATASET_IDENT, NDATASET_IDENT: res.outParameters.NDATASET_IDENT,
NDATASET_CONFIG_IDENT: res.outParameters.NDATASET_CONFIG_IDENT NDATASET_CONFIG_IDENT: res.outParameters.NDATASET_CONFIG_IDENT,
NREQUEST_CONFIG_IDENT: res.outParameters.NREQUEST_CONFIG_IDENT
}, },
loader: false, loader: false,
showErrorMessage: false, showErrorMessage: false,