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

[BugWrong] Не происходит сохраниние в БД значений расчитанных по флагу f_stop;


Author Message
Written on: 15. 10. 2013 [13:17]
aleax
Alexey Bondarchuk
Topic creator
registered since: 27.01.2010
Posts: 73
Система:
OpenSCADA 0.8.0.8 svn 2006
sqlite3 3.7.17
Debian 7.2; amd64

Создал шаблон и парметр логического контроллера со следующей программой:
JAVASCRIPT
t_f_start_only	t_f_start_only	Целый	Вход	Только чтение	Константа	0
t_f_stop_only	t_f_stop_only	Целый	Вход	Только чтение	Константа	0
t_not_clean	t_not_clean	Целый	Вход	Только чтение	Константа	0
t_clean	t_clean	Целый	Вход	Только чтение	Константа	0
f_start	Флаг запуска функции	Логический	Вход	Не атрибут	Константа	0
f_stop	Флаг останова функции	Логический	Вход	Не атрибут	Константа	0
f_frq	Частота обсчёта функции (Гц)	Вещественный	Вход	Не атрибут	Константа	1000
f_err	Ошибка функции	Строка	Вход	Не атрибут	Константа	0
 
using Special.FLibSYS;
 
if (f_start)
{
	t_f_start_only=tmTime();
	t_clean=0;
}
 
t_not_clean=tmTime();
t_clean=tmTime();
 
if (f_stop)
{
	t_f_stop_only=tmTime();
	t_clean=0;
}
 
SYS.messDebug("","f_start="+f_start+" f_stop="+f_stop+" t_f_start_only="+t_f_start_only+" t_f_stop_only="+t_f_stop_only+" t_not_clean="+t_not_clean+" t_clean="+t_clean);


Переменная t_f_start_only вычисляется только при старте (f_start=true);
переменная t_f_stop_only вычисляется только при останове (f_іещз=true);
переменная t_not_clean вычисляется каждый раз;
переменная t_clean при старте и останове обнуляется, в "основном цикле" программы вычисляется также как и t_not_clean.

При тестовом запуске и последующем завершении работы системы наблюдаю в терминале следующий вывод (несущественные строки упущены):

~/work/openscada/test/f_start_stop_test $ openscada --Config="./oscada.xml" pts/6
1|/WorkStation/ | Загрузка!
1|/WorkStation/sub_DAQ/mod_DAQGate/ | Подключение модуля.
1|/WorkStation/sub_Transport/mod_Sockets/ | Подключение модуля.
<skip>
1|/WorkStation/sub_Transport/mod_SSL/ | Подключение модуля.
1|/WorkStation/sub_DAQ/mod_LogicLev/cntr_S1/ | Загрузка конфигурации контроллера!
1|/WorkStation/sub_UI/mod_VCAEngine/ | Загрузка модуля.
1|/WorkStation/sub_UI/mod_VCAEngine/wlb_originals/ | Загрузка библиотеки виджетов.
1|/WorkStation/sub_UI/mod_VCAEngine/wlb_originals/ | Включение библиотеки виджетов.
1|/WorkStation/ | Запуск!
1|/WorkStation/sub_Transport/ | Пуск подсистемы.
1|/WorkStation/sub_DAQ/mod_LogicLev/cntr_S1/ | Включение контроллера!
1|/WorkStation/sub_Archive/ | Пуск/обновление подсистемы.
3|/WorkStation/ | Нет доступа для создания политики реального времени для 'sub_Archive.vals'. Создан поток по умолчанию!
3|/WorkStation/ | Нет доступа для создания политики реального времени для 'sub_DAQ.redundant'. Создан поток по умолчанию!
1|/WorkStation/sub_DAQ/mod_LogicLev/cntr_S1/ | Запуск контроллера!
0| | f_start=1 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829654 t_clean=1381829654
1|/WorkStation/sub_Archive/ | Пуск/обновление подсистемы.
1|/WorkStation/sub_UI/mod_VCAEngine/ | Старт модуля.
1|/WorkStation/ | Запуск завершён!
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829654 t_clean=1381829654
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829655 t_clean=1381829655
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829656 t_clean=1381829656
1|/WorkStation/ | Останов!
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829658 t_clean=1381829658
1|/WorkStation/sub_UI/mod_VCAEngine/ | Останов модуля.
1|/WorkStation/sub_Archive/ | Останов подсистемы.
1|/WorkStation/sub_DAQ/mod_LogicLev/cntr_S1/ | Останов контроллера!
0| | f_start=0 f_stop=1 t_f_start_only=1381829654 t_f_stop_only=1381829658 t_not_clean=1381829658 t_clean=0
1|/WorkStation/sub_DAQ/mod_LogicLev/cntr_S1/ | Отключение контроллера!
1|/WorkStation/sub_Transport/ | Останов подсистемы.
1|/WorkStation/sub_DAQ/ | Отключение модуля 'DAQGate'!
1|/WorkStation/sub_Transport/ | Отключение модуля 'Sockets'!
<skip>
1|/WorkStation/sub_Transport/ | Отключение модуля 'SSL'!
OpenSCADA system is correctly exited by cause 10.


