[BugWrong]
Не происходит сохраниние в БД значений расчитанных по флагу f_stop;
Автор |
Повідомлення |
Повідомлення створено: 15. 10. 2013 [13:17]
|
aleax
Alexey Bondarchuk
Автор теми
Зареєстрован(а) с: 27.01.2010
Повідомлення: 73
|
Система:
OpenSCADA 0.8.0.8 svn 2006
sqlite3 3.7.17
Debian 7.2; amd64
Создал шаблон и парметр логического контроллера со следующей программой:
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.
В настройках проекта опция "сохранять систему при выходе" включена.
Прилагаю архив в тестовым проектом.
[Повідомлення редагувалось 1 раз(ів), останній раз 15.10.2013 в 13:17.]
Вкладений файл
|
Повідомлення створено: 15. 10. 2013 [15:52]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зареєстрован(а) с: 12.12.2007
Повідомлення: 3750
|
"aleax" wrote:
Значения не равны тому, что было рассчитано на последней итерации программы. Собственно в первую очередь интересует сохранение тех значений, с которыми производятся вычисления по флагу f_stop.
Собственно это не ошибка, а порядок такой.
Сохранение по опции "Сохранять при выходе" происходит непосредственно перед вызовом глобальной остановки системы, и это логично поскольку это последняя точка когда все данные есть и они актуальны. Сам-же процесс остановки и последний вызов с установкой флага "f_stop" никогда не рассматривался как производственный и данные полученные в его результате актуальными к типовому состоянию объекта.
Кроме того это технически проблематично, точнее нужно пропускать основной цикл сохранения, а сохранять непосредственно из контекста объекта контроллера, сразу после остановки, когда контекст данных ещё доступен и объект не помечен как остановлен (иначе все атрибуты станут EVAL). Возвращаясь к формулировке непроизводительности последнего вызова я необходимости в этом не вижу, да и как-то ни разу не нужно такое было.
Learn, learn and learn better than work, work and work.
|
Повідомлення створено: 15. 10. 2013 [17:04]
|
aleax
Alexey Bondarchuk
Автор теми
Зареєстрован(а) с: 27.01.2010
Повідомлення: 73
|
Ну в принципе понятно. Просто функционал f_stop воспринимался как некоторый "деструктор" в котором можно было бы сделать какие-то операции, при завершении работы. Значит сохранение в БД не входит в перечень этих операций.
Тогда такой вопрос. Можно ли исключить некоторые переменные из сохранения в БД (таблица_io), при этом оставив их доступными для, например, построения связей с ними?
|
Повідомлення створено: 15. 10. 2013 [19:27]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зареєстрован(а) с: 12.12.2007
Повідомлення: 3750
|
"aleax" wrote:
Ну в принципе понятно. Просто функционал f_stop воспринимался как некоторый "деструктор" в котором можно было бы сделать какие-то операции, при завершении работы. Значит сохранение в БД не входит в перечень этих операций.
Сохранение в БД прямо с вычислением и не связано. Кстати, можно сохранить из f_stop, если очень хочется, прямо вызвав такую команду.
"aleax" wrote:
Тогда такой вопрос. Можно ли исключить некоторые переменные из сохранения в БД (таблица_io), при этом оставив их доступными для, например, построения связей с ними?
Странное желание!
Если будете в f_start эти переменные инициировать в дефолтные значение то желаемый результат и получите.
Learn, learn and learn better than work, work and work.
|
Повідомлення створено: 16. 10. 2013 [14:48]
|
aleax
Alexey Bondarchuk
Автор теми
Зареєстрован(а) с: 27.01.2010
Повідомлення: 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’е.
|
Повідомлення створено: 16. 10. 2013 [19:30]
|
roman
Roman Savochenko
Moderator Contributor Developer
Зареєстрован(а) с: 12.12.2007
Повідомлення: 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.
|
Повідомлення створено: 16. 10. 2013 [20:32]
|
aleax
Alexey Bondarchuk
Автор теми
Зареєстрован(а) с: 27.01.2010
Повідомлення: 73
|
"roman" wrote:
Надо попробовать, как БД переходит из фазы dump и обратно, может тогда в репозитории проекта их в виде дампа и хранить.
Мы в репозитории храним в бинарном виде, но через хуки имеем удобный дифф. Вот те скрипты и настройки для гита, которые мы используем.
Фактически процесс разработки и внедрения выглядит следующим образом:
1) Разработка с фиксированием прогресса в git’е
2) На "релиз" назначается git tag
3) Скрипт обертка над git archive создает tar.gz архив с проектом по заданному тегу (уже без истории разработки)
4) Скрипт обертка над dpkg -b создает deb пакет из tar.gz который и ставиться заказчику
5) В случае необходимости у заказчика снимается рабочая директория, копируется с перезаписью в репозиторий, ну и по git diff видно что поменялось
в сравнении с последним коммитом (либо заданным тегом/веткой, и т.д.)
Потому, что б иметь в репозитории рабочую БД, а не её дамп, в нем собственно БД и храниться в исходном виде.
|
|
|