EnglishУкраїнськаmRussian
Login/New
Topic with no new replies

автоматически отчеты о цикле


Author Message
Written on: 16. 09. 2017 [23:38]
arcsin
Аркадий Кисель
Contributor
Topic creator
registered since: 17.02.2017
Posts: 77
объект автоматизации: паровой автоклав. в каждом цикле есть определенные состояния в зависимости от температуры и времени. номер состояния я получаю из контроллера. по окончанию цикла надо сгенерировать отчет похожий на Таблица мгновенных значений, но в состояниях 2,4 период должен быть 60сек, а в состоянии №3 - 10 сек.

в контроллере логического уровня я могу отследить время каждого перехода. как лучше поступить дальше? если генерацию отчета организовать в JavaLikeCalc? то как организовать его "одиночный" запуск? есть ли смысл как-то привязываться к Таблице мгновенных значений?

просматривать из скады эти отчеты не нужно.
Written on: 17. 09. 2017 [09:50]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"arcsin" wrote:

в контроллере логического уровня я могу отследить время каждого перехода. как лучше поступить дальше? если генерацию отчета организовать в JavaLikeCalc? то как организовать его "одиночный" запуск? есть ли смысл как-то привязываться к Таблице мгновенных значений?

просматривать из скады эти отчеты не нужно.

Если просматривать не нужно то зачем таблица мгновенных значений и что такое "одиночный" запуск" в этом контексте?
Вообще читайте документацию!

Learn, learn and learn better than work, work and work.
Written on: 20. 09. 2017 [02:50]
arcsin
Аркадий Кисель
Contributor
Topic creator
registered since: 17.02.2017
Posts: 77
получилось сделать csv файл в javalikecalc, эту функцию планирую вызывать из LogicLev. будет ли влиять генерация отчета на время выполнения процедуры в LogicLev, или оно по умолчанию создается "отдельным потоком"? вызываю типа такого:
JAVASCRIPT
DAQ.JavaLikeCalc.Avtoklav.report(1,2,3,4);
т.е. не создаю контроллер в JavaLikeCalc.
и еще вопрос как получить pdf из таблицы? вижу несколько вариантов csv -> LibreOffice Calc -> pdf, tex -> pdflatex -> pdf, html -> браузер/конвертер -> pdf. вроде бы каждый вариант в теории рабочий, но может кто-то уже решал такую задачу.
Written on: 20. 09. 2017 [09:15]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"arcsin" wrote:

получилось сделать csv файл в javalikecalc, эту функцию планирую вызывать из LogicLev. будет ли влиять генерация отчета на время выполнения процедуры в LogicLev, или оно по умолчанию создается "отдельным потоком"?

Отдельный поток это отдельный объект контроллера LogicLev, как собственно и любого объекта контроллера источника данных, соответственно все объекты параметров этого контроллера выполняются последовательно в том потоке, о чём и говорит статус выполнения.

"arcsin" wrote:

и еще вопрос как получить pdf из таблицы? вижу несколько вариантов csv -> LibreOffice Calc -> pdf, tex -> pdflatex -> pdf, html -> браузер/конвертер -> pdf. вроде бы каждый вариант в теории рабочий, но может кто-то уже решал такую задачу.

LibreOffice по нормальному из командной строки CSV не разбирает, во всяком случае я не видел. Неплохо преобразовывает из HTML, хотя только для "чистых", скрытые теги он показывает, а рамки таблиц не берёт из CSS.

Learn, learn and learn better than work, work and work.
Written on: 29. 09. 2017 [00:17]
arcsin
Аркадий Кисель
Contributor
Topic creator
registered since: 17.02.2017
Posts: 77
сделал отчет чере latex.

результат приложил. из основных преимуществ по сравнению с html: дублирование шапки таблицы на каждом листе, нумерация листов.

установка дистрибутив openscada(debian)
sudo apt-get update
sudo apt-get install texlive-base
sudo apt-get install texlive-latex-base
sudo apt-get install texlive-lang-cyrillic
sudo apt-get install texlive-fonts-recommended

всего 200 мб.




JAVASCRIPT
using Special.FLibSYS;
 
time1++;time2++;time3++;time4++;
 
//var Curtime = SYS.time();
path_tmp = "/tmp/LaTeX_Reports/";
path_rep = "/home/scada/Reports/" + Special.FLibSYS.tmFStr(time1,"%Y/%m_%B")+"/";
 
test=sysCall("mkdir -p "+path_tmp);
test=sysCall("mkdir -p "+path_rep+"pdf/");
 