Как видим, вычисления происходят так, как мы ожидаем, и на последнем "шаге" мы имеем правильные значения переменных.

0| | f_start=1 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829654 t_clean=1381829654
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829654 t_clean=1381829654
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829655 t_clean=1381829655
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829656 t_clean=1381829656
1|/WorkStation/ | Останов!
0| | f_start=0 f_stop=0 t_f_start_only=1381829654 t_f_stop_only=0 t_not_clean=1381829658 t_clean=1381829658
1|/WorkStation/sub_UI/mod_VCAEngine/ | Останов модуля.
1|/WorkStation/sub_Archive/ | Останов подсистемы.
1|/WorkStation/sub_DAQ/mod_LogicLev/cntr_S1/ | Останов контроллера!
0| | f_start=0 f_stop=1 t_f_start_only=1381829654 t_f_stop_only=1381829658 t_not_clean=1381829658 t_clean=0


После завершения работы скады получаем содержимое соответствующей "io" таблицы БД:

sqlite3 DATA/MainSt.db 'SELECT * FROM "LogLevPrm_S1_io";'
P1|t_f_start_only|1381829654
P1|t_f_stop_only|0
P1|t_not_clean|1381829656
P1|t_clean|1381829656
P1|f_start|0
P1|f_stop|0
P1|f_frq|1
P1|f_err|0


Значения не равны тому, что было рассчитано на последней итерации программы. Собственно в первую очередь интересует сохранение тех значений, с которыми производятся вычисления по флагу f_stop.

В настройках проекта опция "сохранять систему при выходе" включена.
Прилагаю архив в тестовым проектом.


[This article was edited 1 times, at last 15.10.2013 at 13:17.]
Attachment

f_start_stop_test.tar.gz (File type: application/x-tar-gz, Size: 942.62 kilobytes) — 1650 downloads
Written on: 15. 10. 2013 [15:52]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"aleax" wrote:

Значения не равны тому, что было рассчитано на последней итерации программы. Собственно в первую очередь интересует сохранение тех значений, с которыми производятся вычисления по флагу f_stop.

Собственно это не ошибка, а порядок такой.

Сохранение по опции "Сохранять при выходе" происходит непосредственно перед вызовом глобальной остановки системы, и это логично поскольку это последняя точка когда все данные есть и они актуальны. Сам-же процесс остановки и последний вызов с установкой флага "f_stop" никогда не рассматривался как производственный и данные полученные в его результате актуальными к типовому состоянию объекта.

Кроме того это технически проблематично, точнее нужно пропускать основной цикл сохранения, а сохранять непосредственно из контекста объекта контроллера, сразу после остановки, когда контекст данных ещё доступен и объект не помечен как остановлен (иначе все атрибуты станут EVAL). Возвращаясь к формулировке непроизводительности последнего вызова я необходимости в этом не вижу, да и как-то ни разу не нужно такое было.

Learn, learn and learn better than work, work and work.
Written on: 15. 10. 2013 [17:04]
aleax
Alexey Bondarchuk
Topic creator
registered since: 27.01.2010
Posts: 73
Ну в принципе понятно. Просто функционал f_stop воспринимался как некоторый "деструктор" в котором можно было бы сделать какие-то операции, при завершении работы. Значит сохранение в БД не входит в перечень этих операций.

Тогда такой вопрос. Можно ли исключить некоторые переменные из сохранения в БД (таблица_io), при этом оставив их доступными для, например, построения связей с ними?
Written on: 15. 10. 2013 [19:27]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"aleax" wrote:

Ну в принципе понятно. Просто функционал f_stop воспринимался как некоторый "деструктор" в котором можно было бы сделать какие-то операции, при завершении работы. Значит сохранение в БД не входит в перечень этих операций.

Сохранение в БД прямо с вычислением и не связано. Кстати, можно сохранить из f_stop, если очень хочется, прямо вызвав такую команду.

"aleax" wrote:

Тогда такой вопрос. Можно ли исключить некоторые переменные из сохранения в БД (таблица_io), при этом оставив их доступными для, например, построения связей с ними?

Странное желание!
Если будете в f_start эти переменные инициировать в дефолтные значение то желаемый результат и получите.

Learn, learn and learn better than work, work and work.
Written on: 16. 10. 2013 [14:48]
aleax
Alexey Bondarchuk
Topic creator
registered since: 27.01.2010
Posts: 73
"roman" wrote:

Сохранение в БД прямо с вычислением и не связано. Кстати, можно сохранить из f_stop, если очень хочется, прямо вызвав такую команду.

Вызвав через XML-реквест сохранения в БД, или как?

"roman" wrote:

Странное желание!
Если будете в f_start эти переменные инициировать в дефолтные значение то желаемый результат и получите.

Действительно, на самом деле хочется странного :)

В общем суть идеи была такова.
Есть некая БД "configProj.db".
В ней "живут" контроллеры логического уровня, и их параметры (много ~=500). Некоторые из атрибутов используются для хранения данных (уставки, границы, и т.п.), в других — результаты вычислений, которые уже идут "наверх" в GUI. Вопросов с начальной инициализацией нет. По f_start’у все приводится к нужному виду.

Но тут, захотелось странного.
Сам проект (файлы БД, xml-конфиг, вспомогательные shell-скрипты, и т.п.) мы храним в системе контроля версий git.
Для более человечной работы с бинарными файлами БД повесили хуки на действия diff и merge для файлов данного типа, в которых производится дамб БД в текстовый файл, ну и diff понему достаточно информативен и полезен. И все вроде хорошо).

Но тут, захотелось странного :-)
При импорте файла "configProj.db" из продакшина мы можем с помощью git diff посмотреть какие параметры (да и что вообще) менялись по сравнению с предыдущей версией этого фала.
Отлично видно изменённые параметры уставок, границ и т.п., т.е. все что может меняться в процессе эксплуатации системы.
Но, кроме того, тут же вылазят и изменения тех атрибутов, в которых лежат результаты вычислений, которые точки зрения логики работы будут все-равно инициализированы по f_start.
Но с точки зрения удобства просмотра — они замусоривают вывод diff.

Ну и я решил попробовать по f_stop, возвращать атрибуты с вычислениями к начальному состоянию, в надежде, что при сохранении они запишутся в БД, ну и соответственно не будут вылазить в diff’е.
Written on: 16. 10. 2013 [19:30]
roman
Roman Savochenko
Moderator
Contributor
Developer
registered since: 12.12.2007
Posts: 3750
"aleax" wrote:

"roman" wrote:

Сохранение в БД прямо с вычислением и не связано. Кстати, можно сохранить из f_stop, если очень хочется, прямо вызвав такую команду.

Вызвав через XML-реквест сохранения в БД, или как?

Ну да, команду "save". Только сейчас она скорее всего не сработает, поскольку изменение объекта помечается после самого вычисления, команда "save" для неименённого объекта не будет иметь эффекта. Добавил аргумент "force" для принудительного сохранения, независимо от факта изменения, в конце недели выгружу в рабочую версию. Но попробовать можете.

"aleax" wrote:

...
Отлично видно изменённые параметры уставок, границ и т.п., т.е. все что может меняться в процессе эксплуатации системы.
Но, кроме того, тут же вылазят и изменения тех атрибутов, в которых лежат результаты вычислений, которые точки зрения логики работы будут все-равно инициализированы по f_start.
Но с точки зрения удобства просмотра — они замусоривают вывод diff.

Из таких соображений сохранение не рассматривалось, хотя в одном из проектов такая проблема поднималась, почему и метка времени в объекты с процедурами была добавлена, что-бы отслеживать факт последнего изменения и актуальность.

Надо попробовать, как БД переходит из фазы dump и обратно, может тогда в репозитории проекта их в виде дампа и хранить.

"aleax" wrote:

Ну и я решил попробовать по f_stop, возвращать атрибуты с вычислениями к начальному состоянию, в надежде, что при сохранении они запишутся в БД, ну и соответственно не будут вылазить в diff’е.

OK, попробуйте.

Learn, learn and learn better than work, work and work.
Written on: 16. 10. 2013 [20:32]
aleax
Alexey Bondarchuk
Topic creator
registered since: 27.01.2010
Posts: 73
"roman" wrote:

Надо попробовать, как БД переходит из фазы dump и обратно, может тогда в репозитории проекта их в виде дампа и хранить.


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

Фактически процесс разработки и внедрения выглядит следующим образом:
1) Разработка с фиксированием прогресса в git’е
2) На "релиз" назначается git tag
3) Скрипт обертка над git archive создает tar.gz архив с проектом по заданному тегу (уже без истории разработки)
4) Скрипт обертка над dpkg -b создает deb пакет из tar.gz который и ставиться заказчику
5) В случае необходимости у заказчика снимается рабочая директория, копируется с перезаписью в репозиторий, ну и по git diff видно что поменялось
в сравнении с последним коммитом (либо заданным тегом/веткой, и т.д.)

Потому, что б иметь в репозитории рабочую БД, а не её дамп, в нем собственно БД и храниться в исходном виде.



3127