var fileName = Special.FLibSYS.tmFStr(time1,"%Y-%m-%d-%H-%M-%S");
 
 
function getRow_tex (time) 
{
	temperature = Special.FLibSYS.str2real(DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Temperature1",time,1));
	temperatureWMax = 122.0;//DAQ.JavaLikeCalc.lib_Avtoklav.getVal("",time,1);
	temperatureWMin = 121.0;//DAQ.JavaLikeCalc.lib_Avtoklav.getVal("",time,1);
	status = Special.FLibSYS.str2int(DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.status",time,0));
	Row = Special.FLibSYS.tmFStr(time,"%H:%M:%S")+" \& ";
	Row +=DAQ.JavaLikeCalc.lib_Avtoklav.status2str(status)+" \& ";
	Row +=Special.FLibSYS.tmFStr(
				DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.LogicLev.time_rel.time_rel.time_rel",time,0),"%M:%S")+" \& ";
 
	if((temperature > temperatureWMax) || ((temperature < temperatureWMin)&&(status == 3)))
		Row +="\textbf{"+DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Temperature1",time,1)+"} \& ";
	else	
		Row +=DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Temperature1",time,1)+" \& ";
	Row +=DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Pressure",time,2);
	Row+=" \endline \n";
	Row+=" \hline \n";
 
return Row; 
}
var mode = DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.mode",time1,0);
var mode_str = DAQ.JavaLikeCalc.lib_Avtoklav.mode2str(mode);
var saveFile=
"\documentclass[a4paper,12pt]{report} \n"+
"\usepackage[a4paper,vmargin=2cm,hmargin=1cm]{geometry} \n"+
"\usepackage[T2A]{fontenc} \n"+
"\usepackage[utf8]{inputenc} \n"+
"\usepackage[russian]{babel} \n"+
"\usepackage{longtable} \n"+
" \n"+
"\begin{document} \n"+
"\begin{center} \n"+
"\setlength{\parskip}{0.5cm} %Расстояние между абзацами \n"+
"{\huge ОТЧЕТ О ПРОПАРКЕ} \n"+
" \n"+
"{\Large Дата:"+Special.FLibSYS.tmFStr(time1,"%Y-%m-%d")+"}\n"+
"{\Large Режим:"+mode_str+"} \n"+
" \n"+
"{\Large Начало прогрева: "+Special.FLibSYS.tmFStr(time1,"%H:%M:%S")+"} \n"+
" \n"+
"\begin{longtable}{|*5{p{3cm}|}} \n"+
"\hline \n"+
"{\bf Время} & {\bf Состояние} & {\bf Время сост.} & {\bf Температура} & {\bf Давление} \endline \hline \n"+
"%%\endfirsthead \n"+
"\endhead \n";
 
for(time=time1;time<time2;time+=60)
{
	saveFile+=getRow_tex(time);
}
for(time=time2;time<time3;time+=10)
{
	saveFile+=getRow_tex(time);
}
for(time=time3;time<time4;time+=60)
{
	saveFile+=getRow_tex(time);
}
saveFile+=
"\hline \n"+
"\end{longtable} \n"+
"\end{center} \n"+
"\end{document} \n";
 
SYS.fileWrite(path_tmp+"report.tex",saveFile);
test=sysCall("cd "+path_tmp+"; pdflatex "+path_tmp+"report.tex");
 
test=sysCall("mv "+path_tmp+"report.pdf "+path_rep+"pdf/"+fileName+".pdf");
 
return test;



ЗЫ 1) запятую в числах получаю в измененной функции getVal c помощью strParse.
2)по поводу импорта из csv с точкой в текстовый процессорах: excel не спрашивает локаль, и импортирует с точкой. libreoffice спрашивает, и с английской локалью импортирует норм
Attachment

report.pdf (File type: application/pdf, Size: 32 kilobytes) — 1307 downloads
report.tex (File type: application/octet-stream, Size: 5.11 kilobytes) — 1583 downloads
Written on: 30. 09. 2017 [10:30]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"arcsin" wrote:

...
ЗЫ 1) запятую в числах получаю в измененной функции getVal c помощью strParse.
2)по поводу импорта из csv с точкой в текстовый процессорах: excel не спрашивает локаль, и импортирует с точкой. libreoffice спрашивает, и с английской локалью импортирует норм


Прокомментирую:
- Всё, что Вы использовали из "Special.FLibSYS", есть в прямо в ядре по "SYS".
- Запятую можно подставить простой заменой точки, функцией "replace()".
- Про Excel особенностей не знаю ибо нет такого. :)

А в целом это нормально.

Learn, learn and learn better than work, work and work.
Written on: 30. 09. 2017 [22:59]
arcsin
Аркадий Кисель
Contributor
Topic creator
registered since: 17.02.2017
Posts: 77
Роман, спасибо за комментарии. :)
с replace() НАМНОГО лучше и красивее. искал его, но первым попался вариант с позицией, и посчитал что другого варианта нет.
ушел от своего getVal в библиотеке. завернул стандартную функцию в обертку.

JAVASCRIPT
var logFile = ""; 
path_tmp = "/tmp/LaTeX_Reports/";
path_rep = "/home/scada/Reports/" + SYS.strftime(time1,"%Y/%m_%B")+"/";
 
logFile+=SYS.system("mkdir -p "+path_tmp)+"\n\n";
logFile+=SYS.system("mkdir -p "+path_rep+"pdf/")+"\n\n";
 
var fileName = SYS.strftime(time1,"%Y-%m-%d-%H-%M-%S");
 
 
function getVal(addr,time,prec)
{
	archtor = "FSArch.1s";
	uTime = 0;
	strong = false;
	return DAQ.JavaLikeCalc.lib_doc.getVal(addr,time,uTime,prec,archtor,strong);
}
 
 
 
function getRow_tex (time) 
{
	temperature = (getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Temperature1",time,1));
	temperatureWMax = 122.0;//DAQ.JavaLikeCalc.lib_Avtoklav.getVal("",time,1);
	temperatureWMin = 121.0;//DAQ.JavaLikeCalc.lib_Avtoklav.getVal("",time,1);
	status = (getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.status",time,0));
	Row = SYS.strftime(time,"%H:%M:%S")+" \& ";
	Row +=DAQ.JavaLikeCalc.lib_Avtoklav.status2str(status)+" \& ";
	Row +=SYS.strftime(getVal("DAQ.LogicLev.time_rel.time_rel.time_rel",time,0),"%M:%S")+" \& ";
 
	if((temperature >= temperatureWMax) || ((temperature < temperatureWMin)&&(status == "3")))
		Row +="\textbf{"+getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Temperature1",time,1)+"} \& ";
	else	
		Row +=getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Temperature1",time,1)+" \& ";
	Row +=getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.Pressure",time,2);
	Row+=" \endline \n";
	Row+=" \hline \n";
 
return Row.replace(".",","); 
}
var mode = DAQ.JavaLikeCalc.lib_Avtoklav.getVal("DAQ.ModBus.Avtoklav.Owen_PLC63.mode",time1,0);
var mode_str = DAQ.JavaLikeCalc.lib_Avtoklav.mode2str(mode);
var saveFile=
"\documentclass[a4paper,12pt]{report} \n"+
"\usepackage[a4paper,vmargin=2cm,hmargin=1cm]{geometry} \n"+
"\usepackage[T2A]{fontenc} \n"+
"\usepackage[utf8]{inputenc} \n"+
"\usepackage[russian]{babel} \n"+
"\usepackage{longtable} \n"+
" \n"+
"\begin{document} \n"+
"\begin{center} \n"+
"\setlength{\parskip}{0.5cm} %Расстояние между абзацами \n"+
"{\huge ОТЧЕТ О ПРОПАРКЕ} \n"+
" \n"+
"{\Large Дата:"+SYS.strftime(time1,"%Y-%m-%d")+"}\n"+
"{\Large Режим:"+mode_str+"} \n"+
" \n"+
"{\Large Начало прогрева: "+SYS.strftime(time1,"%H:%M:%S")+"} \n"+
" \n"+
"\begin{longtable}{|*5{p{3cm}|}} \n"+
"\hline \n"+
"{\bf Время} & {\bf Состояние} & {\bf Время сост.} & {\bf Температура} & {\bf Давление} \endline \hline \n"+
"%%\endfirsthead \n"+
"\endhead \n";
 
for(time=time1;time<time2;time+=60)
{
	saveFile+=getRow_tex(time);
}
for(time=time2;time<time3;time+=10)
{
	saveFile+=getRow_tex(time);
}
for(time=time3;time<time4;time+=60)
{
	saveFile+=getRow_tex(time);
}
saveFile+=
//"\hline \n"+
"\end{longtable} \n"+
"\end{center} \n"+
"\end{document} \n";
 
logFile+=SYS.fileWrite(path_tmp+"report.tex",saveFile)+"\n\n";
 
logFile+=SYS.system("cd "+path_tmp+"; pdflatex "+path_tmp+"report.tex");
 
logFile+=SYS.system("mv "+path_tmp+"report.pdf "+path_rep+"pdf/"+fileName+".pdf");
return SYS.fileWrite(path_tmp+fileName+".oscada.log");


[This article was edited 1 times, at last 05.10.2017 at 00:20.]



17116